sympress / assets
WordPress asset management library with optional Symfony-kernel integration.
Requires
- php: ^8.5
- ext-dom: *
- ext-json: *
- symfony/filesystem: ^8.0
- symfony/finder: ^8.0
Requires (Dev)
- brain/monkey: ^2.6
- friendsofphp/php-cs-fixer: ^3.94
- johnpbloch/wordpress-core: >=7.0
- mikey179/vfsstream: ^1.6
- mockery/mockery: ^1.6
- php-stubs/wordpress-stubs: >=7.0@stable
- phpstan/phpstan-mockery: ^2.0
- symfony/var-dumper: ^8.1
- sympress/kernel: ^1.1.1
- sympress/qa: ^0.1.2
Suggests
- sympress/kernel: Enables the optional Symfony-kernel bundle integration.
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-06 18:19:29 UTC
README
| nav_order | 5 |
|---|
Output Filters
Output filters modify the final script or link tag.
<?php use SymPress\Assets\Script; $script = (new Script('site', plugin_dir_url(__FILE__) . 'assets/site.js')) ->withAttributes(['crossorigin' => 'anonymous']);
Included Filters
AttributesOutputFiltersets additional attributes.InlineAssetOutputFilteremits small, allowed CSS or JS files inline.AsyncStyleOutputFilterloads non-critical CSS throughpreload.
Style::preload() requests AsyncStyleOutputFilter. Supply the page's intentional
per-request CSP nonce through sympress_assets_csp_nonce (value, asset). When a
nonempty nonce and WP_HTML_Tag_Processor are available, output contains a preload
link plus a nonce-bearing script using addEventListener, with no onload attribute.
The nonce must match the page's script-src policy; putting a nonce on a link does
not authorize inline event handlers. The script handles already completed/cache-hit
loads, and a noscript copy keeps the original stylesheet. Existing media, integrity,
crossorigin and fetchpriority are preserved. Without a nonce the original blocking
stylesheet is returned, so strict script-src-attr 'none' remains supported.
Inline files must satisfy the allowed canonical path/extensions and 32KB limit, including the actual read bytes. Raw JavaScript containing closing/opening script prefixes, HTML comment openings, or U+2028/U+2029 falls back to its external tag. There is no semantics-preserving universal rewrite for strings, regexps and tagged templates; external fallback keeps the exact program bytes. CSS closing style prefixes are escaped case-insensitively. Inline output retains nonce and removes external-only integrity/src/loading attributes.
For scripts, AsyncScriptOutputFilter and DeferScriptOutputFilter are
deprecated. Use Script::async() or Script::defer() instead.
Custom Filter
<?php use SymPress\Assets\Asset; use SymPress\Assets\Script; $filter = static function (string $html, Asset $asset): string { return str_replace('></script>', ' data-handle="' . esc_attr($asset->handle()) . '"></script>', $html); }; $script = (new Script('site', plugin_dir_url(__FILE__) . 'assets/site.js')) ->withFilters($filter);
Supplied SRI and request snapshots
Loader configuration and dependency JSON may provide integrity (space-separated sha256/384/512 base64 digests) and crossorigin (anonymous/use-credentials). Digest format/decoded length is validated and anonymous is the default. Hashes must come from a trusted build for the exact bytes served. The library does not synthesize integrity from URLs/versions or fetch remote files; no remote integrity guarantee is possible without supplied build metadata. Inline tags omit external integrity.
RequestFiles shares canonical path/stat/content/JSON snapshots across assets and loaders. Repeated reads and missing paths reuse a request snapshot, while allowed root policy decisions remain local to their policy context. Call SymPress\Assets\IO\RequestFiles::reset() at every request boundary in a long-running worker, and recreate per-request asset objects. Normal PHP request teardown already clears this memory. New/changed manifests and symlink targets are observed after reset; do not modify build files partway through a request. PHP dependency execution remains separately opt-in and size-bounded.
CSP preload requires an intentional page nonce via sympress_assets_csp_nonce; without it CSS stays blocking. Supplied build SRI and request-scoped file snapshots are documented in output filters. Long-running workers must reset RequestFiles and recreate request asset objects at each boundary.