Skip to content

Commit 0f24833

Browse files
committed
Added "How to Use a Custom Version Strategy for Assets"
1 parent 42598a7 commit 0f24833

File tree

2 files changed

+219
-16
lines changed

2 files changed

+219
-16
lines changed

frontend/custom_version_strategy.rst

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
.. index::
2+
single: Asset; Custom Version Strategy
3+
4+
How to Use a Custom Version Strategy for Assets
5+
===============================================
6+
7+
.. versionadded:: 3.1
8+
Support for custom version strategies was introduced in Symfony 3.1.
9+
10+
Asset versioning is a technique that improves the performance of web
11+
applications by adding a version identifier to the URL of the static assets
12+
(CSS, JavaScript, images, etc.) When the content of the asset changes, its
13+
identifier is also modified to force the browser to download it again instead of
14+
reusing the cached asset.
15+
16+
Symfony supports asset versioning thanks to the
17+
:ref:`version <reference-framework-assets-version>` and
18+
:ref:`version_format <reference-framework-assets-version-format>` configuration
19+
options. If your application requires a more advanced versioning, such as
20+
generating the version dynamically based on some external information, you can
21+
create your own version strategy.
22+
23+
Creating your Own Asset Version Strategy
24+
----------------------------------------
25+
26+
The following example shows how to create a version strategy compatible with
27+
`gulp-buster`_. This tool defines a configuration file called ``busters.json``
28+
which maps each asset file to its content hash:
29+
30+
.. code-block:: json
31+
32+
{
33+
"js/script.js": "f9c7afd05729f10f55b689f36bb20172",
34+
"css/style.css": "91cd067f79a5839536b46c494c4272d8"
35+
}
36+
37+
Implement VersionStrategyInterface
38+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
39+
40+
Asset version strategies are PHP classes that implement the
41+
:class:`Symfony\\Component\\Asset\\VersionStrategy\\VersionStrategyInterface`.
42+
In this example, the constructor of the class takes as arguments the path to
43+
the manifest file generated by `gulp-buster`_ and the format of the generated
44+
version string::
45+
46+
// src/AppBundle/Asset/VersionStrategy/GulpBusterVersionStrategy.php
47+
namespace AppBundle\Asset\VersionStrategy;
48+
49+
use Symfony\Component\Asset\VersionStrategy\VersionStrategyInterface;
50+
51+
class GulpBusterVersionStrategy implements VersionStrategyInterface
52+
{
53+
/**
54+
* @var string
55+
*/
56+
private $manifestPath;
57+
58+
/**
59+
* @var string
60+
*/
61+
private $format;
62+
63+
/**
64+
* @var string[]
65+
*/
66+
private $hashes;
67+
68+
/**
69+
* @param string $manifestPath
70+
* @param string|null $format
71+
*/
72+
public function __construct($manifestPath, $format = null)
73+
{
74+
$this->manifestPath = $manifestPath;
75+
$this->format = $format ?: '%s?%s';
76+
}
77+
78+
public function getVersion($path)
79+
{
80+
if (!is_array($this->hashes)) {
81+
$this->hashes = $this->loadManifest();
82+
}
83+
84+
return isset($this->hashes[$path]) ? $this->hashes[$path] : '';
85+
}
86+
87+
public function applyVersion($path)
88+
{
89+
$version = $this->getVersion($path);
90+
91+
if ('' === $version) {
92+
return $path;
93+
}
94+
95+
$versionized = sprintf($this->format, ltrim($path, '/'), $version);
96+
97+
if ($path && '/' === $path[0]) {
98+
return '/'.$versionized;
99+
}
100+
101+
return $versionized;
102+
}
103+
104+
private function loadManifest(array $options)
105+
{
106+
return json_decode(file_get_contents($this->manifestPath), true);
107+
}
108+
}
109+
110+
Register the Strategy Service
111+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
112+
113+
After creating the strategy PHP class, register it as a Symfony service.
114+
115+
.. configuration-block::
116+
117+
.. code-block:: yaml
118+
119+
# app/config/services.yml
120+
services:
121+
app.assets.versioning.gulp_buster:
122+
class: AppBundle\Asset\VersionStrategy\GulpBusterVersionStrategy
123+
arguments:
124+
- "%kernel.root_dir%/../busters.json"
125+
- "%%s?version=%%s"
126+
public: false
127+
128+
.. code-block:: xml
129+
130+
<!-- app/config/services.xml -->
131+
<?xml version="1.0" encoding="UTF-8" ?>
132+
<container xmlns="http://symfony.com/schema/dic/services"
133+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
134+
xsi:schemaLocation="http://symfony.com/schema/dic/services
135+
http://symfony.com/schema/dic/services/services-1.0.xsd"
136+
>
137+
<services>
138+
<service id="app.assets.versioning.gulp_buster"
139+
class="AppBundle\Asset\VersionStrategy\GulpBusterVersionStrategy" public="false">
140+
<argument>%kernel.root_dir%/../busters.json</argument>
141+
<argument>%%s?version=%%s</argument>
142+
</service>
143+
</services>
144+
</container>
145+
146+
.. code-block:: php
147+
148+
// app/config/services.php
149+
use Symfony\Component\DependencyInjection\Definition;
150+
151+
$definition = new Definition(
152+
'AppBundle\Asset\VersionStrategy\GulpBusterVersionStrategy',
153+
array(
154+
'%kernel.root_dir%/../busters.json',
155+
'%%s?version=%%s',
156+
)
157+
);
158+
$definition->setPublic(false);
159+
160+
$container->setDefinition('app.assets.versioning.gulp_buster', $definition);
161+
162+
Finally, enable the new asset versioning for all the application assets or just
163+
for some :ref:`asset package <reference-framework-assets-packages>` thanks to
164+
the :ref:`version_strategy <reference-assets-version-strategy>` option:
165+
166+
.. configuration-block::
167+
168+
.. code-block:: yaml
169+
170+
# app/config/config.yml
171+
framework:
172+
# ...
173+
assets:
174+
version_strategy: 'app.assets.versioning.gulp_buster'
175+
176+
.. code-block:: xml
177+
178+
<!-- app/config/config.xml -->
179+
<?xml version="1.0" encoding="UTF-8" ?>
180+
<container xmlns="http://symfony.com/schema/dic/services"
181+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
182+
xmlns:framework="http://symfony.com/schema/dic/symfony"
183+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
184+
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
185+
186+
<framework:config>
187+
<framework:assets version-strategy="app.assets.versioning.gulp_buster" />
188+
</framework:config>
189+
</container>
190+
191+
.. code-block:: php
192+
193+
// app/config/config.php
194+
$container->loadFromExtension('framework', array(
195+
// ...
196+
'assets' => array(
197+
'version_strategy' => 'app.assets.versioning.gulp_buster',
198+
),
199+
));
200+
201+
.. _`gulp-buster`: https://www.npmjs.com/package/gulp-buster

reference/configuration/framework.rst

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,8 @@ collection each time it generates an asset's path:
893893
),
894894
));
895895
896+
.. _reference-framework-assets-packages:
897+
896898
packages
897899
........
898900

@@ -963,22 +965,6 @@ Each package can configure the following options:
963965
* :ref:`version <reference-framework-assets-version>`
964966
* :ref:`version_format <reference-assets-version-format>`
965967

966-
.. _reference-templating-version-strategy:
967-
.. _reference-assets-version-strategy:
968-
969-
version_strategy
970-
................
971-
972-
**type**: ``string`` **default**: ``null``
973-
974-
This specifies the id of the service to use as the version strategy for
975-
all rendered asset paths. Version strategies must implement
976-
:class:`Symfony\\Component\\Asset\\VersionStrategy\\VersionStrategyInterface`.
977-
978-
.. note::
979-
980-
This parameter cannot be set at the same time as ``version``.
981-
982968
.. _reference-framework-assets-version:
983969
.. _ref-framework-assets-version:
984970

@@ -1099,6 +1085,22 @@ is set to ``5``, the asset's path would be ``/images/logo.png?version=5``.
10991085
any URL rewriting. The latter option is useful if you would like older
11001086
asset versions to remain accessible at their original URL.
11011087

1088+
.. _reference-assets-version-strategy:
1089+
.. _reference-framework-assets-version_strategy:
1090+
.. _reference-templating-version-strategy:
1091+
1092+
version_strategy
1093+
................
1094+
1095+
**type**: ``string`` **default**: ``null``
1096+
1097+
The service id of the :doc:`asset version strategy </frontend/custom_version_strategy>`
1098+
applied to the assets.
1099+
1100+
.. note::
1101+
1102+
This parameter cannot be set at the same time as ``version``.
1103+
11021104
templating
11031105
~~~~~~~~~~
11041106

0 commit comments

Comments
 (0)