Add multiple custom post types quickly and easily

24/02-2011 | (0)

Here is a simple snippet of code to use when you want to add multiple custom post types and custom taxonomies to a theme or a plugin. Just add the values to the array and the custom post types and custom taxonomies will be added to your wordpress install.

Works from wordpress 3.0+

  Quick & Easy Custom Post Types
$cpts = array(
	'pt' => array( // unique value
		'post_type' => '', // post type name
		'supports' => array(''), // supports title, editor, author, comments etc. (optional, default: title, editor)
		'singular' => '', // post type singular label
		'plural' => '', // post type plural label
		'item_singular' => '', // post type singular item label (optional, if none is supplied, uses singular)
		'item_plural' => '', // post type plural item label (optional, if none is supplied, uses plural)
		'position' => '', // post type position in backend menu (optional, default: 20)
		'slug' => '', // post type slug
$ctaxs = array(
	'tx' => array(
		'taxonomy' => '', // taxonomy name
		'singular' => '', // taxonomy singular label
		'plural' => '', // taxonomy plural label
		'hierarchical' => '', // taxonomy hierarchical
		'slug' => '', // taxonomy slug
		'pts' => array('') // post types that are supported by the taxonomy
if(is_array($cpts)) {
add_action('init', 'wpreso_custom_posttypes');
function wpreso_custom_posttypes() {
	global $cpts;
	foreach($cpts as $cpt){
		$item_singular_label = ((isset($cpt['item_singular']) && !empty($cpt['item_singular']))? $cpt['item_singular'] : $cpt['singular'] );
		$item_plural_label = ((isset($cpt['item_plural']) && !empty($cpt['item_plural']))? $cpt['item_plural'] : $cpt['plural'] );
		$menu_position = ((isset($cpt['position']) && !empty($cpt['position']))? $cpt['position'] :  20);
		$labels = array(
			'name' => __($cpt['plural'], 'wpreso'),
			'singular_name' => __($cpt['singular'], 'wpreso'),
			'add_new' => __('Add New', 'wpreso'),
			'add_new_item' => __('Add New '.$item_singular_label, 'wpreso'),
			'edit_item' => __('Edit '.$item_singular_label, 'wpreso'),
			'new_item' => __('New '.$item_singular_label, 'wpreso'),
			'view_item' => __('View '.$item_singular_label, 'wpreso'),
			'search_items' => __('Search '.$item_plural_label, 'wpreso'),
			'not_found' =>  __('No '.$item_plural_label.' Found', 'wpreso'),
			'not_found_in_trash' => __('No '.$item_plural_label.' found in Trash', 'wpreso'),
			'parent_item_colon' => ''
		$supports = ((isset($cpt['supports']) && !empty($cpt['supports']) && is_array($cpt['supports']))? $cpt['supports'] : array( 'title', 'editor') );
		$args = array(
			'label' => __($cpt['singular'], 'wpreso'),
			'labels' => $labels,
			'public' => true,
			'publicly_queryable' => true,
			'map_meta_cap' => true,
			'rewrite' => array('slug' => $cpt['slug']),
			'capability_type' => 'post',
			'hierarchical' => false,
			'menu_position' => $menu_position,
			'supports' => $supports
	add_filter('post_updated_messages', 'wpreso_posttype_updated_messages');
function wpreso_posttype_updated_messages( $messages ) {
	global $cpts;
	foreach($cpts as $cpt){
		$messages[$cpt['post_type']] = array(
			0 => '', // Unused. Messages start at index 1.
			1 => sprintf( __($cpt['singular'].' Updated. <a href="%s">View '.$cpt['singular'].'</a>', 'wpreso'), esc_url( get_permalink($post_ID) ) ),
			2 => __('Custom Field Updated.', 'wpreso'),
			3 => __('Custom Field Deleted.', 'wpreso'),
			4 => __($cpt['singular'].' Updated.', 'wpreso'),
			/* translators: %s: date and time of the revision */
			5 => isset($_GET['revision']) ? sprintf( __($cpt['singular'].' restored to revision from %s', 'wpreso'), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
			6 => sprintf( __($cpt['singular'].' Published. <a href="%s">View '.$cpt['singular'].'</a>', 'wpreso'), esc_url( get_permalink($post_ID) ) ),
			7 => __($cpt['singular'].' Saved.', 'wpreso'),
			8 => sprintf( __($cpt['singular'].' Submitted. <a target="_blank" href="%s">Preview '.$cpt['singular'].'</a>', 'wpreso'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ),
			9 => sprintf( __($cpt['singular'].' scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview '.$cpt['singular'].'</a>', 'wpreso'),
			  // translators: Publish box date format, see
			  date_i18n( __( 'd/m-Y @ H:i', 'wpreso'), strtotime( $post->post_date ) ), esc_url( get_permalink($post_ID) ) ),
			10 => sprintf( __($cpt['singular'].' Draft Updated. <a target="_blank" href="%s">Preview '.$cpt['singular'].'</a>', 'wpreso'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ),
		return $messages;
add_action('init', 'wpreso_custom_taxonomies');
function wpreso_custom_taxonomies(){
	global $ctaxs;
	foreach($ctaxs as $ct){
		// Add new taxonomy, make it hierarchical (like categories)
		$taxlabels = array(
			'name' => __( $ct['plural'], 'wpreso' ),
			'singular_name' => __( $ct['singular'], 'wpreso'),
			'search_items' =>  __( 'Search '.$ct['plural'], 'wpreso'),
			'all_items' => __( 'All '.$ct['plural'], 'wpreso'),
			'parent_item' => __( 'Parent '.$ct['singular'], 'wpreso'),
			'parent_item_colon' => __( 'Parent '.$ct['singular'].':', 'wpreso'),
			'edit_item' => __( 'Edit '.$ct['singular'], 'wpreso'),
			'update_item' => __( 'Update '.$ct['singular'], 'wpreso'),
			'add_new_item' => __( 'Add New '.$ct['singular'], 'wpreso'),
			'new_item_name' => __( 'New '.$ct['singular'].' name', 'wpreso'),
		register_taxonomy($ct['taxonomy'],$ct['pts'], array(
			'hierarchical' => $ct['hierarchical'],
			'labels' => $taxlabels,
			'show_ui' => true,
			'query_var' => true,
			'rewrite' => array( 'slug' => $ct['slug'] ),

Add page/post slug class to menu item classes

04/01-2011 | (2)

I have not written anything for a long while, and before I had not written much as I am not really a blogger and I only write something when I actually have something that I want to share, which I do today.

Once in a while you have to create a menu that has different colors for each menu item. Now since the introduction of the menu builder in wordpress 3.0 or with one of the menu builder plugins like WP menubar, you can add a class to each item. This though gets a bit tedious if you work on a local version of the site first and then have to update everything on a production version later.

Personally I think that the page/post slug should be part of the menu item classes instead of the menu item id number which less intuitive to use as classes in your style sheet, but it is probably a matter of taste.

Anyway, here is a filter that you can put in your functions.php to automatically add menu-item-slug, where slug in the page/post slug to the menu item classes, when you use the new WordPress menu system, wp_nav_menu. It also checks to see if you have a permalink structure and if it is not present, it will not add anything to your menu item classes.

function add_slug_class_to_menu_item($output){
	$ps = get_option('permalink_structure');
		$idstr = preg_match_all('/<li id="menu-item-(\d+)/', $output, $matches);
		foreach($matches[1] as $mid){
			$id = get_post_meta($mid, '_menu_item_object_id', true);
			$slug = basename(get_permalink($id));
			$output = preg_replace('/menu-item-'.$mid.'">/', 'menu-item-'.$mid.' menu-item-'.$slug.'">', $output, 1);
	return $output;
add_filter('wp_nav_menu', 'add_slug_class_to_menu_item');

Thanks to Josh Stauffer for a great simple way to get the page/post slug.
Also thanks to these guys on the WP forums for explaining how to add filters to the menu items. By the way, this is also a great resource if you want to add first/last classes to your menu items.

How to dynamically add stylesheets to your wordpress theme

14/10-2009 | (1)

If you use a lot of different stylesheets for your theme, it can get a little tedious to add them all to your header.php file. You could import them in your style.css, but some of the great minification plugins do not support import.

If you organize all your stylesheets in a sub-folder in your theme, you can use the below function to automatically register and add them to your theme, provided that you use the wp_head() function in the head section of your header.php.


  • Add the below code to your functions.php file in your theme folder.
  • Add your stylesheets to a sub-folder named css.
  • You can add a print stylesheet, by calling it print.css, for a good starting point, try out Hartija.
  • For handheld devices, you can add a stylesheet called either iphone.css or handheld.css.
  • Lastly you can add a stylesheet for projection, and yes it should be called projection.css.
  • All the above stylesheets should be placed in the CSS folder.
  • If you want to use a different location for your stylesheets, you can change the location in the last part of the themeCSSUrl and themeCSSDir variables, to point to your desired location.
add_action('wp_print_styles', 'add_stylesheets');
function add_stylesheets() {
  $themeCSSUrl =  get_stylesheet_directory_uri() . '/css/';
  $themeCSSDir = dirname(__FILE__). '/css/';
  if ($handle = opendir($themeCSSDir)) {
    while (false !== ($file = readdir($handle))) {
      if(end(explode(".",$file))=='css') {
        if($file=='print.css') {
          wp_register_style(current(explode(".",$file)), $themeCSSUrl.$file,array(),'0.8','print');
          wp_enqueue_style( current(explode(".",$file)));
        } elseif($file=='handheld.css' || $file=='iphone.css') {
          wp_register_style(current(explode(".",$file)), $themeCSSUrl.$file,array(),'1.0','handheld');
          wp_enqueue_style( current(explode(".",$file)));
        } elseif($file=='projection.css') {
          wp_register_style(current(explode(".",$file)), $themeCSSUrl.$file,array(),'1.0','projection');
          wp_enqueue_style( current(explode(".",$file)));
        } else {
          wp_register_style(current(explode(".",$file)), $themeCSSUrl.$file,array(),'1.0','screen');
          wp_enqueue_style( current(explode(".",$file)));

Update 8/4-2011
changed get_bloginfo('template_url') to get_stylesheet_directory_uri() to make this work for child themes as suggested by Paul.

WPreso Video Flow v0.3 released

01/10-2009 | (0)

This fixes an error discovered by Jonas from ZORN D SIGN in which Video Flow tried to include a document from Video FeatureBox, so that if you did not have WPreso Video FeatureBox installed as well, it would crash your whole site.

WPreso Video plugins updated to version 0.2

30/09-2009 | (2)

WPreso Video FeatureBox and WPreso Video Flow have been updated to version 0.2.

The dependency on the deprecated function mime_content_type() has been removed.

The function would check the mime type of the files in the plugin CSS directory and would then include the files which where CSS files.

Due to the fact that the function has been deprecated and some servers do not support the function, this validation has been removed. It now only checks the extension.

FileInfo might be used in the future, but as far as I have read, support for this could also be limited, so the best option is to wait until PHP 6 that should bring new built in support for file mime types.

WPreso Video Plugins released on Extend

16/09-2009 | (0)

Today I released two of my plugins

This is the first time I have release a plugin to the public, so there might be some quirks that I will have to figure out along the way, but I hope people will enjoy them.

I will also be releasing another video plugin soon, which is called WPreso Video Carousel, you can already view in action on the showcase site It is a Video Carousel, but I will have more info on it in a later post and on its own plugin page, until then, I hope you enjoy these two.

Launch of

15/09-2009 | (0)

WPreso launches with two WordPress plugins, WPreso Video FeatureBox and WPreso Video Flow, soon to be available on

More info on the plugins can be found on their respective pages:

or go to the plugins page.

Hope you enjoy them.

This website uses a Hackadelic PlugIn, Hackadelic SEO Table Of Contents 1.7.3.