The Power of Custom Post Types in WordPress 3.0

There has been quite a bit of discussion — especially from a developer perspective — on the custom post types introduced in WordPress 2.9 and refined and made accessible in WordPress 3.0. They are a powerful addition to WordPress and opens up quite a bit of CMS-style possibilities in a powerful new way. However:

“Power corrupts. Knowledge is power. Study hard. Be evil.”

So, with that quote (found un-attributed on the interwebs), let us venture forth and learn about the power of custom post types.

What are custom post types?

In WordPress each time you write a post, page, draft, upload an image, or allow something to auto-save you create an entry in the “posts” table in your database. Each entry in this table has a type associated with it that allows WordPress to go back and search for posts limited by a particular type. The main loop in WordPress for example, searches the posts table for post_type=”post” and post_status=”publish”. Images have an entry under the post type of “attachment”. Pages get “page,” etc.

A custom post type is quite simply one that is not included with WordPress by default. Either you or a plugin have registered the post type to exist.

Why would I need a custom post type?

For many blogs and websites there is no need for creating various custom post types. Thinking about the type of information you want to put on your site, ask some questions:

  • Do I need discrete categorical or tag-type information applied to this information?
    (if yes, this is a good candidate for custom post types)
  • Is this a variation of a blog post?
    (if yes, use categories, tags, page templates, or other means to modify a post rather than anything custom)
  • Do I need to display traditional pages, blog posts, and a 3rd completely unrelated type of information?
    (if yes, you’re in the right place)

While creating a custom post type is much easier in WordPress 3.0 there’s still quite a bit of developer/designer work to be done. If your data type can fit within the existing schema of pages and posts: use those.

Do you have any examples?

I thought you’d never ask. I have three examples to show. The first where custom post types were used, the second where they could have been used to make organization better, and a third where they were not and should not be used.

This website is very much under development, but still serves as a good example. On this site, bicycling hazards are collected and displayed on a custom Google map. I wanted to retain the use of pages for actual static pages on the site and posts for a future blog. Plus, doing so many custom loops having a custom post type to query made things much easier. In this case, each bicycling hazard is an entry in the “hazard” post type — a 3rd type of information requiring a discrete categorical-type taxonomy.

Prior to WordPress 3.0 there was no easy way to create the UI for custom post types (and before 2.9 they weren’t an option at all). Unfortunately this site was developed right around the 2.9 release so in order to get the extensive listings of Artists, Authors, and Art Festivals pages and custom fields were pressed into service. While it works, I would completely re-think that scenario under WordPress 3.0. Artists, Authors, and Musicians would get their own custom post-type and Art Festivals would get another.

It may have been tempting (had this site been developed under WP 3.0) to use custom post types for each of the artists. Instead, I chose to re-purpose the authors model which makes it very easy to attribute pages (artwork) and posts (news) to a particular artist. I could have taken this one step further and created a custom user type (i.e. instead of author) to manage the exact capabilities I needed to give them. In this way, it would be much more flexible than custom post types could be.

How to implement Custom Post Types

There are a bunch of tutorials on how to implement custom post types. Rather than repeat the same information, I’m going to link to some of the better ones

  • WP-Engineer: This was actually written well before 3.0 was released, but it’s a very good article and was the first one I used.
  • Kovshenin: Once you’ve gotten the basic custom post type up and running, this article explains how to modify and extend the various settings to actually be able to use it.
  • WP Codex: It’s always good to go to the source, and the WP Codex has decent information the topic. I’d read the article about post types (linked above) as well as the primary function: register_post_type.

    Now that you know what custom post types are all about and have some ideas on when to use them and when to not use them: go forth and be evil.

WordPress Anti-Hacker

4:00AM. I’ve deleted a line of obfuscated javascript from my client’s website probably 20 times now — once every 10 to 20 minutes. In between I’m staring at lines of information from the raw files, scanning through hundreds of WordPress files, and inspecting database entries to try and find why this line of code keeps coming back. The code is some seriously bad stuff: it creates a small iframe, loads in code from some crazy location (usually China or Russia) that causes the browser to download a .PDF file that’s infected with a trojan. It’s also attempting to set and modify existing cookies to siphon affiliate linking from places like

It’s taken me hours to track this thing down. I’ve found bits of code in the database, a huge PHP file hidden in the images directory, another bit of code in a template file of an unused theme, and another bit of code inside the active theme’s functions.php file. It’s a freakin’ mess. I’d like to share some of what I’ve learned about how to bust this stuff and maybe even prevent it in the future, but I’m warning you — before we go any further — it’s going to take time.


There are some sites out there that can give you some pointers on telling if you’ve been hacked, but it seems that the big, in-your-face, method is getting a browser or search engine warning:

Firefox's example attack site warning
Firefox's example attack site warning

I think most people’s reactions fall into two categories: WTF!? and “not again…”

Unless you happen to be a system admin, I think the first step, really, should be to contact your web host provider for a few reasons:

  • They may be able to very quickly pin-point the vulnerability, so you can patch it. Or at least point you to the file that is causing issues.
  • If it’s their fault, they can start working on the problem
  • If it’s going to affect other people they can take action to mitigate that risk

Here’s a good example: The recent spate of hacked WordPress blogs was due to an incorrectly configured server at a major hosting company *cough* network solutions… *cough* I suggest opening up an urgent trouble ticket or sending an email to your hosting company that says something like this:

Dear web hosting provider,
My website has been compromised and is now displaying in Firefox|Chrome|Google as a malicious site. I’m currently taking steps to determine the issue and solve the problem. I wanted you to be aware in case the vulnerability is server-side, or the hack could effect other websites on our shared server or database. I am running WordPress 2.9 (and list any other web software you have installed such as osCommerce, etc — there is no need to list plugins or themes).

My website url: http://
My username:

Please let me know of anything you find during your investigation.

After that’s taken care of, here’s what I recommend you do.

  • Make a complete backup of your site, right now. Yes, with the bad code and everything. This includes the database. Whatever hack you got may be able to wipe your entire installation — or your web host might! I use wp-db-backup to backup my database, and FileZilla FTP to backup my files.
  • Download and install the WP-Exploit scanner — It’ll give you a list of files with hinky code inside them that you can then go edit. It will also scan your database for weird code that you can delete.
  • Manually scan through all, yes all, of your wp-uploads folder looking for anything strange. Specifically a .php file floating around in there (other than the very first index.php), or an image or other file that you never uploaded.
  • Download your raw access logs (this is something the server administrator sets up, usually through cpanel) and scan through those. Pay special attention to any POST requests to strange pages, or GET requests with very strange data in the request.
  • If you are using anything less than the current version of WordPress, upgrade now.
  • Cross your fingers and hope the hack doesn’t come back.

An apple a day, keeps hackers at bay

Once you’ve gotten past all the hack mess — or if you never got there in the first place — here are some ways to keep your WP installation a bit less hacker prone:

The #1 way to prevent your blog from getting screwed with is by keeping your WordPress installation updated with the latest version. A lot of times, the WordPress team will patch zero-day bugs and push out an incremental upgrade. A zero-day bug means it’s a vulnerability that has been known (published) for zero days. As soon as that new version of WP hits, the timer starts ticking.

The above bit of advice usually comes with a partner: backups! While they aren’t going to keep you from getting hacked, they can make recovery a lot less painful. At least keep regular backups of your content (database and wp-content folder).

If you haven’t ever seen your wp-config.php file, download it and make sure that your authentication keys are set to something. This is not okay:

define(‘AUTH_KEY’, ‘put your unique phrase here’);
define(‘SECURE_AUTH_KEY’, ‘put your unique phrase here’);
define(‘LOGGED_IN_KEY’, ‘put your unique phrase here’);
define(‘NONCE_KEY’, ‘put your unique phrase here’);

If they look like that, go to the authentication key generator at and get yourself some new ones.

Now, if you’re a power user, you’re probably rolling your eyes a bit. Perhaps you should head on over to the codex article on hardening WordPress. Everyone else should probably do a search for “security” in the WordPress Plugins repository. There’s a lot of duplicated functionality, so pick a plugin that is easy to use and scans your configuration for weaknesses. There’s a lot there, so just remember that the #1 way to keep your site safe is by keeping it updated.

Three-Oh Feature Freeze

WordPress versioning is intentionally sequential. WordPress 2.9 came after 2.8 which came after 2.7. In between there were various security updates and these took on the form of 2.9.2 (the current version as of this writing). Although sequential version numbers are predictable, it gives us no sense of scale between versions. For example, WordPress 2.7 introduced a massive change to the user interface as well as a plethora of slick new features.

WordPress 3.0 promises to be another one of these major releases, but geared more toward developers. WP 2.9 introduced the first add_theme_support item: thumbnail selection. This allowed theme authors to declare that they supported something and automatically reveal another administrative back-end panel. WP 3.0 adds a few more of these items, and goes a few steps further toward supporting a full-featured CMS… and social network…and blog network.

  • Theme support: Post-types. While technically WP 2.9 supports custom post-types (something other than the default post, page, and attachment), there is no easy way to implement these post-types. WP 3.0 provides the necessary code to easily add new write panels into the back-end for these custom post types. For example, on this site I might have a custom post type of “design-page” as well as the standard page and post. I first read about how easy it will be to implement these based on a tutorial on Granted, things could drastically change by the time 3.0 is released, but it would likely just become easier.
  • Theme support: Custom Navigation. Theme authors will be able to add a spot for a menu bar that is then controlled from the back-end. Like a sidebar widget, all of the styling of the menu bar will be controlled by the theme’s stylesheet, while the basic structure for the menu will happen automatically by WordPress. This, I feel, will prove to be very popular with end-users while saving some serious development time. WooThemes is taking care of the development of Custom Navigation.
  • The biggest back-end development in WP 3.0 is the merge of WordPress and WordPress MU (multi-user). Now blog authors will be able to click a button and have the ability to create a blog network — that is, allow other people to sign up for and author blogs under the same domain name (think A popular plugin for WPMU is BuddyPress  which transforms WPMU into a full-blown social network with friending, status messages, groups, etc. BuddyPress was recently re-written and now works in conjunction with WP 3.0 (as a blog network) but also on any stand-alone installation of WordPress. This reduces the technical barriers to creating a social network to almost nothing.
  • Apparently WP 3.0 will allow the person installing WP for the first time to choose the username instead of defaulting to “admin.” Typically when I install WP, one of the things I do is create a new user with administrator rights, then go into the database and delete the “admin” user. This is a simple security tactic to foil hackers who rely on the username being admin.

WordPress 3.0 is currently in feature-freeze (as of March 1) — which means no new features will be added. From here until its scheduled release in early April it’s all about testing and bug fixes. If you’re interested in participating, head on over to trac and get involved in WP development.