jump to content

Installing WordPress 2.8 on a Windows server: an anatomy of a web site

The company that hosts my website — CS New Media — provide Linux or Windows hosting. As I’m a developer who works mainly in Microsoft technologies, I’ve opted for the Windows hosting package which also supports ASP.NET 3.5, PHP 5, MS SQL Server and MySQL.

This guide details how I set up Bassett-Jones.com and dealt with any problems along the way. There was a learning curve as I hadn’t much exposure to PHP, but documentation is one of PHP and WordPress’s strengths.

  1. Setting up a basic Wordpress installation
  2. Setting user-friendly custom permalinks
  3. Designing the theme
  4. Creating custom theme pages
  5. Getting hugh.bassett-jones.com subdomain to work as a Wordpress page
  6. Installing standard plugins plugins
  7. Modifying and tweaking plugins
  8. Writing custom plugins

1. Setting up a basic Wordpress installation

Difficulty: One star out of five

WordPress’s basic set up and installation is wonderfully simple.

Things to check first with your web host documentation:

Following the Famous 5-Minute Installation Guide

  1. Create a database and database user e.g. wordpress1 and wordpress1user
  2. Download the latest version of WordPress and unzip
  3. Rename the wp-config-sample.php file to wp-config.php.
  4. Edit the following lines in the newly renamed wp-config.php.
    /** The name of the database for WordPress */
    define('DB_NAME', 'wordpress1');
    
    /** MySQL database username */
    define('DB_USER', 'wordpress1user');
    
    /** MySQL database password */
    define('DB_PASSWORD', 'userpassword');
    
    /** MySQL hostname */
    define('DB_HOST', 'mysql5.webhost.com');
  5. Copy all the files to your web server
  6. Visit the start page to complete the installation

2. Setting user-friendly custom permalinks

Difficulty: Two stars out of five

Windows 2003 and IIS 6 do not include URL rewriting and so cannot map a page such as www.bassett-jones.com/?page_id=9 to the more friendly www.bassett-jones.com/hugh/ in the same way that Apache does using mod_rewrite.

If your web host supports custom error pages, you can use this to create user-friendly custom permalinks.

Request -> Status 404 Not Found -> wp-404-handler.php -> Status 200 Success

  1. Create a new page called wp-404-handler.php
  2. Add the following code
    <?php
      $_SERVER['REQUEST_URI'] = substr($_SERVER['QUERY_STRING'], strpos($_SERVER['QUERY_STRING'],   ':80')+3);
      $_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI'];
      include('index.php');
    ?>
  3. Upload wp-404-handler.php to your web server
  4. Set your custom error page to point to wp-404-handler.php. View instructions for Helm control panel.
  5. I like the web site addresses in the format www.bassett-jones.com/post-title/, so from the WordPress Dashboad go to Settings > Permalinks > Common Settings > Custom Structure and set to /%postname%/.

Note that once this is done, the page at the custom permalink will not accept any forms with a method of post. This means that some of the plugins break and may need tweaking as detailed in 7. Modifying and tweaking plugins.

3. Designing the theme

Difficulty: Three stars out of five

I already had an idea how I wanted the site to look based on the previous version. Sketching out the design in Balsamiq Mockups showed the main areas of the two different types of pages — one for entries, and one for pages such as Search, About and Tags.

Sketch of post page

page sketch

The Template Hierarchy and default theme give a breakdown and example of how to construct a custom theme. My post page design fitted into the standard Header → Content → Sidebar → Footer theme design.

To manage the different styles between post-type pages and standard pages, I created two styles sheets style.css and page.css. The header.php then includes either one depending on the type of page:

<?php if (is_page() || is_404() || is_search() || is_archive() ) { ?>
  <link rel="stylesheet" href="<?php bloginfo('template_directory') ?>/page.css" type="text/css" media="screen" />
<?php } else { ?>
  <link rel="stylesheet" href="<?php bloginfo('stylesheet_url') ?>" type="text/css" media="screen" />
<?php } ?>

The sidebar blocks 3 – 7 are automatically handled through the administration interface and sidebar.php by using:

<?php dynamic_sidebar() ?>

4. Creating custom theme pages

Difficulty: Three stars out of five

My theme required separate pages for AboutAllContactHughRandom, Search, and Tags. About, Contact and Hugh could use the standard template, while the rest would need a custom theme page each. codex.wordpress.org/Creating_a_Search_Page details the steps of how to create a search page using a custom template file. The other pages were created in a similar way.

  1. Create a new page template
  2. On the edit page dashboard option, choose the template file to use

All pages and posts

<?php
  /*
  Template Name: All
  */
?>

...

<?php query_posts('orderby=post_modified&order=desc'); ?>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
  <div class="post">
    <h2 id="post-<?php the_ID(); ?>"><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h2>
    ...
  </div>
<?php endwhile; endif; ?>

<?php $pages = get_pages('orderby=post_modified&order=desc'); ?>
<?php foreach ($pages as $page) { ?>
  <div class="page">
    <h2><a href="<?php echo get_page_link($page->ID) ?>"><?php echo ucfirst($page->post_title) ?></a></h2>
    ...
  </div>
<?php } ?>

Go to a random page

<?php
/*
Template Name: Random
*/
?>
<?php
  $rand = new WP_Query();
  $rand->query('showposts=1&orderby=rand');

  while ($rand->have_posts()) : $rand->the_post();
    $location = "Location: " . get_permalink();
  endwhile; 

  header($location,true,302);
?>

Search site

<?php
/*
Template Name: Search
*/
?>
<?php get_header(); ?>

<div id="main">
  <h1>Search Bassett-Jones.com</h1>
  <?php get_search_form() ?>
</div>

<?php get_footer(); ?>

Tag cloud

<?php
/*
Template Name: Tags
*/
?>
<?php get_header(); ?>

<div id="main">
  <h1>Tags o' plenty</h1>
  <?php wp_tag_cloud(); ?>
</div>

<?php get_footer(); ?>

5. Getting hugh.bassett-jones.com subdomain to work as a Wordpress page

Difficulty: Two stars out of five

WordPress is installed on www.bassett-jones.com, but I like the style of hugh.bassett-jones.com instead of www.bassett-jones.com/hugh/. My web host sets up subdomains to map to a sub folder of the main domain. This means that hugh.bassett-jones.com needs to map to a file that exists at www.bassett-jones.com/hugh/index.php.

This page /hugh/index.php then retrieves the real page content.

<?php
if($_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"] == "www.bassett-jones.com/hugh/") {
  header("Location: http://hugh.bassett-jones.com",true,301);
  exit;
}
echo file_get_contents('http://www.bassett-jones.com/?page_id=9');
?>

The above code checks if www.bassett-jones.com/hugh/ is being requested, and if so permanently redirects to hugh.bassett-jones.com. It then retrieve the Hugh page using the hard-coded page_id, as /hugh/ would continually loop.

6. Installing standard plugins plugins

Difficulty: One star out of five

These are the plugins that required no modification and extend the standard WordPress installation. They were installed using the Dashboard Plugins Installation and Widget Panel.

Akismet Checks comments against the Akismet web service to see if they look like spam or not and reduces the amount of unwanted comments.

flickrRSS Integrates photos from the flickr RSS and allows you to specify the template HTML.

Google XML Sitemaps Automatically generate a sitemaps.org compatible site map for search engines to find content.

Raw HTML capability On a per-post basis, disable the automatic html conversion of the WordPress rich text editor. Useful for posts with with code in them.

Wordpress.com stats Simple visitor tracking and analysis.

WP-Memory-Usage Shows the current memory usage and limit on the Dashboard.

7. Modifying and tweaking plugins

Difficulty: Four stars out of five

Tiny Contact Form

By default, Tiny Contact Form has an empty form action that POSTs the contact data back to the page that it is currently on (around line 76 in tiny-contact-form.php).

<form action="" method="post">

This does not work with 2. Setting user-friendly custom permalinks, as only GET actions are supported. I modified the action to post to the underlying page address instead:

<form action="' . get_bloginfo("url") . '/?page_id=' . get_the_ID() . '" method="post">

Commenting on pages does not need a similar modification, as the comment form POSTs to wp-comments-post.php.

WPtouch iPhone Theme

WPtouch is an excellent plugin that formats the content of the web site when accessing from an iphone or similar mobile device.

Version 1.9 does not support skins, so any modifications will be overwritten with updates, but it looks like 2.0 will support them.

I’ve edited the bottom of header.php to include a brief intro about me on every page.

<div id="hugh" style="position: relative; -webkit-border-radius: 8px;">
  <img style="width: 100%; display: block;" src="<?php bloginfo('wpurl'); ?>/wp-content/themes/hugh/images/hughmini.jpg" alt="Hugh"/>
  <h2 style="position: absolute;"><a href="http://hugh.bassett-jones.com">Hi, I'm Hugh.</a></h2><p>Cheerful husband and developer based in Hampshire, UK <a href="http://hugh.bassett-jones.com">Read more …</a></p>
</div>

8. Writing custom plugins

Difficulty: Four stars out of five

document html outlineI had a clear idea of how I wanted the theme to look and what the html produced needed to be.

Some plugins such as flickrRSS allow template html to be used for each item, but others did not quite fit what I needed.

Recent Tweets, YouTube Videos, and Xbox Games all follow the basic pattern of retrieving an XML document from another location, parsing and extracting relevant data into html before storing and displaying on the page.

To reduce the number of times the page requests data from the external sites, I cache the html in the database and only request new data once every 24 hours.

One response to Installing WordPress 2.8 on a Windows server: an anatomy of a web site

  1. jasongul says:

    Many thanks for an explanation, now I will know. I have a joke for you =) Which day of the week is the best for a dental appointment? Toothday. http://rxviaproed.fizwig.com/images/top.gif 1]vigera medicine online 1]viagara generic Idaho 1]vigra cheap Illinois

Leave a reply