Posting some WordPress tips at the day job

During the week I work at a Vermont-based web agency called Union Street Media, where I’m fortunate to spend every day working with a great team on WordPress-powered websites. I’m going to start posting some of the things you’d usually expect to see here at on the company blog. It will mostly be tips that I uncover during the work day after failing to find a good solution via Google. The first of these posts covers adding content to the end of all posts of a specific type. I’ve used that technique to build a plugin which allows our project managers to create project milestone signoff forms directly on the site.

Stay tuned for more WordPress posts from me both here on and over at the USM Interactive Blog.

Connecting Slim Framework and MySQL

Slim Framework is a very light PHP framework that’s great for building web applications and REST APIs. The Slim Hello World example, found right on the homepage, will get you up and running in a matter of minutes. Once you’ve done that, the next step is to create a template and use it to display data from a database. Read on to find out how.


We’ll create a very simple database to get our data from. It will have a single table, “friends,” which contains three fields: id, name, and job. Here’s the SQL for that table:

CREATE TABLE `friends` (
   `id` int(10) unsigned not null auto_increment,
   `name` varchar(255),
   `job` varchar(255),
   PRIMARY KEY (`id`)

INSERT INTO `friends` (`id`, `name`, `job`) VALUES 
('1', 'Sam', 'Gardener'),
('2', 'Molly', 'Chef'),
('3', 'Evan', 'Web Developer');

Database connection

Slim doesn’t come with a database connection utility of its own. You can use any database connection toolkit you like. If you have a favorite, use it!. We’ll be using the MySQLi object, which is the modern way to connect to a MySQL database in native PHP. Put the following code in index.php or stash it in another file and include that file in index.php. In my case I’ve put it in a file at lib/mysql.php.

function connect_db() {
	$server = 'localhost'; // this may be an ip address instead
	$user = 'user';
	$pass = 'pass';
	$database = 'slim_db';
	$connection = new mysqli($server, $user, $pass, $database);

	return $connection;

Getting the data

Index.php is the main controller for your application. If you set up the Hello World example you’ve already used it to route requests, accept variables through the URL, and return data. Now we’ll use it to fetch MySQL data and render it in a template. In this case, we’ll set up a route for ‘/’ so that when you visit the root of your application you get a list of your friends from the database. Here’s the entire index.php file:

require 'Slim/Slim.php';
$app = new \Slim\Slim(); $app->get('/', function () use ($app) {
	require_once 'lib/mysql.php';
	$db = connect_db();
	$result = $db->query( 'SELECT id, name, job FROM friends;' );
	while ( $row = $result->fetch_array(MYSQLI_ASSOC) ) {
		$data[] = $row;

	$app->render('friends.php', array(
			'page_title' => "Your Friends",
			'data' => $data


After setting up Slim this code creates a route for ‘/’ which you’ve already seen. From there, we include the mysql connection function we created earlier and connect to the database. Next we get a record set ($result) and loop through all records, storing them as $data. Finally, we pass that data (plus any other data we need) to a template using Slim’s render() method.


Templates allow you to show your data off to the world. There are many template languages that you can add to Slim using custom Views, but for now we’ll use a simple PHP file as our template. By default, templates will go in a directory called templates/ in the root of your application.

You can pass data when you render a template. In this example we’ll pass a page title and the MySQL data that we converted to an associative array previously. Here’s what our template file, named friends.php, looks like:

<!doctype html>
<meta charset="utf-8">
<title><?php echo $this->data['page_title']; ?></title>
foreach ($this->data['data'] as $friend) {
	echo $friend['id'].' - '.$friend['name'].' - '.$friend['job'].'</br />';

That’s it!

Once you’ve got all of these pieces in place, you’ll have a functioning Slim application. Just visit the root of your application and you should see a list of friends from the database!

Download the full test application with commented code

Canonical domain redirects with Apache Virtual Hosts

There are plenty of reasons you might have multiple domains pointing to the same site. In addition, it’s usually wise to configure your site so that it’s available at both and But it’s usually a good idea to make sure all of these domain variations point to one proper, canonical domain.

There are a number of ways to set up canonical redirects in Apache. The most popular is probably using .htaccess, but you can also use Virtual Hosts. I prefer that method because it lives outside the web root, so other developers on my team are less likely to tamper with it. Here’s how you do it:

<VirtualHost *:80>
 RedirectMatch permanent ^/(.*)$1 

<VirtualHost *:80>
 ServerAdmin webmaster@localhost

DocumentRoot /var/www/
# continue configuring your site here

In this example,, and will all redirect to, which is the primary or canonical location of your site. After the ServerName line in the first block you can put in as many ServerAlias lines as you want, and they’ll all forward to the domain that you specify in the RedirectMatch line.

Note that if you have www in the domain of a WordPress site and you follow these instructions to remove the www, you will get a redirect loop. Instead, update your WordPress config first, and then update the virtual host config.

Crucial skills for people who work on the web

Sideproject has written up a great list of skills for people who work on the front end of websites. It includes learning a CMS (I favor WordPress, in case you hadn’t noticed,) taking a thoughtful approach to front-end frameworks and CSS preprocessors, learning the details of Responsive Design instead of just how to hide pictures and change the navigation, and more.

We’re all working in a time when the role of a front-end developer is expanding. Being pretty good at HTML and CSS doesn’t cut it anymore. Sideproject’s post is a great guide toward beginning to think about the other skills you should master in order to be a highly versatile and employable designer/developer.

Original post:


Lower the WordPress SEO meta box priority

WordPress SEO by Yoast is a great plugin, but its meta box gets high priority on your post edit screen and that can be a little annoying–particularly when it shows up in the middle of your other meta boxes. Fortunately, Yoast has put a filter in place so you can adjust the priority.

To lower the priority of the WordPress SEO meta box, you can put the following code in your theme’s functions.php file:

function lower_wpseo_priority( $html ) {
    return 'low';
add_filter( 'wpseo_metabox_prio', 'lower_wpseo_priority' );

Pretty simple fix for a common annoyance.

Convert OpenWeatherMap’s Kelvin temperatures with PHP’s API returns temperatures in degrees Kelvin, which is probably the best temperature scale for scientific use but is meaningless to most people in day-to-day life. Here are a couple of functions to convert it to your temperature scale of choice:


function k_to_f($temp) {
    if ( !is_numeric($temp) ) { return false; }
    return round((($temp - 273.15) * 1.8) + 32);


function k_to_c($temp) {
	if ( !is_numeric($temp) ) { return false; }
	return round(($temp - 273.15));

If you want to preserve decimal points, you can remove or modify the round() function to get the level of precision you want. Personally, I’ve never found decimal places in temperatures useful day-to-day.

Import multiple WordPress posts with the same name

Update: A previous version of this post recommended modifying the importer, which was the only option at the time. Fortunately, WordPress Importer 0.6.2 implements the wp_import_existing_post filter which makes this much easier to implement. The content of this post has been updated to reflect this improvement.

By default, the WordPress import plugin will not create multiple posts with the same name which were created on the same date. I’m not entirely certain why this is the default behavior but in an era where WordPress is so much more than a blogging engine there is no limit to the number of cases where it isn’t desirable. Maybe you have a post type for business locations that is arranged hierarchically and each location has a child page called “Contact Us.” Maybe a hundred other things.

In such cases, I’ve found moving a site from my production server to the live server is problematic, because the WordPress Importer plugin discards all but the first instance of a post. Fortunately, this behavior is easily changed with a filter implemented in the WordPress Importer.

When the plugin iterates through all of the items in the import file, it checks to see whether or not it should create a post for the current item. Here, I implement a filter which basically tells the importer that there are no duplicate posts.

In your your theme or in a plugin, add the following filter:

 * Tell the importer that none of your posts are duplicates.
function my_filter_post_exists() {
	return 0;
add_filter( 'wp_import_existing_post', 'my_filter_post_exists()', 10, 0 );

By setting $post_exists = 0 you are telling the importer that the post doesn’t exist, which makes it work the way you probably want it to.

Redirecting from to a self-hosted blog

I am occasionally asked if Simple 301 Redirects will allow you to redirect your old blog on to your new self-hosted blog installed from It won’t but there’s an easy way to do just that.

Simple 301 Redirects only works if you can install it on the site you’re redirecting from. Since you’re redirecting from a blog you won’t be able to install my plugin there. What you can do instead is utilize a premium upgrade offered by called Site Redirect, accessible from the dashboard.

As of January 2014 it costs $13 a year. What it does is redirect all of the URLs from your blog to the same URL at a domain of your choosing. It is, in essence, a domain-level redirect.

How long should you pay for it?

Determining how long to keep your Domain Redirect in place depends on where your traffic comes from. You should be OK to cancel it after a year or two if most of your traffic comes from search engines. Search engines will see the 301 redirect and update their indexes.

If most of your traffic comes from inbound links on other sites you may want to keep the redirect in place indefinitely so those links continue working forever.

Redirect all 404 pages to your WordPress home page

I’m occasionally asked to redirect every 404 error on a site to the home page. There are a couple of reasons why you might not want to do this (see below) but there are also valid cases where it could be the right move for your site. If you’ve decided it’s the right thing to do, here’s how to accomplish it easily in WordPress:

Edit or create 404.php in your theme directory. Replace all of the content inside with the following lines:

wp_redirect(site_url(), 301);

And that’s all there is to it!

Why shouldn’t you do that?

There are a couple of reasons that redirecting all 404 errors could be problematic.

First, search engines are said not to pass all of a page’s link equity to the redirected page unless the content is very similar. So redirecting pages that used to rank well to the home page won’t work as a sneaky way to boost your home page.

Probably more importantly, though, is the fact that it will be difficult to monitor which links are 404ing since they’ll all just end up on the home page. The usefulness of Google Webmaster Tools and other methods of monitoring 404 requests is not just in preventing future 404s. The real power is that it helps you identify what your users are looking for and where they’re failing to find it. Fixing all 404s in an automated way makes that more difficult.

Avoiding Timeout When Exporting Large WordPress Sites

When exporting large WordPress sites with thousands of posts and comments, I occasionally run into an issue where the WordPress export tool times out before it’s finished building the XML export file. This can usually be remedied by updating the config files for Apache and PHP. Temporarily increasing the amount of time allowed for a single request should solve the problem. Note that you’ll need access to your server’s config files to make these changes. If you don’t have access, explain to your web host what you’re trying to do and they should be able to help you out.

Assuming you have access, here are some values that you can try:

In the Apache config file, try setting Timeout 300, which means that a single request is allowed to take up to 300 seconds to process before it’s shut down.

You’ll have to make a similar change in the PHP config file. That line will look like max_execution_time = 300. While you’re in there, you may also want to increase the maximum amount of memory available to PHP for a single request. memory_limit = 256M should do the trick.

After you’ve made your config updates, restart Apache so that they take effect. Now you should be able to export your site without any problems. Be patient, as it can take several minutes to export a large site. The values above will give you up to 5 minutes. If it takes longer than that, the process will continue to timeout and you’ll have to make the values even larger.

It’s important to note that after you’re done with the export you should change the settings back to their initial values. No ordinary request should take 300 seconds. Leaving the timeout values that high will allow poorly written scripts to tie up Apache processes for a long time, which will seriously impact your server’s performance.