A few days ago, I decided to replace my motherboard’s dirty, noisy, five-year old Socket 478 cpu fan with a brand new and significantly larger Ultra fan and heat sink. As I opened the case, it crossed my mind to just unscrew the old fan and screw in the new fan. I suppose some part of me anticipated major headaches ahead, but I didn’t listen to that part. Instead, I listened to the part of me that said, “The right way is to use the new, larger and therefore better heat sink.”

I lifted the levers of the heat sink brackets, breaking the first one and in the process charging past another clear warning sign. After carefully easing the brackets off the mount with a flat-head screwdriver, I gently pulled on the heat sink, rocking it slightly but not twisting it. With a quiet sound similar to velcro being pulled apart, the heat sink was free and I was looking into the empty socket on the motherboard—the cpu was stuck to the heat sink.

With only minimal exertion, I had managed to pull out the cpu along with the heat sink; the two still very firmly attached to one another with some sort of adhesive that Gateway used instead of grease. Figuring wrongly that because it came out so easily, it should go back in without much trouble, I lined up the pins and tried to press the chip back into the socket. The still-attached heat sink, of course, preventing me from lifting the socket’s locking bar. Luckily, I quickly realized that this plan held the very real potential for disaster, and that if the chip wasn’t already broken, bent pins would certainly ruin any chance of salvaging it. So, I backed off and consulted Google, where I found some excellent advice.

Placing the chip/heat sink combo on the table with the pins up, I wet a partially denuded Q-Tip with Goo Gone and worked it along the seam, being careful to avoid getting any Goo Gone on the PCB or in the gap between the PCB and the chip’s metal cap. Then I paced around anxiously for ten minutes and applied a few more drops. The instructions suggested placing a credit card against the seam of the chip and the heat sink and tapping the card with a hammer, so I tried that, but was afraid that a tap powerful enough to free the cpu might also break it. So I instead placed the point of a pocket knife in the seam, angled toward the heat sink, and gave that a few timid taps. And lo, the chip dropped right off. With more Goo Gone and some cotton balls, I removed the remaining adhesive from the chip, wiped it down with rubbing alcohol for good measure, greased it and replaced it in the socket.

Then I tried to set the new Ultra heat sink into place, but it was ever so slightly too wide for the mount. This put me over the edge. After about 2 hours of panic and visions of coughing up for a new motherboard and chip, I was stuck using the old heat sink. So I cleaned it off, screwed the new fan into it, and clipped it into place. I hit the power button, and amazingly, it POSTed and booted normally, after a warning that Windows wasn’t shut down properly.

Strike another one for doing a project the easy way instead of the right way.

I’ve written a WordPress plugin that will convert the page title and post title to ‘title case’ capitalization. Title case is also often referred to as “headline style”, and incorrectly as “initial caps” or “init caps”. Title case means that the first letter of each word is capitalized, except for certain small words, such as articles, coordinating conjunctions, and short prepositions. The first and last words in the title are always capitalized.

This plugin may be useful if you’re trying to give the titles on your site a consistent appearance, but it’s no substitute for writing a good title. There are way too many exceptions and rules to make a simple script behave correctly all of the time.

The plugin is smart enough to not capitalize the following:

  • Coordinating conjunctions (and, but, or, nor, for)
  • Prepositions of four or fewer letters (with, to, for, at, and so on) (limited)
  • Articles (a, an, the) unless the article is the first word in the title

But the plugin isn’t perfect. It won’t capitalize an article that is the last word in the title. It fails on subordinating conjunctions. It conservatively de-capitalizes only some of the prepositions, hopefully reducing the chance of incorrect behavior. For example, it leaves the word over caps, because over can be an adverb, an adjective, a noun, or a verb (caps) or a preposition (not caps), and determining how a word is being used in a title is really beyond the scope of a humble plugin.

The plugin requires you to edit it for certain product names, like “iPod”, and cool-people names, like “Olivia d’Abo” or “Jimmy McNulty”. It’s not savvy enough to know that acronyms, like “HTML”, should be all caps unless they’re used in particular ways, such as in the case of “Using the .html Suffix”, unless you tell it. That said, editing the plugin for these particular words is very easy.

Even with all these limitations, it beats using CSS to {text-transform: capitalize} the titles or just applying PHP’s ucwords() to the entire thing. But I’m guessing that dissatisfaction with one or both of those two methods is what brought you to this page in the first place.

On the upside, it capitalizes any word following a semicolon or a colon, e.g.: “Apollo: A Retrospective Analysis”. It also capitalizes any word immediately preceded by a double or single quote, but only if you haven’t bypassed WordPress’s fancy quotes feature.

How it works

The plugin first finds all words that begin with a double or single fancy WordPress quote and adds a space behind the quote. It capitalizes all of the words in the title with ucwords(), then selectively de-capitalizes some of the words using preg_replace(). It then uses str_ireplace(), a case-insensitive string replace function, to correct the odd capitalization of certain other words. Finally, it removes the spaces behind the quotes.

The code

This is what the code looks like. It should be pretty easy to follow what’s happening.

<?php

function ardamis_titlecase($title) {
		$title = preg_replace("/&#8220;/", '&#8220; ', $title); // find double quotes and add a space behind each instance
 		$title = preg_replace("/&#8216;/", '&#8216; ', $title); // find single quotes and add a space behind each instance
		$title = preg_replace("/(?<=(?<!:|;)W)(A|An|And|At|But|By|Else|For|From|If|In|Into|Nor|Of|On|Or|The|To|With)(?=W)/e", 
'strtolower("$1")', ucwords($title));  // de-capitalize certain words unless they follow a colon or semicolon
		$specialwords = array("iPod", "iMovie", "iTunes", "iPhone", " HTML", ".html", " PHP", ".php"); // form a list of specially treated words
		$title = str_ireplace($specialwords, $specialwords, $title); // replace the specially treated words
		$title = preg_replace("/&#8220; /", '&#8220;', $title); // remove the space behind double quotes
		$title = preg_replace("/&#8216; /", '&#8216;', $title); // remove the space behind single quotes

		return $title;
}

add_filter('wp_title', 'ardamis_titlecase');
add_filter('the_title', 'ardamis_titlecase');

?>

Download

Download the plugin, upload it to your site, and activate it.

Download the Title Case Capitalization WordPress plugin

Further customization

The plugin won’t alter words written in all caps or CamelCase. You could use ucwords(strtolower($title)) to convert the entire $title to lowercase before applying ‘ucwords’. This may fix instances where someone has typed in a bunch of titles with the caps lock key on. But you’ll then have to compensate for words that should be all caps, like ‘HTML’, ‘NBC’, or ‘WoW’, in $specialwords.

An alternative using a ‘foreach’ loop

It’s possible to do something similar using a foreach loop. This isn’t as graceful, in my opinion, but I suppose it’s possible that someone may find it works better.

<?php

function ardamis_titlecase($title) {
	$donotcap = array('a','an','and','at','but','by','else','for','from','if','in','into','nor','of','on','or','the','to','with'); 
	// Split the string into separate words 
	$words = explode(' ', $title); 
	foreach ($words as $key => $word) { 
		// Capitalize all but the $donotcap words and the first word in the title
		if ($key == 0 || !in_array($word, $donotcap)) $words[$key] = ucwords($word); 
		if (preg_match("/^&#8220;/", $word))
			$words[$key] = '&#8220;' . ucwords(substr($word, 7));
		elseif (preg_match("/^&#8216;/", $word))
			$words[$key] = '&#8216;' . ucwords(substr($word, 7));
	} 
	// Join the words back into a string 
	$newtitle = implode(' ', $words); 
	return $newtitle; 
}

add_filter('wp_title', 'ardamis_titlecase');
add_filter('the_title', 'ardamis_titlecase');

?>

Credits

Thanks to Chris for insight into the preg_replace code at http://us2.php.net/ucwords. Thanks to Thomas Rutter for insight into the foreach code at SitePoint Blogs » Title Case in PHP.

I’d like to create a WordPress theme using only some of the template files. Unfortunately, when it comes to theme inheritance, it seems that WordPress allows you only two choices. Your custom theme:

  1. may contain a stylesheet and images, this “theme” then inherits all of the template files from another theme, or
  2. must contain a complete set of template files, which is, at its most minimal, style.css and index.php.

Apparently, there is no way to create a theme with a partial set of template files. Adding the line “Template: default” to the theme header section of a custom stylesheet will allow that theme to inherit all of the template files from the default theme, but it will also cause WordPress to ignore any files in the custom theme.

In my opinion, there should be an option to make WordPress fall back on the default theme when an expected file isn’t found in a custom theme. A custom theme could then contain only those files that have been modified from the default, so that future changes any unmodified default theme files are automatically inherited by the custom theme after upgrading.

The argument against this type of behavior is that, should the default theme be radically changed, it’s possible that such inheritance will result in a broken custom theme. This is a valid concern, but since I’ve been using WordPress, the files of the Kubrick theme haven’t changed in such a way as to break as a result of this inheritance.

I’m hoping that someone out there has come up with a way to change this behavior and make the themes degrade gracefully. According to Ryan Boren‘s post on the wordpress.org support forums

You can’t pick and choose certain files to inherit, you must inherit a full set of templates. It’s an all or nothing deal. For awhile we did allow individual inheritance, but it confused the hell out of people and was a bit too heavyweight during page load since the code had to go looking in multiple locations in order to put a theme together. That’s why I call themes that inherit templates from other themes “stylesheet only” themes. They don’t have any templates of their own.

As a possible solution, I suppose one could use PHP includes in otherwise empty template files to include the default files.

I’m getting a periodic blue screen of death (BSOD) with my D-Link AirPlus DWL-G520 wireless network PCI card. The BSOD occurs intermittently, but will always occur immediately after I click on a link in a web page.

More precisely, I’m using a D-Link AirPlus Xtreme G 108Mbps PCI Adapter DWL-G520 Wireless PCI Adapter(rev.B) card with WPA-PSK network authentication and TKIP data encryption. I haven’t gone to the trouble of opening the case to find the exact hardware specs, because I have a lot of crap piled on top of it. The driver (according to the D-Link web site) is version 3.18, released on 5/9/2005. According to Windows Device Manager, it’s driver version 4.0.0.1414, released on 3/22/2005. Thanks for the added confusion, guys.

This card then connects to a D-Link DI-624 Wireless Router with hardware version C3 and firmware version 2.70. I realize that there is a newer firmware version out there, version 2.75, but I’m not sure it’s Xbox compatible, so I’m holding off on updating.

The error itself is a STOP: 0x000000D1 DRIVER_IRQL_NOT_LESS_OR_EQUAL which occurs in the file A3AB.SYS.

I’ve looked into this problem, and while there are a few bulletin board topics mentioning the A3AB.SYS BSOD, they generally tend to suggest using Atheros drivers instead of the D-Link-recommended drivers. The deal is that Atheros developed the chipset, AR5002G, for the DWL-G520, and also writes its own drivers for the chipset which are more recent than the drivers supplied by D-Link. At least one poster recommended the Ekahau Wireless Utility and Driver. After ruling out some other possible causes, I’ll probably try these alternate drivers.

My theory is that the error is due to the WPA-PSK / TKIP encryption, which I turned on shortly before getting the BSOD for the first time. Unfortunately, to test the theory that the error is related to the WPA-PSK / TKIP encryption, I would have to fiddle with my network security for a few days, something I’m unwilling to do.

It has been suggested that the error is caused by the network card overheating due to its proximity to the video card, and while excess heat may be the cause of someone’s problems, my system functioned perfectly fine for months with the cards in their current slots. It’s still a good idea to try to keep your other PCI cards as far away as possible from the video card, because that thing will generate some heat.

Furthermore, some people report that when they search their system for A3AB.SYS, they get multiple files, but with different sizes and time stamps. There is also the implication that A3AB.SYS should exist only in the D-Link drivers folder created when the driver is installed, and not in C:WINDOWSSYSTEM32DRIVERS. Whether this is actually problematic is something I’d have to look into.

Another possibility raised on the boards is that the BSOD is caused by the router’s Super G Mode, specifically, by the Super G with Dynamic Turbo option. Of the possible fixes, this is the easiest to test, so it’s going to be the first one I try. I’ve changed the mode to Super G without Turbo on the router.

To sum up, the D-Link AirPlus DWL-G520 wireless network PCI card seems to be a bona fide piece of crap some of the time.

Update: August 28, 2006

Well, after a few weeks of using the router with the turbo mode disabled, there have been no BSODs. Who’da thunk it? If you’re having similar problems with your router, I would recommend that you change the mode from Super G with Dynamic Turbo to Super G without Turbo. To do this, log into the router’s admin panel, and from the Home tab, click on the Wireless button. Change the value in the Super G Mode : drop down menu to “Super G without Turbo”.

I needed to find a satisfactory way of adding WordPress tags and theme elements (such as the sidebar) to pages that exist outside of WordPress. A non-WordPress page could then appear to be seemlessly incorporated into the site, wherein the layout automatically updates with changes to the theme template files, and could use the same header, sidebar, and footer as a normal WordPress page.

The first few solutions that I found involved adding a line to each non-WordPress page. This does indeed allow the page to incorporate WordPress tags, theme elements and styles, but there is a serious drawback to this method because of the way WP manages a web site.

When you click on the link to a WP page, or enter it into the address bar, you aren’t actually going to a file that resides at that address. Instead, WP uses that address as an instruction to pull various database entries and form an index.php page that resides in the WP installation directory. For example, while the address for this page appears to be http://www.ardamis.com/2006/07/10/wordpress-googlebot-404-error/ , the actual page is at http://www.ardamis.com/index.php.

WordPress assumes that it is responsible for every page on the site, and that there are no pages on the site that it doesn’t know about. If you try to browse to a page that WP doesn’t know about, it sends you a 404 error page instead. This is what you want it to do, so long as you don’t create any pages outside of WordPress.

But a problem arises when you do want to create a page that WP doesn’t know about. When you visit the page, WP checks the database and finds that it doesn’t exist, so it puts a 404 error in the http header, but the page does exist, so Apache sends the page with the 404 error. This behavior seemed to cause some problems with some versions of IE but none with Firefox. It did, however, result in a 404 header being given to Googlebot, so that non-WordPress pages would incorrectly show up in Google Sitemaps as Not Found.

To get around this problem and send the correct http header code: HTTP Status Code: HTTP/1.1 200 OK, I needed to require a different file, wp-config.php, and then select specific functions for use in the page. results in a page that can use all of the desired tags and theme elements and also sends the correct header code: HTTP Status Code: HTTP/1.1 200 OK

The following code results in a page that can use all of the tags and theme elements (you may need to adjust the path to wp-config.php):

<?php require('./wp-config.php');
$wp->init();
$wp->parse_request();
$wp->query_posts();
$wp->register_globals();
?>

<?php get_header(); ?>

<div id="content">
<div class="post">
<h2>*** Heading Goes Here ***</h2>
<div class="entry">
*** Content in Paragraph Tags Goes Here ***
</div>
</div>
</div>

<?php get_sidebar(); ?>

<?php get_footer(); ?>

Testing the method

Using wp-blog-header.php as the include, I created a GoogleBot/WordPress 404 Testing Page as the index.php file in the /testing/ folder. I added the url http://www.ardamis.com/testing/ to my Google xml sitemap, and waited for the sitemap to be downloaded. Sure enough, a few days later Google Sitemaps was listing the /testing/ url among the Not Found errors.

The next step was to remove what I suspected was the culprit, the include of the WordPress header, wp-blog-header.php, and see if Googlebot could again access the page. A few days after removing the include, and after the sitemap was downloaded, the Not Found error disappeared. I’m interpreting this as Googlebot once again successfully crawling the page.

The third step was to use the above code, including wp-config.php and then testing the HTTP Request and Response Header. The header looks ok, and Googlebot likes it. It looks like this does the trick.

MG2 / MiniGal 2 is a free and easy-to-use PHP image gallery script. It is being offered as a non-profit service for photographers and webmasters who want a simple, fast and good-looking image gallery on their web site. No database is required, which makes MG2 ideal for people who want a PHP image gallery script but don’t have access to a SQL database.

I’ve been using MG2 / MiniGal 2 for over a year, and it’s perfect for sites that have a few dozen images to display, but that don’t require a massive image CMS. MG2 is very lightweight, weighing in at around 200k zipped, and customizable via template-based themes. It installs easily and features a web-based admin panel which allows images to be uploaded and titles and descriptions assigned to them.

MG2 finally validates as XHTML 1.0 Strict

MG2 claims to produce valid HTML out of the box, but I’ve found it to be otherwise. Because some lines of code bypass the template system, and some of those lines happened to contain attributes which are illegal in XHTML 1.0 Strict, it was necessary to make a number of changes to the core files before the gallery would output valid code. Until these core files were modified, even the most carefully constructed template would fail to validate because of elements beyond the template’s control.

The developer, Thomas Rybak, is assumed to be busy working on a new version, so I decided to pick up the baton and modify the most recent version, 0.5.1, to make the output code validate as XHTML 1.0 Strict. This update is not intended to be a new version or a fork; to whatever extent possible, the script remains the property of Thomas Rybak.

I have also created a new MiniGal theme template, called “minimalist,” which uses valid XHTML and CSS, and have included it in the download. Minimalist is loaded as the default theme during new installations and incorporates some improvements over the previous default theme, “rounded,” particularly in the area of search engine optimization. For example, the thumbnails page’s title tag now shows the current folder name and the gallery name, and the view image page’s title tag shows the image title, folder name, and gallery name. Each individual image page now contains a meta description tag which outputs the description for that image. (This description should be kept brief, less than 20 words, for best effect.)

Changes to the core and template files

The following changes to the MG2 / MiniGal 2 core and theme template files do not add any new functionality, but in some cases make existing functions more useful:

  • Removed all the illegal attributes that were preventing validation as XHTML 1.0 Strict, such as “align”, “border”, and “target”.
  • Replaced some unnecessary tables with divs.
  • Added a PHP “if statement” to hide the slide show link on those pages where it would be invalid. (Ex. pages that contain only subfolders)
  • Added a PHP “if statement” to hide the pages navigation on those pages where it would be pointless.
  • Clicking on an image during a slide show opens that image’s view image page, stopping the slide show.
  • Added a PHP “if/else” to display “(untitled)” if an image has no title.
  • Added a link back to the main gallery page from all subfolder pages.
  • Removed the automatic insertion of “<br />” at the end of the image description. The description is now meta tag friendly (see included templates).
  • The “Powered by…” td colspan now knows how many columns the page displays, rather than just using 100 to be safe.
  • Removed some of the meta robots instructions. Google is able to index the image gallery, so why not allow it to do so? (Robots are still banned from the slide show.)
  • Each image’s alt and title tags now return the image’s title.
  • Copyright changed to 2006.

Further refining MG2 usability and SEO with new functionality

One of my major complaints with MG2′s folder handling was that when viewing an image, the user couldn’t see what folder the image belonged to. My changes to the templates permit the view image page template (and optionally, the slide show template) to display the last folder to be opened, which in most cases should be the folder within which the currently viewed image belongs. This is accomplished by assigning the name of the last viewed folder to a variable: $lastfolder. The value of $lastfolder is then stored in an external file named “lastfolder.php” located in the gallery root where it can be retrieved later via an include in the view image page template.

Each thumbnails page can be thought of as a folder containing more folders, images, or a combination of both. Each thumbnails page has a name, which is defined by the gallery admin during folder creation, and which is stored by MG2 as the variable $currentfolder. The value of $currentfolder changes every time a new folder is opened. The gallery title is permanently assigned to the value of $mg2->gallerytitle. My script uses these two rules to determine the current location. While the user is viewing the gallery root, $currentfolder will equal that gallery’s gallery title. While the user is viewing any thumbnails page, the value of $lastfolder will be equal to the MG2-defined variable $currentfolder.

In an attempt to lighten the processing load, the script checks to see if the user has changed folders by comparing the value of $lastfolder with that of $currentfolder, and only writes to the file if the values are not equal. (This means that going back and forth between a folder and one of the images it contains does not necessitate writing to the file.)

Detail of the changes to the thumbnails page script

The page title is generated as follows: each time the thumbnails page loads, it checks to see if the current location is the image gallery root. If the location is the gallery root, the page title displays the gallery title. (ex.: My gallery) If the location is not the gallery root, the title displays the name of the current folder, followed by a separator, followed by the gallery title. (ex.: Folder A | My gallery)

Breadcrumb navigation is handled in a similar way. I’ve arranged the navigation in the Minimalist theme template to expand left to right, but the elements could easily be reordered to expand in another direction. If the current location is the gallery root, then the location is displayed as just the gallery title. (ex.: Location: My gallery) If the current location is not the root, then the location is displayed as the gallery title acting as a link back to the gallery root, followed by a separator, followed by the name of the current folder. (ex.: Location: My gallery | Folder A)

The thumbnails page also defines a variable, $lastfolder, as being equal to the name of the current folder, and saves the value in an external file to be retrieved later by the view image page. Each time the thumbnail page loads, it reads the value, if any, of the variable $lastfolder from the file “lastfolder.php” located in the gallery root. The page determines if the current location is other than the gallery root, then checks to see if we have changed folders by comparing the value of $lastfolder to the MG2-defined value of the variable $currentfolder. If we have changed folders, the page updates $lastfolder by redefining $lastfolder as equal to $currentfolder and then writing the new value to lastfolder.php.

Phew. Had enough? Ok, the download below contains the full MG2 / MiniGal 2 v0.5.1 PHP image gallery script, with the core files modified to produce valid XHTML 1.0 Strict code and the above described changes to functionality, plus the new “minimalist” custom theme template files. Please treat this as a work in progress. It should function as described, but if you notice anything amiss, please post a comment.

Download MG2 v0.5.1-Ardamis

This post was written in 2006. As of WordPress 2.5 (released in 2008), a new seplocation parameter has been added to wp_title. This allows you to reverse the page title and blog name in the title tag, in much the same way as I have described in this post. The page at http://codex.wordpress.org/Function_Reference/wp_title provides this example:

<title><?php wp_title('|',true,'right'); ?><?php bloginfo('name'); ?></title>

I’d recommend using it, instead of the admittedly complicated instructions below.

Getting the title tag just right in WordPress isn’t as easy as it ought to be. Currently, a popular title syntax for SEO purposes shows the page’s title, followed by a pipe separator, followed by the site’s name. In practice, this preferred syntax would appear as “Page Title | Site Name”. For whatever reason, the default theme in WordPress has this order reversed, so that each page’s title starts with the blog name, followed by a » separator, some useless clutter, another » separator and then the page’s title. The instructions below will help you optimize the title tag to take advantage of the prefered method.

The code for the default WordPress title tag, which is found in the “header.php” file, looks like this:

<title><?php bloginfo('name'); ?> <?php if ( is_single() ) { ?> &raquo; Blog Archive <?php } ?> <?php wp_title(); ?></title>

It seems like it should be an easy thing to clean up. We remove the unnecessary “Blog Archive” stuff and then switch the two title template tags, putting <?php bloginfo('name'); ?> behind <?php wp_title(); ?>.

Our title tag code now looks like this:

<title><?php wp_title(); ?><?php bloginfo('name'); ?></title>

But if you make this obvious change and reload one of your blog’s post pages in your browser, you’ll notice that the separator, which is inextricably part of the wp_title template tag, wants to be in front of the page title and is now the very first character in your browser’s title bar, resulting in something like “» Page Title Blog Title”. Furthermore, we are missing a desired separator between the page title and the blog title.

Let’s first do something about that initial separator. The wp_title tag we’ve been using so far, <?php wp_title(); ?>, is abbreviated, meaning that there are some options that are being allowed to fall back to their default states because we haven’t specifically provided otherwise. Changing the behavior of the wp_title separator is as easy as manipulating these options in the unabbreviated wp_title template tag. The full tag, including the options, looks something like: <?php wp_title('sep', display); ?>, where ‘sep‘ stands for whatever separator you want and display is either “true” or “false”, depending on whether you want the title displayed. For example, if you want to use the pipe symbol ” | ” to appear at the beginning of your post title, you would use: <?php wp_title('|'); ?>. (The display option defaults to “true”, which is what we want here, so I’ll omit that part in the future for the sake of brevity.)

This fiddling with different separators works just fine when the elements of the title are in the default order, but when we put wp_title at the beginning of our title tag, we get a separator as the first character in our title. We don’t want a separator in front of the Page Title, so we will use the ‘sep‘ option described above to tell WordPress to use an empty string (represented by the absence of text between two quotes) as the separator, like so: <?php wp_title(''); ?>. This is the preferred method for removing the leading separator from the wp_title tag. Now the code for our title tag looks like:

<title><?php wp_title(''); ?><?php bloginfo('name'); ?></title>

This title will cause your browser’s title bar to display “Page Title Blog Name”. We are getting closer to what we want.

Without explaining exactly how it works, let me just offer you an optional line of code to selectively add or omit a separator between the Page Title and the Blog Name as appropriate for each page: <?php if(wp_title(' ', false)) { echo ' | '; } ?>. Place this line of code between the wp_title and bloginfo template tags, as so:

<title><?php wp_title(''); ?><?php if(wp_title(' ', false)) { echo ' | '; } ?><?php bloginfo('name'); ?></title>

Reload the page again, and your title bar should show you exactly what we want, “Page Title | Blog Name”, without a leading separator. Any page without a Page Title, the home page, for example, will just have “Blog Name” in the title tag. Everything up to this point is explained on the WordPress Codex page dealing with Template Tags/wp_title. For most users, this is as far as one wants or needs to go to achieve the desired result.

Further optimization

But… if you’re really humorless about clean code, there’s more to be done. If you view the source code of these pages, you’ll notice that there are a handful of spaces after the opening title tag and before your Page Title. Yikes. Lucky for you, I like my code to be tidy and am also pretty interested in SEO, and for both of these reasons, albeit in unequal parts, these leading spaces in the title tag are unacceptable.

There are three ways to make WordPress close up the spaces whenever we declare an empty string as our separator, as in: <?php wp_title(''); ?>. The first method requires editing a file in the WordPress core. The second method is accomplished by adding a few lines of code to your theme’s ‘functions.php’ file. The third method uses a simple plugin.

Using any of these methods to remove the spaces will also remove the separator that WP wants to add between the year, month, and DD.MM.YY date of the titles of the monthly archives. So if your separator was a pipe symbol, they looked something like: 2006 | December | 17.12.06 | Ardamis.com and after removing the spaces they will look like: 2006 December 17.12.06 | Ardamis.com

Method 1 – the core file

This method involves hacking a core file. This is the most direct way to get the desired result. It basically corrects the problem the moment it happens.

For WordPress version 2.2

The file we want to edit is: wp-includesgeneral-template.php. Open it up and find the following lines (beginning at line 224):

$prefix = '';
if ( !empty($title) )
	$prefix = " $sep ";

Add the line if ( $prefix == ' ' ) { $prefix = ''; } below the block, so that the block now reads:

$prefix = '';
if ( !empty($title) )
	$prefix = " $sep ";
	
if ( $prefix == '  ' ) { $prefix = ''; }

Method 2 – functions.php

If you’re not comfortable editing a core file, and if you don’t want to install yet another plugin, this method will also work. Open the ‘functions.php’ file in your theme folder and add the following lines. Depending on your theme, functions.php may already contain some PHP code; that’s ok, just tuck this in at the end. The first line of functions.php should be <?php and the last line should be ?>. If those lines don’t exist, add them and then add the following code between them.

function af_titledespacer($title) {
	return trim($title);
}

add_filter('wp_title', 'af_titledespacer');

Method 3 – a plugin

If plugins are more your speed, you can get the same results with my Despacer plugin.

Download the Despacer WordPress plugin

Utilizing the changes in the template files

We can now remove the separator and the annoying blank spaces on an instance-by-instance basis by specifying an empty string as the separator, as so: <?php wp_title(''); ?>. By way of example, to hide the separator and remove the blank spaces, a “Page Title | Blog Name” title tag would look like:

<title><?php wp_title(''); ?><?php if(wp_title(' ', false)) { echo ' | '; } ?><?php bloginfo('name'); ?></title>

If anyone finds a better way of arriving at this result, preferably entirely within the template files, please leave me a comment, or post to the WordPress support forum.

You may notice that one poster to the WordPress forums suggests that the search engines don’t care if there is white space in a web page. While I agree that the search engines and browsers don’t have any problem parsing pages that contain chunks of white space, a gap at the beginning of the title tag looks very unnatural to me. No human would intentionally add a bunch of blank spaces to the beginning of the tag, and it’s generally understood that for SEO purposes, a page that looks handcrafted is superior to one that looks like it has been slapped together by a script. This may not be a problem now, but Google and the other search engines are constantly working to remove spam/garbage/scraped sites from their results, and they may one day use weirdly unnatural artifacts like this to identify them.

These Godaddy promotion / coupon codes were confirmed valid as of June 30, 2006. Godaddy expires promotional codes pretty regularly, so it pays to just search for codes when you need them and then try a bunch to find the best discount.

There is a great list of GoDaddy coupon codes at Fat Wallet that is more up-to-date than this one, but even then, some are expired or invalid.

  • david = $1
  • usa6 = $1
  • candy = $1
  • todd = 10%
  • gdbb730 = 10%
  • gdbb85710 = 10%
  • gdbb776 = 10% off non-domain renewals and $7.50 .com & .net renewals
  • goox025afc = 7.49 .com renewals
  • OYH10 = $2.50 off / $7.49 .com and renewals
  • gd4920d5 = 20% off
  • BBCN10AF = 20% off $40 or more
  • BB73025 = 25% off $75 or more
  • gdbba46 = 25% off $75 or more
  • gda3145a = 26% off
  • DEC2012E = 25% off
  • OCT12BB = 30% off $100 or more

For starters, Petopia is a wonderful site for identifying pets. It has a wealth of information on potential pets’ colors, abilities, levels, attack speeds, locations, etc. It is an essential site for all Hunters.

How do I teach my pet new abilities?

New abilities are first taught to you, not directly to your pet. Once you know an ability, you can then teach it to as many pets as you wish, as long as the pet is of sufficient level, is the correct species and has enough “training points.”

You learn new abilities from Pet Trainer NPCs and from various beasts. The Pet Trainers are found in the capital cities and mid-level villages and teach only the Growl ability and improvements to your pet’s armor, health, and resistances. These abilities can be learned by all pets.

All other abilities are taught to you by various tameable beasts. A pet’s species (bear, wolf, cat, etc.) limits which abilities it can learn, so you have to pick a species that fits your needs. Each pet starts off with some sort of ability, so let’s use Bite as a common example. While your pet may know only Bite 1, there are other beasts out there that know higher ranks of Bite, among other abilities.

Every ten levels, your pet will be able to learn the next higher rank of its species’ abilities. Using Petopia as a guide, identify a beast that knows the ability and rank you wish to teach your current pet. Now, stable your current pet and go tame the one that knows the ability. Once tamed, fight a few mobs, and as the pet’s ability is triggered, you’ll learn it. After you get the message, “You have learned a new ability…” you can abandon this pet and get your old one out of the stable. With the pet summoned, open your Beast Training window and teach it the new ability.

Why isn’t my pet gaining experience?

Pets of equal level with you won’t gain experience.

For maximum efficiency, tame a pet shortly after you level up, and get one a level below your own. E.g., given the choice of taming a level 19 or 20 beast, a hunter who just turned level 20 should choose the level 19.

How do pets gain loyalty?

The short answer is your pet will gain loyalty as it gains experience. More precisely, it seems to me that a pet’s loyalty increases faster when fighting something that would give you experience (this only matters if your pet is many levels below you). Furthermore, it seems that a pet gains loyalty at a reduced rate, or possibly not at all, if it’s not gaining experience. Someone with more patience than I can test this. To be sure, sitting around with your pet fed, but not doing anything, isn’t a satisfying way to increase its loyalty. I’ve spent many hours fishing with a happily fed pet beside me, and it didn’t gain any loyalty.

How do I train my pet?

The Beast Training button, which could be more accurately named, is somewhat strangely located in the General tab of your spell book. It looks like an old-fashioned slingshot. With your pet summoned, click the Beast Training button and a tradeskill-type window will open, showing you the abilities that you can teach to your pet along with the “training point” cost of each.

You don’t need to teach a pet each rank incrementally; that is, you can skip from Bite 1 to Bite 3 without you or your pet learning Bite 2 so long as your pet is of sufficient level and has enough “training points.”

The point cost of each ability assumes that you haven’t learned any previous ranks. For example, if rank 3 costs 25 points, but you already know rank 2 at 15 points, to upgrade will only cost the difference: 10 points. It would be nice if this was calculated for you, but it isn’t. So, unless you want to do the math, train the skills important to you first, and then use up the rest of your points with less important skills. As an example, I want my pet to do as much DPS as possible, so I first train the extra attack abilities (Bite, Claw, etc.) to their maximum level, then use the rest of the points on health and armor, and finally on resistances.

If you have more than one pet, say a DPS pet and a Tank pet, you can focus their training on different things and maximize their strengths for each purpose.

Good luck, and good hunting.

I’m finally somebody

My arm hurts from patting myself on the back. Today I noticed that my Google PageRank has moved from 0 to 1.

And, while playing around the Technorati site, I noticed this interesting page: How Much Is Your Blog Worth? Well, as it turns out, my blog is worth a bit over $550. I guess that can only go up, seeing as Google itself finds me 10 times more important now than just a few hours ago.