Category: Genesis

MSDLAB Toolkit

This is what I use for most of my WordPress Sites. The GitHub repository has most of the custom stuff that I use over and over. Generally speaking, I simply customize as needed per client. Not the “properest” way to do it, but faster and more cost effective for the client. Sometimes I do a major update when I find myself doing very similar customizations over and over.

Themes

Genesis Framework

Mad Science themes are built as child themes for the Genesis framework by StudioPress. Genesis themes work differently from other WordPress themes, because they rely strongly on hooks and actions. These two important keywords can take a bit of fiddling with to wrap your head around, but they are built into every part of WordPress, and once you understand them, they make it very simple to customize layout, activity, and even functionality of a WordPress site.

There are some nice reference sites for Genesis. I find myself going back to the visual hook guide frequently, as well as other areas of Genesis Tutorials.

You will need to install the Genesis theme on any site that you will be installing a genesis child theme.

MSDLAB Starter Theme

A Genesis starter theme with Twitter Bootstrap & Font Awesome support using LESS. On GitHub. Copy and rename to use.

Plugins

Premium Plugins

Custom Plugins

The GitHub repository has a number of customized plugins. The one that is used on almost every site I do is MSD Site Settings. The others are mostly customizations of existing plugins. As I have time I am making them into “child plugins” so that they don’t need to be updated every time a source plugin is updated.

Plugin Directory Plugins

Can be found as favorites under my username, Foxydot. I don’t use all of these on every site, obviously, but these are ones I use often and trust.

Tools

The one tool I rely on quite a bit is WPAlchemy. There is a copy in the GitHub repository, at the WP_CONTENT_DIR level, because that’s where my plugins and themes call it from. You can place it anywhere you like, and there are probably old copies in my plugins too. Yes, you can do all of this the Tadlock Way (and the Tadlock Way is usually the right way), but I find WPAlchemy to be a small overhead price to pay for ease of use and function.

Bootstrapping genesis

This was kind of a cool thing I was doing to have two different sidebar layouts on pages vs. posts/cpts, but the client decided to go with one layout overall, so now I’m saving it here.

/*** Bootstrappin **/

add_filter( 'genesis_attr_site-inner', 'msdlab_bootstrap_site_inner', 10);
add_filter( 'genesis_attr_breadcrumb', 'msdlab_bootstrap_breadcrumb', 10);
add_filter( 'genesis_attr_content-sidebar-wrap', 'msdlab_bootstrap_content_sidebar_wrap', 10);
add_filter( 'genesis_attr_content', 'msdlab_bootstrap_content', 10);
add_filter( 'genesis_attr_sidebar-primary', 'msdlab_bootstrap_sidebar', 10);

/*** Bootstrappin **/

function msdlab_bootstrap_site_inner( $attributes ){
    $attributes['class'] .= ' container';
    return $attributes;
}

function msdlab_bootstrap_breadcrumb( $attributes ){
    $attributes['class'] .= ' row';
    return $attributes;
}

function msdlab_bootstrap_content_sidebar_wrap( $attributes ){
    $attributes['class'] .= ' row';
    return $attributes;
}

function msdlab_bootstrap_content( $attributes ){
    $layout = genesis_site_layout();
    switch($layout){
        case 'content-sidebar':
        case 'sidebar-content':
            if(is_page()){
                $attributes['class'] .= ' col-md-7 col-sm-12';
            } else {
                $attributes['class'] .= ' col-md-9 col-sm-12';
            }
            break;
        case 'content-sidebar-sidebar':
        case 'sidebar-sidebar-content':
        case 'sidebar-content-sidebar':
            break;
        case 'full-width-content':
            $attributes['class'] .= ' col-md-12';
            break;
    }
    return $attributes;
}

function msdlab_bootstrap_sidebar( $attributes ){
    $layout = genesis_site_layout();
    switch($layout){
        case 'content-sidebar':
        case 'sidebar-content':
            if(is_page()){
                $attributes['class'] .= ' col-md-4 col-md-offset-1 hidden-sm hidden-xs';
            } else {
                $attributes['class'] .= ' col-md-3 hidden-sm hidden-xs';
            }
            break;
        case 'content-sidebar-sidebar':
        case 'sidebar-sidebar-content':
        case 'sidebar-content-sidebar':
            break;
        case 'full-width-content':
            $attributes['class'] .= ' hidden';
            break;
    }
    return $attributes;
}

Making Genesis & Bootstrap play nice together

This is going to be a multi-post solution set, I’m sure. I started out with a jQuery solution. It worked ok, but wasn’t really what I wanted:

//bootstrap
    $('.site-inner').addClass('container');
    //$('.wrap').addClass('row');
    $('.content-sidebar .content-sidebar-wrap').addClass('row');
    $('.content-sidebar .content').addClass('col-md-8 col-sm-12');
    $('.content-sidebar .sidebar').addClass('col-md-4');

Then I started digging into the Genesis context filters. This will probably work better and be more portable in the future. (Obviously this is jsut a part of it.)

/*** Bootstrappin **/

add_filter( 'genesis_attr_site-inner', 'msdlab_bootstrap_site_inner', 10);
add_filter( 'genesis_attr_breadcrumb', 'msdlab_bootstrap_breadcrumb', 10);
add_filter( 'genesis_attr_content-sidebar-wrap', 'msdlab_bootstrap_content_sidebar_wrap', 10);
add_filter( 'genesis_attr_content', 'msdlab_bootstrap_content', 10);
add_filter( 'genesis_attr_sidebar-primary', 'msdlab_bootstrap_sidebar', 10);

function msdlab_bootstrap_site_inner( $attributes ){
    $attributes['class'] .= ' container';
    return $attributes;
}

function msdlab_bootstrap_breadcrumb( $attributes ){
    $attributes['class'] .= ' row';
    return $attributes;
}

function msdlab_bootstrap_content_sidebar_wrap( $attributes ){
    $attributes['class'] .= ' row';
    return $attributes;
}

function msdlab_bootstrap_content( $attributes ){
    $layout = genesis_site_layout();
    switch($layout){
        case 'content-sidebar':
        case 'sidebar-content':
            $attributes['class'] .= ' col-md-7 col-sm-12';
            break;
        case 'content-sidebar-sidebar':
        case 'sidebar-sidebar-content':
        case 'sidebar-content-sidebar':
            break;
        case 'full-width-content':
            $attributes['class'] .= ' col-md-12';
            break;
    }
    return $attributes;
}

function msdlab_bootstrap_sidebar( $attributes ){
    $layout = genesis_site_layout();
    switch($layout){
        case 'content-sidebar':
        case 'sidebar-content':
            $attributes['class'] .= ' col-md-4 col-md-offset-1 hidden-sm hidden-xs';
            break;
        case 'content-sidebar-sidebar':
        case 'sidebar-sidebar-content':
        case 'sidebar-content-sidebar':
            break;
        case 'full-width-content':
            $attributes['class'] .= ' hidden';
            break;
    }
    return $attributes;
}

Genesis Widget Formatting

Genesis has a pretty cool filter available to override the default settings for a widget area. You can use this to filter all of the widget area layouts:

function msdlab_register_sidebar_defaults($args){
    $args = array(
            'before_widget' => genesis_markup( array(
                'html5' => '<section id="%1$s" class="widget %2$s">',
                'xhtml' => '<div id="%1$s" class="widget %2$s">',
                'echo'  => false,
            ) ),
            'after_widget'  => genesis_markup( array(
                'html5' => '</div></section>' . "\n",
                'xhtml' => '</div></div>' . "\n",
                'echo'  => false
            ) ),
            'before_title'  => '<h4 class="widget-title widgettitle">',
            'after_title'   => genesis_markup( array(
                'html5' => '</h4>'."\n".'<div class="widget-wrap">',
                'xhtml' => '</h4>'."\n".'<div class="widget-wrap">',
                'echo'  => false,
            ) ),
        );
   return $args;
}

The issue comes when you try to activate it. Because the default widget areas are registered before the filter is defined, it won’t work unless you do something like so:

remove_action( 'genesis_setup', 'genesis_register_default_widget_areas' ); //remove initial setup of default widgets
add_action( 'after_setup_theme', 'genesis_register_default_widget_areas' ); //move them to AFTER the theme files are loaded
add_filter('genesis_register_sidebar_defaults','msdlab_register_sidebar_defaults'); //and here's the filter

Genesis 2 CPT Archive Settings

This is pretty cool.

Basically, you can add backend editing to the CPT archive with something like this:

function register_snippet_post_type(){
  
  // custom post type arguments
	$post_type_args = array(
		'label'		=> __( 'Snippet' ),
		'description'	=> __( 'Display code snippets' ),
		'public'	=> true,
		'show_ui'	=> true,
		'show_in_menu'	=> true,
		'has_archive'	=> true,
		'supports'	=> array( 'title', 'editor', 'genesis-cpt-archives-settings' )
	);
	
	// register the 'snippet' post type
	register_post_type( 'snippet', $post_type_args );
	
}

Loopy Post Navigation

Make posts loop back around to the other end:

<?php
function apple_post_navigation()
{
	global $post;

		$categories = get_the_category( $post->ID );
		$category = $categories[0]->cat_name;
		$last_post = get_boundary_post( TRUE, '', FALSE );
		$first_post = get_boundary_post( TRUE, '', TRUE );
		?>
    <div class="prev_next">
        <div class="nav_left">
            <span class="prev">
            <?php 
            if(get_adjacent_post(TRUE, NULL, TRUE)){
				previous_post_link('%link', '< Previous '.$category , TRUE);
			} else {
				print $last_post->ID;
				print '<a rel="last" href="'.get_permalink($last_post[0]->ID).'">< Previous '.$category.'</a>';
			}
			 ?>
            </span>
         </div><div class="nav_right">
            <span class="next">
            <?php 
            if(get_adjacent_post(TRUE, NULL, FALSE)){
				next_post_link('%link', 'Next '.$category.' >' , TRUE);
			} else {
				print $first_post->ID;
				print '<a rel="first" href="'.get_permalink($first_post[0]->ID).'">Next '.$category.' ></a>';			
			}
			 ?>
			 </span>
        </div>
    </div>
<?php

}
?>

Adding Meta to the Theme Stettings

Something changed in 1.8+ and the old hook no longer works. To make the hook work again, and keep things backwards compatible, try something like this:

add_action( 'admin_menu', 'childtheme_add_footer_tag_settings_box', 11 );
/**
 * Add new box to the Genesis->Theme Settings page.
 *
 */
function childtheme_add_footer_tag_settings_box() {
	global $_genesis_theme_settings_pagehook;
	if(!$_genesis_theme_settings_pagehook){
		$_genesis_theme_settings_pagehook = 'toplevel_page_genesis';
	}
	add_meta_box( 'genesis-theme-settings-style', __( 'Meta Box title', 'childtheme' ), 'childtheme_theme_settings_footer_tag_box', $_genesis_theme_settings_pagehook, 'column2' );
}

Genesis Post Image

Default only works on certain pages/posts:

add_action('genesis_post_content', 'genesis_do_post_image');
/**
* Post Image
*/
function genesis_do_post_image() {
if ( !is_singular() && genesis_get_option('content_archive_thumbnail') ) {
$img = genesis_get_image( array( 'format' => 'html', 'size' => genesis_get_option('image_size'), 'attr' => array( 'class' => 'alignleft post-image' ) ) );
printf( '%s', get_permalink(), the_title_attribute('echo=0'), $img );
}

}

Here’s a sample fix:

remove_action( 'genesis_post_content','genesis_do_post_image');
add_action( 'genesis_before_post_content','tapestry_do_post_image');</code>

function tapestry_do_post_image() {
$img = genesis_get_image( array( 'format' =&gt; 'html', 'size' =&gt; genesis_get_option('image_size'), 'attr' =&gt; array( 'class' =&gt; 'aligncenter post-image' ) ) );
printf( '<a title="%s" href="%s">%s</a>
<div class="clear"></div>
', get_permalink(), the_title_attribute('echo=0'), $img );
}