wilycode / template-assets
Page-scoped CSS and JavaScript asset collection, versioning, bundling, and minification for WilyCode Template.
Requires
- php: ^8.4
- matthiasmullie/minify: ^1.3
- wilycode/template: ^0.1
Requires (Dev)
- phpunit/phpunit: ^11.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-15 23:51:48 UTC
README
Page-scoped CSS and JavaScript asset collection for WilyCode Template, with development cache busting and production bundling.
WilyCode PHP Ecosystem
This library is part of WilyCode, a collection of independent PHP components. Each package has its own repository, Composer installation and releases.
Requirements
- PHP 8.4 or newer.
wilycode/template^0.1.matthiasmullie/minify^1.3for production CSS/JS minification.
Installation
composer require wilycode/template-assets:^0.1
Quick start
Register the extension on an existing TemplateEngine:
<?php use WilyCode\Template\Assets\AssetMode; use WilyCode\Template\Assets\Assets; use WilyCode\Template\Extension\TemplateAssetExtension; $assets = new Assets( publicBasePath: __DIR__ . '/public', mode: $production ? AssetMode::Production : AssetMode::Development, ); $engine->addExtension(new TemplateAssetExtension($assets));
publicBasePath points to the web-accessible directory and must exist. By default, generated production files go into public/assets/build and are referenced by /assets/build/....
In your .tpl file, declare the assets your page needs:
@css('/assets/css/site.css')
@js('/assets/js/app.js')
In a layout, emit the collected tags at the desired positions:
<head>
@renderCss()
</head>
<body>
@yield('content')
@renderJs()
</body>
The @css(...) and @js(...) directives register files without rendering tags. The @renderCss() and @renderJs() directives output the tags. The extension also shares the Assets collector as $assetManager, without overwriting WilyApp's separate $assets view variable.
Asset modes
| Mode | Behavior |
|---|---|
AssetMode::Development |
Keep each file separate. Append ?v=<filemtime> to existing local files. Preserve existing query strings and URL fragments. |
AssetMode::Production |
Minify and combine contiguous runs of existing local CSS/JS files into bundles under /assets/build. The filename incorporates a SHA-256 fingerprint of each source's contents and URL path. |
Both modes preserve declaration order, omit exact duplicate URL registrations, and escape generated HTML attributes.
Remote URLs (including protocol-relative URLs) remain separate, and the public base URL is not prepended to them. Missing local files also remain separate rather than causing a build failure. Remote or missing files split a production bundle into separate local runs, preserving ordering between dependencies.
CSS relative paths: The minifier receives a target file path so that it can rewrite relative URLs for the build directory. Test any CSS imports, fonts, and images used by your project before deployment. Bundle fingerprints reflect the registered CSS source files, not the contents of files imported or embedded by the minifier; if those dependencies change independently, rebuild assets and invalidate external caches as part of deployment.
Additional options
$assets = new Assets( publicBasePath: __DIR__ . '/public', publicBaseUrl: '/admin', mode: AssetMode::Production, buildDir: '/assets/build', );
publicBaseUrlprefixes local asset URLs (for example,/admin/js/app.js). Absolute remote URLs remain unchanged.buildDiris a URL-style directory within the public root; traversal such as..is not allowed. Symlinks in the build path must not leave the public root, and cached bundle paths may not be symlinks.- Production bundle names are content-based, so changing an existing source normally creates a new filename; old bundles may be removed during deployment housekeeping.
Lifecycle
An Assets instance collects declarations until it is no longer used. Create a fresh collector for each request or independently rendered page to avoid carrying registrations between pages. In a long-running server, do not share the same mutable collector across unrelated requests.
API
| Method / template function | Purpose |
|---|---|
addCss(string $path) / @css(...) |
Register CSS once, in order. |
addJs(string $path) / @js(...) |
Register JavaScript once, in order. |
renderCss() / @renderCss() |
Generate CSS links or production bundles. |
renderJs() / @renderJs() |
Generate script tags or production bundles. |
Development
composer install
composer validate --strict
composer test
The test suite covers output ordering, external assets, source fingerprints, path safety, and integration with wilycode/template. GitHub Actions runs it on PHP 8.4.
Development-only directories such as tests/ and .github/ are omitted from the usual Composer dist archive; they remain available in the Git repository. A --prefer-source Git checkout includes them.
License
MIT — see LICENSE.