Advertisement

WordPress: Beginner to Master, Part 1

by
Student iconAre you a student? Get a yearly Tuts+ subscription for $45 →

Throughout this six-part beginner-to-master series, we'll be using the advanced features of WordPress to create our own portfolio & blog, complete with an options page, multiple styles and support for the new WordPress 2.7 features.

In day one, we're handling the preparation and admin sections by creating our Options page.


Also available in this series:

  1. WordPress: Beginner to Master, Part 1
  2. WordPress: Beginner to Master, Part 2
  3. WordPress: Beginner to Master, Part 3
  4. WordPress: Beginner to Master, Part 4
  5. WordPress: Beginner to Master, Part 5
  6. WordPress: Beginner to Master, Part 6

Overview

By the end of this series, we will have created Innovation – a premium-quality WordPress template perfect for showcasing a portfolio and hosting a blog; complete with the following features:

  • Options page for handling the advanced nature of the template, without having to edit any files manually.
  • 3 built-in colour schemes – with easy switching between them.
  • Homepage and Portfolio page templates, with a widget-ready footer and sidebar.
  • Compatibility with WordPress 2.5+.
  • Threaded & paged comments support for WordPress 2.7.
  • A custom widget for displaying your latest posts, with a preview image, on your homepage.

The theme will come with three styles built-in, DeepBlue, RedSpace and SoftLight, but you will be able to easily add your own colour schemes:




The plan for each day:

  1. Preparation & Admin Options page.
  2. Homepage layout. Creating a custom WordPress loop. Using widget areas. Footer.
  3. Blog posts loop. Sidebar. Single blog layout.
  4. Portfolio page. Seperating 'single' pages dependant on category. Single portfolio page.
  5. Comments layout. Archives. Search.
  6. Face lift – the 'RedSpace' alternative colour scheme. Creating a custom widget.

 

What previous experience do I need?

Experience with xHTML & CSS is a must (as I won't go over much of this code in detail).

It would also be very useful to have some basic understanding of PHP (such as using variables, arrays, conditional statements and 'foreach' and 'while' loops. Check out Jeffrey's excellent "Diving into PHP" screencast series.

Having some knowledge of WordPress (even just knowing your way around the Dashboard!) would definitely improve your experience. Check out Drew's "WordPress for Designers" screencast series.

Jump to a Section

Getting Started

Today, we will be handling the core back-end code which the rest of theme will rely upon. You will first need a fresh install of WordPress, preferably the latest version (2.7 at time of writing); however the template will work with any version above 2.5. Inside the /wp-content/themes/ folder, create new folders and files with the following structure:

  • /innovation/
    • /styles/
      • /deepblue/
      • deepblue.css
    • functions.php
    • index.php
    • page.php
    • page-home.php
    • page-portfolio.php
    • style.css
    • var.php

functions.php will contain code for our options page and widgets amongst other things.

index.php is used for displaying latest posts.

page.php will the template used for most single pages.

page-home.php will be our frontpage template.

page-portfolio.php will be our portfolio page.

var.php will be used to retrieve our options from the database.

style.css will contain most of our styling.

/styles/deepblue.css will contain the styling for our first colour-scheme.

These aren't all the files we will need. We'll create the others as we go along so that you can understand what each is for.

Preparing Files

The two page- files are custom page templates, so that we can lay content out differently on pages assigned these templates. For WordPress to recognize them, inside page-home.php enter the following:

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

Similarly, inside page-portfolio.php enter:

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

The Template Name is the name used by WordPress when selecting a page template. get_header(); is a WordPress function to load the header.php file (which we'll create later).

And add the following to page.php. We don't need to give this file a template name, as it is the default template.

 
<?php 
get_header(); ?>

We also need to assign some details such as name, description and author for our theme. This is done in a comment block at the top of style.css:

 
/* 
Theme Name: Innovation 
Theme URI: http://www.danharper.me/innovation 
Description: An advanced portfolio & blog theme built by Dan Harper as part of a tutorial series for NETTUTS.com 
Version: 1.0 
Author: Dan Harper 
Author URI: http://www.danharper.me 
*/

Categories & Pages

To save time later, we will create the relevant categories & pages we will need now. In your WordPress dashboard, activate the theme (it will be using the name we defined in the CSS previously) - don't worry that the theme is empty, we're moving to that later.


Now create three new Pages. One named 'Home', and the other 'Portfolio'. Select the Page Template for each of them as 'Homepage' and 'Portfolio' respectively. Name the final page 'Blog' and use the default page template.


Also create a new category named 'Portfolio'. This is what we will use to post portfolio items in.


Make WordPress a CMS

From your Dashboard, go to Settings -> Reading. For 'Front Page Display' set Front page to the 'Home' page you created, and Posts page to 'Blog':


Options Page

This is probably going to seem a little backwards, but we are going to create an options page for our theme before we do any work on the actual front-end. This is because the entire theme depends upon the options on the page, and it wouldn't make sense to do those other parts first.

For those who don't know, the options page is an extra page in the WordPress Dashboard we are adding which holds a number of options for our theme. These are:

  • Colour Scheme
  • Portfolio Category
  • Blog Page
  • Google Analytics code

Inside functions.php start with the following. The $themename variable defines the name of the theme which will be used for the page's title in the Dashboard (Innovation). And $shortname is used to make our options unique - if you change this, you will have to change several instances throughout the code (so don't change it ;)).

 
<?php 
$themename = "Innovation"; 
$shortname = "ts";

Categories Drop-Down

Next we will create the code which gets all the categories for us to use in the 'Portfolio' drop-down option:

 
/* Get Categories into a drop-down list */ 
$categories_list = get_categories('hide_empty=0&orderby=name'); 
$getcat = array(); 
foreach($categories_list as $acategory) { 
	$getcat[$acategory->cat_ID] = $acategory->cat_name; 
} 
$category_dropdown = array_unshift($getcat, "Choose a category:");

This code uses WordPress' get_categories(); function to retrieve a list of all the category names, and using a foreach(); loop to add each name & ID into an array named $getcat for use later in the code. Finally, we use array_unshift to insert "Choose a category:" at the top of the array.

Pages Drop-Down

Next is another similar drop-down option which selects a page name. The code for this is very similar to the previous one:

 
/* Get Pages into a drop-down list */ 
$pages_list = get_pages(); 
$getpag = array(); 
foreach($pages_list as $apage) { 
	$getpag[$apage->ID] = $apage->post_title; 
} 
$page_dropdown = array_unshift($getpag, "Select a page:");

Like getting the categories, we are using WordPress' get_pages(); function to get a list of all the page names, and the result is placed into the $getpag array for use later.

Stylesheet Drop-Down

There is also a drop-down option for selecting a stylesheet. This code is a little more complicated:

 
/* Get Stylesheets into a drop-down list */ 
$styles = array(); 
if(is_dir(TEMPLATEPATH . "/styles/")) { 
	if($open_dirs = opendir(TEMPLATEPATH . "/styles/")) { 
		while(($style = readdir($open_dirs)) !== false) { 
			if(stristr($style, ".css") !== false) { 
				$styles[] = $style; 
			} 
		} 
	} 
} 
$style_dropdown = array_unshift($styles, "Choose a colour scheme:");

The above code uses the PHP opendir(); function, followed by readdir(); to open our /styles/ folder and get a list of all the files in there.

We then use stristr(); to limit the list to only the .css files (to stop the folders from being outputted aswell), and the results are passed into the $styles array.

The Options Array

All our options will be stored in their own arrays so that we can mass-process them later in the code:

 
/* The Options*/ 
$options = array ( 
 
	array(	"name" => "General", 
		"type" => "title"), 
	 
	array(	"type" => "open"), 
	 
	array(	"name" => "Colour Scheme", 
		"desc" => "Which colour scheme would you like?", 
		"id" => $shortname."_colourscheme", 
		"type" => "select", 
		"std" => "Choose a colour scheme:", 
		"options" => $styles), 
	 
	array(	"name" => "Portfolio Category", 
		"desc" => "Select the category portfolio items are being posted in.", 
		"id" => $shortname."_portfolio_cat", 
		"type" => "select", 
		"std" => "Choose a category:", 
		"options" => $getcat), 
	 
	array(	"name" => "Blog page", 
		"desc" => "Select the page used as a blog (posts) page.", 
		"id" => $shortname."_blogpage", 
		"type" => "select", 
		"std" => "Select a page:", 
		"options" => $getpag), 
		 
	array(	"name" => "Google Analytics", 
		"desc" => "Insert your Google Analytics (or other) code here.", 
		"id" => $shortname."_analytics_code", 
		"type" => "textarea"), 
	 
	array(	"type" => "close") 
 
);

Each array is one option, and contains name, desc, id and type parameters. The ID is very important, and is what we'll be using to reference the option later in the code. For example, to get the Portfolio Category, we would check the $ts_portfolio_cat (ts is the shortname we referenced at the top of the document.)

Options Back-end

The following code makes our options page appear in the Dashboard (it's under "Design" in WordPress 2.6 or below), and saves the options into the database.


 
function mytheme_add_admin() { 
global $themename, $shortname, $options; 
if ( $_GET['page'] == basename(__FILE__) ) { 
if ( 'save' == $_REQUEST['action'] ) { 
foreach ($options as $value) { 
update_option( $value['id'], $_REQUEST[ $value['id'] ] ); } 
foreach ($options as $value) { 
if( isset( $_REQUEST[ $value['id'] ] ) ) { update_option( $value['id'], $_REQUEST[ $value['id'] ]  ); } else { delete_option( $value['id'] ); } } 
header("Location: themes.php?page=functions.php&saved=true"); 
die; 
} else if( 'reset' == $_REQUEST['action'] ) { 
foreach ($options as $value) { 
delete_option( $value['id'] ); } 
header("Location: themes.php?page=functions.php&reset=true"); 
die; 
} 
} 
if(!function_exists('wp_list_comments')) { 
add_theme_page($themename." Options", $themename, 'edit_themes', basename(__FILE__), 'mytheme_admin'); 
} else { 
add_menu_page($themename." Options", $themename, 'edit_themes', basename(__FILE__), 'mytheme_admin'); 
} 
} 
function mytheme_admin() { 
global $themename, $shortname, $options; 
if ( $_REQUEST['saved'] ) echo '<div id="message" class="updated fade"><p><strong>'.$themename.' settings saved.</strong></p></div>'; 
if ( $_REQUEST['reset'] ) echo '<div id="message" class="updated fade"><p><strong>'.$themename.' settings reset.</strong></p></div>'; 
?> 
<div class="wrap"> 
<hr /> 
<h2><?php echo $themename; ?> settings</h2> 
<form method="post">

We're not going to go through the code as it would take this tutorial off-track too much. Just copy & paste it and think of it as some magic code from the WordPress Gods which makes your theme work.

This next code checks each of our options for their type attribute, and styles them into a table. So options with "type" => "select" would output as a drop-down box, or "type" => "textarea" would output as a textarea.

 
<?php foreach ($options as $value) {  
switch ( $value['type'] ) { 
 
case "open": ?> 
<table width="100%" border="0" style="background-color:#F1F1F1; border:1px solid #E3E3E3; border-top:none; padding:10px;"><?php 
 
break; 
case "close": 
?> 
</table><br /><?php 
 
break; 
case "title": 
?> 
<table width="100%" border="0" style="background-color:#6D6D6D; border: 1px solid #E3E3E3; padding:5px 10px;"> 
<tr> 
<td colspan="2"> 
<h3 style="color:#fff; font-family:Georgia,'Times New Roman',Times,serif; font-weight: bold;"><?php echo $value['name']; ?></h3> 
</td> 
</tr> 
</table><?php 
 
break; 
case 'text': 
?> 
<tr> 
<td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td> 
<td width="80%"><input style="width:400px;" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>" type="<?php echo $value['type']; ?>" value="<?php if ( get_settings( $value['id'] ) != "") { echo get_settings( $value['id'] ); } else { echo $value['std']; } ?>" /></td> 
</tr> 
<tr> 
<td><small><?php echo $value['desc']; ?></small></td> 
</tr><tr><td colspan="2" style="margin-bottom:5px;border-bottom:1px dotted #C8C8C8;">&nbsp;</td></tr><tr><td colspan="2">&nbsp;</td></tr> 
<?php  
 
break; 
case 'textarea': 
?> 
<tr> 
<td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td> 
<td width="80%"><textarea name="<?php echo $value['id']; ?>" style="width:400px; height:200px;" type="<?php echo $value['type']; ?>" cols="" rows=""><?php if ( get_settings( $value['id'] ) != "") { echo stripslashes(get_settings( $value['id'] )); } else { echo $value['std']; } ?></textarea></td> 
</tr> 
<tr> 
<td><small><?php echo $value['desc']; ?></small></td> 
</tr><tr><td colspan="2" style="margin-bottom:5px;border-bottom:1px dotted #C8C8C8;">&nbsp;</td></tr><tr><td colspan="2">&nbsp;</td></tr> 
<?php  
 
break; 
case 'select': 
?> 
<tr> 
<td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td> 
<td width="80%"><select style="width:240px;" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>"><?php foreach ($value['options'] as $option) { ?><option<?php if ( get_settings( $value['id'] ) == $option) { echo ' selected="selected"'; } elseif ($option == $value['std']) { echo ' selected="selected"'; } ?>><?php echo $option; ?></option><?php } ?></select></td> 
</tr> 
<tr> 
<td><small><?php echo $value['desc']; ?></small></td> 
</tr><tr><td colspan="2" style="margin-bottom:5px;border-bottom:1px dotted #C8C8C8;">&nbsp;</td></tr><tr><td colspan="2">&nbsp;</td></tr> 
<?php 
 
break; 
case "checkbox": 
?> 
<tr> 
<td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td> 
<td width="80%"><? if(get_settings($value['id'])){ $checked = "checked=\"checked\""; }else{ $checked = ""; } ?> 
<input type="checkbox" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>" value="true" <?php echo $checked; ?> /> 
</td> 
</tr> 
<tr> 
<td><small><?php echo $value['desc']; ?></small></td> 
</tr><tr><td colspan="2" style="margin-bottom:5px;border-bottom:1px dotted #C8C8C8;">&nbsp;</td></tr><tr><td colspan="2">&nbsp;</td></tr> 
<?php 
 
break; 
}  
} 
?> 
<p class="submit"> 
<input name="save" type="submit" value="Save changes" />  
<input type="hidden" name="action" value="save" /> 
</p> 
</form> 
<form method="post"> 
<p class="submit"> 
<input name="reset" type="submit" value="Reset" /> 
<input type="hidden" name="action" value="reset" /> 
</p> 
</form> 
<?php 
} 
add_action('admin_menu', 'mytheme_add_admin');

Finally, at the end of the file, insert:

 
require(TEMPLATEPATH . "/var.php");

We require() our var.php file which will contain code for retrieving our options.

Note that we have to use TEMPLATEPATH in require() or include() tags so that it is browsing to our theme directory, and not the root WordPress directory.

Retrieving These Options

Now those options are in the Dashboard, we need to be able to use them in our theme. Insert the following code into var.php:

 
<?php 
 
/* Get all our options from the database */ 
global $options; 
foreach ($options as $value) { 
	if (get_settings( $value['id'] ) === FALSE) { $$value['id'] = $value['std']; 
	} else { $$value['id'] = get_settings( $value['id'] ); } 
} 
 
/* Get Portfolio category ID from the name */ 
$ts_portfolio_cat = $wpdb->get_var("SELECT term_id FROM $wpdb->terms " 
	."WHERE name='$ts_portfolio_cat'"); 
 
/* Get Blog page ID from the name */ 
$ts_blogpage = $wpdb->get_var("SELECT `ID` FROM $wpdb->posts " 
	."WHERE post_title='$ts_blogpage' AND post_type='page' LIMIT 1"); 
 
?>

The first section of the code retrieves all our options from the database. However we have a problem: our Category & Page options send back the name of the category or page - but we'd prefer the ID as it's easier to use in WordPress functions.

The next two parts of the code do exactly that. We run a SQL query to get the appropriate ID. These options are now stored in the $ts_portfolio_cat and $ts_blogpage variables.

Now we have the admin side finished, login to your Dashboard, and set the appropriate settings for each of the options. Choose deepblue.css for the colour-scheme for now.


Summary

That concludes Day 1 of WordPress Week. Tomorrow, we'll be creating our homepage layout, making a custom 'WordPress Loop' and handeling widget areas.

Part 2 - Loops and Widgets.

Advertisement