Webrouse/n-asset-macro
, (*1)
Asset macro for Latte and Nette Framework., (*2)
Useful for assets cache busting
with gulp, webpack and other similar tools., (*3)
Requirements
Nette 3
is fully supported and tested., (*4)
Installation
The best way to install webrouse/n-asset-macro is using Composer:, (*5)
$ composer require webrouse/n-asset-macro
Then register the extension in the config file:, (*6)
# app/config/config.neon
extensions:
assetMacro: Webrouse\AssetMacro\DI\Extension
Usage
Macro can by used in any presenter or control template:, (*7)
{* app/presenters/templates/@layout.latte *}
<script src="{asset resources/vendor.js}"></script>
<script src="{asset //resources/main.js}"></script>
It prepends path with $basePath
or $baseUrl
(see absolute) and loads revision from the revision manifest:, (*8)
<script src="/base/path/resources/vendor.d78da025b7.js"></script>
<script src="http://www.example.com/base/path/resources/main.34edebe2a2.js"></script>
See the examples for usage with gulp, webpack., (*9)
Revision manifest
Revision manifest is a JSON file that contains the revision (path or version) of asset., (*10)
It can be generated by various asset processors such as gulp and webpack, see examples., (*11)
Revision manifest is searched in the asset directory and in the parent directories up to %wwwDir%
., (*12)
Expected file names: assets.json
, busters.json
, versions.json
, manifest.json
, rev-manifest.json
., (*13)
The path to revision manifest can be set directly (instead of autodetection):, (*14)
# app/config/config.neon
assetMacro:
manifest: %wwwDir%/assets.json
Or you can specify asset => revision
pairs in config file:, (*15)
# app/config/config.neon
assetMacro:
manifest:
'js/vendor.js': 16016edc74d # or js/vendor.16016edc74d.js
'js/main.js': 4b82916016 # or js/main.4b82916016.js
Revision manifest may contains asset version or the asset path. Both ways are supported., (*16)
Method 1: asset version in file name (preferable)
With this method, the files have a different name at each change., (*17)
Example revision manifest:, (*18)
{
"js/app.js": "js/app.234a81ab33.js",
"js/vendor.js": "js/vendor.d67fbce193.js",
"js/locales/en.js": "js/locales/en.d78da025b7.js",
"js/locales/sk.js": "js/locales/sk.34edebe2a2.js",
"css/app.css": "css/app.04b5ff0b97.js"
}
With the example manifest, the expr. {asset "js/app.js"}
generates: /base/path/js/app.234a81ab33.js
., (*19)
Method 2: asset version as a query string
This approach looks better at first glance. The asset path is still the same, and only the parameter in the query changes., (*20)
However, it can cause problems with some cache servers, which don't take the URL parameters into account., (*21)
Example revision manifest:, (*22)
{
"js/app.js": "234a81ab33",
"js/vendor.js": "d67fbce193",
"js/locales/en.js": "d78da025b7",
"js/locales/sk.js": "34edebe2a2",
"css/app.css": "04b5ff0b97"
}
With the example manifest, the expr. {asset "js/app.js"}
generates: /base/path/js/app.js?v=234a81ab33
., (*23)
Asset macro automatically detects which of these two formats of revision manifest is used., (*24)
Macro arguments
The format is defined by the second macro parameter or using the format
key (default %url%
)., (*25)
format
can be used with needed => false
to hide whole asset expression (eg. <link ...
) in case of an error., (*26)
You can also use it to include asset content instead of a path., (*27)
Placeholder |
Example output |
%content% |
<svg>....</svg> (file content) |
%path% |
js/main.js or js/main.8c48f58df.js
|
%raw% |
8c48f58df or js/main.8c48f58df.js
|
%base% |
%baseUrl% if absolute => true else %basePath%
|
%basePath% |
/base/path |
%baseUrl% |
http://www.example.com/base/path |
%url% |
%base%%path% (default format) eg. /base/path/js/main.8c48f58df.js
|
{* app/presenters/templates/@layout.latte *}
{asset 'js/vendor.js', '<script src="%url%"></script>'}
<script src="{asset 'js/livereload.js', format => '%path%?host=localhost&v=%raw%'}"></script>
needed
Error handling is set in the configuration using: missingAsset
, missingManifest
and missingRevision
keys., (*28)
These settings can by overrided by third macro parameter or using needed
key (default true
)., (*29)
Argument needed => false
will cause the missing file or the missing revision record will be ignored., (*30)
Missing version will be replaced with unknown
string., (*31)
Example of needed
parameter
* absent.js
file doesn't exist.
* missing_rev.js
exists but doesn't have revision in manifest (or the manifest has not been found)., (*32)
{asset 'js/absent.js', '<script src="%url%"></script>', FALSE}
{asset 'js/missing_rev.js', format => '<script src="%url%"></script>', needed => FALSE}
Generated output:, (*33)
<script src="/base/path/js/missing_rev.js?v=unknown"></script>
absolute
Output URL type - relative or absolute - is defined by fourth macro parameter or using absolute
key (default false
)., (*34)
If absolute => true
or asset path is prefixed with //
eg. (//assets/js/main.js
), the absolute URL will be generated instead of a relative URL., (*35)
{asset 'js/vendor.js'} {* equal to {asset 'js/vendor.js', absolute => false} *}
{asset '//js/vendor.js'} {* equal to {asset 'js/vendor.js', absolute => true} *}
Generated output:, (*36)
Caching
In production mode is the macro output cached in default application's cache storage., (*37)
It can be changed in the configuration using the boolean cache
key., (*38)
Configuration
Default configuration, which usually doesn't need to be changed:, (*39)
# app/config/config.neon
assetMacro:
# Cache generated output
cache: %productionMode%
# Path to revision manifest or asset => revision pairs,
# if set, the autodetection is switched off
manifest: null # %wwwDir%/assets/manifest.json
# File names for automatic detection of revision manifest
autodetect:
- assets.json
- busters.json
- versions.json
- manifest.json
- rev-manifest.json
# Absolute path to assets dir
assetsPath: %wwwDir%/ # %wwwDir%/assets
# Public path to "assetsPath"
publicPath: / # /assets
# Action if missing asset file: exception, notice, or ignore
missingAsset: notice
# Action if missing manifest file: exception, notice, or ignore
missingManifest: notice
# Action if missing asset revision in manifest: exception, notice, or ignore
missingRevision: notice
# Default format, can be changed in macro using "format => ..."
format: '%%url%%' # character % is escaped by %%
ManifestService
It is also possible to access the manifest from your code using Webrouse\AssetMacro\ManifestService
(from DI container)., (*40)
/** @var ManifestService $manifestService */
$cssAssets = $manifestService->getManifest()->getAll('/.*\.css$/');
Examples
Examples based on nette/sandbox:, (*41)
License
N-asset-macro is under the MIT license. See the LICENSE file for details., (*42)