WP Smith

Creating WordPress & Genesis Websites Since 2010

  • Home
  • About
  • Services
  • Blog
  • Contact

Dec 23 2011

How to Create a Custom Button in Gravity Forms with a Terms of Service Button Example

Written by Travis Smith · Categorized: WordPress

Dec 21 2011

How to Use Genesis Featured Widget Amplified to Link to the Image and Add a Lightbox or WordPress's Thickbox (Using Lightbox Evolution) in Genesis Featured Widget Amplified

So recently, someone contacted me to figure out how to make the Genesis Featured Widget Amplified link to the Image, instead of the post. For example, take a Genesis Child Theme like Crystal, Delicious, Manhattan, Minimum, and/or Scribble. Each of these themes have an area of a portfolio or a row of images which link to their respective posts. However, what if you wanted these images to appear in a lightbox/thickbox? What if you wanted these to link to just the image and not the post?

Genesis Featured Widget Amplified

A lot of plugins are built without hooks and filters, which can be rather frustrating for developers because developers love to change things to "improve" them, which really is just making the plugin/widget do what they want instead of what the purpose of the widget/plugin was designed to do. However, the Genesis Featured Widget Amplified plugin has everything, well almost everything, a person would want in a widget of its kind. Furthermore, it has the appropriate hooks and filters to make things happen without having to hack core, hence the beauty of action hooks.

1. Widget Settings

So the first thing we must do is to have the link, link to the image, not the post. So using the Genesis Featured Widget Amplified, you want to ensure that you have selected Show Featured Image and selected Link to Post (being able to change this would be hacking the core of the plugin). We also want to set the instance identification, here, portfolio.

2. Replacing the Linked Image

Now, we want to remove the current function that creates the link and the image, and create one of our own. However, first we want to make sure we are on the home page and that we have the correct instance.

[php]
add_action ( 'gfwa_before_loop' , 'we_check_portfolio' , 10 , 1 );
function we_check_portfolio( $instance ) {
if ( ! is_home() )
return;
elseif ( ( is_home() ) && ( $instance['custom_field'] == 'portfolio' ) ) {

// Remove all GFWA image functions
remove_action( 'gfwa_before_post_content', 'gfwa_do_post_image' , 5 );
remove_action( 'gfwa_before_post_content', 'gfwa_do_post_image' , 5 );
remove_action( 'gfwa_after_post_content', 'gfwa_do_post_image' , 10 );

// Add our custom function
add_action ( 'gfwa_before_post_content', 'gfwa_do_we_post_image', 8, 1 );

// Add functions back
add_action ( 'gfwa_after_loop' , 'we_add_image' , 10 , 1 );
}
}

function gfwa_do_we_post_image ( $instance ) {
if ( $instance['custom_field'] == 'portfolio' ) {
$image = genesis_get_image( array( 'format' => 'html' , 'size' => $instance['image_size'] ) );
$image_id = get_post_thumbnail_id();
$image = sprintf( '<a href="%s" title="%s" class="%s">%s</a>', wp_get_attachment_url( $image_id ), the_title_attribute( 'echo=0' ), esc_attr( $instance['image_alignment'] ), $image );
echo $image;
}
}

function we_add_image ( $instance ) {
add_action( 'gfwa_before_post_content', 'gfwa_do_post_image' , 5 );
add_action( 'gfwa_post_content', 'gfwa_do_post_image' , 5 );
add_action( 'gfwa_after_post_content', 'gfwa_do_post_image' , 10 );
}

function wps_lightbox_js() {
?>
<script>
jQuery(document).ready(function() {
jQuery("img").parent("a").addClass("lightbox");
});
</script>
<?php
}
add_action( 'wp_footer' , 'wps_lightbox_js' );
[/php]

3. Add WordPress's Thickbox

For the plugin, Lightbox Evolution (which is a good lightbox plugin), this person was using the class lightbox was required. However, you can use WordPress's built-in Thickbox, which is used for the Media Library. To use the WordPress Media Library (and not a plugin), replace function wps_lightbox_js() code with the function below:

[php]
function wps_add_thickbox() {
if(!is_admin()){
wp_enqueue_script( 'thickbox' , null , array( ' jquery ' ) );
wp_enqueue_style( 'thickbox.css' , '/' . WPINC . '/js/thickbox/thickbox.css' , null , '1.0' );
}
}
add_action ( 'init' , 'wps_add_thickbox' );

function wps_thickbox_js(){
?>
<script>
jQuery(document).ready(function() {
jQuery("img").parent("a").addClass("thickbox");
});
</script>
<?php
}
add_action( 'wp_footer' , 'wps_thickbox_js' );
[/php]

Word of Caution

You need to make sure that if you use this code, you are inserting images that Link to the File URL, not the Post URL (which I believe is the default).

Here is an example:

Genesis Featured Widget Amplified Insert
Linked to Post
Genesis Featured Widget Amplified Insert
Linked to File URL/Image

Written by Travis Smith · Categorized: WordPress

Dec 12 2011

Filter Pages by Post Parent and Filter Pages/Posts by Pages/Posts Per on WordPress Edit Pages

Recently I migrated a site that had hundreds of pages, which made page management a potential nightmare. Seeing this potential, I developed a filter that would enable me to see various parts of the pages tree as well as allow me to set the number of pages I wanted to see.

To add a filter on the edit page, you must hook into 'restrict_manage_posts'. The function below will add 2 filters: pages_per filter and a post_parent page filter. The pages_per filter is something that can be used on all post types; however, the post_parent filter should only be used on pages (or other hierarchical post types--but for this tutorial, we will only do pages).

So here's what I did:
[php]
add_action ( 'restrict_manage_posts' , 'wps_restrict_manage_posts' );
function wps_restrict_manage_posts() {
global $typenow;

// only run this filter on page post type
if ( $typenow == 'page' ) {

// Parent Page Filter (HTML)
$args = array(
'child_of' => 0,
'show_option_none' => 'Show all pages',
'depth' => 2, //change this to whatever you want
'name' => 'wps_page_filter',
'selected' => $_GET['wps_page_filter'],
);
$dropdown = wp_dropdown_pages( $args );
}

// Per Page Filter (HTML)
global $wps_per_page;
$wps_per_page = isset( $_GET['wps_per_page'] ) ? (int) $_GET['wps_per_page'] : $wps_per_page;
?>
<select name="wps_per_page" style="width: 110px;">
<option <?php selected( $wps_per_page, 9999 ); ?> value="9999"><?php _e( 'Show all', FDA_DOMAIN ); ?></option>
<?php for( $i=10; $i<=100; $i+=10 ) : ?>
<option <?php selected( $wps_per_page, $i ); ?> value="<?php echo $i; ?>"><?php echo $i; ?> <?php _e( 'per page', FDA_DOMAIN ); ?></option>
<?php endfor; ?>
<?php if ( $wps_per_page != -1 && $wps_per_page != 9999 && ( $wps_per_page%10 != 0 || $wps_per_page > 100 ) ) : ?>
<option <?php selected( true ); ?> value="<?php echo (int) $wps_per_page; ?>"><?php echo (int) $wps_per_page; ?> <?php _e( 'per page', FDA_DOMAIN ); ?></option>
<?php endif; ?>
</select>
<?php
}
[/php]

Now, I wanted to add an option to show only top level pages only. This has to be done manually, darn WordPress for having no good filters in wp_dropdown_pages().
[php]
// Add an option to show top level pages only
add_filter ( 'wp_dropdown_pages' , 'wps_insert_option_in_dropdown' );
function wps_insert_option_in_dropdown ( $output ) {
$filter = $_GET['wps_page_filter'];
if ( $filter == 'parent' )
$selected = ' selected="selected"';
else
$selected = '';
$second_option = 'Show all pages</option><option value="parent"' . $selected . '>Parent Pages Only</option>';
return preg_replace( '#Show all pages</option>#' , $second_option , $output );
}
[/php]

Now, WordPress won't execute the filter for us, so we have to make sure this happens. This can be done in two separate functions; however, since it really doesn't matter pragmatically, we will keep with one function.
[php]
add_filter ( 'parse_query', 'wps_admin_posts_filter' );
function wps_admin_posts_filter( $query ) {
global $pagenow;

// Update pages_per (just because we are here, we do it in this function)
$wps_per_page = $_GET['wps_per_page'];
if ( isset( $wps_per_page ) && ( $wps_per_page == 9999 || ( $wps_per_page % 10 ) == 0 ) )
update_user_option( get_current_user_id(), 'edit_page_per_page', (int) $wps_per_page );

// Change query based on post_parent
$wps_page_filter = $_GET['wps_page_filter'];
if ( is_admin() && $pagenow == 'edit.php' && !empty( $wps_page_filter ) ) {
if ( $wps_page_filter == 'parent' )
$query->query_vars['post_parent'] = 0;
else
$query->query_vars['post_parent'] = $wps_page_filter;
}
}
[/php]

Written by Travis Smith · Categorized: Tutorials, WordPress

Dec 06 2011

How to Automatically Add a Class (like 'first' or 'last') to a WordPress Menu

So recently, I needed a way to dynamically add a 'first' class to all the first child nav menu items of a particular parent nav menu item item. On a simple Google, one tutorial by @WPBeginner suggests that we use a filter.
[php]
//Filtering a Class in Navigation Menu Item
add_filter( 'nav_menu_css_class' , 'special_nav_class' , 10 , 2 );
function special_nav_class( $classes, $item ){
if( is_single() && $item->title == 'Blog' ){
$classes[] = 'current-menu-item';
}
return $classes;
}
[/php]
However great this filter is, this approach won't and cannot be very dynamic.

So I wrote a function (and generalized it) that would accomplish this easily and nicely. This uses a function that I wrote about previously called get_nav_menu_item_children() in a post called How to Get All the Children of a Specific Nav Menu Item that I have modified (12/6).

Given a menu id and a parent item id and the optional class name, the function will automatically add that class to the first child nav menu item. So here is the new function:
[php]
/*
* Adds a class to the first menu item.
*
* Uses update_post_meta() to update a nav menu item.
*
* @param int $menu_id Menu ID, defaults to 0.
* @param int $parent_id Menu item ID, defaults to 0.
* @param string $newclass Class to add, defaults to 'first'.
* @param boolean $remove Remove class from other children, defaults to true.
* @return boolean, false: if no $menu_id or $parent_id, else true.
*/
function wps_update_classes( $menu_id = 0 , $parent_id = 0 , $newclass = 'first' , $remove = true ) {

// Validate inputs
$menu_id = intval ( $menu_id );
$parent_id = intval ( $parent_id );

if ( ( $menu_id == 0 ) || ( $parent_id == 0 ) || ( !is_bool ( $remove ) ) || ( !is_string ( $newclass ) ) )
return false;

// Get & filter nav menu items
$nav_menu_items = wp_get_nav_menu_items( $menu_id , array( 'post_status' => 'publish,draft' ) );
$children = get_nav_menu_item_children( $parent_id , $nav_menu_items );
$first_item = true;

// Cycle through child nav menu items
foreach ( $children as $child ) {
if ( $first_item ) {
//found first item
$first_item = false;
$match = false;

// Cycle through to check for first
foreach ( $child->classes as $class ) {
// Match found
if ( $class == $newclass ) {
$match = true;
break;
}
}

// Update Post if match found
if ( ! $match ) {
if ( $child->classes[0] == '' )
$child->classes[0] = $newclass;
else
$child->classes[] = $newclass;

$menu_item_data = array(
'menu-item-classes' => $child->classes,
);
update_post_meta( $child->ID, '_menu_item_classes', $child->classes );
}
continue;
}

// Cycle through and remove $newclass from other children
if ( $remove ) {
foreach ( $child->classes as $key => $class ) {

// If match, remove $newclass from other children
if ( $class == $newclass ) {
$child->classes[$key] = '';
update_post_meta( $child->ID, '_menu_item_classes', $child->classes );
}
}
}
}

return true;
}
[/php]

So to call this function, you can use something like this:
[php]
add_action( 'init' , 'wps_update_menus' );
function wps_update_menus() {
wps_update_classes( 3 , 277 );
wps_update_classes( 3 , 7 , 'test-class' );
}
[/php]
This bit of code adds 'first' to the first child of menu item 277 on menu 3 and 'test-class' to the first child of menu item 7 on menu 3.

If you want to add the ability to add a 'last' class, you can use this:
[php]
/*
* Sorts a multidimensional array of nav menu items.
*
* @link http://php.net/manual/en/function.sort.php
* @param array $array Multidimensional array to be sorted.
* @param string $index Index to determine the sort.
* @param string $order Must be either asc or desc.
* @param boolean $natsort Sort an array using a "natural order" algorithm.
* @param boolean $case_sensitive Sort via case sensitivity.
* @return boolean, false: if no $menu_id or $parent_id, else true.
*/
function wps_sort_nav_menu_items ( $array, $index, $order, $natsort = FALSE, $case_sensitive = FALSE ) {
if( is_array ( $array ) && count( $array ) > 0 ) {
foreach ( array_keys ( $array ) as $key )
$temp[$key] = $array[$key]->$index;
if( ! $natsort ) {
if ( strtolower( $order ) == 'asc' )
asort( $temp );
else
arsort( $temp );
}
else
{
if ( $case_sensitive === true )
natsort( $temp );
else
natcasesort( $temp );
if( strtolower( $order ) != 'asc' )
$temp = array_reverse ( $temp , TRUE );
}
foreach( array_keys ( $temp ) as $key )
if ( is_numeric ( $key ) )
$sorted[] = $array[$key];
else
$sorted[$key] = $array[$key];
return $sorted;
}
return $sorted;
}

/*
* Adds a class to first/last menu item.
*
* Uses update_post_meta() to update a nav menu item.
*
* @param int $menu_id Menu ID, defaults to 0.
* @param int $parent_id Menu item ID, defaults to 0.
* @param string $newclass Class to add, defaults to 'first'.
* @param boolean $remove Remove class from other children, defaults to true.
* @return boolean, false: if no $menu_id or $parent_id, else true.
*/
function wps_update_classes( $menu_id = 0 , $parent_id = 0 , $newclass = 'first' , $firstlast = 'first' , $remove = true ) {

// Validate inputs
$menu_id = intval ( $menu_id );
$parent_id = intval ( $parent_id );

if ( ( $menu_id == 0 ) || ( $parent_id == 0 ) || ( !is_bool ( $remove ) ) || ( !is_string ( $newclass ) ) || ( !is_string ( $firstlast ) ) )
return false;

// Get & filter nav menu items
$nav_menu_items = wp_get_nav_menu_items( $menu_id , array( 'post_status' => 'publish,draft' ) );
$children = get_nav_menu_item_children( $parent_id , $nav_menu_items );
if ( strtolower( $firstlast ) == 'last' )
$children = wps_sort_nav_menu_items( $children , 'menu_order' , 'desc' );
$first_item = true;

// Cycle through child nav menu items
foreach ( $children as $child ) {
if ( $first_item ) {
//found first item
$first_item = false;
$match = false;

// Cycle through to check for first
foreach ( $child->classes as $class ) {
// Match found
if ( $class == $newclass ) {
$match = true;
break;
}
}

// Update Post if match found
if ( ! $match ) {
if ( $child->classes[0] == '' )
$child->classes[0] = $newclass;
else
$child->classes[] = $newclass;

$menu_item_data = array(
'menu-item-classes' => $child->classes,
);
update_post_meta( $child->ID, '_menu_item_classes', $child->classes );
}
continue;
}

// Cycle through and remove $newclass from other children
if ( $remove ) {
foreach ( $child->classes as $key => $class ) {

// If match, remove $newclass from other children
if ( $class == $newclass ) {
$child->classes[$key] = '';
update_post_meta( $child->ID, '_menu_item_classes', $child->classes );
}
}
}
}

return true;
}
[/php]

So to call this function, you can use something like this:
[php]
add_action( 'init' , 'wps_update_menus' );
function wps_update_menus() {
wps_update_classes( 3 , 277 );
wps_update_classes( 3 , 7 , 'last' , 'last' );
}
[/php]
This bit of code adds 'first' to the first child of menu item 277 on menu 3 and 'last' to the last child of menu item 7 on menu 3.

Written by Travis Smith · Categorized: Tutorials, WordPress

Nov 17 2011

How to Automatically Add Custom Taxonomies to a WordPress Menu

While there is probably a better way to do this, here's my first shot at adding custom taxonomies to the menu. Assuming that you have a custom taxonomy created, say 'wps_projects'. What are your thoughts?

[php]
add_action( 'init' , 'wps_add_custom_tax_menu_item' , 15 );
/**
* Adds terms to a specific part of the menu by location
*
*/
function wps_add_custom_tax_menu_item( ) {
// Edit these three variables
$top_menu_item_name = 'Projects';
$taxonomy = 'wps_projects';
$menu_location = 'primary';

// Get menu by location
$menu = wp_get_nav_menus( array( 'location' => $menu_location ) );
$menu_id = $menu[0]->term_id;

// Get terms from wps_projects
$term_args = array(
'hide_empty' => false,
'parent' => 0,
);

// Get only top level $terms
$terms = get_terms( $taxonomy , $term_args );

// Get items
$items = wp_get_nav_menu_items( $menu_id, array( 'post_status' => 'publish,draft' ) );

// Set parent item id
$default_parent_id = $parent_id = wps_get_nav_menu_item_id( $top_menu_item_name , $items );

// Filter items to only the part of the menu necessary
$items = get_nav_menu_item_children( $parent_id , $items );

// Cycle through top-level terms
foreach ( $terms as $term ) {

if ( !$term->term_id || $term->term_id == 0 )
continue;

// Check for term in menu
$match = wps_check_nav_menu_items( $term , $items );

// If not found, add
if ( $match == false ) {
wps_create_nav_menu_item( $menu_id , $term , $taxonomy , $default_parent_id );
}

// Get term's children
$term_args = array(
'hide_empty' => false,
'child_of' => $term->term_id,
);

$child_terms = get_terms( $taxonomy , $term_args );

// Set new parent item id
$parent_id = wps_get_nav_menu_item_id( $term->name , $items );
if ( ! $parent_id )
$parent_id = $default_parent_id;

if ( $child_terms ) {
// Cycle through children
foreach ( $child_terms as $child_term ) {
if ( !$child_term->term_id || $child_term->term_id == 0 )
continue;
$match = wps_check_nav_menu_items( $child_term , $items );

if ( $match == false ) {
wps_create_nav_menu_item( $menu_id , $child_term , $taxonomy , $parent_id );
}
}
}
}
}

/**
* Returns true/false whether an item is already in the items (via its items)
*
* @param object the parent nav_menu_item ID
* @param object nav_menu_items
* @return boolean returns true/false
*/
function wps_check_nav_menu_items( $term , $items ) {
$match = false;
foreach ( $items as $item ) {
if ( $term->term_id == $item->object_id ) {
$match = true;
break;
}
}
return $match;
}

// Creates a nav_menu_item
/**
* Returns true/false whether an item is already in the items (via its items)
*
* @uses wp_update_nav_menu_item
* @param object the parent nav_menu_item ID
* @param object nav_menu_items
* @return boolean returns true/false
*/
function wps_create_nav_menu_item( $menu_id , $term , $taxonomy , $parent_id , $args = array() ) {
// Setup Menu Item Args
$args = array(
'menu-item-object-id' => $term->term_id,
'menu-item-object' => $taxonomy,
'menu-item-type' => 'taxonomy',
'menu-item-status' => 'publish',
'menu-item-parent-id' => $parent_id,
'menu-item-attr-title' => $term->name,
'menu-item-description' => $term->description,
'menu-item-title' => $term->name,
'menu-item-target' => '',
'menu-item-classes' => 'termid-'.$term->term_id.' parentid-'.$parent_id,
'menu-item-xfn' => '',
);
return wp_update_nav_menu_item( $menu_id, 0, $args );
}

/**
* Returns the nav_menu_item ID of an item that has the term name
*
* @param object the parent nav_menu_item ID
* @param object nav_menu_items
* @return boolean returns true/false
*/
function wps_get_nav_menu_item_id( $term , $nav_menu_items ) {
foreach ( $nav_menu_items as $nav_menu_item ) {
if ( $term == $nav_menu_item->post_excerpt || $term == $nav_menu_item->post_title ) {
return $nav_menu_item->ID;
}
}
return false;
}

/**
* Returns all child nav_menu_items under a specific parent
*
* @param int the parent nav_menu_item ID
* @param array nav_menu_items
* @return array returns filtered array of nav_menu_items
*/
function get_nav_menu_item_children( $parent_id, $nav_menu_items ) {
$nav_menu_item_list = array();
foreach ( (array) $nav_menu_items as $nav_menu_item ) {
if ( $nav_menu_item->menu_item_parent == $parent_id ) {
$nav_menu_item_list[] = $nav_menu_item;
if ( $children = get_nav_menu_item_children( $nav_menu_item->ID, $nav_menu_items ) )
$nav_menu_item_list = array_merge( $nav_menu_item_list, $children );
}
}
return $nav_menu_item_list;
}
[/php]

For use of get_nav_menu_item_children() see previous post: .

Written by Travis Smith · Categorized: WordPress

  • « Previous Page
  • 1
  • …
  • 15
  • 16
  • 17
  • 18
  • 19
  • …
  • 25
  • Next Page »
  • Twitter
  • Facebook
  • LinkedIn
  • Google+
  • RSS

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