Archive for the 'Wordpress' Category

Some Thoughts on Wordpress Training

I seem to train a lot of our clients in Wordpress, so I thought I’d write something up. Copy/Pasted here, for your entertainment.

In my experience, most people think Wordpress training is going to be terribly complicated. Usually, they don’t “get” computers and don’t expect to understand a content management system, either. Once they see how simple Wordpress is, they can usually take care of their content on their own.

I usually start by explaining that they don’t need to worry about copying down any URLs, usernames, or passwords because I’ll send those by email. This is one of those things that stress people out, so already they don’t have to worry about something.

I explain a little bit about the Dashboard. Usually by this time I have cut out most of what shows up on the Dashboard in order to make their lives easier. Nobody cares about the Wordpress Development Blog, so turn that off before-hand. The Dashboard is nice because there’s multiple ways to get at what you’re trying to get at.

Then I explain that there are two kinds of content: Posts and Pages. I explain what they are. The concepts are pretty simple.

Then I show them Posts. Once they see that it’s just a Title, Body, and a Category, you can watch them relax. This isn’t so hard. The editor is friendly and easy to use. Inserting an image is easy. Uploading a PDF is easy. Links? No sweat. They can do this. I usually ignore everything else on the Post form page because it doesn’t matter to them.

I usually go through the process of editing existing Posts, and then creating new Posts. I show off how creating a Post in the News category automatically shows up on the News page, and the Home page. That sort of thing. People are relieved by automation.

When people see that a Career Opportunity is just a Post in a different category, they see how simple it is.

Ask if there are any questions or if anyone would like to see something again. Take a drink of water.

Then I go through Pages. They like that pages are organized hierarchically. And Pages have fewer fields than Posts, so they can handle this, too.

People are often very concerned about screwing something up. I mention the Preview button. I tell them they can check the front end after they’ve made changes, and if anything is wrong, go back and edit it. And I mention the revisions. Nobody has ever needed the revisions.

Any questions?

That’s usually it. The thing I hear almost everyone say is “that’s really simple” and “I’ll have to get in there and play around.” Even after seeing how easy it is, people think it’s voodoo. But nobody really has any trouble with it once they’ve tried it themselves.

Rotating Images on the Home Page with Wordpress

Building on ideas I posted earlier, I’ve come up with a clever way to allow users to manage the images that appear in a rotating-image-block.

Upload the images into a page. I called my page “Rotating Images for the Home Page.” Then, in your template, fetch the contents of that page and format them for display. Once your HTML is set up, your rotating image script can take over.

Remember to hide your page from navs. I’ve started putting all my “special” pages under a page called “Special Pages Not In Menus.” That way, all I have to do is exclude the top-most special page once, and any special pages under it are hidden from the menus as well.

Making Blocks of Content on the Home Page Editable in Wordpress

A popular home page design is a sort of newspaper layout, with lots of little blocks of content. An example of that is this website we did for Gilda’s Club.

What we want to do is make the “Mission” block, in the middle right, editable through Wordpress. It’s actually pretty easy to do.

1. Create a new page. Call it something like Home Page: Mission. Copy/Paste the content in there.

2. If you have the kind of navigation that picks up pages automatically, you’re going to need to add the page id to an exclude list in your wp_list_pages() call. This may be the header navigation, sidebar, and/or footer.

3. Now we’re going to modify our template. Find the part where that block content is hardcoded into the template. Replace it with this:

  $page_id = 541; // change to your page id, obviously
  $post = get_page($page_id);
  setup_postdata($post);
  the_content();

And you’re done.

Wordpress 2.9, Post Thumbnails

One of the cool new things about wp2.9 is support for post thumbnails. What this means is that you can associate an image with a post, as a thumbnail for that post.

Previously I have had to write all kinds of code to pull the first image embedded in the body of the post, resize it, and throw that into the template. For example, a “Current Projects” page. Each project on this page is a Post in the “Current Project” category. You can embed/upload an image into the body. My template then extracts the image from the body, resizes it, makes a link out of it, and displays it on the page that lists all of the Current Project Posts. I’ve done this so many times I copy/paste the code from one project to another.

WP2.9 has this post thumbnail business. Which is brilliant. You enable support for post thumbnails in your theme. Then there’s a new block on the Post edit screen where you pick an image to use as a thumbnail. You don’t upload it to the body, it’s separate and clear. Then I use two functions in my template code to check whether or not there’s a thumbnail for this post, and if so, output it.

Dirt simple. I love it. I played around with this a bit so I know how it works. I can’t wait to put it into practice.

Parse CSV File

I’m using wp-table for a Wordpress project, and you can read in data from a csv file and it builds a table for you. At least, that’s the theory. In fact, it uses PHP’s built-in fgetcsv() function. Which blows.

fgetcsv() does a good job of parsing lines which are comma separated values, but it’s really profoundly retarded about understanding that the end of a line is the end of a record. If you read in 1000 bytes, you could have 10 records/line in there, but it mashes them all into one array.

So I wrote my own. It’s pretty basic, but it works.

function parse_csv_file($file, $columnheadings = false, $delimiter = ';', $enclosure = '"') {
 
	$row = 1;
	$rows = array();
 
	$file_contents = file_get_contents($file);
 
	// determine the line break character sequence
	$line_break = chr(13) . chr(10);
	$pos = strpos($file_contents, $line_break);
	if ($pos === false) { // didn't find that
		$line_break = chr(10);
		$pos = strpos($file_contents, $line_break);
		if ($pos === false) { // not that either
			$line_break = chr(13);
			$pos = strpos($file_contents, $line_break);
			if ($pos === false) { // uh oh
				// Cannot determine line break character sequence.
				exit;
			} else {
				// Line breaks on 13
			}
		} else {
			// Line breaks on 10
		}
	} else {
		// Line breaks on 13.10
	}
 
	$lines = split($line_break, file_get_contents($file));
	foreach ($lines as $line_num => $line) {
		$line = trim($line);
		if ($line == '') continue;
 
		$l = array();
		$enc = false;
		$v = '';
		for ($i = 0; $i < strlen($line); $i++) {
 
			$char = substr($line, $i, 1);
 
			if ($char == $enclosure) {
 
				if ($enc) {
					$enc = false;
				} else {
					$enc = true;
				}
 
			} else if ($char == $delimiter) {
 
				if ($enc) {
					$v .= $char;
				} else {
					$l[] = $v;
					$v = '';
				}
 
			} else {
				$v .= $char;
			}
 
		} // end foreach character in this line
 
		$rows[] = $l;
	}
 
	return $rows;
}

Show/Hide CSS For Three Levels Of Menu/Nav

Written with wordpress in mind, but you can adapt as necessary.

Often you have levels of pages. You’ll have top level pages, and some of them have child pages, and some of those child pages have grandchild pages. Usually what you want is for the menu/navigation/sidebar to limit what it’s displaying. You don’t want to see everything, only what’s under where you are now in the hierarchy.

Default case:
ONE
TWO
THREE
Case 2:
ONE (current page item)
- CHILDA
- CHILDB
- CHILDC
TWO
THREE
Case 3:
ONE (current page parent, current page ancestor)
- CHILDA (current page item)
- - GRANDCHILD
- CHILDB
- CHILDC
TWO
THREE
Case 4
ONE (current page ancestor)
- CHILDA (current page parent)
- - GRANDCHILD (current page item)
- CHILDB
- CHILDC
TWO
THREE

Alright, so here’s the CSS to make this happen:

#menu ul li ul {
	display: none;
}
#menu ul li.current_page_ancestor ul {
	display: block;
}
#menu ul li.current_page_ancestor ul li ul {
	display: none;
}
#menu ul li.current_page_ancestor ul li.current_page_parent ul {
	display: block;
}
#menu ul li.current_page_parent ul li.current_page_item ul {
	display: block;
}
#menu ul li.current_page_parent ul li.current_page_item ul li ul {
	display: none;
}
#menu ul li.current_page_item ul {
	display: block;
}
#menu ul li.current_page_item ul li ul {
	display: none;
}

jQuery Show/Hide for Wordpress Sidebar Widgets

Here’s some handy jQuery code to show/hide menu items in Wordpress’s sidebar.

function sidebarHide(element) {
	// this function hides the ul
	// also calls sidebarPlus
	$('#sidebar ul ' + element +' ul').each(function() {
		$(this).hide('fast');
	});
	sidebarPlus(element);
	return false;
}
function sidebarShow(element) {
	// this function shows the ul
	// also calls sidebarMinus
	$('#sidebar ul ' + element +' ul').each(function() {
		$(this).show('fast');
	});
	sidebarMinus(element);
	return false;
}
function sidebarPlus(element) {
	// function appends a + to the title
	// this plus is a link to show the contents
	$('#sidebar ul ' + element + ' h2').each(function() {
		var text = $(this).text();
		var plus = text.lastIndexOf(" -");
		if (plus > 0) {
			text = text.substring(0, plus);
		}
		var link = '<a href="#" onclick="return sidebarShow(\'' + element + '\');">' + text + ' +</a>';
		$(this).html(link);
	});	
}
function sidebarMinus(element) {
	// function appends a - to the title
	// this minus is a link to hide the contents
	$('#sidebar ul ' + element + ' h2').each(function() {
		var text = $(this).text();
		var minus = text.lastIndexOf(" +");
		if (minus) {
			text = text.substring(0, minus);
		}
		var link = '<a href="#" onclick="return sidebarHide(\'' + element + '\');">' + text + ' -</a>';
		$(this).html(link);
	});	
}
 
 
$(document).ready(function() {
 
	$('#sidebar ul li').each(function() {
		var n = $(this).attr('id');
		if (n != '') {
			sidebarHide('#' + n);
		}
	});
 
});

Getting The Content From Wordpress

Wordpress has all these neat functions for handling parts of a Post, like the_title() and the_exceprt(). Some of them are nice enough to return the value so that you can use it in your PHP code. the_content() is not one of them. But you can hack that function in /wp-includes/post-template.php

function the_content($more_link_text = '(more...)', $stripteaser = 0, $more_file = '', $passback = false) {
	$content = get_the_content($more_link_text, $stripteaser, $more_file);
	$content = apply_filters('the_content', $content);
	$content = str_replace(']]>', ']]&gt;', $content);
 
	if (!$passback) {
		echo $content;
	} else {
		return $content;
	}
}

Get Grandparent Pages in Wordpress

I copied these functions from the Fold Page List plug-in for Wordpress and modified them a little. They are very handy for building breadcrumbs.

/** get_parent_id
  * get the id of the parent of a given page
  * @param int page id
  * @return int the id of the page's parent page
  */
function get_parent_id ( $child = 0 ) {
        global $wpdb;
        // Make sure there is a child ID to process
        if ( $child > 0 ) {
                $result = $wpdb->get_var("SELECT post_parent FROM $wpdb->posts WHERE ID = $child");
        } else {
                // ... or set a zero result.
                $result = 0;
        }
        //
        return $result;
}
/** get_ancestor_ids
  * get an array of ancestor ids for a given page
  * you get an array that looks something like
  * [0] this page id
  * [1] parent page id
  * [2] grandparent page id
  * @param int page you want the ancestry of
  * @param boolean include this page in the tree (optional, default true)
  * @param boolean results top down (optional, default true)
  * @return an array of ancestor ids
  */
function get_ancestor_ids ( $child = 0, $inclusive=true, $topdown=true ) {
        if ( $child && $inclusive ) $ancestors[] = $child;
        while ($parent = get_parent_id ( $child ) ) {
                $ancestors[] = $parent;
                $child = $parent;
        }
        //      If there are ancestors, test for resorting, and apply
        if ($ancestors && $topdown) krsort($ancestors);
        if ( !$ancestors ) $ancestors[] = 0;
        //
        return $ancestors;
 }

Here’s my bread crumb function …

function buildBreadCrumbTrail($showThis = true) {
 
	global $post;
	echo '<a href="/">Home</a>' . chr(10);
	$ancestors = get_ancestor_ids($post->ID, false);
	$num_ancestors = count($ancestors);
 
	foreach ($ancestors as $i => $ancestor_id) {
		if ($ancestor_id > 0) {
			echo ' > <a href="'.get_permalink($ancestor_id).'">'.get_the_title($ancestor_id).'</a>';
		}
	}
 
	if ($showThis) {
		echo ' > <a href="'; the_permalink(); echo '">'; the_title(); echo '</a>' . chr(10);
	}
 
} // end buildBreadCrumbTrail