How OpenMage CSS JS Minify Handles Relative vs Absolute URLs in Script and Link Tags
The Fballiano_CssjsMinify_Model_Observer::httpResponseSendBefore method processes both relative and absolute URLs by extracting only the path component via parse_url(), resolves them against the Magento base directory, and replaces local file references with hash-based minified versions in media/fbminify/ while leaving external URLs untouched.
The fballiano/openmage-cssjs-minify module intercepts HTTP responses to minify JavaScript and CSS assets before they reach the browser. According to the source code in app/code/community/Fballiano/CssjsMinify/Model/Observer.php, the observer distinguishes between local and external resources by attempting filesystem resolution, ensuring only accessible local files undergo minification regardless of whether the original URL was relative or absolute.
URL Extraction and Path Normalization
The minification process begins by parsing the HTML response to identify <script> and <link> tags. The observer uses regular expressions to capture the src and href attribute values, then normalizes these URLs to extract filesystem paths.
Regex Extraction of src and href Attributes
In app/code/community/Fballiano/CssjsMinify/Model/Observer.php, the httpResponseSendBefore method—specifically lines 38-66 for JavaScript and lines 68-96 for CSS—employs regex pattern matching to capture the full attribute value from each tag. This captured string, stored in $matches[2], may represent a relative path (js/app.js), a root-relative path (/js/app.js), or an absolute URL (https://example.com/js/app.js).
Stripping Scheme and Host Components
Once extracted, the URL undergoes immediate normalization via parse_url($url). The module deliberately retains only the path component:
$urlComponents = parse_url($url);
$path = $urlComponents['path'];
For relative URLs, the path component equals the original attribute value. For absolute URLs, the scheme, host, and query segments are discarded, leaving only the path portion (e.g., /js/app.js). This normalization ensures consistent processing regardless of the original URL format.
Filesystem Resolution Logic
After extracting the path, the module attempts to locate the corresponding physical file within the Magento installation. This step determines whether the URL qualifies for minification.
Mapping URLs to the Magento Base Directory
The observer constructs an absolute filesystem path by concatenating the Magento base directory ($baseDir) with the extracted path:
if (file_exists($baseDir . $path)) {
// Proceed with minification
}
Both root-relative URLs (starting with /) and path-relative URLs (without leading slash) resolve correctly against $baseDir. For example, /js/app.js becomes $baseDir . '/js/app.js' while js/app.js becomes $baseDir . 'js/app.js'.
Handling Absolute URLs Pointing to the Same Host
When encountering an absolute URL like https://example.com/skin/frontend/default/theme/style.css, the parse_url() extraction yields /skin/frontend/default/theme/style.css. The module attempts to resolve this path against the local filesystem exactly as it would for a relative URL. If the file exists locally, it undergoes minification; otherwise, the original tag remains unchanged.
Minification and URL Replacement
Once a file passes the existence check, the module generates a minified copy and updates the HTML attribute to reference this new location.
Hash-Based Filename Generation
The module creates a unique filename using an MD5 hash of the path combined with the file's last modified timestamp:
$hash = md5($path) . "-{$time}.js";
This hash is independent of the original URL format, ensuring consistent caching behavior whether the source was relative or absolute.
Constructing the Minified Media URL
Regardless of the original URL style, the replacement URL is always an absolute media URL pointing to media/fbminify/:
<script src="https://example.com/media/fbminify/9a4f2c1e-1678901234.js"></script>
<link href="https://example.com/media/fbminify/3b7d9e5a-1678901234.css" rel="stylesheet">
The observer replaces $matches[2] with this new URL, effectively converting all local resource references—whether originally relative or absolute—into versioned, minified assets served from the media directory.
Practical Implementation Examples
The following scenarios demonstrate how different URL formats are processed by the observer in Fballiano_CssjsMinify_Model_Observer.
Example 1: Root-Relative URL
Original HTML:
<script src="/js/app.js"></script>
<link href="/skin/frontend/default/theme/style.css" rel="stylesheet">
Processing:
- Path extraction:
/js/app.jsand/skin/frontend/default/theme/style.css - Filesystem check:
file_exists($baseDir . '/js/app.js') - Result: Rewritten to minified media URLs
Output:
<script src="https://example.com/media/fbminify/9a4f2c1e-1678901234.js"></script>
<link href="https://example.com/media/fbminify/3b7d9e5a-1678901234.css" rel="stylesheet">
Example 2: Path-Relative URL
Original HTML:
<script src="js/lib/jquery.js"></script>
Processing:
parse_urlreturnsjs/lib/jquery.jsas the path- Resolved to
$baseDir . 'js/lib/jquery.js'
Output:
<script src="https://example.com/media/fbminify/a1b2c3d4-1678901234.js"></script>
Example 3: Absolute Same-Host URL
Original HTML:
<link href="https://example.com/skin/frontend/default/theme/print.css" rel="stylesheet">
Processing:
- Path extracted:
/skin/frontend/default/theme/print.css - Local filesystem lookup succeeds
- Minified copy created and referenced
Output:
<link href="https://example.com/media/fbminify/f5e6d7a8-1678901234.css" rel="stylesheet">
Example 4: External CDN URL (Unchanged)
Original HTML:
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
Processing:
- Path extracted:
/npm/vue@2/dist/vue.js - Filesystem check fails:
$baseDir . '/npm/vue@2/dist/vue.js'does not exist - Fallback: Returns original tag unchanged
Output:
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
Summary
- The
httpResponseSendBeforeobserver inapp/code/community/Fballiano/CssjsMinify/Model/Observer.phpprocesses all<script>and<link>tags through a five-step pipeline: extraction, parsing, filesystem resolution, hash generation, and replacement - Both relative and absolute URLs are normalized using
parse_url()to extract only the path component, discarding schemes, hosts, and query strings - Filesystem resolution occurs via
file_exists($baseDir . $path), treating root-relative and path-relative URLs identically when they reference local files - URLs pointing to external domains fail the filesystem check and remain untouched in the output HTML
- All minified resources are served from
media/fbminify/using hash-based filenames that include timestamps for cache busting
Frequently Asked Questions
Does the module minify external CDN resources?
No. When the observer encounters an absolute URL pointing to an external domain (such as https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js), it extracts the path component and attempts to locate the file at $baseDir . $path. Since this file does not exist on the local server, file_exists() returns false and the original URL is preserved unchanged.
How does the module handle query parameters in asset URLs?
Query strings are stripped during the parse_url() extraction phase. The module keeps only the path component, meaning a URL like /js/app.js?v=2.1.0 is treated as /js/app.js for filesystem resolution. The minified output URL does not retain the original query parameters.
What happens if a referenced JavaScript or CSS file does not exist?
If file_exists($baseDir . $path) returns false—whether due to a typo in a relative URL or an absolute URL pointing to a non-local resource—the observer returns the original HTML tag without modification. This ensures broken links remain detectable while preventing PHP errors from missing files.
Can the module process protocol-relative URLs like //example.com/script.js?
Yes. Protocol-relative URLs (starting with //) are valid input for parse_url(), which extracts the host and path components. The module discards the host and uses only the path for filesystem resolution. If the path maps to an existing local file, it will be minified; if the host is external, the file will not be found locally and the URL remains unchanged.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →