Common set of custom functions for wordpress

May 27, 2010 · Print This Article

When designing WordPress themes, we always add a common set of custom functions to the wordpress theme’s functions.php file. This speeds up development time and optimizing many key aspects of WordPress, because we don’t have to hunt for and individually copy the same slew of functions for every theme.

In this article, we deliver prime collection of custom functions to enhance your WordPress site. These new functions will help you optimize your development process while enhancing WordPress with essential functionality. Not everything presented here is going to be necessary for all of your wordpress themes, so just grab what you need and add it your own custom functions.php file.

Add feed links to header

Since version 2.8, WordPress can add all relevant feed links (main, comments, categories, et al) to your <head> area. It doesn’t happen by default, however, because you have to add the following snippet to make it work:

// add feed links to header
if (function_exists('automatic_feed_links')) {
	automatic_feed_links();
} else {
	return;
}

This will check to see if you’re using a version of WordPress that is compatible, and then enable the automatic feed links. A couple of notes: first, this method assumes that you are not manually including any feed links in your <head>.

Also, seems this functionality was being integrated with add_theme_support, so keep your eyes open for that.

Automatic jQuery inclusion

Here is a way to do it from your theme’s functions.php file:

// smart jquery inclusion
if (!is_admin()) {
	wp_deregister_script('jquery');
	wp_register_script('jquery', ("http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"), false);
	wp_enqueue_script('jquery');
}

This code ensures that only one copy of jQuery is included, and calls it from Google’s servers to save bandwidth and take advantage of any primed caches that happen to be visiting.

Note that this function needs to be located before the threaded-comments function in order for it to work.

Enable threaded comments

Enabling threaded comments requires adding a snippet of code into your <head> area just before the wp_head tag. After a little experimenting, We discovered that we can include this snippet from the functions.php file:

// enable threaded comments
function enable_threaded_comments(){
	if (!is_admin()) {
		if (is_singular() AND comments_open() AND (get_option('thread_comments') == 1))
			wp_enqueue_script('comment-reply');
		}
}
add_action('get_header', 'enable_threaded_comments');

This helps keep your document <head> a little cleaner. Note that this function needs to be located after the jQuery-inclusion function in order for it to work.

Remove unwanted crap from the head section

As we’ve mentioned before, WordPress spits out a ton of crap in the document <head> – stuff like the version number and WLW, RSD, and index links. To clean things up, we add this nice little snippet into the functions.php template:

// remove junk from head
remove_action('wp_head', 'rsd_link');
remove_action('wp_head', 'wp_generator');
remove_action('wp_head', 'feed_links', 2);
remove_action('wp_head', 'index_rel_link');
remove_action('wp_head', 'wlwmanifest_link');
remove_action('wp_head', 'feed_links_extra', 3);
remove_action('wp_head', 'start_post_rel_link', 10, 0);
remove_action('wp_head', 'parent_post_rel_link', 10, 0);
remove_action('wp_head', 'adjacent_posts_rel_link', 10, 0);

Add Google Analytics to the footer

Another annoying task that has to be done for all of the sites we create is adding Google Analytics code to the footer.php file. Recently it occurred to us to just add the code to our functions.php and never worry about it again:

// add google analytics to footer
function add_google_analytics() {
	echo '<script src="http://www.google-analytics.com/ga.js" type="text/javascript"></script>';
	echo '<script type="text/javascript">';
	echo 'var pageTracker = _gat._getTracker("UA-XXXXX-X");';
	echo 'pageTracker._trackPageview();';
	echo '</script>';
}
add_action('wp_footer', 'add_google_analytics');

A couple of notes here: first, obviously you want to replace the “UA-123456-1” with your actual GA code. Second, you may want to check out the three currently available Analytics options and modify the code accordingly. Currently, this function is using the newer “ga.js” tracking code, but that is easily changed to either of the other methods.

Custom excerpt length

Instead of using the default 55-word limit, this function enables you to specify any length for your excerpts.

// custom excerpt length
function custom_excerpt_length($length) {
	return 80;
}
add_filter('excerpt_length', 'custom_excerpt_length');

Just set your preferred number of words by editing the “80” to whatever you wish.

Custom excerpt “continue” string

Or whatever they call that funky bracketed ellipses thing “[…]” that is appended to your post excerpts by default. Maybe you like to remove the brackets, but with this functions.php snippet you can change it to anything:

// custom excerpt ellipses for 2.9+
function custom_excerpt_more($more) {
	return '...';
}
add_filter('excerpt_more', 'custom_excerpt_more');

/* custom excerpt ellipses for 2.8-
function custom_excerpt_more($excerpt) {
	return str_replace('[...]', '...', $excerpt);
}
add_filter('wp_trim_excerpt', 'custom_excerpt_more'); 
*/

As you can see, there are two different versions of this code, depending on your version of WordPress. We like to stay current, so we commented out the older method but left it there in case you need it. For either version of this technique, just replace the “…” with “pants on the ground” or whatever happens to suit your needs.

No “more” jumping for the “read more” link

One of the weirdest things that WordPress does is “jump” the reader to the location of the “<!–more–&grt;” tag on the single-post-view when the “read more” link is clicked. It’s just awkward — if the jump was on the same page, it would make sense, but to load a new page and then take the reader halfway down without explaining anything is just wrong. In any case, here is a nice little function that will stop the jumping once and for all:

// no more jumping for read more link
function no_more_jumping($post) {
	return '<a href="'.get_permalink($post->ID).'" class="read-more">'.'Continue Reading'.'</a>';
}
add_filter('excerpt_more', 'no_more_jumping');

Nothing else needs to be done for this to work – just plug it in and enjoy your new “jumpless” functionality.

Note that this is also a convenient place to customize the “read more” link with whatever attributes or custom text you wish.

Add a favicon to your wordpress

You just gotsta have a favicon for your wordpress, and this code makes it super easy to do. Just create your image and upload to site’s root directory. The following code in your functions.php file makes it so by adding the required line to your <head> area:

// add a favicon to your 
function blog_favicon() {
	echo '<link rel="Shortcut Icon" type="image/x-icon" href="'.get_bloginfo('wpurl').'/favicon.ico" />';
}
add_action('wp_head', 'blog_favicon');

Feel free to change the directory to whatever you desire. Also make sure that the wp_head is present within your theme’s header.php file.

Add a different favicon for your blog’s Admin area

While we’re here, let’s add a unique favicon to our Admin pages, so that they are easier to recognize when bookmarked or working with tabs. Just create a favicon and upload to your theme’s /images/ directory. This code takes care of the rest:

// add a favicon for your admin
function admin_favicon() {
	echo '<link rel="Shortcut Icon" type="image/x-icon" href="'.get_bloginfo('stylesheet_directory').'/images/favicon.png" />';
}
add_action('admin_head', 'admin_favicon');

As before, feel free to change the directory to whatever you desire. It might be best to keep your admin favicon in a separate directory than your wordpress favicon.

Custom Admin Login logo

You know that snazzy blue WordPress logo that is branding your various login pages? Yeh, you can change that to whatever you want. Just create your custom login image, name it “custom-login-logo.png”, and upload it to your theme’s /images/ directory. This code will take care of the rest:

// custom admin login logo
function custom_login_logo() {
	echo '<style type="text/css">
	h1 a { background-image: url('.get_bloginfo('template_directory').'/images/custom-login-logo.png) !important; }
	</style>';
}
add_action('login_head', 'custom_login_logo');

The key here is to make sure that the path and image names match that of your setup. Also, when creating your image, you may want to keep in mind the properties of the original: 30px length, 31px height, transparent GIF format, and header background color of #464646 (for the image matte).

Disable unused widget areas

This handy function is for removing unwanted widget areas from our theme – a must for customizing existing themes:

// disable all widget areas
function disable_all_widgets($sidebars_widgets) {
	//if (is_home())
		$sidebars_widgets = array(false);
	return $sidebars_widgets;
}
add_filter('sidebars_widgets', 'disable_all_widgets');

This code is plug-&-play – no other modifications need to be made.

Note: if you only want to disable widgets on your Home page, then remove the two comment slashes (“//”) from the third line.

Kill the WordPress update nag

This is one of someone favorites, but it’s not for everyone. In any case, you know that “Please update now..” message that appears on every page in the WordPress Admin when new versions are available? This sweet little function kills it dead (or disables it, actually):

// kill the admin nag
if (!current_user_can('edit_users')) {
	add_action('init', create_function('$a', "remove_action('init', 'wp_version_check');"), 2);
	add_filter('pre_option_update_core', create_function('$a', "return null;"));
}

Feel free to comment this one out or remove it if you rely on the Admin nag to keep you informed of changes.

Include category ID in body_class and post_class

By default, WordPress body_class and post_class do not include the ID of the category of the current post. This custom function changes all that:

// category id in body and post class
function category_id_class($classes) {
	global $post;
	foreach((get_the_category($post->ID)) as $category)
		$classes [] = 'cat-' . $category->cat_ID . '-id';
		return $classes;
}
add_filter('post_class', 'category_id_class');
add_filter('body_class', 'category_id_class');

Even if you aren’t using it, it’s a nice function to have around, which is why it’s included here for this custom functions.php template of essential functions.

Get the first category ID

Another useful function when working with different categories is the ability to get the first category ID of the current post. This function makes it happen:

// get the first category id
function get_first_category_ID() {
	$category = get_the_category();
	return $category[0]->cat_ID;
}

Strictly plug-&-play: just use <?php get_first_category_ID(); ?> in your theme template file to access the data.

Insert custom content after each post

If you look at the different things contained within a typical post, you will find many common and repetitive items, such as feed links, copyright information, and social-media bookmarks. While there’s nothing wrong with inserting this content into your single.php template, it is sometimes easier to manage things from the functions.php file. For example, we include a brief copyright statement at the end of each post. By including the following code in our functions.php template, it’s something that happens automatically:

// add custom post content
function add_post_content($content) {
	if(!is_feed() && !is_home()) {
		$content .= '<p>This article is copyright © '.date('Y').' '.bloginfo('name').'</p>';
	}
	return $content;
}
add_filter('the_content', 'add_post_content');

The trick here is an old one, but it’s extremely useful. By changing the line beginning with “$content.”, you can add just about any content you like.

Insert custom content in your feeds

Just as with the previous method, this function makes it possible to automatically add any content to your feeds. Yes, we know there are plugins that will make your feed footers do backflips, but for a simple copyright message or other info, We think it is easier and more efficient to simply toss a few lines into your custom functions.php template:

// add custom feed content
function add_feed_content($content) {
	if(is_feed()) {
		$content .= '<p>This article is copyright © '.date('Y').' '.bloginfo('name').'</p>';
	}
	return $content;
}
add_filter('the_excerpt_rss', 'add_feed_content');
add_filter('the_content', 'add_feed_content');

As before, you can change the added content to whatever you want by editing the “$content” variable. Once in place, this will append a dynamic copyright message to each post in your feed.

Note: if you happen to be adding the same content to your web pages (using the previous method) and your feeds (using this method), you may combine the two functions like so:

// add custom content to feeds and posts
function add_custom_content($content) {
	if(!is_home()) {
		$content .= '<p>This article is copyright © '.date('Y').' '.bloginfo('name').'</p>';
	}
	return $content;
}
add_filter('the_excerpt_rss', 'add_custom_content');
add_filter('the_content', 'add_custom_content');

Remember that if you use this combined function that you should remove or comment out both of the individual ones to avoid duplicate output. It will be included but commented out in the complete functions.php template file.

Completely remove the version number from pages and feeds

A commonly cited security measure for WordPress-powered sites involves removing the automatically generated version number from appearing in the <head> section of your pages’ source code. This type of security technique is referred to as “security through obscurity,” and aims at hiding potentially sensitive information from a would-be attacker. Here’s a function that does the job:

// remove version info from head and feeds
function complete_version_removal() {
	return '';
}
add_filter('the_generator', 'complete_version_removal');

This will remove your site’s version and generator information from all of your pages and feeds, making it a little bit harder for the bad guys and a little bit safer for you and your visitors.

Customize the admin footer message

Customization is what makes your online experience something special. For your own sites and for your clients’ sites, it is nice to customize the generic admin footer message with something a little more useful, informative, and inspiring. This little gem makes it easy:

// customize admin footer text
function custom_admin_footer() {
	echo '<a href="http://www.livexp.net/">Live Experience</a>';
} 
add_filter('admin_footer_text', 'custom_admin_footer');

Here, for the sake of example, we are including a link to my site, but you can customize the content with just about anything you wish.

Enable HTML markup in user profiles

When customizing their profiles, users may want to include a hyperlink, bold text, or some other HTML markup. By default, WordPress prevents this from happening, but you can easily enable it with this friendly little snippet:

// enable html markup in user profiles
remove_filter('pre_user_description', 'wp_filter_kses');

Note: Enabling HTML may be best left to sites that have open user-registration disabled. Use with discretion.

Delay feed update after posting

As a chronic perfectionist, Maybe we hate it when we post something only to discover an error a few minutes later.

// delay feed update
function publish_later_on_feed($where) {
	global $wpdb;

	if (is_feed()) {
		// timestamp in WP-format
		$now = gmdate('Y-m-d H:i:s');

		// value for wait; + device
		$wait = '5'; // integer

		// http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_timestampdiff
		$device = 'MINUTE'; // MINUTE, HOUR, DAY, WEEK, MONTH, YEAR

		// add SQL-sytax to default $where
		$where .= " AND TIMESTAMPDIFF($device, $wpdb->posts.post_date_gmt, '$now') > $wait ";
	}
	return $where;
}
add_filter('posts_where', 'publish_later_on_feed');

This code quietly and automatically gives us an extra five minutes before my post is added to our feeds. If you need more or less than five minutes, just edit the “$wait” variable with the integer of your choice.

Add an Admin link to the WordPress “All-Settings” page

As we’ve explained before, WordPress makes it easy to view and edit your blog settings from the Admin area. Thanks to a file named “options.php”, WordPress will display all of your database settings and enable you to edit a majority of them. To view this page, you need to log in as Admin and enter this URL in your browser’s address bar:

http://domain.tld/wp-admin/options.php

Having access to your “All-Settings” page can be extremely helpful, so it’s nice to display a direct link for easy access. The following slice of code in your functions.php file is all that’s needed:

// admin link for all settings
function all_settings_link() {
	add_options_page(__('All Settings'), __('All Settings'), 'administrator', 'options.php');
}
add_action('admin_menu', 'all_settings_link');

Once in place, you will see a link to your “All Settings” page in the WordPress Admin. You can change the name of the link to whatever you prefer by editing the two instances of “All Settings”.

Remove all nofollow attributes from comments

There are a million ways to remove nofollow from your comments, but nothing is as easy as this method :

// remove nofollow from comments
function xwp_dofollow($str) {
	$str = preg_replace(
		'~<a ([^>]*)\s*(["|\']{1}\w*)\s*nofollow([^>]*)>~U',
		'<a ${1}${2}${3}>', $str);
	return str_replace(array(' rel=""', " rel=''"), '', $str);
}
remove_filter('pre_comment_content',     'wp_rel_nofollow');
add_filter   ('get_comment_author_link', 'xwp_dofollow');
add_filter   ('post_comments_link',      'xwp_dofollow');
add_filter   ('comment_reply_link',      'xwp_dofollow');
add_filter   ('comment_text',            'xwp_dofollow');

That code will remove all instances of the nefarious “nofollow” attribute from all comment items, including the author link and comment text. This is a great way to automatically remove nofollow with no plugins or hacking required.

Enable easy display of your post’s word count

This function enables you to display your post’s word count without cluttering up the WordPress loop. To display the word count of your posts, first place this in your functions.php file:

// count words in posts
function word_count() {
	global $post;
	echo str_word_count($post->post_content);
}

Then, simply place this anywhere in your loop where you would like the number to appear:


So for example, you could display your post’s word count to your visitors with something like:

<p>This post contains a whopping <?php word_count(); ?> words.</p>

We can also easily display the word count of other items, such as the post title:

<?php echo str_word_count($post->post_title); ?>

Likewise, we can exclude the function from functions.php and get the word count with a single line of code in the loop:

<?php echo str_word_count($post->post_content); ?>

Just slap em anywhere in your post loop to display your word count. Not always needed, but nice to have available.

Enable delete and spam links for comments

Managing your comments is easily done via the Admin, but we also like to see things from the outside, as they appear to the public. Browsing through comments as they appear on your site helps you catch things that may have eluded routine approvals in the Admin’s comment listings. To help facilitate this process, I like to include a backwards-compatible set of spam and delete links next to each comment. This makes it super-easy to cultivate comments live on the site.

// spam & delete links for all versions of wordpress
function delete_comment_link($id) {
	if (current_user_can('edit_post')) {
		echo '| <a href="'.get_bloginfo('wpurl').'/wp-admin/comment.php?action=cdc&c='.$id.'">del</a> ';
		echo '| <a href="'.get_bloginfo('wpurl').'/wp-admin/comment.php?action=cdc&dt=spam&c='.$id.'">spam</a>';
	}
}

Once this is included in your functions.php file, displaying the links is as easy as adding this to your comments loop:

<?php delete_comment_link(get_comment_ID()); ?>

Disable all WordPress feeds

It is easy to disable all feed functionality for your site. Here is the functions.php code:

Note: Only use this function if you want to disable your feeds! This function will be commented out of the complete functions.php file.

// disable all feeds
function fb_disable_feed() {
	wp_die(__('<h1>Feed not available, please visit our <a href="'.get_bloginfo('url').'">Home Page</a>!</h1>'));
}
add_action('do_feed',      'fb_disable_feed', 1);
add_action('do_feed_rdf',  'fb_disable_feed', 1);
add_action('do_feed_rss',  'fb_disable_feed', 1);
add_action('do_feed_rss2', 'fb_disable_feed', 1);
add_action('do_feed_atom', 'fb_disable_feed', 1);

This function will quietly and completely disable all of your site’s feeds, including all different formats. With this code in place, any request for your feed will return the following message in a nice, big set of h1 tags: Feed not available, please visit our Home Page!

This message is easily customized by editing the “wp_die” argument in the function.

Customize the default gravatars and add your own

Instead of suffering with the rather dull default gravatars, use this code to customize your own:

// customize default gravatars
function custom_gravatars($avatar_defaults) {

	// change the default gravatar
	$customGravatar1 = get_bloginfo('template_directory').'/images/gravatar-01.png';
	$avatar_defaults[$customGravatar1] = 'Default';

	// add a custom user gravatar
	$customGravatar2 = get_bloginfo('template_directory').'/images/gravatar-02.png';
	$avatar_defaults[$customGravatar2] = 'Custom Gravatar';

	// add another custom gravatar
	$customGravatar3 = get_bloginfo('template_directory').'/images/gravatar-03.png';
	$avatar_defaults[$customGravatar3] = 'Custom gravatar';

	return $avatar_defaults;
}
add_filter('avatar_defaults', 'custom_gravatars');

Of course, you can manually choose a default gravatar by specifying its location via the “get_avatar” template tag, but this method makes it so much easier. Not only does it replace the default with multiple custom gravatars, but it also goes the extra mile by displaying them in the WordPress Admin area under Settings > Discussion. From there, you can select any of your custom gravatars by simply selecting it and clicking the “Update” button. Nothing could be easier.

A few notes about this function:

1. As is, it adds three new gravatars to choose as defaults.
2. Each gravatar should be located in your theme’s images directory.
3. You can add as many default gravatars as you would like by emulating the code pattern.
4. If you keep your custom gravatars someplace else, be sure and edit the image paths accordingly.

Disable automatic formatting in post content via shortcode

How to prevent WordPress from automatically formatting chunks of post content by using a shortcode. This is very useful for posting code, poetry, or anything else that you would like to display in raw format. To do this, we add the following snippet to our functions.php file:

// disable auto formatting in posts
function my_formatter($content) {
	$new_content = '';
	$pattern_full = '{(\[raw\].*?\[/raw\])}is';
	$pattern_contents = '{\[raw\](.*?)\[/raw\]}is';
	$pieces = preg_split($pattern_full, $content, -1, PREG_SPLIT_DELIM_CAPTURE);

	foreach ($pieces as $piece) {
		if (preg_match($pattern_contents, $piece, $matches)) {
			$new_content .= $matches[1];
		} else {
			$new_content .= wptexturize(wpautop($piece));
		}
	}

	return $new_content;
}
remove_filter('the_content', 'wpautop');
remove_filter('the_content', 'wptexturize');
add_filter('the_content', 'my_formatter', 99);

With that code in place, you can insert unformatted code into your posts via the “[raw]” shortcode, for example:

[raw]Unformatted content[/raw]

Anything contained within those shortcodes will be left unformatted when displayed in your posts.

Escape HTML entities in comments

How to automatically escape encoded HTML entities in the comments that readers leave on your posts? This is especially useful for blogs that deal in heavy code exchanges on post threads. This enables your commentators to simply wrap their code in <code> tags and not have to worry about manually converting characters such as angled brackets (“<” & “>”) into their encoded equivalents (“<” & “>”).

// escape html entities in comments
function encode_code_in_comment($source) {
	$encoded = preg_replace_callback('/<code>(.*?)<\/code>/ims',
	create_function('$matches', '$matches[1] = preg_replace(array("/^[\r|\n]+/i", "/[\r|\n]+$/i"), "", $matches[1]); 
	return "<code>" . htmlentities($matches[1]) . "</"."code>";'), $source);
	if ($encoded)
		return $encoded;
	else
		return $source;
}
add_filter('pre_comment_content', 'encode_code_in_comment');

Once in place in your functions.php file, simply tell your commentators to wrap their code snippets in <code> tags. In other words, any content wrapped in <code> tags will be encoded automatically. Plus, in order to prevent unwanted <br /> tags, this function also automatically removes line breaks after the opening <code> tag and before the closing <code> tag.

Custom comments display callback function

When designing your theme’s comments.php file, you can use either WordPress’ default code or create your own for full control over your comments display. If you’re rolling your own, it is often easiest to grab a solid comments-display template and customize it to suit your needs. After many iterations and much refining, here is the comments callback function that We usually begin with:

// custom comments callback function

function custom_comments_callback($comment, $args, $depth) {
	$GLOBALS['comment'] = $comment; ?>

	<li <?php comment_class(); ?> id="comment-<?php comment_ID(); ?>">
		<div class="comment-wrap">
			<?php echo get_avatar(get_comment_author_email(), $size = '50', $default = bloginfo('stylesheet_directory').'/images/gravatar.png'); ?>

			<div class="comment-intro">
            			<?php printf(__('%s'), get_comment_author_link()); ?> – <a class="comment-permalink" href="<?php echo htmlspecialchars(get_comment_link($comment->comment_ID)); ?>"><?php comment_date('F j, Y'); ?> @ <?php comment_time(); ?></a><?php edit_comment_link('Edit', ' – ', ''); ?>
			</div>
			<?php if ($comment->comment_approved == '0') : ?>

			<p class="comment-moderation"><?php _e('Your comment is awaiting moderation.'); ?></p>
			<?php endif; ?>

			<div class="comment-text"><?php comment_text(); ?></div>

			<div class="reply" id="comment-reply-<?php comment_ID(); ?>">
				<?php comment_reply_link(array_merge($args, array('reply_text'=>'Reply', 'login_text'=>'Log in to Reply', 'add_below'=>'comment-reply', 'depth'=>$depth, 'max_depth'=>$args['max_depth']))); ?> 

			</div>
		</div>

<?php } // WP adds the closing </li>

There’s a lot going on here, so let’s highlight the important stuff:

  1. Do not add the closing </li> element – WordPress does this for you.
  2. This function calls for a default gravatar in your theme’s “images” directory. Either ensure you’ve got the required image in place or edit the code to reflect your site’s reality.
  3. Once this function is included in your functions.php file, you can display it by using the following comments loop in your comments.php file:
<?php if (have_comments()) : ?>
<ol class="commentlist">
	<?php wp_list_comments('type=comment&style=ol&callback=custom_comments_callback'); ?>
</ol>
<?php else : ?>

Notice the third parameter for the wp_list_comments template tag? that’s what makes it go. Also important is the “style=ol” parameter, which tells WordPress that we are using an ordered list for comments and that it should automatically close the markup with a </li> element.


Your choice for site templates and wordpress themes

Comments

Got something to say?

You must be logged in to post a comment.