Skip to content

Instantly share code, notes, and snippets.

@tsmith512
Created December 24, 2012 23:23
Show Gist options
  • Save tsmith512/4371029 to your computer and use it in GitHub Desktop.
Save tsmith512/4371029 to your computer and use it in GitHub Desktop.
Utility WordPress functions for cleaner output and theme code
<?php
/**
* tsmith512's Common WordPress Functions
*
* Handy WordPress functions for cleaner theme code and WordPress output. This
* is not (yet) a plugin because it is so closely tied to the theme code. Include
* it directly in a theme's functions.php file.
*
* @package tsmith512-wordpress
* @author Taylor Smith (www.tsmithcreative.com)
* @link https://gist.github.com/4371029
* @version 0.1
*/
/**
* Add and remove actions. Runs on after_setup_theme at lower priority
*/
function tsmith_start() {
// Cleanup the header output
add_action('init', 'tsmith_head_cleanup');
// Because who the hell still uses "Links"?!
add_action( 'admin_menu', function() { remove_menu_page('link-manager.php'); } );
}
add_action('after_setup_theme','tsmith_start', 20);
/**
* Strip WP version from RSS output
*/
add_filter('the_generator', function(){ return ''; } );
/**
* WordPress puts too much junk in <head>, remove it. Much of this taken from
* @eddiemachado's Bones base theme, which includes a ton of awesome cleanup!
* @link https://github.com/eddiemachado/bones/blob/master/library/bones.php
*/
function tsmith_head_cleanup() {
// Remove the WP version from <head> -- NOT a substitute for updating WordPress!
remove_action( 'wp_head', 'wp_generator' );
// links for adjacent posts
remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 );
// Remove Windows Live Writer Manifest and RSD links
remove_action('wp_head', 'wlwmanifest_link');
remove_action('wp_head', 'rsd_link');
}
/**
* Generates the contents of the title tag:
*
* If home page with site description !empty: Site Name | Description
* If home page with no site description: Site Name
* Else: Page Name | Site Name
*
* @return title as string
*/
function tsmith_make_title() {
// Determine what WordPress thinks this page title is without a separator
$wp_title = wp_title('', false);
// Get the site name
$site_name = get_bloginfo('name');
// Get the site description
$site_desc = get_bloginfo('description');
// Are we on the home/front page, is wp_title 'Home', or is wp_title empty?
if ( is_front_page() || is_home() || $wp_title == "Home" || empty($wp_title) ) {
// If we have no description, return the site name
if ( empty($site_desc) ) return $site_name;
// Looks like we've got a site description:
return ($site_name . " | " . $site_desc);
} else {
return ( $wp_title . ' | ' . $site_name );
}
}
/**
* Generates a "Headline" for non singular page loads. Like a more verbose title.
*
* Adapted from: http://perishablepress.com/how-to-generate-perfect-wordpress-title-tags-without-a-plugin/
*
* @param $headline (string, optional): the prefix for the headline
* @return the completed headline
*/
function tsmith_make_headline($headline = '') {
$headline .= ' ';
if (function_exists('is_tag') && is_tag()) {
$headline .= 'Tag Archive for &quot;' . $tag . '&quot;';
} elseif (is_archive()) {
$headline .= ( wp_title('', false) . ' Archive' );
} elseif (is_search()) {
$headline .= 'Search for &quot;' . wp_specialchars($s) . '&quot;';
} elseif (!(is_404()) && (is_single()) || (is_page())) {
$headline .= wp_title('', false);
} elseif (is_404()) {
$headline .= 'Not Found';
} elseif (is_front_page()) {
$headline .= get_bloginfo('name');
}
return $headline;
}
/**
* Get the top-most ancestor of a page
*
* @param $post (int, required): A page ID whose highest ancestor we need.
* @return that page's ID
*/
function tsmith_get_top_ancestor($post) {
if ( ! is_page() ) { return false; }
// In WP3.5+, using the new WP_Post class, the best way to get the ancestors
// we need is to use get_queried_object(). This gives us:
// [ Parent, Grandparent, Great Grandparent, ..., Top-Ancestor ]
$ancestors = get_queried_object()->ancestors;
// Add the current post ID to the beginning of the array, in case this is a
// top-level page to get: [ Me, Parent, Grandparent, ..., Top-Ancestor ]
array_unshift($ancestors, get_queried_object_id());
// Whatever the last element is, it's the top-level ancestor.
return end($ancestors);
}
/**
* Replace the WP3.5 Gallery shortcode.
*
* This implements the functionality of the Gallery Shortcode for displaying
* WordPress images on a post. It replaces the built-in function by hooking onto
* the post_gallery filter, which, if returns !empty, halts the execution of the
* [gallery] shortcode and returns the output of this function.
*
* My version differs thusly:
* - Removes the <style> block, assuming CSS is in place in the theme
* - Removes the <br style="clear:both"> that breaks columns
* - Removes the <br style="clear:both"> at the end of the block
* - Removes the gallery-columns-# class and counter
* - Do this yourself in CSS for better responsive galleries. Fixed numbers of
* columns aren't good for responsive layouts.
* - Adds the $instance key to the link's "rel" attribute for Colorbox to allow
* previous/next between images.
*
* @param array $attr Attributes of the shortcode.
* @return string HTML content to display gallery.
*/
function tsmith_gallery_shortcode($output, $attr) {
global $post;
// Determine the instance number for this gallery to add id and rel attributes
static $instance = 0;
$instance++;
// The new media manager's Gallery builder passes the 'ids' attribute, pre-ordered
if ( ! empty( $attr['ids'] ) ) {
// 'ids' is explicitly ordered, unless you specify otherwise.
if ( empty( $attr['orderby'] ) ) $attr['orderby'] = 'post__in';
$attr['include'] = $attr['ids'];
}
// We're trusting author input, validate and sanitize it
if ( isset( $attr['orderby'] ) ) {
$attr['orderby'] = sanitize_sql_orderby( $attr['orderby'] );
// If nothing is left, unset it.
if ( !$attr['orderby'] ) unset( $attr['orderby'] );
}
// Merge default values with provided shortcode attributes
extract(shortcode_atts(array(
'order' => 'ASC',
'orderby' => 'menu_order ID',
'id' => $post->ID,
// @TODO: Still not sure about this tag scheme... a dl for each slide?
'itemtag' => 'dl',
'icontag' => 'dt',
'captiontag' => 'dd',
'size' => 'thumbnail',
'include' => '',
'exclude' => ''
), $attr));
// The post ID, used to get attachment children of this specific post. This is
// necessary to get relevant items when not using the ids/include attribute.
$id = intval($id);
// Okay so WP's "random" order is just database order. Faster than using MySQL
// rand, so we'll leave it.
if ( 'RAND' == $order ) $orderby = 'none';
if ( !empty($include) ) {
// If we have specific inclusions (or author used the media manager's gallery)
$_attachments = get_posts( array(
'include' => $include,
'post_status' => 'inherit',
'post_type' => 'attachment',
'post_mime_type' => 'image',
'order' => $order,
'orderby' => $orderby
) );
$attachments = array();
foreach ( $_attachments as $key => $val ) {
$attachments[$val->ID] = $_attachments[$key];
}
} elseif ( !empty($exclude) ) {
// If we have exclusions but no inclusions/ids. Get all child attachments
// except those excluded.
$attachments = get_children( array(
'post_parent' => $id,
'exclude' => $exclude,
'post_status' => 'inherit',
'post_type' => 'attachment',
'post_mime_type' => 'image',
'order' => $order,
'orderby' => $orderby
) );
} else {
// Neither inclsuions nor exclusions. Get all child attachments.
$attachments = get_children( array(
'post_parent' => $id,
'post_status' => 'inherit',
'post_type' => 'attachment',
'post_mime_type' => 'image',
'order' => $order,
'orderby' => $orderby
) );
}
if ( empty($attachments) ) return '';
// If this is an RSS feed, return the images only, do not format the gallery
if ( is_feed() ) {
$output = "\n";
foreach ( $attachments as $att_id => $attachment )
$output .= wp_get_attachment_link($att_id, $size, true) . "\n";
return $output;
}
// Prepare markup variables:
$itemtag = tag_escape($itemtag);
$captiontag = tag_escape($captiontag);
$selector = "gallery-{$instance}";
$size_class = sanitize_html_class( $size );
$gallery_div = "<div id='$selector' class='gallery galleryid-{$id} gallery-size-{$size_class} link-{$attr['link']}'>";
$output = apply_filters( 'gallery_style', $gallery_style . "\n\t\t" . $gallery_div );
// The gallery style filter allows a CSS block to be prefixed to the $output.
// I removed it in favor of returning unformatted galleries to style in-theme.
$i = 0;
foreach ( $attachments as $id => $attachment ) {
$link = isset($attr['link']) && 'file' == $attr['link'] ? wp_get_attachment_link($id, $size, false, false) : wp_get_attachment_link($id, $size, true, false);
// Add the instance key to the "rel" attribute for Colorbox
$link = str_replace( 'a href' , 'a rel="' . $selector . '" href' , $link );
$output .= "<{$itemtag} class='gallery-item'>";
$output .= "
<{$icontag} class='gallery-icon'>
$link
</{$icontag}>";
if ( $captiontag && trim($attachment->post_excerpt) ) {
$output .= "
<{$captiontag} class='wp-caption-text gallery-caption'>
" . wptexturize($attachment->post_excerpt) . "
</{$captiontag}>";
}
$output .= "</{$itemtag}>";
}
$output .= "
</div>\n";
return $output;
}
add_filter('post_gallery', 'tsmith_gallery_shortcode', 10, 2);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment