Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing htaccess for auto-versioning: htaccess regex Rewrite rule not picking up pattern
    primarykey
    data
    text
    <p>Using a suggestion in the answer to <a href="https://stackoverflow.com/questions/118884/what-is-an-elegant-way-to-force-browsers-to-reload-cached-css-js-files">this question</a>, as well as <a href="http://derekville.net/2009/auto-versioning-javascript-and-css-files/" rel="nofollow noreferrer">this article</a> which offers an almost identical solution, I've been trying to set up htaccess to handle an autoversioning rule on my js and css files.</p> <p>The reason I want to do this is that I change them quite a lot, but still want them to be cached by browsers for aggressively long periods, without having to manually enter a new version number each time they are changed.</p> <p>The method used is simple: (1) a function appends a version number to files using the date on which they were changed, on the pattern <code>[filename].[version_number].[suffix]</code>, so <code>style.css</code>, for instance, would become, say, <code>style.1300638388.css</code>; (2) using php, the versioned number is included in the stylesheet declaration for my site's pages, and this is served to client browsers who will request a fresh copy if the versioned file name differs from that they have cached; (3) a RewriteRule in .htaccess using mod_rewrite rewrites the versioned number, reverts it to its original value and serves the updated file.</p> <p>The code I'm using at each of these three stages is listed below. I'm testing this on the stylesheet in a sandbox version of my blog on <a href="http://edge.donaldjenkins.net/" rel="nofollow noreferrer">http://edge.donaldjenkins.net/</a></p> <h3>1. In WordPress's functions.php file</h3> <pre><code>// Allows autoversioning of css and js files /** * Given a file, i.e. /css/base.css, replaces it with a string containing the * file's mtime, i.e. /css/base.1221534296.css. * * @param $file The file to be loaded. Must be an absolute path (i.e. * starting with slash). */ function auto_version($file) { if(strpos($file, '/') !== 0 || !file_exists($_SERVER['DOCUMENT_ROOT'] . $file)) return $file; $mtime = filemtime($_SERVER['DOCUMENT_ROOT'] . $file); return preg_replace('{\\.([^./]+)$}', ".$mtime.\$1", $file); } </code></pre> <h3>2. In the <code>&lt;head&gt;</code> portion of my blog files</h3> <pre><code>&lt;!-- Stylesheets --&gt; &lt;link rel="stylesheet" href="&lt;?=auto_version('/path/to/style.css')?&gt;" /&gt; </code></pre> <h3>3. In the .htaccess file</h3> <pre><code># Allow versioning for js and css files RewriteEngine On RewriteRule ^(.*)\.[\d]+\.(css|js)$ $1.$2 [L] # Strip out the version number # End Allow versioning for js and css files </code></pre> <p>With the setup described above, pages display without any formatting, and source code of the generated page shows that the stylesheet is referenced as the versioned number—which of course doesn't exist on the server.</p> <p>This would suggest that the function is correctly changing the name of the stylesheet, but that for some reason the regex pattern in the RewriteRule in .htaccess isn't catching the file name and rewriting it. In fact, it doesn't even catch it if I change it to <code>^style.1300638388.css$ style.css [L]</code>.</p> <p>I've tried several patterns, to no avail, but must be missing something pretty basic.</p> <p><code>mod_rewrite</code> is on on the server and runs without issues for several other RewriteRule instances.</p> <p><strong>UPDATE</strong></p> <p>The only other RewriteRule in the <code>.htaccess</code>file is the standard WordPress pretty url rewrite rule. I doubt it interferes with this one, although obviously I can't easily test without the WordPress rule as this would completely break page generation:</p> <pre><code># BEGIN WordPress &lt;IfModule mod_rewrite.c&gt; RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] &lt;/IfModule&gt; # END WordPress </code></pre> <p><strong>UPDATE 2: SOLVED</strong></p> <p>CharlesLeaf in a comment below pointed out that as the WordPress rule was before the versioning one, the latter would not be carried out. This actually was the reason and allowed me answer the question by grouping the two rules, as follows:</p> <pre><code>&lt;IfModule mod_rewrite.c&gt; # Allow versioning for js and css files RewriteEngine On RewriteRule ^(.*)\.[\d]+\.(css|js)$ $1.$2 [L] # Strip out the version number # End Allow versioning for js and css files # BEGIN WordPress RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php # END WordPress &lt;/IfModule&gt; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload