Skip to content

Commit d3308be

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

File tree

2 files changed

+217
-16
lines changed

2 files changed

+217
-16
lines changed

frontend/custom_version_strategy.rst

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

reference/configuration/framework.rst

+17-16
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,21 @@ 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-templating-version-strategy:
1090+
1091+
version_strategy
1092+
................
1093+
1094+
**type**: ``string`` **default**: ``null``
1095+
1096+
The service id of the :doc:`asset version strategy </frontend/custom_version_strategy>`
1097+
applied to the assets.
1098+
1099+
.. note::
1100+
1101+
This parameter cannot be set at the same time as ``version``.
1102+
11021103
templating
11031104
~~~~~~~~~~
11041105

0 commit comments

Comments
 (0)