<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>timwhitlock.info &#187; wordpress</title>
	<atom:link href="http://timwhitlock.info/blog/tag/wordpress/feed/" rel="self" type="application/rss+xml" />
	<link>http://timwhitlock.info</link>
	<description>Tim Whitlock&#039;s personal site and blog</description>
	<lastBuildDate>Thu, 15 Dec 2011 13:51:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Varnish with PHP (and WordPress)</title>
		<link>http://timwhitlock.info/blog/2010/08/21/varnish-with-php-and-wordpress/</link>
		<comments>http://timwhitlock.info/blog/2010/08/21/varnish-with-php-and-wordpress/#comments</comments>
		<pubDate>Sat, 21 Aug 2010 15:34:16 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[varnish]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://web.2point1.com/?p=544</guid>
		<description><![CDATA[The final stage in speeding up my blog was to add some serious caching to the front of it. This may even have been overkill, because it was already pretty swift under nginx/php-fpm, but cutting out the database connections would speed it up even more. I had a quick go with the W3 Total Cache [...]]]></description>
			<content:encoded><![CDATA[<p>The final stage in <a href="http://web.2point1.com/2010/08/17/now-powered-by-wordpress-3-nginx-and-php-fpm/">speeding up my blog</a> was to add some serious caching to the front of it. This may even have been overkill, because it was already pretty swift under <a href="http://web.2point1.com/2010/08/17/php-fpm-5-3-3-under-nginx/" target="_blank">nginx/php-fpm</a>, but cutting out the database connections would speed it up even more.</p>
<p>I had a quick go with the <a href="http://wordpress.org/extend/plugins/w3-total-cache/" target="_blank">W3 Total Cache</a> WordPress plug-in, but it seems rather biased to running Apache (which I&#8217;m not) and I experienced some strange errors that I failed to immediately fix. Rather than wrestle with it, or try other WordPress caches, I decided to get to grips with <a href="http://varnish-cache.org/" target="_blank">Varnish</a>. This is something I&#8217;d been meaning to do for ages, and of course it isn&#8217;t limited to WordPress &#8211; <a href="http://varnish-cache.org/" target="_blank">Varnish</a> is a fabulous caching solution for whatever site you&#8217;re building.</p>
<p><span id="more-544"></span>The challenge with deploying Varnish to any site is to ensure you cache as much as you can while ensuring dynamic content is fresh when required. With WordPress as an example, the cases are fairly obvious. While logged in to the admin screens you don&#8217;t want to cache anything, but the outside world reading your posts should get cached pages whenever possible. In their simplest forms, these cases <em>almost </em>work out of the box with Varnish, but there are a few gotchas. There is also scope to cache more aggressively if you choose to, and most importantly you&#8217;ll want to ensure that when content is altered, the changes are visible to everyone immediately.</p>
<p><strong>Cookie gotcha no.1 </strong></p>
<p>By default, if you send a cookie to Varnish it assumes quite sensibly that you are in some way expecting dynamic content from the back end. e.g. you may be an admin user, logged in to the site. Of course Varnish can&#8217;t actually know what the cookie is for, so when your browser sends a completely redundant Google Analytics <a href="http://code.google.com/apis/analytics/docs/concepts/gaConceptsCookies.html" target="_blank">UTM cookie</a>, you&#8217;ll miss the cache. On this site, that means Varnish would only serve you a maximum of one cached page per visit.</p>
<p><strong>Anonymous session cookies</strong></p>
<p>If a visitor comments on a WordPress site, they are pseudo-logged-in by way of a simple cookie exchange. This means the site can do niceties like pre-populate comment forms for commenting again. These niceties are exactly that, so if you overlook this functionality and block those cookies you can serve more cached pages. In my case, I am happy to make this trade.</p>
<p>The following snippet from my configuration shows how I&#8217;ve maximised anonymous user caching while ensuring admin users always get dynamic content</p>
<pre>sub vcl_recv {
  # ...
  # admin users always miss the cache
  if( req.url ~ "^/wp-(login|admin)" || req.http.Cookie ~ "wordpress_logged_in_" ){
    return (pass);
  }
  # ignore any other cookies
  unset req.http.Cookie;
  return (lookup);
}</pre>
<p><strong>Purging when content changes</strong></p>
<p>HTTP defines a wealth of cache control headers that allow applications and clients to specify what is to be cached and for how long, etc.. but there is no standard way to tell a cache that certain content is to be purged. This is the main challenge of deploying Varnish to a site like WordPress.  A post may be updated, or a user may comment. You&#8217;ll want to purge any affected pages from the cache immediately, regardless of their original expiry. Putting that business logic into your VCL configuration would be hugely impractical &#8211; it&#8217;s really your application&#8217;s jurisdiction.</p>
<p>I looked at various purging techniques, and by far the best approach in my opinion is for your application to talk directly to the <a href="http://varnish-cache.org/wiki/CLI" target="_blank">Varnish administration CLI </a>which listens on the network on a different port to the cache itself. As long as your backend can access your front end by a secure, internal address, you can execute commands on all your Varnish front ends any time you want from your application.</p>
<p>To achieve this, I first had a look at the <a href="http://wordpress.org/extend/plugins/wordpress-varnish/" target="_blank">wp-varnish plug-in</a> which uses the <a href="http://varnish-cache.org/wiki/VCLExamplePurging" target="_blank">HTTP PURGE</a> method. I don&#8217;t like this approach at all; it&#8217;s very limited, too closely coupled to the VCL config, and also this plug-in doesn&#8217;t purge all pages relating to changes, such as tag and archive indexes.</p>
<p><strong>So, I rolled my own</strong></p>
<p>I started by writing a <a href="http://github.com/timwhitlock/php-varnish/blob/master/VarnishAdminSocket.php" target="_blank">VarnishAdminSocket</a> class, which talks to Varnish from PHP. This was pretty easy to do, because the <em>varnishadm</em> program uses a very basic text-based protocol. This isn&#8217;t designed for WordPress, this is designed for use in any PHP application.</p>
<p>My <a href="http://github.com/timwhitlock/php-varnish" target="_blank"><strong>php-varnish</strong> toolkit is on Github</a>. It includes a <a href="http://github.com/timwhitlock/php-varnish/blob/master/wordpress-plugin.php" target="_blank">WordPress plug-in </a>which I am using on this site and you can see <a href="http://github.com/timwhitlock/php-varnish/blob/master/wordpress-plugin/wordpress.vcl" target="_blank">the VCL configuration</a> I am using too.</p>
]]></content:encoded>
			<wfw:commentRss>http://timwhitlock.info/blog/2010/08/21/varnish-with-php-and-wordpress/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>WordPress 3 &#8230; yep, it&#8217;s still WordPress</title>
		<link>http://timwhitlock.info/blog/2010/08/21/wordpress-3-is-still-wordpress/</link>
		<comments>http://timwhitlock.info/blog/2010/08/21/wordpress-3-is-still-wordpress/#comments</comments>
		<pubDate>Sat, 21 Aug 2010 13:38:42 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://web.2point1.com/?p=516</guid>
		<description><![CDATA[As part of my &#8220;speeding up my blog&#8221; series, I planned to write a nice, informative post about upgrading to WordPress 3, deploying your theme to a CDN, and getting it all running under nginx. Unfortunately WordPress irritated me so much in the process, that this has turned into more of rant. Sorry in advance. [...]]]></description>
			<content:encoded><![CDATA[<p>As part of my &#8220;<a href="http://web.2point1.com/2010/08/17/now-powered-by-wordpress-3-nginx-and-php-fpm/">speeding up my blog</a>&#8221; series, I planned to write a nice, informative post about upgrading to WordPress 3, deploying your theme to a CDN, and getting it all <a href="http://web.2point1.com/2010/08/17/php-fpm-5-3-3-under-nginx/">running under nginx</a>. Unfortunately WordPress irritated me so much in the process, that this has turned into more of rant. Sorry in advance.</p>
<p>I have a like/hate relationship with WordPress. That is to say that it does a lot, it has a great admin area and there&#8217;s a large community producing themes and plug-ins. However, I am a PHP developer of many years, and every time I come into direct contact with the core WordPress code-base I end up being sick in my mouth.</p>
<p><em><span id="more-516"></span>What&#8217;s to hate?</em> Well it kind of reminds me of that old BMW advert (or was it Audi?) the one with the swan &#8211; On the surface it glides effortlessly, but under the water it&#8217;s an ugly son of a bitch, churning away to get the job done.  I had the misfortune of working on a nasty WPMU project last year and found myself looking under the <a href="http://simple.wikipedia.org/wiki/British_English#Vocabulary_in_British_English" target="_blank">bonnet</a> more than was good for me. Not only is WordPress a horribly written piece of PHP, (and possibly responsible for many a bad word said about PHP itself) it has a legacy of incremental improvements alongside a legacy of community-contributed code that strives to remain as reverse compatible as possible.</p>
<p>If you don&#8217;t want to read my rantings, skip to <a href="#bitattheend">the bit at the end</a>, otherwise &#8230; WordPress, let me count the ways a hate thee.</p>
<p><strong>1. Base URL hell</strong></p>
<p>I wanted to get as much of my static assets onto a CDN as I could &#8211; a topic I&#8217;ll cover in full later. This means serving static files (such as images and css) from a different base URL. It <em>should</em> be simple to upload your theme and plug-in directories to another server and ensure that WordPress points to the correct assets in your HTML. It is not simple. Just look at the <a href="http://codex.wordpress.org/Determining_Plugin_and_Content_Directories" target="_blank">hideousness of determining base URLs in WordPress</a>. This simple task should not require a complex plug-in to cover all possible legacy issues. Furthermore, WordPress allows <em>all</em> plug-ins to mess around with base URLs, which means one plug-in might completely undo the work of another.</p>
<p>Oh, by the way &#8211; WordPress defines the constant <code>WP_CONTENT_URL</code> before it loads any plug-ins, so the only way to override this is to define it in <code>wp-config.php</code>.</p>
<p><strong>2. Canonical domain ridiculousness</strong></p>
<p>If you access a WordPress site from a domain that is not hard-wired into the site&#8217;s database, it will redirect you to the &#8216;correct&#8217; URL. This is the default behaviour. So, if you want to host the same exact site from a different domain, or different port, (e.g. for debugging a distributed system) you will have to write a WordPress plug-in to override this behaviour. Why does this annoy me?</p>
<ol>
<li>It is not PHP&#8217;s job to decide what domain a site lives on &#8211; that is the job of the web server. A domain redirect like this should be done at server config level.</li>
<li>No system should hard-wire its domain into database-saved preferences. This is nuts, and WordPress does it in multiple places.</li>
</ol>
<p><strong>3. Magic quotes are the Devil\\\&#8217;s work</strong></p>
<p>Magic quotes are so utterly evil that they have been <a href="http://php.net/manual/en/security.magicquotes.php" target="_blank">removed from PHP 5.3</a>. They are testament to the amateur reputation of PHP. However, even in earlier versions of PHP, magic quotes could be easily disabled, and anyone who knows what they&#8217;re doing with PHP will have been doing so  for years. Furthermore any system written properly would insist on them being disabled. Not so with WordPress. In fact, being able to disable magic quotes poses a problem for WordPress. How can it guarantee to work if you can forcibly disable magic quotes?</p>
<p>Answer: By forcing them <em>even more forcibly</em>. WordPress 3 forces all script input through its own <code>wp_magic_quotes</code> function. Funnily enough <a href="http://wordpress.org/search/wp_magic_quotes" target="_blank">this isn&#8217;t documented</a>, but <a href="http://gist.github.com/542222" target="_blank">it looks like this</a>.</p>
<p><strong>4. mysqli support &#8211; or not.</strong></p>
<p>The core WordPress code-base uses the old mysql database driver. When I say <em>old</em>, consider that the mysqli (improved) extension was introduced for versions of MySQL &gt; 4.1.3  in PHP 5, which came out of beta in <strong>2004</strong>. WordPress does have a drop-in replacement system though, which allows you to place your own <code>db.php</code> file in <code>wp-content</code>. Here&#8217;s the third-party-developed <a href="http://barahmand.com/2010/06/wordpress-3-and-mysqli/" target="_blank">mysqli adapter for WordPress</a> that I am using on this site.</p>
<p>So that&#8217;s okay then, right? Well, judging by the required location for the <code>db.php</code> file, this adapter system looks rather like an after-thought. Using the alternative database adapter means calling <code>require_wp_db()</code> rather than just including the original <code>wp-includes/wp-db.php</code> file. Great &#8211; except is every plug-in out there doing this? Even WordPress itself isn&#8217;t fully patched to support this. At the time of writing, the &#8220;<em>famous </em>5-minute installer&#8221; uses the mysql adapter only &#8211; I had to <a href="http://gist.github.com/542243" target="_blank">patch wp-admin/install.php</a> to be able to install WordPress with only mysqli on my system.</p>
<p><strong>5. Depreciated code handling</strong></p>
<p>Watch out for depreciated function names. For example: WordPress changed <code>wp_specialchars</code> to <code>esc_html</code>. This will result in notices being raised in older themes, which you&#8217;ll only see if you enable <code>WP_DEBUG</code>. It&#8217;s a good idea to find-and-replace these if you&#8217;re upgrading an old theme to WP3. I don&#8217;t <em>really </em>hate WordPress for this, but it seems a bit of a pointless change, and isn&#8217;t it a bit late in the day for being pedantic about naming conventions? A whim like this just contributes to the amount of legacy in the system and the amount of code devoted to handling depreciation. There&#8217;s a 2,500 line file devoted to depreciating functions that are to be removed &#8220;later&#8221;. Making a clean break with WordPress 3 would have prevented many people from upgrading, so I understand why they do this; I just don&#8217;t like the effect it has on the code-base.</p>
<p>I could go on, but I&#8217;m hungry. If you want more, see what <a href="http://wonko.com/post/wordpresss_idea_of_sql_injection_security_addslashes" target="_blank">this guy has to say on the topic</a>.</p>
<p><a name="bitattheend"></a></p>
<p><strong>The bit at the end</strong></p>
<p>All in all, I&#8217;m disappointed that WordPress 3 wasn&#8217;t taken as an opportunity to improve upon its own legacy. It is fairly clear that popularity with amateurs, &#8216;ease of use&#8217; and backward compatibility is more important to the team than creating good, robust software that developers will appreciate. <a href="http://drupal.org/" target="_blank">Drupal</a> sets a much better example. I&#8217;m not saying I don&#8217;t have any gripes with Drupal, but they are much happier to take reduced backward compatibility on the chin when they release new versions. This means more incompatible modules, but such is the price of progress.</p>
]]></content:encoded>
			<wfw:commentRss>http://timwhitlock.info/blog/2010/08/21/wordpress-3-is-still-wordpress/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>WPTouch</title>
		<link>http://timwhitlock.info/blog/2009/08/28/137/</link>
		<comments>http://timwhitlock.info/blog/2009/08/28/137/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 21:50:38 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://web.2point1.com/?p=137</guid>
		<description><![CDATA[I just installed the WPTouch WordPress plugin which gives iPhone and Android visitors a tailored mobile UI. It&#8217; s great, here&#8217;s a pic of the iPhone interface (courtesy of @pepijndevos)]]></description>
			<content:encoded><![CDATA[<p>I just installed the <a href="http://www.bravenewcode.com/wptouch/" target="_blank">WPTouch WordPress plugin</a> which gives iPhone and Android visitors a tailored mobile UI.</p>
<p>It&#8217; s great, here&#8217;s a pic of the iPhone interface (courtesy of <a href="http://twitpic.com/photos/pepijndevos" target="_blank">@pepijndevos</a>)</p>
<p><span id="more-137"></span></p>
<div id="attachment_140" class="wp-caption alignnone" style="width: 424px"><img class="size-full wp-image-140" title="26226005-8196aba93e4cd8e2855d88c6d52a19b8.4a9850d7-full" src="http://web.2point1.com/wp-content/uploads/2009/08/26226005-8196aba93e4cd8e2855d88c6d52a19b8.4a9850d7-full.png" alt="WPTouch iPhone screen grab " width="414" height="770" /><p class="wp-caption-text">WPTouch iPhone screen grab </p></div>
]]></content:encoded>
			<wfw:commentRss>http://timwhitlock.info/blog/2009/08/28/137/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Model, View, Control Freak &#8211; Part 3</title>
		<link>http://timwhitlock.info/blog/2009/02/26/model-view-control-freak-part-3/</link>
		<comments>http://timwhitlock.info/blog/2009/02/26/model-view-control-freak-part-3/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 22:00:18 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[smarty]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://web.2point1.com/2009/02/26/model-view-control-freak-part-3/</guid>
		<description><![CDATA[« part 1 « part 2  Part 3 &#8211; Hacking the library Code libraries essentially provide abstraction. Abstraction is good. But anyone who regularly uses third party code in their work has at some point hit the knowledge wall; that point where the abstracted nature of the library leaves you helpless in resolving an apparent [...]]]></description>
			<content:encoded><![CDATA[<p><em><a href="http://web.2point1.com/2009/01/31/model-view-control-freak-part-1/">« part 1</a> <a href="http://web.2point1.com/2009/01/31/model-view-control-freak-part-2/">« part 2</a> </em></p>
<h3> Part 3 &#8211; Hacking the library</h3>
<p>Code libraries essentially provide abstraction. Abstraction is good. But anyone who regularly uses third party code in their work has at some point hit the knowledge wall; that point where the abstracted nature of the library leaves you helpless in resolving an apparent problem. You have limited choices &#8211; Wait for a patch, hit the forums, or hack it yourself. The latter is probably the worst thing to do, but deadlines are deadlines.<span id="more-96"></span></p>
<h4>To hack or not to hack</h4>
<p>I&#8217;d like to point out straight away that I don&#8217;t condone the hacking of third party code. If you hack a library it is much harder to update if a new version comes out.  The biggest risk is that you may destabilize another part if the system without realizing it. The author knows much more about the code than you, so unless it&#8217;s a project you&#8217;re deeply involved in it&#8217;s probably best to leave it alone. Ultimately if a reputable library is causing you problems, the chances are that either you&#8217;re using it wrongly, or you&#8217;re using the wrong tool for the job. However, theory and practice don&#8217;t always correlate, so bring on the anecdotes &#8230;</p>
<h4>Smarty</h4>
<p><a href="http://www.smarty.net/" target="_blank">Smarty</a> is almost synonymous with <em>PHP templating engine</em>. Smarty and I go way back and I&#8217;ve generally had a good experience, so I decided to use it recently in a bespoke CMS for one of <a href="http://publicreative.com/" target="_blank">our clients.</a> I used the disk caching features extensively and the CMS back office was designed to clear the cache whenever content is edited. It worked great, and when the client&#8217;s server team asked how the application would cope across multiple web servers all accessing a common <a href="http://en.wikipedia.org/wiki/Network_File_System_(protocol)" target="_blank">NFS</a>, I said it should be fine. I figured that the OS would take care of file locking and other such low level stuff that I generally don&#8217;t have to worry about, but mainly I was putting my trust in Smarty &#8211; A project that&#8217;s been around this long surely would have died out if it couldn&#8217;t cope with such a common server configuration. I was wrong. As it turns out, Smarty cannot cope with multiple servers reading and writing from the same cache. The reason for this took me hours to work out.. PHP has a <a href="http://www.php.net/clearstatcache" target="_blank">file status cache</a>, which will cause some serious confusion when multiple processes are modifying the same files during a script execution. The library didn&#8217;t seem to make any attempt to recover from errors that might be caused by this -</p>
<p><em>- so I hacked it.  </em></p>
<p>I&#8217;ll post my full solution at a later date, but basically it involves clearing the stat cache at certain, critical points.</p>
<h4>WordPress</h4>
<p>Another very popular PHP project &#8211; you are looking at right now. I&#8217;ve installed it a number of time on various different servers, but today I ran into trouble. To my astonishment even the latest version of WordPress (2.7) doesn&#8217;t support the <em>mysqli</em> extension. Only the old, arguably obsolete, mysql extension is supported. Depending on your server, you may not be able to install the old extension. This is the situation I ended up in today. I failed to find any trustworthy patches out there -</p>
<p><em>- so I hacked it.</em></p>
<p>It was fortunately fairly easy to replace all <code>mysql_*</code> function calls with <code>mysqli_*</code> function calls, but only time will tell if it will cause problems.</p>
<p>If you have any library hacking anecdotes, please post a comment</p>
]]></content:encoded>
			<wfw:commentRss>http://timwhitlock.info/blog/2009/02/26/model-view-control-freak-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

