WP Smith

Creating WordPress & Genesis Websites Since 2010

  • Home
  • About
  • Services
  • Blog
  • Contact

Jan 02 2012

Developing a Custom Post Type and a Custom Taxonomy in Genesis with Custom Pages, Part 1

Recently, someone contacted me to develop a custom post type setup for their website, and they were lamenting how there is nothing on the web that succinctly walks them through the process: soup to nuts. So here's my attempt! However, I am going to assume basic knowledge of custom post types. If you haven't read through my Understanding Custom Post Types series yet, you may want to do that.

First, I created a new php file called wps-admin-functions.php. This is where we will house our Custom Post Types, Taxonomies, and Metaboxes. We could have added this to our theme’s function.php file but this will allow us to have a separate file dedicated to our newly added features. To do this, simply create a new text document in your favorite text editor and save as wps-admin-functions.php.

1. Register your Custom Post Type

[php]<?php
// registration code for discbrakes post type
function wps_register_discbrakes_posttype() {
$labels = array(
'name' => _x( 'Disc Brakes', 'post type general name' ),
'singular_name' => _x( 'Disc Brake', 'post type singular name' ),
'add_new' => _x( 'Add New', 'Disc Brake'),
'add_new_item' => __( 'Add New Disc Brake '),
'edit_item' => __( 'Edit Disc Brake '),
'new_item' => __( 'New Disc Brake '),
'view_item' => __( 'View Disc Brake '),
'search_items' => __( 'Search Disc Brakes '),
'not_found' => __( 'No Disc Brake found' ),
'not_found_in_trash' => __( 'No Disc Brakes found in Trash' ),
'parent_item_colon' => ''
);

$supports = array( 'title' , 'editor' , 'thumbnail' , 'excerpt' , 'revisions' );

$post_type_args = array(
'labels' => $labels,
'singular_label' => __( 'Disc Brake' ),
'public' => true,
'show_ui' => true,
'publicly_queryable' => true,
'query_var' => true,
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'rewrite' => array( 'slug' => 'discbrakes' ),
'supports' => $supports,
'menu_position' => 5,
'taxonomies' => array( 'wps_axlesizes' ),
'menu_icon' => 'http://mydomain.com/wp-content/themes/lib/images/discbrakes-icon.png'
);
register_post_type( 'wps_discbrakes' , $post_type_args );
}
add_action( 'init', 'wps_register_discbrakes_posttype' );
[/php]

Notice in this code that I associate my custom post type with my coming custom taxonomy: 'taxonomies' => array( 'wps_axlesizes' ),. Also, note that I am using a prefix on both my custom post type and taxonomy. The reason this is done is that there may be a naming conflict with a plugin or other code in your theme. The prefix uniquely identifies it to prevent this. It is a best practice, and make sure you do not use the wp_ or genesis_ prefixes.

2. Register your Custom Taxonomy

[php]<?php
// registration code for AxleSizes taxonomy
function wps_register_axlesizes_tax() {
$labels = array(
'name' => _x( 'Axle Sizes', 'taxonomy general name' ),
'singular_name' => _x( 'Axle Size', 'taxonomy singular name' ),
'add_new' => _x( 'Add New Axle Size', 'Axle Size'),
'add_new_item' => __( 'Add New Axle Size' ),
'edit_item' => __( 'Edit Axle Size' ),
'new_item' => __( 'New Axle Size' ),
'view_item' => __( 'View Axle Size' ),
'search_items' => __( 'Search Axle Sizes' ),
'not_found' => __( 'No Axle Size found' ),
'not_found_in_trash' => __( 'No Axle Size found in Trash' ),
);

$pages = array( 'wps_discbrakes' );

$args = array(
'labels' => $labels,
'singular_label' => __( 'Axle Size' ),
'public' => true,
'show_ui' => true,
'hierarchical' => false,
'show_tagcloud' => false,
'show_in_nav_menus' => true,
'rewrite' => array('slug' => 'axle-sizes'),
);
register_taxonomy( 'wps_axlesizes' , $pages , $args );
}
add_action( 'init' , 'wps_register_axlesizes_tax' );[/php]

Custom Post TypeNotice in the registration, the taxonomy is associated with my custom post type: $pages = array( 'wps_discbrakes' );.

Once these are registered, you should see your custom post type to the left under POST.

3. Create my Metaboxes
With metaboxes, you can go the long way; however, I prefer to use a class. Soon WordPress will have a metabox class, hopefully in WordPress 3.3, so this section will be rendered "obsolete" yet still usable. First, download the custom metabox code from GitHub. For a great explanation of the code, see Bill Erickson's tutorial. Because of the tutorial, I won't break down this section.

Once downloaded, place the metabox folder in your lib folder in the child theme folder so that: CHILD_URL . '/lib/metabox/init.php'

So the file structure is
CHILD-THEME-FOLDER

  • IMAGES FOLDER
  • LIB FOLDER
    • METABOX FOLDER
    • IMAGES FOLDER
    • wps-admin-functions.php
  • functions.php
  • style.css
  • readme.txt

[php]<?php
// Create Metaboxes
$prefix = '_wps_';
add_filter( 'cmb_meta_boxes', 'wps_create_metaboxes' );
function wps_create_metaboxes() {
global $prefix;

$meta_boxes[] = array(
'id' => 'disk-brakes-info',
'title' => 'Disk Brakes Information',
'pages' => array( 'wps_discbrakes' ), // post type
'context' => 'normal',
'priority' => 'low',
'show_names' => true, // Show field names left of input
'fields' => array(
array(
'name' => 'Instructions',
'desc' => 'In the right column upload a featured image. Make sure this image is at least 900x360px wide. Then fill out the information below.',
'id' => $prefix . 'title',
'type' => 'title',
),
array(
'name' => 'Part Number',
'desc' => 'Enter the part number (e.g., XXXXXXX)',
'id' => $prefix . 'part_number',
'type' => 'text'
),
array(
'name' => 'Rotor',
'desc' => '',
'id' => $prefix . 'rotor',
'type' => 'select',
'options' => array(
array('name' => 'Stainless Steel', 'value' => 'stainless-steel'),
array('name' => 'E-Coat (Black)', 'value' => 'e-coat-black'),
array('name' => 'Option Three', 'value' => 'none')
)
),
array(
'name' => 'Caliper',
'desc' => '',
'id' => $prefix . 'caliper',
'type' => 'select',
'options' => array(
array('name' => 'Stainless Steel', 'value' => 'stainless-steel'),
array('name' => 'E-Coat (Black)', 'value' => 'e-coat-black'),
array('name' => 'Option Three', 'value' => 'none')
)
),
array(
'name' => 'Mounting Bracket',
'desc' => '',
'id' => $prefix . 'mounting_bracket',
'type' => 'select',
'options' => array(
array('name' => 'Stainless Steel', 'value' => 'stainless-steel'),
array('name' => 'E-Coat (Black)', 'value' => 'e-coat-black'),
array('name' => 'Option Three', 'value' => 'none')
)
),
array(
'name' => 'Weight per Axle Set',
'desc' => 'e.g., 45 LBS.',
'id' => $prefix . 'weight_per_axle_set',
'type' => 'text'
),
),
);

return $meta_boxes;
}

// Initialize the metabox class
add_action( 'init', 'be_initialize_cmb_meta_boxes', 9999 );
function be_initialize_cmb_meta_boxes() {
if ( !class_exists( 'cmb_Meta_Box' ) ) {
require_once(CHILD_DIR . '/lib/metabox/init.php');
}
}
[/php]

This will create the metaboxes for the custom post type.
Custom Post Type Metaboxes

4. Clear Permalinks
Now in your admin area, navigate to Settings > Permalinks and click Save Changes. This will flush and clear your permalinks. This is important if you are getting strange 404 Page Not Found errors.

So our finished product is this: wps-admin-functions.php

[php]
<?php

/**
* Admin Functions
*
* This file is responsible for registering the
* custom post types, taxonomies, and metaboxes.
*
* @author Travis Smith <[email protected]>
* @copyright Copyright (c) 2011, Travis Smith
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
*
*/

// registration code for discbrakes post type
// registration code for discbrakes post type
function wps_register_discbrakes_posttype() {
$labels = array(
'name' => _x( 'Disc Brakes', 'post type general name' ),
'singular_name' => _x( 'Disc Brake', 'post type singular name' ),
'add_new' => _x( 'Add New', 'Disc Brake'),
'add_new_item' => __( 'Add New Disc Brake '),
'edit_item' => __( 'Edit Disc Brake '),
'new_item' => __( 'New Disc Brake '),
'view_item' => __( 'View Disc Brake '),
'search_items' => __( 'Search Disc Brakes '),
'not_found' => __( 'No Disc Brake found' ),
'not_found_in_trash' => __( 'No Disc Brakes found in Trash' ),
'parent_item_colon' => ''
);

$supports = array( 'title' , 'editor' , 'thumbnail' , 'excerpt' , 'revisions' );

$post_type_args = array(
'labels' => $labels,
'singular_label' => __( 'Disc Brake' ),
'public' => true,
'show_ui' => true,
'publicly_queryable' => true,
'query_var' => true,
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'rewrite' => array( 'slug' => 'discbrakes' ),
'supports' => $supports,
'menu_position' => 5,
'taxonomies' => array( 'wps_axlesizes' ),
'menu_icon' => 'http://mydomain.com/wp-content/themes/lib/images/discbrakes-icon.png'
);
register_post_type( 'wps_discbrakes' , $post_type_args );
}
add_action( 'init', 'wps_register_discbrakes_posttype' );

// registration code for AxleSizes taxonomy
function wps_register_axlesizes_tax() {
$labels = array(
'name' => _x( 'Axle Sizes', 'taxonomy general name' ),
'singular_name' => _x( 'Axle Size', 'taxonomy singular name' ),
'add_new' => _x( 'Add New Axle Size', 'Axle Size'),
'add_new_item' => __( 'Add New Axle Size' ),
'edit_item' => __( 'Edit Axle Size' ),
'new_item' => __( 'New Axle Size' ),
'view_item' => __( 'View Axle Size' ),
'search_items' => __( 'Search Axle Sizes' ),
'not_found' => __( 'No Axle Size found' ),
'not_found_in_trash' => __( 'No Axle Size found in Trash' ),
);

$pages = array( 'wps_discbrakes' );

$args = array(
'labels' => $labels,
'singular_label' => __( 'Axle Size' ),
'public' => true,
'show_ui' => true,
'hierarchical' => false,
'show_tagcloud' => false,
'show_in_nav_menus' => true,
'rewrite' => array('slug' => 'axle-sizes'),
);
register_taxonomy( 'wps_axlesizes' , $pages , $args );
}
add_action( 'init' , 'wps_register_axlesizes_tax' );

// Create Metaboxes
$prefix = '_wps_';
add_filter( 'cmb_meta_boxes', 'wps_create_metaboxes' );
function wps_create_metaboxes() {
global $prefix;

$meta_boxes[] = array(
'id' => 'disk-brakes-info',
'title' => 'Disk Brakes Information',
'pages' => array( 'wps_discbrakes' ), // post type
'context' => 'normal',
'priority' => 'low',
'show_names' => true, // Show field names left of input
'fields' => array(
array(
'name' => 'Instructions',
'desc' => 'In the right column upload a featured image. Make sure this image is at least 900x360px wide. Then fill out the information below.',
'id' => $prefix . 'title',
'type' => 'title',
),
array(
'name' => 'Part Number',
'desc' => 'Enter the part number (e.g., XXXXXXX)',
'id' => $prefix . 'part_number',
'type' => 'text'
),
array(
'name' => 'Rotor',
'desc' => '',
'id' => $prefix . 'rotor',
'type' => 'select',
'options' => array(
array('name' => 'Stainless Steel', 'value' => 'stainless-steel'),
array('name' => 'E-Coat (Black)', 'value' => 'e-coat-black'),
array('name' => 'Option Three', 'value' => 'none')
)
),
array(
'name' => 'Caliper',
'desc' => '',
'id' => $prefix . 'caliper',
'type' => 'select',
'options' => array(
array('name' => 'Stainless Steel', 'value' => 'stainless-steel'),
array('name' => 'E-Coat (Black)', 'value' => 'e-coat-black'),
array('name' => 'Option Three', 'value' => 'none')
)
),
array(
'name' => 'Mounting Bracket',
'desc' => '',
'id' => $prefix . 'mounting_bracket',
'type' => 'select',
'options' => array(
array('name' => 'Stainless Steel', 'value' => 'stainless-steel'),
array('name' => 'E-Coat (Black)', 'value' => 'e-coat-black'),
array('name' => 'Option Three', 'value' => 'none')
)
),
array(
'name' => 'Weight per Axle Set',
'desc' => 'e.g., 45 LBS.',
'id' => $prefix . 'weight_per_axle_set',
'type' => 'text'
),
),
);

return $meta_boxes;
}

// Initialize the metabox class
add_action( 'init', 'wps_initialize_cmb_meta_boxes', 9999 );
function wps_initialize_cmb_meta_boxes() {
if ( !class_exists( 'cmb_Meta_Box' ) ) {
require_once(CHILD_DIR . '/lib/metabox/init.php');
}
}
[/php]

Written by Travis Smith · Categorized: Custom Post Types, Genesis

Dec 29 2011

How to Remove Specific Posts from Blog Page in Genesis

Recently, I needed to remove a specific post from a blog page. Here's how I did it.

[php]
add_filter( 'genesis_custom_loop_args', 'wps_exclude_post' );
function wps_exclude_post ( $args ) {
$args['post__not_in'] = array(6586); //Post ID
return $args;
}
[/php]

This code adds an argument to the WordPress query called 'post__not_in' which takes an array of post IDs. So, I could just create a laundry list of posts I don't want in; however, in my case I only needed to exclude one.

As always, this code goes in functions.php.

Written by Travis Smith · Categorized: Genesis

Dec 22 2011

How to Add a Custom Field Shortcode to Use Any Custom Field in Posts

In another tutorial I am writing, one for non-coders, I needed a way to pull in custom fields into the post. Currently (and sadly), in Genesis there is no way to do this; however, Genesis does have a great php function that already does this, genesis_get_custom_field(). So turning that into a shortcode is rather easy. Just add the following to your functions.php code:

[php]
add_shortcode( 'post_field', 'genesis_post_field_shortcode' );
/**
* Returns the value of a custom field.
*
* Supported shortcode attributes are:
* field (field name),
*
* @param array $atts Shortcode attributes
* @return string Shortcode output
*/
function genesis_post_field_shortcode( $atts ) {

$defaults = array(
'field' => '',
);
$atts = shortcode_atts( $defaults, $atts );

return genesis_get_custom_field( $atts['field'] );
}
[/php]
To use the shortcode, you just insert [ post_field field="my_field_name"] (without the space in the front) and boom! It works!

Written by Travis Smith · Categorized: Genesis, Tutorials

Dec 08 2011

How to Add Genesis Custom Content Columns to the Editor (to Appear in Visual Mode)

Recently, I had a need to have the custom columns of WordPress on the backend to be used in the Visual Editor. So thanks to a few tutorials out there regarding this, especially Alison's Mastering the TinyMCE Styles Dropdown in the WordPress Visual Editor, who has a great plugin, Custom Styles Dropdown, and WPEngineer's, Customize WordPress WYSIWYG Editor (more for a better understanding). Another option is the Advanced TinyMCE WordPress Plugin. I plan to develop this into a plugin, coming soon...

However, this tutorial will focus solely on the Custom Content Columns for Genesis users. If you need an explanation, please see Alison's Mastering the TinyMCE Styles Dropdown in the WordPress Visual Editor post.

Add this to your functions.php file.
[php]
add_filter( 'mce_buttons_2', 'wps_mce_buttons_2' );
/**
* Show the style dropdown on the second row of the editor toolbar.
*
* @param array $buttons Exising buttons
* @return array Amended buttons
*/
function wps_mce_buttons_2( $buttons ) {

// Check if style select has not already been added
if ( isset( $buttons['styleselect'] ) )
return;

// Appears not, so add it ourselves.
array_unshift( $buttons, 'styleselect' );
return $buttons;

}

add_filter( 'tiny_mce_before_init', 'wps_mce_before_init' );
/**
* Add column entries to the style dropdown.
*
* 'text-domain' should be replaced with your theme or plugin text domain for
* translations.
*
* @param array $settings Existing settings for all toolbar items
* @return array Amended settings
*/
function wps_mce_before_init( $settings ) {

$style_formats = array(

array(
'title' => __( 'First Half', 'text-domain' ),
'block' => 'div',
'classes' => 'one-half first',
),
array(
'title' => __( 'Half', 'text-domain' ),
'block' => 'div',
'classes' => 'one-half',
),
array(
'title' => __( 'First Third', 'text-domain' ),
'block' => 'div',
'classes' => 'one-third first',
),
array(
'title' => __( 'Third', 'text-domain' ),
'block' => 'div',
'classes' => 'one-third',
),
array(
'title' => __( 'First Quarter', 'text-domain' ),
'block' => 'div',
'classes' => 'one-fourth first',
),
array(
'title' => _( 'Quarter', 'text-domain' ),
'block' => 'div',
'classes' => 'one-fourth',
),
array(
'title' => __( 'First Fifth', 'text-domain' ),
'block' => 'div',
'classes' => 'one-fifth first',
),
array(
'title' => __( 'Fifth', 'text-domain' ),
'block' => 'div',
'classes' => 'one-fifth',
),
array(
'title' => __( 'First Sixth', 'text-domain' ),
'block' => 'div',
'classes' => 'one-sixth first',
),
array(
'title' => __( 'Sixth', 'text-domain' ),
'block' => 'div',
'classes' => 'one-sixth',
),
);

// Check if there are some styles already
if ( $settings['style_formats'] )
$settings['style_formats'] = array_merge( $settings['style_formats'], json_encode( $style_formats ) );
else
$settings['style_formats'] = json_encode( $style_formats );

return $settings;

}
[/php]

This will result in this:
Custom Columns in the Editor

However, the HTML will contain the necessary classes and styles and will be:
[html]
<div class="one-half first">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean quam massa, iaculis vel vehicula aliquam, iaculis ut risus. Mauris luctus, justo quis blandit vestibulum, dui lorem rhoncus massa, non aliquam ante erat at dolor. In facilisis libero in libero pharetra eu pellentesque mauris convallis. In vitae tortor lorem. Nullam aliquet ligula vel lectus pretium eget elementum massa laoreet. In hac habitasse platea dictumst. Quisque lacinia odio vitae nisl dictum euismod. Suspendisse eget nisl quis leo pulvinar cursus. Aliquam vel elit vehicula neque consectetur blandit eu eget nisi. Maecenas vitae risus quis lacus feugiat dictum sed eget arcu. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla feugiat massa ut mauris viverra porta.</div>
<div class="one-half">Fusce porttitor libero ut libero aliquam vitae faucibus lorem tincidunt. Phasellus pharetra libero et eros pellentesque eget feugiat eros adipiscing. Pellentesque massa augue, interdum ut facilisis et, pellentesque et justo. Proin consectetur venenatis vehicula. Aliquam interdum ullamcorper urna, quis volutpat massa dictum non. Integer placerat nunc porttitor lacus volutpat ultricies. Integer ornare ultrices nibh sed hendrerit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</div>
[/html]

Now you can also add the following to incorporate your CSS into the Visual Editor to achieve a closer representation on the backend (that will eventually appear on the front end):
[php]
add_editor_style();
[/php]
Now, the add_editor_style(); is a really cool feature. Now you can add a stylesheet to your child theme's folder called editor-style.css, and any style that you want to appear in the editor will now appear in the visual editor as it would on the external pages. So to get the custom column classes, you will need to create the editor-style.css.

Here is what your visual editor will look like with the use of add_editor_style();
Custom Columns with add_editor_style()

However, you do not need to add the add_editor_style(); for this to work. Adding the add_editor_style(); only allows the style to be applied inside the Visual editor.

[css]
/* Column Classes
------------------------------------------------------------ */

.five-sixths,
.four-fifths,
.four-sixths,
.one-fifth,
.one-fourth,
.one-half,
.one-sixth,
.one-third,
.three-fifths,
.three-fourths,
.three-sixths,
.two-fifths,
.two-fourths,
.two-sixths,
.two-thirds {
float: left;
margin: 0 0 20px;
padding-left: 3%;
}

.one-half,
.three-sixths,
.two-fourths {
width: 48%;
}

.one-third,
.two-sixths {
width: 31%;
}

.four-sixths,
.two-thirds {
width: 65%;
}

.one-fourth {
width: 22.5%;
}

.three-fourths {
width: 73.5%;
}

.one-fifth {
width: 17.4%;
}

.two-fifths {
width: 37.8%;
}

.three-fifths {
width: 58.2%;
}

.four-fifths {
width: 78.6%;
}

.one-sixth {
width: 14%;
}

.five-sixths {
width: 82%;
}

.first {
clear: both;
padding-left: 0;
}
[/css]

Or simply download the file below and place inside your child theme folder.
Download: [download id="17"]

Written by Travis Smith · Categorized: Genesis, Tutorials

Dec 07 2011

How to Add a Default Custom Header to Your Genesis Child Theme

Recently, I needed to add a header that the client may want to be able to change later. So the obvious solution is a custom header that defaulted to whatever I needed to make it. So here's what I did:

[php]
// Add Custom Header
define( 'HEADER_TEXTCOLOR' , 'ffffff'); //change the number to whatever you want
define( 'HEADER_IMAGE' , CHILD_URL . '/images/logo.png');
define( 'HEADER_IMAGE_WIDTH' , 960 ); //change the number to whatever you want
define( 'HEADER_IMAGE_HEIGHT' , 200 ); //change the number to whatever you want

// gets included in the site header
function wps_header_style() {
?><style type="text/css">
#header {
background: url(<?php header_image(); ?>);
}
</style><?php
}

// gets included in the admin header
function wps_admin_header_style() {
?><style type="text/css">
#headimg {
width: <?php echo HEADER_IMAGE_WIDTH; ?>px;
height: <?php echo HEADER_IMAGE_HEIGHT; ?>px;
background: no-repeat;
}
</style><?php
}

add_custom_image_header( 'wps_header_style', 'wps_admin_header_style' );
[/php]

If you do not want them to be able to change the color of the text then...

[php]
// Add Custom Header
define( 'NO_HEADER_TEXT' , true );
define( 'HEADER_TEXTCOLOR' , '');
define( 'HEADER_IMAGE' , CHILD_URL . '/images/logo.png');
define( 'HEADER_IMAGE_WIDTH' , 960 ); //change the number to whatever you want
define( 'HEADER_IMAGE_HEIGHT' , 200 ); //change the number to whatever you want

// gets included in the site header
function wps_header_style() {
?><style type="text/css">
#header {
background: url(<?php header_image(); ?>);
}
</style><?php
}

// gets included in the admin header
function wps_admin_header_style() {
?><style type="text/css">
#headimg {
width: <?php echo HEADER_IMAGE_WIDTH; ?>px;
height: <?php echo HEADER_IMAGE_HEIGHT; ?>px;
background: no-repeat;
}
</style><?php
}

add_custom_image_header( 'wps_header_style', 'wps_admin_header_style' );
[/php]

Written by Travis Smith · Categorized: Genesis

  • « Previous Page
  • 1
  • …
  • 5
  • 6
  • 7
  • 8
  • 9
  • …
  • 20
  • Next Page »
  • Twitter
  • Facebook
  • LinkedIn
  • Google+
  • RSS

Copyright © 2025 � WP Smith on Genesis on Genesis Framework � WordPress � Log in