Archive for the 'WordPress' Category

15 minutes could save you…

Monday, May 17th, 2010

Since I have a ton of things to do, I decided it was about time to spend some time with this blog, performance optimization-wise. Not do anything special, just the bare minimum, the no-brainer, works-every-time, easy stuff. And I'm quite happy with the results.

I only looked at the homepage, although the results will be seen throughout the site. Unfortunately there was a youtube video on the homepage, otherwise the results would have been even better, KB-wise

gzip on

First things first - turning compression on. I've previously whined about the host of this blog, site5.com and how I wasn't able to enable compression for some tests and had to make PHP do the compression. Turned out, all it takes is just ask and open a support ticket. Second level support decided to compile Apache with mod_deflate and I was good to go. I put this in .htaccess:

AddOutputFilterByType DEFLATE text/css text/plain text/xml application/javascript application/json

This blog has no JavaScript, just HTML and CSS. The HTML became 5K (from 23K) and CSS became 3 something (from 11K)

Flush

Decided to go fancy here and do first byte flush early on. That, of course, can be problematic, especially on shared hosting. I mean problematic is to have gzip working together with flushing (tips). Eventually I gave up wrestling with .htaccess and php.ini settings and let PHP handle it. That's why you may notice that text/html is missing from the DEFLATE list above.

So all it took was going to my WordPress theme, finding something called header.php and adding two lines of PHP.

One at the top:

<?php ob_start("ob_gzhandler"); ?>
<!DOCTYPE html ...

And one at the bottom:

<?php ob_flush(); flush(); ?>

Now the header part is flushed in one chunk and the rest in another. Check it in chunkview...

favicon.ico

I have no favicon so I get a lot of 404s, since browsers insist on downloading this little thing. So I created one. Took a social profile photo, croped (Option+K) and played with green colors in Mac's built-in Preview program. Then, ImageMagick:

$ convert -resize 16x16 dude.png PNG8:favicon16.png
$ convert favicon16.png favicon.ico

FTP. Done. No mo' 404s for favicon.

Minifying CSS

Copy-paste into CSSMin and CSS lost 30% of its weight. Now after gzipping and minifying, the CSS went from total 11.3K to 2.6K.

Cover images

I have some book covers on the homepage. One was simply linked to the publisher's site (extra DNS, connection...). Also turned out the publisher has redesigned the site so there was also a redirect. Disaster. Also the image was a 26K PNG where it could be 4k JPEG.

$ convert cover.png cover.png.jpg
$ jpegtran -copy none -optimize cover.png.jpg > cover.jpg

And just like that - 4 book covers were optimized.

Before/after

And that's all I did. I can probably do Expries headers too, convert/sprite all smiley GIFs and so on but that means touching more of WordPress, so I stopped here.

Now the page loads (onload) in 1.2 seconds, down from 2.2 (45% faster).

There are fewer DNS lookups, no 404s, no 301s

Page weight is down from 285K to 186K (34%). Actually if you exclude the youtube 142K SWF, the result is: 143K (before) to 44K (after) or a page weight saving of 70%. Not bad, not bad at all.

And the waterfalls. Before:

After:

PageSpeed score only went from 84/100 to 87/100 which was not impressive at all. I think 84K may have been too generous, but maybe not, given how worse sites there are out there.

So this is it - 15 minutes could save you 45% page load time and 70% download sizes :)

 

Flipity flop – mmm.phpied.com

Thursday, November 19th, 2009

Randomly browsing something on the iPhone it occurred to me that people could prefix their mobile sites with "mmm" instead of "m" or "i", as in mmm.mysite.tld. It's longer, true, but I don't think it will take longer to type three m's instead of one. And it's funny - mmm, it's like www. Only... flipped.

So I tweeted about it, got some good reasons why not to use something like this and Lucas Smith (of YUI fame) joked that I could setup mmm to deliver the same as www, only flipped.

Now, English is not my first language, so I miss out on many expressions, nuances, humor and so on. And there, I took it verbatim. :D

mmm.phpied.com

Ladies, and gentlemen, announcing the flipped version of this blog - http://mmm.phpied.com

You should be able to browse the whole site on its head, maybe with the exception of "popular posts" and other places, where I've hardcoded www.

how-to

All the changes had to be in my wordpress template, of course.

CSS first. Developer extraordinaire Ryan Grove have already solved the problem of x-browser flipping, so that was easy. At the bottom of the stylesheet, I added a new declaration block:

.flip {
  -moz-transform: rotate(180deg);
  -webkit-transform: rotate(180deg);
  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
}

Now the only thing was to add the class name to the body whenever the domain is mmm. That took some digging around WordPress, but eventually I decided to short-circuit the function call that takes the home URL option. WordPress provides a hook for that. So I added this to the beginning of functions.php in my template.


function mmm() {
  if (substr($_SERVER['HTTP_HOST'], 0, 4) === 'mmm.') {
    return 'http://mmm.phpied.com';
  } else {
    return 'http://www.phpied.com';
  }
}
add_filter('pre_option_home', 'mmm');

Finally, the change to header.php - replacing the body tag with:

<?php
  if (substr($_SERVER['HTTP_HOST'], 0, 4) === 'mmm.') {
    echo '<body class="flip">';
  } else {
    echo '<body>';
  }
?>

And voila - mmm.phpied.com

 

Test post from YQL

Thursday, July 9th, 2009

It works! I can post from YQL

--

Update: The post above was a test posting from YQL. This is pretty cool! YQL (Yahoo Query Language) lets you do SELECTs from any service on the web. Actually doesn't need to be a service, can be HTML (yes, scraping) or even plain text. Anything is data. If you have a service, you can also create custom tables and expose your data. But now you can not only SELECT, but also INSERT, UPDATE, DELETE (see how).

And checking this post I was just able to create a new WordPress post. This is co cool. It means you can interact with any service by simply using familiar SQL syntax. You don't have to know about XML-RPC and the hassles with WordPress or any other service. You don't need to read every service's (sometimes poor) documentation. It's just tables.

 

OpenSearch-enabling your blog

Friday, January 30th, 2009

Have you noticed when you visit some sites, there's a bluish glow in the search engine field in Firefox. Like this:

open search example firefox

What does that even mean? Well, it means you can add this site's search to the drop down list of search engines. This functionality is following the open search standard.

The things are actually pretty simple. You need to have an XML file <link>-ed to from your page.

For example on this blog I have this in the head:

<link 
  rel="search" 
  type="application/opensearchdescription+xml" 
  href="http://www.phpied.com/wp-content/plugins/open-search/open-search-xml.php" 
  title="phpied.com : Search in posts"
/>

So how do you add open search capability to your blog? With the OpenSearch plugin for WordPress, naturally.

BTW, if you're running PHP4 you might get errors during installation, in this case just open up the open-search-class.php and

  • replace all "public static" with empty string
  • replace all "private static" with empty string
  • replace all "self::" with "OpenSearch::"

This is it, enjoy and if you want to change the default icon, you need to look into replacing the image found in /wp-content/plugins/open-search/default-favicon.png

Here's what you get at the end:

And now your readers can add your search to their browser and quickly find content on your blog. Sweet.

 

Half-a**ed Adsense

Sunday, May 18th, 2008

It's official, I switched to the dark side. Not only does this blog has ads but they are Google's adsense. But hey, you gotta try.

Because I was so hesitant and have been postponing this moment for years, I only did it half-way. I added a condition - only show ads when displaying a single blog post and if the post is older than 30 days. This way if you follow this blog regularly by RSS or any other way, you won't see ads when posts are published.

So here's the code in case it's useful for someone. The code is not a wordpress pluggin, I only modified the "Single page" template.

<?php
// 1/2-ass adsense
if (time() - strtotime($post->post_date) > 30 * 24 * 60 * 60) {
?>
  <div style="float: right; padding: 20px">
  <script type="text/javascript"><!--
    google_ad_client = "pub-8608773432853916";
    /* 250x250, created 5/18/08, first phpied test */
    google_ad_slot = "4896717118";
    google_ad_width = 250;
    google_ad_height = 250;
  //-->
  </script>
  <script type="text/javascript" 
   src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
  </div>
<?php
} // end adsense
?>

Basically it's the adsense-generated code wrapped in a div so I can float it and then wrapped in a condition that compares today's timestamp with the post's date.

Let's see what happens, maybe tomorrow I'll wake up rich. Or famous. Or both. :D

 

Sancta Simplicitas: minimalistic WordPress theme using YUI CSS

Friday, April 25th, 2008

Sancta Simplicitas WordPress theme screenshot

Sancta Simplicitas is a WordPress theme that uses YUI CSS utilities: reset, base, fonts, grids. It's very minimalistic in a sense that it's pretty much all white and simple. Hence the name. The theme is probably not usable by itself, but it's a base on top of which you can create your own themes.

When creating a new WordPress theme, people usually take the default Kubrick theme but I personally find Kubrick too much. So Sancta Simplicitas has a very minimal stylesheet and is based on the WordPress classic theme.

The fact that it uses YUI grids makes it trivial to tweak: fixed size vs full width, width of the sidebar, position of the sidebar. Basically right after the <body> there's this:

<div id="doc3" class="yui-t5">

Changing the id doc3 to doc, doc2, doc4 or doc5 will give you different widths of the content. The default doc3 is full width. Then changing the class name yui-t5 will give you different position and width of the sidebar. yui-t1, yui-t2 and yui-t3 put the sidebar on the left hand side, yui-t4, yui-t5 and yui-t6 place it to the right. You can go even crazier from here, nesting grids to get a two-column sidebar and so on, it's really easy with YUI grids and the docs are here.

Download Sancta Simplicitas

» sansim.zip

 

JSPatterns.com up again

Wednesday, March 26th, 2008

After getting 300 megs of wiki content spam, I deleted the old wiki over at http://www.jspatterns.com.

Now restarted the project as a blog with static pages for the javascript patterns and blog posts for anything interesting in the ever so exciting world of JavaScript. So far nothing special there (example), but keep an eye on it, as I plan to fill up the TOC (recovered from the old wiki) with top quality content ;)

I suck at design and wasted two nights to come up with some custom wordpress theme for the new blog. I like the result, but that's just me. I also made the theme available for download, in case someone wants to consider it for a future project.

Talking of spam, yesterday my host deleted 2 gigs!!! of email spam from my hosting account, how crazy is that.

The new JSPatterns.com is running the latest release candidate WordPress 2.5, slick stuff.

 

Uncategorized

Wednesday, September 27th, 2006

Just published my previous posting and saw that apart from putting it in the JSON and JS categories, I've forgotten to take out the WordPress' default "Uncategorized" category. For a moment I wondered how many other people are making the same mistake, so I did a tag search in Technorati for Uncategorized.

uncategorized.png

7,102,321 posts! Compared to 33,637 posts with the tag "Comedy" which had the biggest font size in the homepage tagcloud. Man, as much as I like WordPress, I would blame the usability of the software in this case. 7 million incorrectly tagged posts cannot be wrong.

The other funny thing about the technorati page is the sponsored link, did you notice: "Find Uncategorized here, thousands of products..." ;)

BTW, just checked again and the posts are now 7,103,019. So it's like 1000 new uncategorized posts every 10-15 minutes.

Yeah, and I'm totally tagging this post Uncategorized! :D

 

Hosted blog at wordpress.com

Friday, November 25th, 2005

WordPress.com was launched after a testing, pre-go-live period. So now the question "how to start blogging" has a very simple answer:

How to start blogging ... in 5 minutes or less?

  1. Go to http://wordpress.com
  2. Fill-in 3 (three!) fields
  3. Check you email
  4. Login
  5. Write (something interesting)
  6. Click "Publish"

You can do this in 5 minutes or less, right? To me, this is the fasted way to start blogging ever! If you had any excuses to not start blogging and sharing your wisdom, now you don't :D

Not to mention how slick the interface is. Drag and drop, WYSIWYG, image upload (so intuitive!) - just to name a few bells and whistles.

» http://wordpress.com

 

Nielsen’s list of blog usability issues and me

Tuesday, October 18th, 2005

Jakob Nielsen posted his vision on the top 10 usability problems with blogs. As always, a fascinating read, a bit exaggerated at times, a bit of provoking touch at times... if you haven't, be sure to subscribe to get notified when he posts a new article in his Alertbox.

Anyway, here's the list along with some comments. Basically I'm running pretty unmodified version of the popular WordPress software (although most of the issues are blogger related, not software's) and I'm guilty as charged on most of those points :(

  1. No Author Biographies - half guilty, I have a scan of my ZCE certificate, it's a start!
  2. No Author Photo - guilty. On the todo list!
  3. Nondescript Posting Titles - well, I'm doing my best
  4. Links Don't Say Where They Go - yep, sometimes they don't. The use of the "title" attribute is suggested in the article, which is very nice, I have only two issues with it.
    First, it's not very widespread, therefore people don't expect to see it, hence they don't rest their mouses on links, waiting for descriptions. And as Mr. Nielsen would be the first to agree, setting and meeting expectations is critical.
    Second issue - it's a common concept in SEO that thou shalt always use title attributes. Therefore all SE optimizers plus all spammers will make sure they use titles up to a point where it's no longer considered "organic" optimization. So at some point Google will decrease the value of the title if not penalize you for its overuse. Something like: "Hmm, all links have titles on this page, fishy, veeery fishy..."
    On the other hand I do hate it when a see links like "Some people say" where every word is a link to a different site.
    And let me be nasty on this - Jakob has a link in his article and then says: To see a link title in action, mouse over the "link titles" link. Well, that sentence makes two incorrect assumptions jeopardizing
    the usability of the article: a/ the visitor has a mouse and is capable of using it and b/ the link title is supported by the visitor's browser
  5. Classic Hits are Buried - guilty as charged, I've been meaning to put a "Most popular posts" on the side. Sometimes I resist my urge to post new entries only to avoid pushing a popular posting out of the homepage.
  6. The Calendar is the Only Navigation - Not guilty, I have categories. It really is annoying when calendar is the only option to navigate a blog. But I believe this is fixed in most blogging apps. Maybe this was an issue at the beginning, when all blogs were more "logs" than "web".
  7. Irregular Publishing Frequency - guilty. Hmm, but scheduled publishing sounds more like work and blogging is supposed to be fun.
  8. Mixing Topics - guilty. But than again, a person has many interests and does it make sense to setup new blogs (and establish a posting schedule!) every time you want to post on a different subject. I think 7. and 8. are more aimed at more of the corporate-enterprise-marketing-ad blend of blogs out there.
  9. Forgetting That You Write for Your Future Boss - guilty. Actually no, not guilty! I've never thought I'm writing for a future boss, so how could I forget :D
  10. Having a Domain Name Owned by a Weblog Service - Not guilty, I own my shiny domain.

I can only add to the list:
11. Miles of homepage
I mean when you list the latest postings in their full length on the homepage. Apart from making the page too long and slower, it makes it unusable when you've structured your postings with header tags. In such cases it's hard to tell which is the title of the posting and which is a heading tag in its body. Personally I tweaked my WP install to show only summary on the homepage.

 

HTML entities converter

Thursday, June 16th, 2005

Often when you post code (in WordPress for example), you need to manually convert your >s into &gt;s, <s into &lt;s and so on. It can become tedious at times, so today I created this tool to help me out: HTML entities converter. (http://www.w3clubs.com/htmlentities.php) So I simply paste the code there and I get the converted text, ready to be used in a WordPress-powered posting.

In terms of implementation the tool is nothing more than a handy way to call the PHP function htmlentities(). The source code is also available for anyone curious enough to look under the hood.

 

highlighting php source code in WordPress

Friday, March 11th, 2005

The source code highlighting was probably the first feature I was missing in WordPress. I briefly googled my options and decided it would be quicker to add the missing feature myself, since it looked pretty straightforward.

So what I did:
1. I added a hilite() function in functions-formatting.php
<?php

function hilite($text)

{

    $text = str_replace('<? php', '<?php', $text);

    return preg_replace_callback(

             "'<\?php.*?\?>'si",

             create_function(

                 '$matches',

                 'return highlight_string($matches[0], true); '

             ),

             $text);

}

?>

The first line of the function is pretty curious, I agree. I needed it because I noticed that WP is adding a space between < and ? before saving to the database.

2. I added call to the new function in default-filters.php

add_filter('the_content', 'hilite');

... just before this line

add_filter('the_content', 'wptexturize');

And it worked! Only that the highlighting itself for some reason is using the HTML font tag (God forbid!), but I believe that's server setup.

Edit:
I added the filter to one more place in default-filters.php, in order to highlight source code when listing excerpts, for example category listing on an archive listing. So default-filters.php looks more like:
add_filter('the_content', 'hilite');
add_filter('the_content', 'wptexturize');
add_filter('the_excerpt', 'hilite');
add_filter('the_excerpt', 'wptexturize');

 

Smart quotes in WP

Monday, March 7th, 2005

I didn't like the way WP is adding smart qoutes to my posts. This is especially annoying when you post programming code. So it had to go :-\
I couldn't find an option to disable smart-quoting in the WordPress back-end so I took a look at the code and commented a few lines.

The commented lines were in
/wp-include/functions-formatting.php
in the wptexturize() function
right after the cockney conversions.

/*
$curl = preg_replace("/'s/", '&#8217;s', $curl);
$curl = preg_replace("/'(\d\d(?:&#8217;|')?s)/", "&#8217;$1", $curl);
$curl = preg_replace('/(\s|\A|")\'/', '$1&#8216;', $curl);
$curl = preg_replace('/(\d+)"/', '$1&#8243;', $curl);
$curl = preg_replace("/(\d+)'/", '$1&#8242;', $curl);
$curl = preg_replace("/(\S)'([^'\s])/", "$1&#8217;$2", $curl);
$curl = preg_replace('/(\s|\A)"(?!\s)/', '$1&#8220;$2', $curl);
$curl = preg_replace('/"(\s|\S|\Z)/', '&#8221;$1', $curl);
$curl = preg_replace("/'([\s.]|\Z)/", '&#8217;$1', $curl);
$curl = preg_replace("/ \(tm\)/i", ' &#8482;', $curl);
$curl = str_replace("''", '&#8221;', $curl);
*/

In this code snippet, the conversion of (tm) into ™ was also disabled, this is the line before the last one. Feel free to keep it your code, it was just easier to comment out the whole block.