KenntWas.de – Technische Tipps

Technische Informationen zu Linux, (Oracle-) Datenbanken und mehr

[english] WordPress: Get W3TC 0.9.2.1 running with minify and gzip compression

| 21 Comments

Get W3TC 0.9.2.1 running with minify

This is the english Version

I have kindly been asked to translate this post. This is the english version. (Deutsche Version hier).

After having problems with W3 Total Cache (W3TC) 0.9.2.1 (german), here are some tips how to get W3TC running. There are some bugs and problems  with the .htaccess files. For example the errormessage “Bad file param format“.

Update 24.06.2011: Patch added

I’ve added a patch because W3TC always overwrites wp-content/w3tc/min/.htaccess again when the plugin is enabled/disabled.

My Situation

Until now my (german) provider is 1&1. I was happy with them for a long time. But for WordPress installations 1&1 is not so applicable. Everey php-process gets a maximum of 40MB ram. Therefore I had to disable the german translation in wordpress. mod_deflate seems also to be missing an the server.

My first Update to W3TC 0.9.2.1 went wrong (german). Now I installed the plugin from scratch and confired it again. W3TC needs some changes in the .htaccess files. I first let W3TC do the changes, then I modified the files and made the readonly (please backup your files before any W3TC installation or update).

Befor working with W3TC you should read some basics (german)!

Minify: no .gzip files

I was willing to use minify, but it didn’t work for me (and others). While checking the minify-cache wp-content/w3tc/min I realized that the compressed files din’t have the correct extension. The .gzip was missing.  (“default.include.949302381.css.” instead of “default.include.949302381.css.gzip“) .

W3TC: gzip-Endung fehlt

W3TC: gzip-Endung fehlte

W3TC tries to determine the extension itself, but this went wrong.

set encodeMethod to gzip

In the file

wp-content/plugins/w3-total-cache/lib/Minify/Minify/Controller/Base.php

there is no value for encodeMethod, it is left empty. Probably ist does not work in my installation because the needed apache-modules are missing.

After setting maunally ‘encodeMethod’ => ‘gzip’, the cache files are generated with the right extension (.gzip instead of .)

public function getDefaultMinifyOptions() {
 return array(
 'isPublic' => true
 ,'encodeOutput' => function_exists('gzdeflate')
 ,'encodeMethod' => 'gzip'   //MN: was null, set it to gzip // determine later
 ,'encodeLevel' => 9
 ,'minifierOptions' => array() // no minifier options
 ,'contentTypeCharset' => 'utf-8'
 ,'maxAge' => 1800 // 30 minutes
 ,'rewriteCssUris' => true
 ,'bubbleCssImports' => false
 ,'processCssImports' => false
 ,'quiet' => false // serve() will send headers and output
 ,'debug' => false

Minify-Cache

The Minify-Cache is located in wp-content/w3tc/min/.
In this directory the is a .htaccess file and the script index.php, wich constructs the (minify-) cache.

W3TC: Minify-Cache

W3TC: Minify-Cache

“Bad file param format”

I love this errormessage. Everytime when the minify-cache-script in wp-content/w3tc/min/index.php is not able to create an correct file, you’ll get this error. One reason are mistakes in the .htaccess-files which W3TC generates. index.php does not get all the get-variables it needs to do his job.

When index.php does not get all the variables, the program puts “Bad file param format” into every .js oder .css – file it creates (only one line with the error message). The browser cannot work with this.

I corrected the errors and made every .htaccess file readonly, so that W3TC cannot overwrite them again.

In the W3TC settings Minify/General I instruct W3TC to use “fancy links” when calling wp-content/w3tc/min/index.php (instead of using the get method).

W3TC: Minify/General

W3TC: Minify/General

 

 

wp-content/w3tc/min/.htaccess

Her are the things I changed in .htaccess in the directory wp-content/w3tc/min.
(Be aware: the file is not complete, the begining of the file is not included).

 
... # BEGIN W3TC Minify core <IfModule mod_rewrite.c> RewriteEngine On RewriteBase /blog/wp-content/w3tc/min/ RewriteRule ^w3tc_rewrite_test$ index.php?w3tc_rewrite_test=1 [QSA,L] RewriteCond %{HTTP:Accept-Encoding} gzip #MN: make sure there's no trailing .gzip on the url # otherwise we would add it twice and get # "Bad file param format" ReWriteCond %{REQUEST_FILENAME} !^.+\.gzip$ RewriteRule .* - [E=APPEND_EXT:.gzip] RewriteCond %{REQUEST_FILENAME}%{ENV:APPEND_EXT} -f RewriteRule (.*) $1%{ENV:APPEND_EXT} [QSA,L] RewriteRule (.*) index.php?file=$1 [QSA,L] </IfModule> # END W3TC Minify core

My WordPress installation is located in a subdirectory blog/ (remove this or change it to your subdirectory!).

Patch for wp-content/plugins/w3-total-cache/lib/W3/Plugin/Minify.php

You cannot protect wp-content/w3tc/min/.htaccess. Whenever you disable / enable the plugin, W3TC overwrites the file.

In order to prevent this, you should change the sources in
wp-content/plugins/w3-total-cache/lib/W3/Plugin/Minify.php

 

 

function generate_rules_core_apache() {
     $cache_dir = str_replace(w3_get_document_root(), '', w3_path(W3TC_CACHE_FILE_MINIFY_DIR));

     $engine = $this->_config->get_string('minify.engine');
     $browsercache = $this->_config->get_integer('browsercache.enabled');
     $compression = ($browsercache && $this->_config->get_boolean('browsercache.cssjs.compression'));

     $rules = '';
     $rules .= W3TC_MARKER_BEGIN_MINIFY_CORE . "\n";
     $rules .= "<IfModule mod_rewrite.c>\n";
     $rules .= "    RewriteEngine On\n";
     $rules .= "    RewriteBase " . $cache_dir . "/\n";
     //MN:  $rules .= "    RewriteRule ^w3tc_rewrite_test$ index.php?w3tc_rewrite_test=1 [L]\n";
     $rules .= "    RewriteRule ^w3tc_rewrite_test$ index.php?w3tc_rewrite_test=1 [QSA,L]\n";
     if ($engine == 'file') {
         if ($compression) {
             $rules .= "    RewriteCond %{HTTP:Accept-Encoding} gzip\n";                  
             // MN:  $rules .= "    #MN: make shure there's no trailing .gzip on the url\n"; 
             $rules .= "    #    otherwise we would add it twice and get\n";  
             $rules .= "    #    Bad file param format\n";  
             $rules .= "    ReWriteCond %{REQUEST_FILENAME} !^.+\\.gzip\$\n";
             $rules .= "    RewriteRule .* - [E=APPEND_EXT:.gzip]\n";
         }
         $rules .= "    RewriteCond %{REQUEST_FILENAME}%{ENV:APPEND_EXT} -f\n";          
         // MN: $rules .= "    RewriteRule (.*) $1%{ENV:APPEND_EXT} [L]\n";
         $rules .= "    RewriteRule (.*) $1%{ENV:APPEND_EXT} [QSA,L]\n";
     }  
     // MN: $rules .= "    RewriteRule (.*) index.php?file=$1 [L]\n";
     $rules .= "    RewriteRule (.*) index.php?file=$1 [QSA,L]\n";
     $rules .= "</IfModule>\n";
     $rules .= W3TC_MARKER_END_MINIFY_CORE . "\n";
     return $rules;
}

 

ReWriteRule [QSA,L] instead of [L]

Following the proposal of pull-start I use [QSA,L] instead of [L] in all ReWrite rules.

From the help pages of mod_rewrite
qsappend|QSA
‘ (query string append)
This flag forces the rewrite engine to append a query string part of the substitution string to the existing string, instead of replacing it. Use this when you want to add more data to the query string via a rewrite rule.

In the ReWrite rule

RewriteRule (.*) index.php?file=$1 [QSA,L]

index.php gets passed the new Parameter file=$1 supplementary to the other parameters (from the http-request). Only with [L] index.php would be called only with one parameter an bail out with the errormessage.

Avoid double gzip

I also had to put in some security against doubling the .gzip extension, wich would also result in the errormessage “Bad file param format”.
A request of the file abc.css.gzip would be changed by the ReWrite rules to abc.css.gzip.

RewriteCond %{HTTP:Accept-Encoding} gzip
 #MN: make sure there's no trailing .gzip on the url
 #    otherwise we would add it twice and get
 #    "Bad file param format"
 ReWriteCond %{REQUEST_FILENAME} !^.+\.gzip$
 RewriteRule .* - [E=APPEND_EXT:.gzip]

[E:APPEND_EXT:.gzip]

Some background:

With

RewriteRule .* - [E=APPEND_EXT:.gzip]

the url is not changed (-). This statemens set an environment-variable APPEND_EXT=.gzip.

This variable is appended to the requested filename (http-request). When the variable is empty nothing changes (“complicated “NOP”). The name of the environment variable does not matter (gere APPEND_EXT).

When the file abc.css.gzip exists (-f), it will be delivered directly (this is the cache!).
If it doesn’t exists, the request is passed to index.php, which constructs the file.

 

 RewriteRule .* - [E=APPEND_EXT:.gzip]
 RewriteCond %{REQUEST_FILENAME}%{ENV:APPEND_EXT} -f     # existiert abc.ccc.gzip ?
 RewriteRule (.*) $1%{ENV:APPEND_EXT} [QSA,L]

/.htaccess-Datei in the main directory

I also did some changes in the .htaccess-file in the main directory.

Deleting empty lines

W3TC inserts many empty lines into this file (60?). You may / should delete this empty alines but be aware not to delete anything else (at the end of the file).

/.htaccess: Start

The start of my main .htaccess containes some nomal things

  • activation of php5  (nedded for 1&1)
  • setting of the timezone (othewise W3TC would complain during the check)
  • Redirection from www.mydomain.de to mydomain.de

##
## MUST be php5
AddType x-mapp-php5 .php
AddHandler x-mapp-php5 .php
##

# W3TC needs timezone
<IfModule php5_module>
 php_value date.timezone Europe/Berlin
</IfModule>

## redirect www to non www
<IfModule mod_rewrite.c>
 RewriteEngine on
 RewriteCond %{HTTP_HOST} ^www.mydomain.de [NC]
 RewriteRule (.*) http://mydomain.de/$1 [R=301,L]
</IfModule>

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
...

/.htaccess: W3TC Cache Core

Then W3TC sets some Content-Types und mod_deflate options  (W3TC Browser Cache).

In the last part of the file, I also changed [L] to  [QSA,L].
The last line looks different if you don’t use “fancy Links”.

# BEGIN W3TC Page Cache core
<IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteBase /
 RewriteRule ^(.*\/)?w3tc_rewrite_test$ $1?w3tc_rewrite_test=1 [QSA,L]
 RewriteCond %{HTTP_USER_AGENT} (2\.0\ mmp|240x320|alcatel|amoi|asus|au\-mic|audiovox|avantgo|benq|bird|blackberry|blazer|cdm|cellphone|danger|ddipocket|docomo|dopod|elaine/3\.0|ericsson|eudoraweb|fly|haier|hiptop|hp\.ipaq|htc|huawei|i\-mobile|iemobile|j\-phone|kddi|konka|kwc|kyocera/wx310k|lenovo|lg|lg/u990|lge\ vx|midp|midp\-2\.0|mmef20|mmp|mobilephone|mot\-v|motorola|netfront|newgen|newt|nintendo\ ds|nintendo\ wii|nitro|nokia|novarra|o2|openweb|opera\ mobi|opera\.mobi|palm|panasonic|pantech|pdxgw|pg|philips|phone|playstation\ portable|portalmmm|\bppc\b|proxinet|psp|qtek|sagem|samsung|sanyo|sch|sec|sendo|sgh|sharp|sharp\-tq\-gx10|small|smartphone|softbank|sonyericsson|sph|symbian|symbian\ os|symbianos|toshiba|treo|ts21i\-10|up\.browser|up\.link|uts|vertu|vodafone|wap|willcome|windows\ ce|windows\.ce|winwap|xda|zte) [NC]
 RewriteRule .* - [E=W3TC_UA:_low]
 RewriteCond %{HTTP_USER_AGENT} (acer\ s100|android|archos5|blackberry9500|blackberry9530|blackberry9550|blackberry\ 9800|cupcake|docomo\ ht\-03a|dream|htc\ hero|htc\ magic|htc_dream|htc_magic|incognito|ipad|iphone|ipod|kindle|lg\-gw620|liquid\ build|maemo|mot\-mb200|mot\-mb300|nexus\ one|opera\ mini|samsung\-s8000|series60.*webkit|series60/5\.0|sonyericssone10|sonyericssonu20|sonyericssonx10|t\-mobile\ mytouch\ 3g|t\-mobile\ opal|tattoo|webmate|webos) [NC]
 RewriteRule .* - [E=W3TC_UA:_high]
 RewriteCond %{HTTP_COOKIE} w3tc_referrer=.*(google\.com|yahoo\.com|bing\.com|ask\.com|msn\.com) [NC]
 RewriteRule .* - [E=W3TC_REF:_search_engines]
 RewriteCond %{HTTPS} =on
 RewriteRule .* - [E=W3TC_SSL:_ssl]
 RewriteCond %{SERVER_PORT} =443
 RewriteRule .* - [E=W3TC_SSL:_ssl]
 RewriteCond %{HTTP:Accept-Encoding} gzip
 RewriteRule .* - [E=W3TC_ENC:.gzip]
 RewriteCond %{REQUEST_METHOD} !=POST
 RewriteCond %{QUERY_STRING} =""
 RewriteCond %{REQUEST_URI} \/$
 RewriteCond %{REQUEST_URI} !(\/wp-admin\/|\/xmlrpc.php|\/wp-(app|cron|login|register|mail)\.php|wp-.*\.php|index\.php) [NC,OR]
 RewriteCond %{REQUEST_URI} (wp-comments-popup\.php|wp-links-opml\.php|wp-locations\.php) [NC]
 RewriteCond %{HTTP_COOKIE} !(comment_author|wp-postpass|wordpress_\[a-f0-9\]\+|wordpress_logged_in) [NC]
 RewriteCond "%{DOCUMENT_ROOT}/blog/wp-content/w3tc/pgcache/%{REQUEST_URI}/_index%{ENV:W3TC_UA}%{ENV:W3TC_REF}%{ENV:W3TC_SSL}.html%{ENV:W3TC_ENC}" -f
 RewriteRule .* "/blog/wp-content/w3tc/pgcache/%{REQUEST_URI}/_index%{ENV:W3TC_UA}%{ENV:W3TC_REF}%{ENV:W3TC_SSL}.html%{ENV:W3TC_ENC}" [QSA,L]
</IfModule>
# END W3TC Page Cache core

Compability-Check

In 0.9.2.1 is slightly better than in the previous version. But the are still problems with the lightbox. Not everything is readable. When you put the browser into fullscreen mode (F11 in firefox), you’ll be able to read the last lines too.

Result

After some difficulties W3TC works fine for me. Perhaps this is useful for you. I write protected the .htaccess files (call the properties in yout ftp or sftp-client and remove all W-Flags (write)). The cache directoty itself must be writable, because W3TC recreates its cache here.

21 Comments

  1. Thanks, saved my site today!

  2. How To Remove Query String Css Cache File ?

    Example :

    81999.css?52314

    Change to 81999.css

  3. Under “Browser Cache/General” there is an Option
    “Prevent caching of objects after settings change”

    Leave this option unchecked.
    I’m not really shure, but I think that this option adds this query string to every request.
    It did not work for me.

  4. This page is loaded without styles. I advise that you delete your browser cache and reloading this page because it looks bad. It seems you still have some problems with CSS.

  5. Yes, I saw it.
    I forgot to make the .htaccess-files readonly again :-(
    W3TC likes to overwrite them :-(
    Now everything should work again.

  6. W3 Total cache has been Updated version to 0.9.2.2 and fix this problem.

  7. Pingback: [German] Wordpress: W3Total Cache 0.9.2.1 zum Laufen bringen | KenntWas.de - Technische Tipps

  8. Pingback: [english] W3TC 0.9.2.1: Patch for wp-content/plugins/w3-total-cache/lib/W3/Plugin/Minify.php | KenntWas.de - Technische Tipps

  9. I have message on admin bar

    Unfortunately an error occurred while creating the minify cache. Please check your settings to ensure your site is working as intended.

    How to fix this problem ?

    • Do you have the problem again?
      Check your .htaccess files (w3tc modifies them). The cache directory (wp-content/w3tc) must be writable by w3tc.

      • Help me !!! I Do not fix this problem

        Recently an error occurred while creating the CSS / JS minify cache: Some files were unavailable, please check the settings to ensure the site is working as intended.

        • Your css is minified.
          “Some files were unavailable” perhaps means, that the files (.css) are gone because you changed or updated something else than W3TC (a plugin?).
          In “Minify/Cascasing Style Sheets” (middle of the page) check, whether all files (css) are available (“Verify URI”). Exclude (Delete-Button) them, if they are missing.

  10. I am still using W3TC 0.9.2.1 here.
    But this is not your problem.
    Some of your other plugins might got updated (by you!).
    Check your Minify/CSS-Settings for .css that exist anymore.
    (Can only be done if manual mode is activated).

Leave a Reply

Required fields are marked *.