Category Archives: Tutorials

Tutorials and how-to’s, and answers to common computer questions.

I was working on a theme for the image gallery Plogger when an old problem cropped up again. I was adding links to thumbnail images, and had given the anchor a padding of 3 pixels and a 1 pixel border so that the link formed a sort of picture frame around the image. It looked fine in IE7, with a consistent 3 pixels of space on all 4 sides of the image between the image and the anchor’s border. But in Firefox, the top and sides had 3 pixels of space between the image and the anchor’s border, but the bottom had 5 pixels of space. For some reason, an additional 2 pixel gap was appearing below the image, between the image and the bottom border of the anchor.

This extra CSS space below images wrapped in anchor tags had plagued me in the past, and I had always just found a work-around, such as applying the padding and/or border to the image. But this time, I decided to figure out what was going on. I Googled for awhile and finally hit on a forum thread that explained the fix. As it turns out, Firefox allows for something called ‘line descent’, which, in typography, is the amount of space below the baseline of a font.

Most scripts share the notion of a baseline: an imaginary horizontal line on which characters rest. In some scripts, parts of glyphs lie below the baseline. The descent spans the distance between the baseline and the lowest descending glyph in a typeface, and the part of a glyph that descends below the baseline has the name “descender”.

http://en.wikipedia.org/wiki/Typeface

So the descender would be the lowest portion of lowercase letters such as ‘g,’ ‘j,’ ‘p.’ ‘q,’ and ‘y’. Why Firefox wants to accommodate that by adjusting the bottom of an anchor tag remains a mystery to me.

The fix is to add img {vertical-align: bottom;} where appropriate to your CSS. In practice, it eliminates the CSS space under the image in Firefox by pulling up the bottom of the anchor, rather than by pushing down the image. There is no apparent change in IE7.

This post illustrates a method of centering the thumbnails in the album view of the PHP image gallery Plogger. The method automatically adjusts for thumbnails of varying widths and pages containing less than a full row of images.

This method should work in any theme that uses the unordered list derived from the default Plogger theme and that has a fixed and determinable width for the element ‘ul.slides’.

Overview of the method

In brief, the template file album.php is edited to add a PHP script that figures out how many thumbnails are in the first row and then adjusts the left margin of each ‘li.thumbnail’ in order to keep the same amount of space on either side of each image. The user is required to manually set 3 variables: $center_thumbs, $total_space and $thumb_padding, and the script does the rest.

Line-by-line documentation

Below is all of the relevant code, to be placed into the theme file ‘album.php’.

<?php plogger_load_picture();
// Set variables for the thumbnails
$capt = plogger_get_picture_caption();
$date = plogger_get_picture_date();
// Find thumbnail width
$thumb_info = plogger_get_thumbnail_info();
$thumb_width = $thumb_info[0]; // The width of the thumbnail image, in pixels.
$thumb_height = $thumb_info[1];	// The height of the thumbnail image, in pixels.
		
// Set album page options
$center_thumbs = 'true'; // When the value of "$center_thumbs" is set to 'true', the theme will center the thumbnail images 
$total_space = 798; // Set the value of $total_space to equal the width, in pixels, of the interior of 'ul.slides' (i.e. after deducting for any padding)
$thumb_padding = 33; // Set the value of $thumb_padding to equal the sum of all padding and borders on 'ul.slides li.thumbnail', the thumbnail image and the anchor tag (this can be tricky to calculate)

$thumbs_on_page = $GLOBALS["available_pictures"]; 
$actual_thumb_width = $thumb_width + $thumb_padding; 
$max_thumbs_per_row = floor($total_space / $actual_thumb_width); 
($thumbs_on_page < $max_thumbs_per_row)? $thumbs_per_row = $thumbs_on_page : $thumbs_per_row = $max_thumbs_per_row ; 
$avail_space = $total_space - ($thumbs_per_row * $actual_thumb_width); 
$left_margin = floor($avail_space / ($thumbs_per_row + 1)); 
?>


<li class="thumbnail"<?php if ($center_thumbs == 'true') echo 'style="margin-left: ' . $left_margin . 'px"'; ?>>

Here’s how the whole thing works, with each code section followed by a description of what’s happening:

$center_thumbs = 'true'; // When the value of "$center_thumbs" is set to 'true', the theme will center the thumbnail images 
$total_space = 798; // Set the value of $total_space to equal the width, in pixels, of the interior of 'ul.slides' (e.g.: after deducting for any padding)
$thumb_padding = 33; // Set the value of $thumb_padding to equal the sum of all padding and borders on 'ul.slides li.thumbnail', the thumbnail image and the anchor tag (this can be tricky to calculate)

The centering feature can be toggled on and off by setting $center_thumbs to ‘true’ or any other value. The user will need to specify integer values for $total_space and $thumb_padding, as described in the commented lines.

$thumbs_on_page = $GLOBALS["available_pictures"];

The number of available pictures on the current page is assigned to the $thumbs_on_page variable.

$actual_thumb_width = $thumb_width + $thumb_padding;

The actual width of each ‘li.thumbnail’ is calculated and saved as the variable $actual_thumb_width. The width of the thumbnail image is available to the theme as $thumb_width, but the user must specify a value for $thumb_padding, which is an integer equal to the sum of all of the padding and borders on the thumbnail image, the surrounding anchor tag, and the ul list item ‘.thumbnail’. This can be rather tricky to calculate, so you may want to increase your figure by a few pixels just to be safe.

$max_thumbs_per_row = floor($total_space / $actual_thumb_width);

The maximum possible number of thumbnails per row is calculated by dividing the useable width of ‘ul.slides’ by the actual width of a ‘li.thumbnail’, then rounding down the quotient to the next lowest integer using the PHP function floor(). For example, if the quotient of $total_space / $actual_thumb_width is 4.9, $max_thumbs_per_row would equal 4, because 5 thumbnails would be wider than the available space.

($thumbs_on_page < $max_thumbs_per_row)? $thumbs_per_row = $thumbs_on_page : $thumbs_per_row = $max_thumbs_per_row ;

The actual number of thumbs in the first row is calculated and assigned to $thumbs_per_row using a ternary operator. If the number of thumbs on the current page is less than the maximum number possible in a single row, it follows that the row isn’t full, and the number of thumbs on the page is assigned to the variable $thumbs_per_row. However, if the number of thumbs on the page is equal to or greater than the maximum number possible in a single row, it follows that the first row contains the maximum number possible, and so the thumbs will be spaced as though every row is full. Doing it this way maintains the grid, but if one wanted partially filled rows to be centered according to the number of remaining images, that would be possible.

$avail_space = $total_space - ($thumbs_per_row * $actual_thumb_width);

The amount of white space, $avail_space, is calculated by subtracting from the total usable space the sum of the widths of the thumbs in the first row.

$left_margin = floor($avail_space / ($thumbs_per_row + 1));

Finally, the number of pixels for the left margin of each ‘li.thumbnail’, $left_margin, is calculated by dividing $avail_space by the sum of 1 plus the number of thumbs in the first row, and then rounding down the quotient to the next lowest integer. The number of thumbs must be increased by 1 to account for the white space to the right of the last thumbnail.

In practice, the white space to the right of last thumbnail may be a few pixels wider or narrower than the left margins, but this deviation should be limited to within 4 or 5 pixels.

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-includes\general-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.

Updated for XAMPP version 1.6.5

Some time ago, I decided to start phasing out static xhtml in favor of pages using PHP includes. To test these new pages, I used apachefriends.org’s wonderful XAMPP (which I really can’t recommend highly enough) to install Apache, MySQL, and PHP (among other things). Once I had my local server running, I put each dev site into its own folder in \htdocs\ and navigated to them by http://127.0.0.1/foldername/.

This setup was functional but far from ideal, as the index pages for these local sites weren’t in what could be considered a root directory, which lead to some tip-toeing around when creating links.

Then I discovered the NameVirtualHost feature in Apache. NameVirtualHost allows the server admin to set up multiple domains/hostnames on a single Apache installation by using VirtualHost containers. In other words, you can run more than one web site on a single machine. This means that each dev site (or domain) can then consider itself to have a root directory. You will be able to access each local site as a subdomain of “localhost” by making a change to the HOSTS file. For example, I access the local dev version of this site at http://ardamis.localhost/.

This works great for all sorts of applications that rely on the site having a discernible root directory, such as WordPress.

Unfortunately, setting up NameVirtualHost can be kind of tricky. If you are having problems configuring your Apache installation to use the NameVirtualHost feature, you’re in good company. Here’s how I managed to get it working:

For XAMPP version 1.6.5

  1. Create a folder in drive:\xampp\htdocs\ for each dev site (adjust for your directory structure). For example, if I’m creating a development site for ardamis.com on my d: drive, I’d create a folder at:
    d:\xampp\htdocs\ardamis\
  2. Edit your HOSTS file (in Windows XP, the HOSTS file is located in C:\WINDOWS\system32\drivers\etc\) to add the following line, where sitename is the name of the folder you created in step 1. Don’t change or delete the existing “127.0.0.1 localhost” line.
    127.0.0.1 sitename.localhost
    

    Add a new line for each dev site folder you create.

    Continuing with the example, I’ve added the line:
    127.0.0.1 ardamis.localhost

  3. Open your drive:\xampp\apache\conf\extra\httpd-vhosts.conf file and add the following lines to the end of the file, using the appropriate letter in place of drive. Do this step only once. We’ll add code for each dev site’s folder in the next step. (Yes, keep the asterisk.)
    NameVirtualHost *:80
    <VirtualHost *:80>
        DocumentRoot "drive:/xampp/htdocs"
    ServerName localhost
    </VirtualHost>
    

    My DocumentRoot line would be:
    DocumentRoot "d:/xampp/htdocs"

  4. Immediately after that, add the following lines, changing sitename to the name of the new dev site’s folder, again using the appropriate letter in place of drive. Repeat this step for every folder you’ve created.
    <VirtualHost *:80>
        DocumentRoot "drive:/xampp/htdocs/sitename"
        ServerName sitename.localhost
    </VirtualHost>
    

    My DocumentRoot line would be:
    DocumentRoot "d:/xampp/htdocs/ardamis"
    My ServerName line would be:
    ServerName ardamis.localhost

  5. Reboot your computer to be sure it’s using the new HOSTS file (you’ll have to at least restart Apache). You should now be able to access each dev domain by way of:
    http://sitename.localhost/

For XAMPP version 1.4

If you are using an older version of XAMPP (like XAMPP version 1.4) without the httpd-vhosts.conf file, use the instructions below.

  1. Create a folder in your drive:\apachefriends\xampp\htdocs\ for each local version of your site. For example, if I’m creating a development site for ardamis.com on my f: drive, I’d create a folder at:
    f:\apachefriends\xampp\htdocs\ardamis\
  2. Open your HOSTS file (in Windows XP, the HOSTS file is located in C:\WINDOWS\system32\drivers\etc\) and add the following line, where sitename is the name of the folder you created in step 1. Repeat this step, as necessary, for each folder you create. Don’t change or delete the existing “127.0.0.1 localhost” line.
    127.0.0.1 sitename.localhost
    

    Continuing with the example, I’ve added the line:
    127.0.0.1 ardamis.localhost

  3. Open your drive:\apachefriends\xampp\apache\conf\httpd.conf file and add the following lines to the end of the file, using the appropriate letter for drive. Do this step only once. We’ll add code for each dev site’s folder in the next step. (Yes, keep the asterisk.)
    NameVirtualHost *:80
    <VirtualHost *:80>
        DocumentRoot "drive:/apachefriends/xampp/htdocs"
    ServerName localhost
    </VirtualHost>
    

    My DocumentRoot line would be:
    DocumentRoot "f:/apachefriends/xampp/htdocs"

  4. Immediately after that, add the following lines, changing sitename to the name of the new folder, using the appropriate letter for drive and repeating this step for every folder you’ve created.
    <VirtualHost *:80>
        DocumentRoot "drive:/apachefriends/xampp/htdocs/sitename"
        ServerName sitename.localhost
    </VirtualHost>
    

    My DocumentRoot line would be:
    DocumentRoot "f:/apachefriends/xampp/htdocs/ardamis"

  5. Reboot and restart Apache. Open a browser; you should now be able to access each folder by way of:
    http://sitename.localhost

I’m assuming that you could change the DocumentRoot line to point to any folder on any drive. I’ll experiment with pointing this at a folder on another drive later.

The official Apache.org documentation for VirtualHost is at http://httpd.apache.org/docs/2.2/vhosts/. You may want to read that for further details before you try to set up virtual hosts.

If you have any questions about the above instructions, the Apache NameVirtualHost function, XAMPP, or anything in between, post a comment, but I can’t promise that I’ll be able to help. I’m learning as I go along, too.