10000 minor #7141 Added "How to Use a Custom Version Strategy for Assets" (… · symfony/symfony-docs@d691f6e · GitHub
[go: up one dir, main page]

Skip to content

Commit d691f6e

Browse files
committed
minor #7141 Added "How to Use a Custom Version Strategy for Assets" (teohhanhui, javiereguiluz)
This PR was merged into the 2.7 branch. Discussion ---------- Added "How to Use a Custom Version Strategy for Assets" This PR finishes the great work made by @teohhanhui in #5489. Commits ------- 1399967 Fixed a label name 981e82d Misc fixes a02f3b3 Added the version_strategy option to the config reference 2830ba0 Added the missing doc label 482fda5 Minor rewords and fixes f038483 Removed an unneeded change ab8fa54 Fixed a rebase error c59cff6 Moved the article to its new location 5971ce0 Removed an unneeded file 40dff64 Minor updates to the doc and service config 80d0ca2 Simplified the intro 4f530d8 Cookbook entry: Asset - Custom Version Strategy
2 parents 98e90a2 + 1399967 commit d691f6e

File tree

2 files changed

+216
-0
lines changed

2 files changed

+216
-0
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:: 2.7
8+
The Asset component was introduced in Symfony 2.7.
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-framework-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: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ Configuration
7575
* `packages`_
7676
* `version`_
7777
* `version_format`_
78+
* `version_strategy`_
7879
* `templating`_
7980
* `hinclude_default_template`_
8081
* :ref:`form <reference-templating-form>`
@@ -945,6 +946,8 @@ collection each time it generates an asset's path:
945946
),
946947
));
947948
949+
.. _reference-framework-assets-packages:
950+
948951
packages
949952
........
950953

@@ -1013,6 +1016,7 @@ Each package can configure the following options:
10131016
* :ref:`base_urls <reference-assets-base-urls>`
10141017
* :ref:`version <reference-framework-assets-version>`
10151018
* :ref:`version_format <reference-assets-version-format>`
1019+
* :ref:`version_strategy <reference-framework-assets-version_strategy>`
10161020

10171021
.. _reference-framework-assets-version:
10181022
.. _ref-framework-assets-version:
@@ -1090,6 +1094,7 @@ option.
10901094
``version``. This makes it easier to increment the cache on each
10911095
deployment.
10921096

1097+
.. _reference-framework-assets-version-format:
10931098
.. _reference-templating-version-format:
10941099
.. _reference-assets-version-format:
10951100

@@ -1130,6 +1135,16 @@ is set to ``5``, the asset's path would be ``/images/logo.png?version=5``.
11301135
any URL rewriting. The latter option is useful if you would like older
11311136
asset versions to remain accessible at their original URL.
11321137

1138+
.. _reference-framework-assets-version_strategy:
1139+
1140+
version_strategy
1141+
................
1142+
1143+
**type**: ``string`` **default**: null
1144+
1145+
The service id of the :doc:`asset version strategy </frontend/custom_version_strategy>`
1146+
applied to the assets.
1147+
11331148
templating
11341149
~~~~~~~~~~
11351150

0 commit comments

Comments
 (0)
0