WP Smith

Creating WordPress & Genesis Websites Since 2010

  • Home
  • About
  • Services
  • Blog
  • Contact

Sep 29 2011

How to Include Another Post Type and Custom Taxonomy on the Genesis Blog Page

So recently, someone asked me to help them assimilate two post types on the Genesis blog page. Since because of the Genesis loops, this becomes quite easy. So here's what we need to do:

  1. Setup the Template Name
  2. Create the Custom Loop
  3. Modify the Post Meta
  4. Customize the Content Display

Setup the Template Name

First and as always, we need to set up the template. You can start by scratch, which this tutorial will do, or you can copy page_blog.php from the genesis folder.
[php]<?php
/**

Template Name: Blog

*/
[/php]

You may want to change the template name to something different so there aren't any confusions with Genesis's version. So something like this would work:
[php]<?php
/**

Template Name: Custom Blog

*/
[/php]

Create the Custom Loop

Now, I have a site with multiple custom post types and what I want to do is to combine two of those post types (post and wps_videos) into the blog feed. Then I want to limit them based on the Genesis category settings as well as incorporate the Video Category (wps_vidcats) in the same manner.

So first, I have to unhook the genesis standard loop.
[php]
remove_action('genesis_loop', 'genesis_do_loop');
[/php]

Then I add my own loop with its custom function.
[php]
add_action( 'genesis_loop', 'wps_custom_do_loop' , 5 );
function wps_custom_do_loop() {
$include = genesis_get_option( 'blog_cat' );
$exclude = genesis_get_option( 'blog_cat_exclude' ) ? explode( ',' , str_replace ( ' ' , '' , genesis_get_option( 'blog_cat_exclude' ) ) ) : '';
[/php]

These lines are right out of the Genesis standard loop. They pull the information set on the Theme Settings page and place them in variables to be used later. However, these are limited to just categories. Now, it is important to note that $include only contains one category id and $exclude contains an array of categories (even if there is only one).

Now, I need to build my $args. In my args, I want to add my post types as well as build my taxonomy query. So continuing inside wps_custom_do_loop:
[php]
$args = array(
'showposts' => genesis_get_option('blog_cat_num'),
'post_type' => array( 'post' , 'wps_videos' ),
'tax_query' => array(
'relation' => 'OR',
array(
'taxonomy' => 'wps_vidcategory',
'field' => 'id',
'terms' => array( 92 )
),
array(
'taxonomy' => 'category',
'field' => 'id',
'terms' => array( $include )
),
)
);
[/php]

So let me break this down for you. 'showposts' pulls from the Genesis Theme Settings page. 'post_type' is where we add the registered names of all the post types we would like to include in an array. 'tax_query' is where I limit the query based on my requirements. Now I wanted to only include posts from one category, which was set on the Genesis Theme Settings page, and I also wanted to do likewise with my videos and include videos from one specific Video Category (here term ID of 92). And since posts and videos do not share the same taxonomy, the tax_query is simple. So, in summary, I wanted posts from one category ($include) OR (and that's my relation argument) posts from my custom taxonomy video category (here 92).

Now, if I wanted, I could replace the last array with a different array to allow for all categories except (again based on category ids entered in Genesis Theme Settings). It would look something like this:
[php]
$args = array(
'showposts' => genesis_get_option('blog_cat_num'),
'post_type' => array( 'post' , 'wps_videos' ),
'tax_query' => array(
'relation' => 'OR',
array(
'taxonomy' => 'wps_vidcategory',
'field' => 'id',
'terms' => array( 92 )
),
array(
'taxonomy' => 'category',
'field' => 'id',
'terms' => $exclude,
'operator' => 'NOT IN'
),
)
);
[/php]

Now, we can finish the function by calling the Genesis Custom Loop.
[php]

genesis_custom_loop( $args );
}
[/php]

So all together the function looks like this (to simply limit posts to one category and vids from another category):
[php]<?php
remove_action('genesis_loop', 'genesis_do_loop');
add_action( 'genesis_loop', 'custom_do_loop' , 5 );

function custom_do_loop() {
$include = genesis_get_option('blog_cat');
$exclude = genesis_get_option('blog_cat_exclude') ? explode(',', str_replace(' ', '', genesis_get_option('blog_cat_exclude'))) : '';
$cf = genesis_get_custom_field('query_args'); /** Easter Egg **/
$args = array(
'showposts' => genesis_get_option('blog_cat_num'),
'post_type' => array( 'post' , 'wps_videos' ),
'tax_query' => array(
'relation' => 'OR',
array(
'taxonomy' => 'wps_vidcategory',
'field' => 'id',
'terms' => array( 92 )
),
array(
'taxonomy' => 'category',
'field' => 'id',
'terms' => array( $include )
),
)
);
genesis_custom_loop( $args );
}
[/php]

Modify the Post Meta

Now, because my videos do not share the same taxonomy with posts (and it could have [dare I say, should have] but the client didn't want it that way). My posts on the blog page that are from the videos custom post type won't have any post meta. I could simply remove it, but since the client wanted it, I simply filter them.

To filter the post meta to include terms from categories and my video categories, simply do a basic if-then statement. Normally Genesis has $post_meta = '[ post_categories] [ post_tags]';. However, I wanted to change it to just display categories.
[php]<?php
/** Customize the post meta function */
add_filter( 'genesis_post_meta' , 'post_meta_filter' );
function post_meta_filter( $post_meta ) {
global $post;
if ( $post->post_type == 'wps_videos' ) {
$vid_cats = get_the_term_list( $post->ID, 'wps_vidcategory' , '' , ', ' , '' );
$post_meta = sprintf( '<span class="categories">%2$s%1$s</span> ', $vid_cats, 'Filed Under: ' );
}
else {
$post_meta = 'Filed Under: Custom Post Types, Genesis, Tutorials, WordPress';
}
return $post_meta;
}
[/php]

Customize the Content Display

Now, because of UX, the video custom post type had a metabox to make displaying the videos consistent. However, if we do nothing then the videos never appear, which is not what we want.

First, I must unhook the standard Genesis content function.
[php]
/** Customize the content */
remove_action( 'genesis_post_content', 'genesis_do_post_content' );
[/php]

Second, I write a basic if-then function to display my videos on the blog page.
[php]<?php
add_action( 'genesis_post_content', 'custom_do_post_content' );
function custom_do_post_content() {
global $post;
if ( $post->post_type == 'wps_videos') {
if( genesis_get_custom_field('_wps_videoembedcode') != '' ) {
?>
<div id="post-<?php the_ID(); ?>" class="video-entry">
<div class="video-embed">
<?php echo genesis_get_custom_field('_wps_videoembedcode'); ?>
</div><!-- end .video-embed -->
<div class="clear"></div>
<?php genesis_do_post_content(); ?>
</div><!-- end .video-entry -->
<?php
}
} //end wps_videos
else {
genesis_do_post_content();
}
}
[/php]

Now, in both, I simply referred back to the genesis_do_post_content() because I just wanted a way to insert my videos for posts with the video custom post type.

Now as with any Genesis template, to initiate the framework, we have to add the Genesis call.
[php]<?php
genesis();
?>[/php]

All Together

[php]<?php
/**

Template Name: Custom Blog

*/

// Custom Loop
remove_action('genesis_loop', 'genesis_do_loop');
add_action( 'genesis_loop', 'custom_do_loop' , 5 );
function custom_do_loop() {
$include = genesis_get_option('blog_cat');
$exclude = genesis_get_option('blog_cat_exclude') ? explode(',', str_replace(' ', '', genesis_get_option('blog_cat_exclude'))) : '';
$cf = genesis_get_custom_field('query_args'); /** Easter Egg **/
$args = array(
'showposts' => genesis_get_option('blog_cat_num'),
'post_type' => array( 'post' , 'wps_videos' ),
'tax_query' => array(
'relation' => 'OR',
array(
'taxonomy' => 'wps_vidcategory',
'field' => 'id',
'terms' => array( 92 )
),
array(
'taxonomy' => 'category',
'field' => 'id',
'terms' => array( $include )
),
)
);
genesis_custom_loop( $args );
}

// Customize the post meta function
add_filter( 'genesis_post_meta' , 'post_meta_filter' );
function post_meta_filter( $post_meta ) {
global $post;
if ( $post->post_type == 'wps_videos' ) {
$vid_cats = get_the_term_list( $post->ID, 'wps_vidcategory' , '' , ', ' , '' );
$post_meta = sprintf( '<span class="categories">%2$s%1$s</span> ', $vid_cats, 'Filed Under: ' );
}
else {
$post_meta = 'Filed Under: Custom Post Types, Genesis, Tutorials, WordPress';
}
return $post_meta;
}

// Customize the content
remove_action( 'genesis_post_content', 'genesis_do_post_content' );
add_action( 'genesis_post_content', 'custom_do_post_content' );
function custom_do_post_content() {
global $post;
if ( $post->post_type == 'wps_videos') {
if( genesis_get_custom_field('_wps_videoembedcode') != '' ) {
?>
<div id="post-<?php the_ID(); ?>" class="video-entry">
<div class="video-embed">
<?php echo genesis_get_custom_field('_wps_videoembedcode'); ?>
</div><!-- end .video-embed -->
<div class="clear"></div>
<?php genesis_do_post_content(); ?>
</div><!-- end .video-entry -->
<?php
}
} //end wps_videos
else {
genesis_do_post_content();
}
}

genesis();
?>
[/php]

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

Sep 09 2011

How to Replace Functions Regardless of the Genesis Hook (via Gary Jones)

Recently, Gary Jones (@GaryJ) posted a bit of code for Jared Atchison (@jaredatch) on Twitter for a plugin that he is working on that will remove functions regardless of where they get hooked. It is a great piece of code. If you find this helpful, please support Gary or tell him how much you appreciate him.

[php]<?php
// Run at get_header to catch all customisations in functions.php

add_action( 'get_header', 'jared_remove_stuff_whichever_hook_they_are_on' );
/**
* Replace some genesis_* functions hooked into somewhere for some jared_* functions
* of the same suffix, at the same hook and priority
*
* @author Gary Jones
*
* @global array $wp_filter
*/
function jared_remove_stuff_whichever_hook_they_are_on() {

global $wp_filter;

// List of genesis_* functions to be replaced with jared_* functions.
// We save some bytes and add the ubiquitous 'genesis_' later on.
$functions = array(
'do_doctype',
'do_nav',
'do_subnav',
'header_markup_open',
'header_markup_close',
'post_info',
'post_meta',
'do_loop',
'footer_markup_open',
'footer_markup_close'
);

// Loop through all hooks (yes, stored under the $wp_filter global)
foreach ( $wp_filter as $hook => $priority) {

// Loop through our array of functions for each hook
foreach( $functions as $function) {

// has_action returns int for the priority
if ( $priority = has_action( $hook, 'genesis_' . $function ) ) {

// If there's a function hooked in, remove the genesis_* function
// from whichever hook we're looping through at the time.
remove_action( $hook, 'genesis_' . $function, $priority );

// Add a replacement function in at the same time.
add_action( $hook, 'jared_' . $function, $priority );
}
}
}

}[/php]

Written by Travis Smith · Categorized: Genesis

Aug 16 2011

How to Make a Genesis Grid Archive Template for Tags

To display posts from a specific tag or tags, you need to add a 'tag' argument to the $grid_args array.

In the StudioPress tutorial about categories, you are given this example for your home.php.
[php highlight="17"]<?php
remove_action( 'genesis_loop', 'genesis_do_loop' );
add_action( 'genesis_loop', 'child_grid_loop_helper' );
/** Add support for Genesis Grid Loop **/
function child_grid_loop_helper() {
if ( function_exists( 'genesis_grid_loop' ) ) {
genesis_grid_loop( array(
'features' => 2,
'feature_image_size' => 0,
'feature_image_class' => 'alignleft post-image',
'feature_content_limit' => 0,
'grid_image_size' => 'grid-thumbnail',
'grid_image_class' => 'alignleft post-image',
'grid_content_limit' => 0,
'more' => __( '[Continue reading...]', 'genesis' ),
'posts_per_page' => 6,
'cat' => '6,7' //enter your category IDs here separated by commas in ' '
) );
} else {
genesis_standard_loop();
}
}

/** Remove the post meta function for front page only **/
remove_action( 'genesis_after_post_content', 'genesis_post_meta' );

genesis();[/php]

Simply change the 'cat' argument to 'tag'. And you can have the customization you want. OR, you can grab it dynamically by making the following changes:
[php highlight="6,18"]<?php
remove_action( 'genesis_loop', 'genesis_do_loop' );
add_action( 'genesis_loop', 'child_grid_loop_helper' );
/** Add support for Genesis Grid Loop **/
function child_grid_loop_helper() {
$term = get_query_var( 'term' );
if ( function_exists( 'genesis_grid_loop' ) ) {
genesis_grid_loop( array(
'features' => 2,
'feature_image_size' => 0,
'feature_image_class' => 'alignleft post-image',
'feature_content_limit' => 0,
'grid_image_size' => 'grid-thumbnail',
'grid_image_class' => 'alignleft post-image',
'grid_content_limit' => 0,
'more' => __( '[Continue reading...]', 'genesis' ),
'posts_per_page' => 6,
'tag' => $term
) );
} else {
genesis_standard_loop();
}
}

/** Remove the post meta function for front page only **/
remove_action( 'genesis_after_post_content', 'genesis_post_meta' );

genesis();[/php]

You can save this as tag.php to make all of your tag archives as a grid. Or, you can simply apply this to a single tag by naming it tag-{SLUG}.php or tag-{ID}.php (see WordPress Codex for Tag Templates for more information).

Written by Travis Smith · Categorized: Genesis, Genesis Grid Loop, Tutorials

Aug 15 2011

How to Make a Custom Taxonomy Genesis Grid Archive Template

First, catch up on the Grid Loops by reading these posts:

  • Customizing the Genesis Grid Content, by Bill Erickson
  • How to Use the Genesis Grid Loop, by Brian Gardner
  • Genesis Grid Loop Advanced, by Gary Jones

Now, that you have a basic understanding of the Grid, let's apply this to a custom taxonomy archives.

First, you need a new document saved as taxonomy-{taxName}.php (for more information, see the WordPress Codex). So if you have a custom taxonomy of "Book Type," registered as 'book_type,' then the file name will be taxonomy-book_type.php.

Second, create the header, just like a page template. This is primarily for your organization and your information. So I just model it after the page template just to be consistent.

[php]<?php
/*
Template Name: Book Type Taxonomy Archive
*/[/php]

Third, you want to set all your customizations like remove post meta, post info, page layout, etc.

Fourth, you want to include the Grid Looper Helper function. This is a standard protocol for the Genesis Grid Loop:
[php]<?php

remove_action( 'genesis_loop', 'genesis_do_loop' );
add_action( 'genesis_loop', 'wps_grid_loop_helper' );
/** Add support for Genesis Grid Loop **/
function wps_grid_loop_helper() {
global $grid_args, $post;
$taxonomy = 'book_type'; //change me
$term = get_query_var( 'term' );
$term_obj = get_term_by( 'slug' , $term , $taxonomy );
$cpt = 'wps_books'; //change me

if ( function_exists( 'genesis_grid_loop' ) ) {
$grid_args_tax = array(
'features' => 0,
'feature_image_size' => 'book_featured',
'feature_image_class' => 'aligncenter post-image',
'feature_content_limit' => 100,
'grid_image_size' => 'book_thumb',
'grid_image_class' => 'aligncenter post-image',
'grid_content_limit' => 0,
'more' => '',
'posts_per_page' => 10,
'post_type' => $cpt,
'paged' => get_query_var('paged') ? get_query_var('paged') : 1,
'tax_query' => array(
array(
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => array( $term_obj->slug ),
)
)
);

printf('<h2 class="book-section"> %s Books</h2>' , $term_obj->name );
genesis_grid_loop($grid_args_tax);
} else {
genesis_standard_loop();
}
}
[/php]

Now, this can be rather complicated and intimidating, so let me break this down for you. While everything is the same as the previous Grid posts, there is one major change and that is the 'tax_query' (WordPress Codex). But just for those readers, who didn't take my advice to read the previous articles, let me briefly explain the $grid_args_tax (for those who know the basic args, skip the next paragraph).

'features' refers to the number of featured posts in the grid loop. So if you want to display 10 but feature 2, you would set this number to 2, posts_per_page to 10 and Genesis will do the math to ensure that everything is kosher. However, in our example, we want zero features for the taxonomy listing. 'feature_image_size' and 'grid_image_size' are the post thumbnail size that you want the image to appear as. 'feature_image_class' and 'grid_image_class' refer to the CSS image class for styling. 'feature_content_limit' and 'grid_content_limit' refers to the number of characters allowed in the content. See the StudioPress articles for futher explanations.

Now 'tax_query' refers to the taxonomy args. It must take an array of arrays of the following args:

  • taxonomy (string): the taxonomy
  • field (string): select taxonomy term by 'id' or 'slug'
  • terms (int/string/array): taxonomy terms
  • operator (string): 'IN', 'NOT IN', 'AND'

In our example, we have the template for a predetermined specific taxonomy and the template dynamically grabbing the appropriate taxonomy term (so someone may be searching for a 'Fiction' Book Type). If you wanted, it could also fetch the taxonomy dynamically, if you wanted all of your taxonomy archives to be on the grid. To do this, simply add the following code: $taxonomy = get_query_var( 'taxonomy' );. For tags and categories, you probably could use this same method; however, there is also a simpler method which I will explain in a later post (Tags and Same Categories and Different Categories).

So, after you set the post type ('post', 'page', or some other custom post type registered name, e.g., 'wps_books') and the taxonomy (which is the same as the latter half of the file name, so in this example 'book_type'), the function first grabs the slug of the term: $term = get_query_var( 'term' ); (more information: get_query_var). Then it calls for the genesis custom grid loop.

Now obviously, with this custom post type, I am going to want to determine my own grid loop content. To do this, I simply make these additions:

[php] <?php
add_action('genesis_before_post', 'wps_custom_grid');
function wps_custom_grid() {
remove_action('genesis_post_content', 'genesis_grid_loop_content');
add_action('genesis_post_content', 'wps_grid_loop_content');
}

function wps_grid_loop_content() {
global $_genesis_loop_args, $wp_query;
//do something
}
[/php]

For an excellent post on customizing the content, see Bill Erickson's post, Customizing the Genesis Grid Loop Content.

Some other good grid functions include the following:
[php]<?php
// Add some extra post classes to the grid loop so we can style the columns
add_filter( 'genesis_grid_loop_post_class', 'wps_grid_loop_post_class' );
/**
* Add some extra body classes to grid posts.
*
* Change the $columns value to alter how many columns wide the grid uses.
*
* @author Gary Jones
* @link http://dev.studiopress.com/genesis-grid-loop-advanced.htm
*
* @global array $_genesis_loop_args
* @global integer $loop_counter
* @param array $classes
*/
function wps_grid_loop_post_class( $grid_classes ) {
global $_genesis_loop_args, $loop_counter;

// Alter this number to change the number of columns - used to add class names
$columns = 3;

// Only want extra classes on grid posts, not feature posts
if ( $loop_counter >= $_genesis_loop_args['features'] ) {

// Add genesis-grid-column-? class to know how many columns across we are
$grid_classes[] = sprintf( 'genesis-grid-column-%s', ( ( $loop_counter - $_genesis_loop_args['features'] ) % $columns ) + 1 );

// Add size1of? class to make it correct width
$grid_classes[] = sprintf( 'size1of%s', $columns );
}
return $grid_classes;
}

// Make sure the first page has a balanced grid
add_action( 'genesis_loop', 'wps_bal_grid_loop' );
function wps_bal_grid_loop() {
global $query_string, $paged, $grid_args, $_genesis_loop_args;

if ( 0 == $paged )
// If first page, add number of features to grid posts, so balance is maintained
$grid_args['posts_per_page'] += $grid_args['features'];
else
// Keep the offset maintained from our page 1 adjustment
$grid_args['offset'] = ( $paged - 1 ) * $grid_args['posts_per_page'] + $grid_args['features'];
}
[/php]

Written by Travis Smith · Categorized: Genesis, Genesis Grid Loop, Tutorials

Aug 03 2011

How to Force a Specific Layout for a Page Template in Genesis

The other day, I was creating a page template using the standard approach used in forcing a specific layout. However, when using page templates, this will work if they have not selected a specific layout on the page in the Genesis Layouts metabox. So you could either hide the Genesis metabox, or you can have the page template ignore any changes made in the layout metabox (less coding!).

The normal procedure is as follows:

[php]
add_filter('genesis_pre_get_option_site_layout', '__genesis_return_full_width_content');
[/php]

However, this ignores any custom fields that may upset this. So since this is pre_get_option_*, the user can accidentally over-ride the "forced" specific layout. So if you don't want the user to over-ride it you need to go a step further. You can add one more line of code to correct and ensure that a page can never have a different layout. One way is to set the post meta to always be whatever you want.

[php]
global $post;
// Force Page Layout for Page Template
update_post_meta( $post->ID, '_genesis_layout', 'full-width-content' );
[/php]

However, the Genesis approach would be to set it via the pre site layout Filter.

Written by Travis Smith · Categorized: Genesis, Tutorials

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

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