Skip to content

Commit e1cb545

Browse files
committed
feature #7254 Added "How to Use a Custom Version Strategy for Assets" (xabbuh)
This PR was merged into the 3.1 branch. Discussion ---------- Added "How to Use a Custom Version Strategy for Assets" Another attempt to finish @teohhanhui's great work from #5489. This will fix #6205. Commits ------- d3308be Added "How to Use a Custom Version Strategy for Assets"
2 parents 42598a7 + d3308be commit e1cb545

File tree

2 files changed

+217
-16
lines changed

2 files changed

+217
-16
lines changed

frontend/custom_version_strategy.rst

Lines changed: 200 additions & 0 deletions
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

Lines changed: 17 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,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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy