8000 feature #4987 Added the documentation for the new Asset component (ja… · symfony/symfony-docs@22eee86 · GitHub
[go: up one dir, main page]

Skip to content

Commit 22eee86

Browse files
committed
feature #4987 Added the documentation for the new Asset component (javiereguiluz)
This PR was submitted for the master branch but it was merged into the 2.7 branch instead (closes #4987). Discussion ---------- Added the documentation for the new Asset component | Q | A | ------------- | --- | Doc fix? | no | New docs? | yes | Applies to | 2.7+ | Fixed tickets | #4982 This PR only adds the "Symfony-agnostic" documentation. After this doc is merged, we have to update the rest of the Symfony documentation with the following changes: ----- **1. Changes in configuration** ```yaml # OLD configuration framework: templating: assets_version: 'v5' assets_version_format: '%%s?version=%%s' assets_base_urls: http: ['http://cdn.example.com'] ssl: ['https://secure.example.com'] packages: # ... # NEW configuration framework: assets: version: 'v5' version_format: '%%s?version=%%s' base_path: ~ base_urls: ['http://cdn.example.com', 'https://secure.example.com'] packages: # ... ``` **2. Changes in Twig templates** `{{ asset() }}` function is the same as before, but now it only allows to set two arguments: ```twig {# Common case: no package name #} {{ asset('logo.png') }} {# When using packages #} {{ asset('logo.png', 'images') }} ``` This means that `absolute` and `version` arguments are no longer available: ```twig {# BEFORE #} {{ asset('logo.png', absolute = true) }} {# AFTER #} {{ absolute_url(asset('logo.png')) }} {# BEFORE #} {{ asset('logo.png', version = 'v5') }} {# AFTER #} {# relative URLs - do nothing (version is automatically appended) #} {{ asset('logo.png') }} {# absolute URLs - get the version with asset_version() and append it manually #} {{ absolute_url(asset('logo.png')) ~ '?' ~ asset_version('logo.png') }} ``` **3. Other changes** * The `asset*()` functions are now defined in the Twig Bridge instead of the Twig Bundle. * ... ----- Lastly, I have a question when using Asset component in a Symfony application: How can I use a custom version strategy in a Symfony application? Commits ------- 7ab379a Lots of fixes and rewordings 9e8de96 Fixed RST syntax issues 5ca85d1 Fixed some RST syntax issues 17269a3 Moved the component documentation to its own folder fab3c89 Fixed a lot of errors and added an introduction 49548b3 Tweaked documentation and added links to API methods/classes 76b8bea Added a missing link reference d39b26e Minor rewording 6d367b1 Added the documentation for the new Asset component
2 parents 78733c3 + 7ab379a commit 22eee86

File tree

4 files changed

+301
-0
lines changed

4 files changed

+301
-0
lines changed

components/asset/index.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Asset
2+
=====
3+
4+
.. toctree::
5+
:maxdepth: 2
6+
7+
introduction

components/asset/introduction.rst

Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
.. index::
2+
single: Asset
3+
single: Components; Asset
4+
5+
The Asset Component
6+
===================
7+
8+
The Asset component manages URL generation and versioning of web assets such
9+
as CSS stylesheets, JavaScript files and image files.
10+
11+
In the past, it was common for web applications to hardcode URLs of web assets.
12+
For example:
13+
14+
.. code-block:: html
15+
16+
<link rel="stylesheet" type="text/css" href="/css/main.css">
17+
18+
<!-- ... -->
19+
20+
<a href="/"><img src="/images/logo.png"></a>
21+
22+
This practice is no longer recommended unless the web application is extremely
23+
simple. Hardcoding URLs can be a disadvantage because:
24+
25+
* **Templates get verbose**: you have to write the full path for each
26+
asset. When using the Asset component, you can group assets in packages to
27+
avoid repeating the common part of their path;
28+
* **Versioning is difficult**: it has to be custom managed for each
29+
application. Adding a version to the asset URLs is essential for some applications
30+
because it allows to control how the assets are cached. The Asset component
31+
allows to define different versioning strategies for each package;
32+
* **Moving assets location** is cumbersome and error-prone: it requires you to
33+
carefully update the URLs of all assets included in all templates. The Asset
34+
component allows to move assets effortlessly just by changing the base path
35+
value associated with the package of assets;
36+
* **It's nearly impossible to use multiple CDNs**: this technique requires to
37+
change the URL of the asset randomly for each request. The Asset component
38+
provides out-of-the-box support for any number of multiple CDNs, both regular
39+
(``http://``) and secure (``https://``).
40+
41+
Installation
42+
------------
43+
44+
You can install the component in two different ways:
45+
46+
* :doc:`Install it via Composer </components/using_components>` (``symfony/asset`` on `Packagist`_);
47+
* Use the official Git repository (https://github.com/symfony/Asset).
48+
49+
Usage
50+
-----
51+
52+
Asset Packages
53+
~~~~~~~~~~~~~~
54+
55+
The Asset component manages assets through packages. A package groups all the
56+
assets which share the same properties: versioning strategy, base path, CDN hosts,
57+
etc. In the following basic example, a package is created to manage assets without
58+
any versioning::
59+
60+
use Symfony\Component\Asset\Package;
61+
use Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy;
62+
63+
$package = new Package(new EmptyVersionStrategy());
64+
65+
echo $package->getUrl('/image.png');
66+
// result: /image.png
67+
68+
Packages implement the :class:`Symfony\\Component\\Asset\\PackageInterface`,
69+
which defines the following two methods:
70+
71+
:method:`Symfony\\Component\\Asset\\PackageInterface::getVersion`
72+
Returns the asset version for an asset.
73+
74+
:method:`Symfony\\Component\\Asset\\PackageInterface::getUrl`
75+
Returns an absolute or root-relative public path.
76+
77+
Versioned Assets
78+
~~~~~~~~~~~~~~~~
79+
80+
One of the main features of the Asset component is to manage the versioning of
81+
the application's assets. Asset versions are commonly used to control how these
82+
assets are cached.
83+
84+
Instead of relying on a simple version mechanism, the Asset component allows to
85+
define advanced versioning strategies via PHP classes. The two built-in strategies
86+
provided by the component are :class:`Symfony\\Component\\Asset\\VersionStrategy\\EmptyVersionStrategy`,
87+
which doesn't add any version to the asset and :class:`Symfony\\Component\\Asset\\VersionStrategy\\StaticVersionStrategy`,
88+
which allows to set the version with a format string.
89+
90+
In this example, the ``StaticVersionStrategy`` is used to append the ``v1``
91+
suffix to any asset path::
92+
93+
use Symfony\Component\Asset\Package;
94+
use Symfony\Component\Asset\VersionStrategy\StaticVersionStrategy;
95+
96+
$package = new Package(new StaticVersionStrategy('v1'));
97+
98+
echo $package->getUrl('/image.png');
99+
// result: /image.png?v1
100+
101+
In case you want to modify the version format, pass a sprintf-compatible format
102+
string as the second argument of the ``StaticVersionStrategy`` constructor::
103+
104+
// put the 'version' word before the version value
105+
$package = new Package(new StaticVersionStrategy('v1', '%s?version=%s'));
106+
107+
echo $package->getUrl('/image.png');
108+
// result: /image.png?version=v1
109+
110+
// put the asset version before its path
111+
$package = new Package(new StaticVersionStrategy('v1', '%2$s/%1$s'));
112+
113+
echo $package->getUrl('/image.png');
114+
// result: /v1/image.png
115+
116+
Custom Version Strategies
117+
.........................
118+
119+
Use the :class:`Symfony\\Component\\Asset\\VersionStrategy\\VersionStrategyInterface`
120+
to define your own versioning strategy. For example, your application may need
121+
to append the current date to all its web assets in order to bust the cache
122+
every day::
123+
124+
use Symfony\Component\Asset\VersionStrategy\VersionStrategyInterface;
125+
126+
class DateVersionStrategy implements VersionStrategyInterface
127+
{
128+
private $version;
129+
130+
public function __construct()
131+
{
132+
$this->version = date('Ymd');
133+
}
134+
135+
public function getVersion($path)
136+
{
137+
return $this->version;
138+
}
139+
140+
public function applyVersion($path)
141+
{
142+
return sprintf('%s?v=%s', $path, $this->getVersion($path));
143+
}
144+
}
145+
146+
Grouped Assets
147+
~~~~~~~~~~~~~~
148+
149+
It's common for applications to store their assets in a common path. If that's
150+
your case, replace the default :class:`Symfony\\Component\\Asset\\Package` class
151+
by :class:`Symfony\\Component\\Asset\\PathPackage` to avoid repeating the same
152+
path time and again::
153+
154+
use Symfony\Component\Asset\PathPackage;
155+
// ...
156+
157+
$package = new PathPackage('/static/images', new StaticVersionStrategy('v1'));
158+
159+
echo $package->getUrl('/logo.png');
160+
// result: /static/images/logo.png?v1
161+
162+
Request Context Aware Assets
163+
............................
164+
165+
If you are also using the HttpFoundation component in your project, for example
166+
in a Symfony application, the ``PathPackage`` class can take into account the
167+
context of the current request::
168+
169+
use Symfony\Component\Asset\PathPackage;
170+
use Symfony\Component\Asset\Context\RequestStackContext;
171+
// ...
172+
173+
$package = new PathPackage(
174+
'/static/images',
175+
new StaticVersionStrategy('v1'),
176+
new RequestStackContext($requestStack)
177+
);
178+
179+
echo $package->getUrl('/logo.png');
180+
// result: /somewhere/static/images/logo.png?v1
181+
182+
When the request context is set (via an optional third argument), in addition to
183+
the configured base path, ``PathPackage`` also prepends the current request base
184+
URL (``/somewhere/`` in this example) to assets. This allows your website to be
185+
hosted anywhere under the web server root directory.
186+
187+
Absolute Assets and CDNs
188+
~~~~~~~~~~~~~~~~~~~~~~~~
189+
190+
Applications that host their assets on different domains and CDNs (*Content
191+
Delivery Networks*) should use the :class:`Symfony\\Component\\Asset\\UrlPackage`
192+
class to generate absolute URLs for their assets::
193+
194+
use Symfony\Component\Asset\UrlPackage;
195+
// ...
196+
197+
$package = new UrlPackage(
198+
'http://static.example.com/images/',
199+
new StaticVersionStrategy('v1')
200+
);
201+
202+
echo $package->getUrl('/logo.png');
203+
// result: http://static.example.com/images/logo.png?v1
204+
205+
In case you serve assets from more than one domain to improve application
206+
performance, pass an array of URLs as the first argument of ``UrlPackage``
207+
constructor::
208+
209+
use Symfony\Component\Asset\UrlPackage;
210+
// ...
211+
212+
$urls = array(
213+
'http://static1.example.com/images/',
214+
'http://static2.example.com/images/',
215+
);
216+
$package = new UrlPackage($urls, new StaticVersionStrategy('v1'));
217+
218+
echo $package->getUrl('/logo.png');
219+
// result: http://static1.example.com/images/logo.png?v1
220+
221+
The selection of the domain which will serve the asset is deterministic, meaning
222+
that each asset will be always served by the same domain. This behavior simplifies
223+
the management of HTTP cache.
224+
225+
Request Context Aware Assets
226+
............................
227+
228+
Similarly to application-relative assets, absolute assets can also take into
229+
account the context of the current request. In this case, only the request
230+
scheme is considered, in order to select the appropriate base URL (HTTPs or
231+
protocol-relative URLs for HTTPs requests, any base URL for HTTP requests)::
232+
233+
use Symfony\Component\Asset\UrlPackage;
234+
use Symfony\Component\Asset\Context\RequestStackContext;
235+
// ...
236+
237+
$package = new UrlPackage(
238+
array('http://example.com/', 'https://example.com/'),
239+
new StaticVersionStrategy('v1'),
240+
new RequestStackContext($requestStack)
241+
);
242+
243+
echo $package->getUrl('/logo.png');
244+
// result: https://example.com/logo.png?v1
245+
246+
Named Packages
247+
~~~~~~~~~~~~~~
248+
249+
Applications that manage lots of different assets may need to group them in
250+
packages with the same versioning strategy and base path. The Asset component
251+
includes a :class:`Symfony\\Component\\Asset\\Packages` class to simplify
252+
management of several packages.
253+
254+
In the following example, all packages use the same versioning strategy, but
255+
they all have different base paths::
256+
257+
use Symfony\Component\Asset\Package;
258+
use Symfony\Component\Asset\PathPackage;
259+
use Symfony\Component\Asset\UrlPackage;
260+
use Symfony\Component\Asset\Packages;
261+
// ...
262+
263+
$versionStrategy = new StaticVersionStrategy('v1');
264+
265+
$defaultPackage = new Package($versionStrategy);
266+
267+
$namedPackages = array(
268+
'img' => new UrlPackage('http://img.example.com/', $versionStrategy),
269+
'doc' => new PathPackage('/somewhere/deep/for/documents', $versionStrategy),
270+
);
271+
272+
$packages = new Packages($defaultPackage, $namedPackages)
273+
274+
The ``Packages`` class allows to define a default package, which will be applied
275+
to assets that don't define the name of package to use. In addition, this
276+
application defines a package named ``img`` to serve images from an external
277+
domain and a ``doc`` package to avoid repeating long paths when linking to a
278+
document inside a template::
279+
280+
echo $packages->getUrl('/main.css');
281+
// result: /main.css?v1
282+
283+
echo $packages->getUrl('/logo.png', 'img');
284+
// result: http://img.example.com/logo.png?v1
285+
286+
echo $packages->getUrl('/resume.pdf', 'doc');
287+
// result: /somewhere/deep/for/documents/resume.pdf?v1
288+
289+
.. _Packagist: https://packagist.org/packages/symfony/asset

components/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ The Components
55
:hidden:
66

77
using_components
8+
asset/index
89
class_loader/index
910
config/index
1011
console/index

components/map.rst.inc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
* :doc:`/components/using_components`
22

3+
* :doc:`/components/asset/index`
4+
5+
* :doc:`/components/asset/introduction`
6+
37
* :doc:`/components/class_loader/index`
48

59
* :doc:`/components/class_loader/introduction`

0 commit comments

Comments
 (0)
0