Archive for the ‘Web Design’ Category


I’ve made my first handful of widget plugins using wordpress.  The first one took me a little over an hour.  The others went by after about twenty minutes.  Once you get the hang of the first one the pattern sets in and the process gets pretty easy.  That isn’t to say that there aren’t some amazingly complex plugins, but the general develop is simple enough to justify using plugins for much smaller tasks.

In my situation, I’m supporting thirty odd websites that all use similar layouts, but they all have a different look and feel.  The individual site owners customarily have a strong say it what goes on their site and how it is to be displayed.  Because these sites are all separate and distinct and may need to be developed independently, I’ve chosen not to unify them as pages of a larger site.  Instead, each site is a separate wordpress.  At current, each site uses the same wordpress theme (developed by me), but that may change.

In this situation, widgets have been invaluable.  They let the individual site owners customize their website but moving the widgets up and down or adding/removing them entirely.  While this arrangement has been amazingly beneficial a few problems have arisen with some of the standard content items between pages.  Every site, for example, has a link to a search tool that exists on a different site.  The obvious solution is to create a text widget, drop the search html code in, and call it a day.  This works…but it requires the site owners, (non-technical) to drop this code in and not drop anything else that might cause problems…that itself is a problem.

I knew early on that an adequate solution would be to “templatize” these common widgets.  For example, I created the search widget with the proper html already included.  I’ve dropped this template into each of the site directories and activated them, so all the directors have to do is move the widget around as necessary.  I’ve done something similar with an ‘hours of operation’ widget, except I’ve given the owners a web form where they can input their actual hours.  The public facing formatting is taken care of by the widget itself and the theme specific stylesheets.

Overall, I was pleasantly surprised to find out that widget development is simple enough that using it as a solution to easy but non-trivial issues is worth the time and effort.

As an example, I’ll break down my hours of operation code:

<?php
/*
Plugin Name: Library Hours
Description: Widget with Control Panel
Author: Robert Drake
Version: 1.0
Date: 1/21/2010
Author URI: RobertDrake.net
*/

This is just a stock comment block to describe the code below, but the name and description are used in wordpress’ backend plugin management so make them useful.

class MHLS_LibraryHours_Widget extends WP_Widget {

By surrounding the rest of the code in this wrapped you take advantage of a whole bunch of code built into wordpress 2.8 that does a lot of the widget stuff for you.  Older guides tend to include this code and the systems are backwards compatible (but not forward, meaning my code wont work prior to 2.8).

function MHLS_LibraryHours_Widget() {
$widget_ops = array('classname' => 'widget_mhls_libraryhours', 'description' => 'Library Hours' );
$this->WP_Widget('mhls_librarywidget', 'MHLS_Library_Hours', $widget_ops);
}

This block is honestly pretty confusing and as far as I can tell most of the names dont really matter all that much as long as you match the function name with the init at the end.  Otherwise you specify a few look and feel type of things in the widget control panel and setup what prefix will go with your variables.  Luckily, all that stuff is handled for you.

function widget($args, $instance) {
extract($args, EXTR_SKIP);
echo $before_widget;
$title = empty($instance['title']) ? '&nbsp;' : apply_filters('widget_title', $instance['title']);
$monday = empty($instance['monday']) ? '&nbsp;' : apply_filters('widget_monday', $instance['monday']);
$tuesday = empty($instance['tuesday']) ? '&nbsp;' : apply_filters('widget_tuesday', $instance['tuesday']);
$wednesday = empty($instance['wednesday']) ? '&nbsp;' : apply_filters('widget_wednesday', $instance['wednesday']);
$thursday = empty($instance['thursday']) ? '&nbsp;' : apply_filters('widget_thursday', $instance['thursday']);
$friday = empty($instance['friday']) ? '&nbsp;' : apply_filters('widget_friday', $instance['friday']);
$saturday = empty($instance['saturday']) ? '&nbsp;' : apply_filters('widget_saturday', $instance['saturday']);
$sunday = empty($instance['sunday']) ? '&nbsp;' : apply_filters('widget_sunday', $instance['sunday']);
echo $before_title . $title . $after_title;
echo '<div id="libraryhourswidget">';
echo 'Monday: <span>' . $monday . '</span><br>';
echo 'Tuesday: <span>' . $tuesday . '</span><br>';
echo 'Wednesday: <span>' . $wednesday . '</span><br>';
echo 'Thursday: <span>' . $thursday . '</span><br>';
echo 'Friday: <span>' . $friday . '</span><br>';
echo 'Saturday: <span>' . $saturday . '</span><br>';
echo 'Sunday: <span>' . $sunday . '</span><br>';
echo '</div>';
echo $after_widget;
}

This is really the meat of the plugin.  Extract takes the data (which is set elsewhere), assigns it to variables, and displays in straight html/css.  This is what will ultimately be output to the screen so whatever you want to see needs to go here.  Throughout the code you’ll notice a $instance being used frequently.  Basically, when the variable names you use aren’t the full variable name.  When I work with the variable monday, I’m actually working with the variable ‘widget_mhls_libraryhours 3 monday’  The first part of the name is specific to the widget name, and the second part is specific to the widget instance.  In order to have multiple copies of the same widget you need to use the instance name to separate one copy from another.

The rest of that function is fairly boring.  The $monday = part uses the tertiary operator in php to assign the variable to a non breaking space if there is no data in the variable.  In another plugin, I had it assign a 0 so I could test for false later and restrict my output.  Otherwise the filters are just sanitizing the user inputs for anything that looks like code.

function update($new_instance, $old_instance) {
$instance = $old_instance;
$instance['title'] = strip_tags($new_instance['title']);
$instance['monday'] = strip_tags($new_instance['monday']);
$instance['tuesday'] = strip_tags($new_instance['tuesday']);
$instance['wednesday'] = strip_tags($new_instance['wednesday']);
$instance['thursday'] = strip_tags($new_instance['thursday']);
$instance['friday'] = strip_tags($new_instance['friday']);
$instance['saturday'] = strip_tags($new_instance['saturday']);
$instance['sunday'] = strip_tags($new_instance['sunday']);
return $instance;
}

Easy function.  When the user changes the data in the form fields this function updates the variables with the new values.  That’s it.  Cake!

function form($instance) {
$instance = wp_parse_args( (array) $instance, array( 'title' => '', 'entry_title' => '', 'comments_title' => '' ) );
$title = strip_tags($instance['title']);
$monday = strip_tags($instance['monday']);
$tuesday = strip_tags($instance['tuesday']);
$wednesday = strip_tags($instance['wednesday']);
$thursday = strip_tags($instance['thursday']);
$friday = strip_tags($instance['friday']);
$saturday = strip_tags($instance['saturday']);
$sunday = strip_tags($instance['sunday']);
?>
<p><label for="<?php echo $this->get_field_id('title'); ?>">Title: <input id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo attribute_escape($title); ?>" /></label></p>
<p><label for="<?php echo $this->get_field_id('monday'); ?>">Monday: <input id="<?php echo $this->get_field_id('monday'); ?>" name="<?php echo $this->get_field_name('monday'); ?>" type="text" value="<?php echo attribute_escape($monday); ?>" /></label></p>
<p><label for="<?php echo $this->get_field_id('tuesday'); ?>">Tuesday: <input id="<?php echo $this->get_field_id('tuesday'); ?>" name="<?php echo $this->get_field_name('tuesday'); ?>" type="text" value="<?php echo attribute_escape($tuesday); ?>" /></label></p>
<p><label for="<?php echo $this->get_field_id('wednesday'); ?>">Wednesday: <input id="<?php echo $this->get_field_id('wednesday'); ?>" name="<?php echo $this->get_field_name('wednesday'); ?>" type="text" value="<?php echo attribute_escape($wednesday); ?>" /></label></p>
<p><label for="<?php echo $this->get_field_id('thursday'); ?>">Thursday: <input id="<?php echo $this->get_field_id('thursday'); ?>" name="<?php echo $this->get_field_name('thursday'); ?>" type="text" value="<?php echo attribute_escape($thursday); ?>" /></label></p>
<p><label for="<?php echo $this->get_field_id('friday'); ?>">Friday: <input id="<?php echo $this->get_field_id('friday'); ?>" name="<?php echo $this->get_field_name('friday'); ?>" type="text" value="<?php echo attribute_escape($friday); ?>" /></label></p>
<p><label for="<?php echo $this->get_field_id('saturday'); ?>">Saturday: <input id="<?php echo $this->get_field_id('saturday'); ?>" name="<?php echo $this->get_field_name('saturday'); ?>" type="text" value="<?php echo attribute_escape($saturday); ?>" /></label></p>
<p><label for="<?php echo $this->get_field_id('sunday'); ?>">Sunday: <input id="<?php echo $this->get_field_id('sunday'); ?>" name="<?php echo $this->get_field_name('sunday'); ?>" type="text" value="<?php echo attribute_escape($sunday); ?>" /></label></p>
<?php
}
}

This function (and I’ve included the closing bracket of the starting class) looks kind of obnoxious but its really just setting up the user form in the backend.  The top half sets the variables and the second half sets a form.  You may be wondering why there is no <form> in there.  Wordpress actually takes care of that stuff so no worries.  It’ll drop your code into its own form and use the standard formatting of the admin panel so everything looks uniform.

add_action( 'widgets_init', create_function('', 'return register_widget("MHLS_LibraryHours_Widget");') );

This is the last line.  It’s used when activating the plugin and registers everything in the appropriate places for wordpress to work with.  Simple plugin.  Simple code.

That’s it.  I’m looking forward to coding up some more and more interesting plugins.  I’ve already got a few ideas in mind for things that would help me.  I’ll try to post things periodically as they become interesting.

I started following WordPress on twitter.  They occasionally toss up some great links, mostly to recent wordcamp presentations.  Here is a video on plugin development.  It”s a great primer for how to start creating custom wordpress plugins.  To skip past the video part and get to his list of internet resources you might enjoy this link.

I am loosely planning on a Servusamanu revision sometime next year, but I don’t really see any new plugins getting made there.  I am involved in some freelance web design (one of my thousand projects) so if anything fun happens there I’ll make sure to repost it here.

While I’m talking about it, the Servusamanu redesign is part of a larger project to collect my various projects under a single house.  Servusamanu has remained a distinct entity throughout its existence, but I’m trying to tidy up and centralize my ‘web presence’ for lack of a better term.

My little site isn’t exactly a high hacker target, but it does get assaulted pretty regularly by roaming bots.  I’ve found it necessary to make periodic tweaks to keep everything running smoothly.  Wordpress is nice because a number of the security precautions that I would normally have to implement myself can be found in plugin form.

I currently use Akismet for spam filtering, WordPress Database Backup for weekly backups, and WordPress Security Scan.  This list includes those plugins with 20 or so more for securing a wordpress install.

Why Authors Have Websites or How I Grew To Love The Web

I happen to be rather lucky.  I’m trying to be an author and I’m already alright at web design.  (This web page is not exactly my best work, but it’ll be getting tweaked soon.)

Websites really are a necessary resource these days.  Authors in particular need a medium to communicate new projects to their audiance.  For authors that stay within certain genres maybe it’s less vital, but any author that has books in a few different sections of the bookstore needs some way of pointing their audiance where to work.

In the case of George RR Martin and Michael Stackpole (the two author’s whose sites I visit the most consistantly) they always have some note on what their doing, what conventions their going to, writing samples, outside projects etc etc.  As a fan it’s fun and informative and kinda cool.  For the author’s it’s building up a brand, just like every other product and service.

I’ve been tweaking the website all day. Right now I’m using Yslow to optimize the site.

I got a C grade overall.

grade

Time to use gzip and add expires headers.

This article ‘Five Ways to Speed Up Page Response Times‘ has been very helpful.

Cheers!