Custom post types & advanced custom fields in Genesis (part 1)

Setting up the custom post type

I recently found myself needing to create a custom post type as well as being able to split the displayed custom posts into two different blocks of pages. This article walks through that process.

In this article I’ll explain how to set up an events custom post type in WordPress as well as adding meta boxes with the advanced custom fields plugin in order to record event dates and to mark the events as current/future or past. We’ll also look at changing the custom post type output within the Genesis Framework (note: affiliate link). With this information we can then split the events into two separate blocks of pages – one for current/future events, and one for past events.

We’ll start by setting up the custom post type. While you could use a plugin such as Custom Post Type UI  we’ll set the custom post type up manually in a plugin. I prefer this method over putting the code in functions.php as the code is then not linked to the theme if you change your sites theme or redesign it, and you can also easily use it elsewhere. Having said that, any custom post types you create still need to be displayed by your theme, so more than likely you will need to do some modifications theme-side (in functions.php or archive template pages) the more complex your output modifications will be.

We’ll also be defining our plugin within a class. This helps with issues created by functions being thrown into the global namespace, and is considered a superior method of defining a plugin. Tom McFarlin has written an in-depth series about implementing object oriented programming in WordPress if you are interested in finding out more.

You create your custom post plugin by creating a file in your plugins folder, and adding a file (for example custom-posts.php) for the plugin code.

Below is the complete plugin code:

/*Plugin Name: KA Custom Posts
*Description: This plugin registers the 'events' post type.
*Text Domain: ka-custom-posts
*Version: 1.0
*License: GNU General Public License v2 or later
*License URI: 

// Exit if accessed directly
    if ( ! defined( 'ABSPATH' ) ) {

    // Check to make sure a class called KA_Custom_Posts doesn't already exist in the global namespace. 
	if ( ! class_exists( 'KA_Custom_Posts' ) ) {

         * Main Web_Developers_Portfolio class
        // Build the class
        class KA_Custom_Posts {

			// function triggered on initialisation
			public function __construct(){
				add_action( 'init', array($this, 'ka_posts_register'));

			function ka_posts_register() {
				// set up labels for Events
				$eventslabels = array(
			 		'name' => 'Events',
			    	'singular_name' => 'Event',
			    	'menu_name' => 'Events',
			    	'new_item' => 'New Event',
			    	'all_items' => 'All Events',
			    	'view_item' => 'View Event',
			    	'search_items' => 'Search Events',
			    	'add_new' => 'Add New Event',
			    	'add_new_item' => 'Add New Event',
			    	'edit_item' => 'Edit Event',
			    	'not_found' =>  'No Events Found',
			    	'not_found_in_trash' => 'No Events found in Trash', 

			    //register post type for Events
				register_post_type( 'event', array(
					'labels' => $eventslabels,
					'has_archive' => true,
			 		'public' => true,
					'supports' => array( 'title', 'editor', 'excerpt', 'custom-fields', 'thumbnail','page-attributes', 'genesis-seo', 'genesis-cpt-archives-settings'  ),
					'taxonomies' => array( 'post_tag', 'category' ),	
					'exclude_from_search' => false,
					'capability_type' => 'post',
					'rewrite' => array( 'slug' => 'events' ),
					'menu_position' => 20,

			} // end function ka_posts_register
		} // end class KA_Custom_Posts
	} // end beginning if statement

// Check if the class has been defined
    // instantiate the plugin class
    $wp_plugin_template = new KA_Custom_Posts();

I won’t break down the above code as there are many resources on developing custom post types online already. We will look in more detail at integrating the custom fields in order to get the custom event post type to do as we want, as well as modifying the output of the events posts through WordPress actions and filters.

I will however point out the following: if you are using the Genesis Framework you can enable Custom Post Type (CPT) archive settings if you want only a minor level of control over the output, including the ability to add a description to the custom post type page in the same way you would for a normal post (via the Archive Settings link in the WordPress admin dashboard, underneath your custom post type name). You would create an archive template for more complex changes, as described later.

Within your register_post_type() function (and you’ll see this in the code above), you would include support for genesis_cpt_archives-settings, as well as setting several arguments to true:

  •  'has_archive' => true
  •  'public' => true
  •  'show_ui' => true (defaults to true if not added)
  •  'show_in_menu' => true (defaults to true if not added)
  • 'supports' => array( 'title', 'editor', 'genesis-seo', 'thumbnail','genesis-cpt-archives-settings' )

After creating and activating the plugin, you’ll need to reconfigure permalinks in the WordPress dashboard. Make sure post name option is selected. You then create a custom link in your menu – set the address to (or whatever you have named your custom post type). The posts from that custom post type should then appear on that page, in the same style and format as a normal blog post.

Modifying the output of the custom post type

To modify the output on the front-end, you then create an archive page for the custom post type: archive-events.php. There is no need to copy and paste all the content from archive.php (located in lib/structure under the main genesis theme). Simply add in filters to modify actions to change what is shown on that template page. You can do the same for single archive pages on single-post_type.php. Below is our archive-events.php file with a description of each filter or action (specific to the Genesis Framework) and what it is changing:

* Archive Events Template - archive-events.php

//This sets the custom post archive to display the fill content from each post.
add_filter( 'genesis_pre_get_option_content_archive','ka_cp_content_display' );
function ka_cp_content_display() {
 return 'full';

//This returns the post thumbnail
add_filter( 'genesis_pre_get_option_content_archive_thumbnail','ka_cp_image_display' );
function ka_cp_image_display() {
 return 1;

//Set the image thumbnail size (options: thumbnail, medium, large, and featured-image if defined in your theme)
add_filter( 'genesis_pre_get_option_image_size','ka_cp_image_size' );
function ka_cp_image_size() {
 return 'featured-image';

//Changes the image alignment.
add_filter( 'genesis_pre_get_option_image_alignment','ka_cp_image_alignment' );
function ka_cp_image_alignment() {
 return 'aligncenter';

// Remove default post title (with link)
remove_action( 'genesis_entry_header','genesis_do_post_title' );

// Function to display the post title without a link
function ka_cp_archive_title() {
	echo '<h2 class="title">' . get_the_title() . '</h2> ';

// Add the new post title without a link
add_action( 'genesis_entry_header','ka_cp_archive_title' );


We can also modify the output further by removing the entry meta associated with each post (the post author and date). This code needs to go in functions.php, as:

//Remove entry meta for the 'events' post type
function events_remove_entry_meta() {
 	remove_post_type_support( 'events', 'genesis-entry-meta-before-content' );
 	remove_post_type_support( 'events', 'genesis-entry-meta-after-content' );
add_action( 'init', 'events_remove_entry_meta', 12 );

In the follow-on article (coming soon) we’ll look at integrating advanced custom fields to our custom post type.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this:
search previous next tag category expand menu location phone mail time cart zoom edit close