Archive for the ‘Wordpress’ Category

WordPress + Lighttpd + WP-Supercache + Mobile Support

Last year I made some work on lighttpd support for wp-supercache. It instantly became very popular and basically anyone running wordpress on lighttpd uses it, even if it lacks support for wp-supercache newest features.

The amazing Jean Pierre Wenzel has recently released an updated version that adds a much needed mobile support.

You can check it out here.

Thanks Jean Pierre!

Lightning speed WordPress with Lighttpd and Supercache, part II

There was an error in the code I wrote for my previous post about lighttpd and wp-supercache. If you kept GZip disabled in you wp-supercache configuration, and your browser sent an Accepts gzip header, lightpress would serve the dynamic page (instead of the cached html page).

I did some refactoring and testing, and here’s the current version of rewrite.lua. This one will serve the correct gzipped or text content, while solving another bug with urls ending in ”/”:

function serve_html(cached_page)
  if (lighty.stat(cached_page)) then
    lighty.env["physical.path"] = cached_page
    print("Serving cached page: " .. cached_page)
    return true
  else
    return false
  end
end
 
function serve_gzip(cached_page)
  if (lighty.stat(cached_page .. ".gz")) then
    lighty.header["Content-Encoding"] = "gzip"
    lighty.header["Content-Type"] = ""
    lighty.env["physical.path"] = cached_page .. ".gz"
    print("Serving gzipped page: " .. cached_page .. ".gz")
    return true
  else
    return false
  end
end
 
attr = lighty.stat(lighty.env["physical.path"])
 
if (not attr) then
  lighty.env["uri.path"] = "/index.php"
  lighty.env["physical.rel-path"] = lighty.env["uri.path"]
  lighty.env["physical.path"] = lighty.env["physical.doc-root"] .. lighty.env["physical.rel-path"]
 
  query_condition = not (lighty.env["uri.query"] and string.find(lighty.env["uri.query"], ".*s=.*"))
  user_cookie = lighty.request["Cookie"] or "no_cookie_here"
  cookie_condition = not (string.find(user_cookie, ".*comment_author.*") or string.find(user_cookie, ".*wordpress.*") or string.find(user_cookie, ".*wp-postpass_.*"))
  if (query_condition and cookie_condition) then
    accept_encoding = lighty.request["Accept-Encoding"] or "no_acceptance"
    cached_page = lighty.env["physical.doc-root"] .. "/wp-content/cache/supercache/" .. lighty.request["Host"] .. lighty.env["request.uri"] .. "/index.html"
    cached_page = string.gsub(cached_page, "//", "/")
    if (string.find(accept_encoding, "gzip")) then
      if not serve_gzip(cached_page) then serve_html(cached_page) end
    else
      serve_html(cached_page)
    end
  end
end

Lighttpd and WP-Supercache? Now you can!

Update: there are some bugs with this code. You can find the newest (and best) version here

It’s often said that if you can’t find something in Google it doesn’t exist, and when I couldn’t find a way to serve WP-Supercached pages via Lighttpd I was pretty sure no one had ever published on the net a solution to my problem.

Nice permalinks were easy to fix, thanks to this tutorial, but cache was a no-go: the lighttpd wiki and the wordpress forums had no info, so I had to cook a solution for myself.

It was easier than I thought though:

-- rewrite.lua, in your WP_ROOT
attr = lighty.stat(lighty.env["physical.path"])
 
if (not attr) then
  lighty.env["uri.path"] = "/index.php"
  lighty.env["physical.rel-path"] = lighty.env["uri.path"]
  lighty.env["physical.path"] = lighty.env["physical.doc-root"] .. lighty.env["physical.rel-path"]
 
  query_condition = not (lighty.env["uri.query"] and string.find(lighty.env["uri.query"], ".*s=.*"))
  user_cookie = lighty.request["Cookie"] or "no_cookie_here"
  cookie_condition = not (string.find(user_cookie, ".*comment_author.*") or string.find(user_cookie, ".*wordpress.*") or string.find(user_cookie, ".*wp-postpass_.*"))
  if (query_condition and cookie_condition) then
    accept_encoding = lighty.request["Accept-Encoding"] or "no_acceptance"
    cached_page = lighty.env["physical.doc-root"] .. "/wp-content/cache/supercache/" .. lighty.request["Host"] .. lighty.env["request.uri"] .. "/index.html"
    if (string.find(accept_encoding, "gzip")) then
      if (lighty.stat(cached_page .. ".gz")) then
        lighty.header["Content-Encoding"] = "gzip"
        lighty.header["Content-Type"] = ""
        lighty.env["physical.path"] = cached_page
      end
    else
      if (lighty.stat(cached_page)) then
        lighty.env["physical.path"] = cached_page
      end
    end
  end
end

This rewrite.lua will serve compressed cached pages to those who accept gzip and plain html to those who prefer not to get gzip, while retaining the nice permalinks.

Tempe.st is dead, long live Tempe.st

Tempe.st is back online, for your reading pleasure. Site5 had a hard drive failure and their tech support had to restore from backups. While restoring they upgraded PHP and tempe.st stopped working because the Textile2 plugin segfaulted. I upgraded Textile2 to the newest version but it still segfaulted, so I had to enable PHP5.

Now it was wp-vimcolor that didn’t want to work. After investigating a bit, with the help of the tech support team I discovered a perl module was missing, and now I am finally back.

Little saturday night adventures :)

Back on the twitter-wagon

A big lot of thanks to Fullo for suggesting me to try twitter-tools to solve the performance related problems I had with twitter.

The plugin is wonderfully written and I customized it just a bit, to fit better with the layout. Now I have another problem, to keep the twitter updates as real-time as possible I had to disable wp-cache, the cache plugin I use on tempe.st, because it doesn’t think that a sidebar update is worth a page refresh.

Anyone can suggest a better cache implementation for wordpress?

Flickr and Yahoo and WordPress

Today I met a bunch of cool people at the Yahoo Italy HQ. I will talk about that in a future post (the very next one), but I had a urge to try Flickr and its integration with wordpress. Let’s see if it works by showing you a picture of my last day in Kyoto in Oct. 2006.

Me buying something to eat in Kyoto Station

Syntax highlighting in WordPress

Syntax highlighting in most CMS/Blog Engines is a straightforward business, you install a plugin and boom your code snippets get highlighted. Simple, right? Right, unless you want to publish erlang snippet :)

The plugin I was using was based on PHP-Geshi, a popular syntax highlighting library that unfortunately doesn’t support erlang. Looking through the wordpress plugin repository I found a little gem: WP-VimColor, based on VimColor, a perl module that uses the Vim syntax highlighting engine.

Good old Vim supports more than 200 languages, and obviously it supports erlang, unfortunately the plugin didn’t want to work with my wordpress installation.

Instead of nice cleanly formatted code I got some gibberish followed by unformatted code and then some gibberish again. I looked into the code and couldn’t find what the problem was, then I remembered I had the same problems with Radiant CMS, that used textile. I use textile on this blog too and deactivating the textile filter solved the gibberish problem, but gave me lots of php errors related to the file functions.

Some more tests revealed the source of this problem:

$in_file = tempnam($GLOBALS['conf']['file_directory_temp'], 'pl');
$out_file = tempnam($GLOBALS['conf']['file_directory_temp'], 'htm');

The two global variables do not exist, so I just replaced them with ”/tmp” and this problem was fixed. I still had the textile conflict problem, to fix it I changed the last two lines of the plugin file to:

add_filter('the_content', 'pre_proccess', 1);
add_filter('the_content', 'vim_color', 2);

and the if block inside _vimcolor_process_color()_ to

if( $multiline ){
  $html = preg_replace('/\r/s','',$html);
  $html = preg_replace('/\n/s','<br />',$html);
  $html = '==<pre class="codeblock">'. $html .'

'; $html = preg_replace('/ /s','&nbsp; ',$html);
}else{ $html = '

'. trim($html) .'
==’;
}

These two fixes make the syntax highlighting filter run before textile and use the ”==” modifier to tell textile not to fiddle with the code.

Now I have beatifully formatted code on my blog and I can also publish erlang snippets, nice!.

Or, as my friend Bard would say:

{bard, comment, Value} = {bard, comment, nice}.