As with many others who are now viewing this post, I have been reading various blogs, forums, and discussion groups to learn and improve my WordPress skills. Over the past 12 months I have been on a mission to substitute my use of plugins by adding code to my functions.php file instead.

While I completely agree that plugins are very useful in many situations, my experience proved that in 90% of usage cases although a plugin might exist, actually utilizing it could create unnecessary complications and compatibility issues. Additionally in a great deal of cases such plugins added menus and other admin elements which I don't want or need.

More often than not I have found that by analyzing the code of plugins I was able to strip out the piece of code I wanted and hard code it into my functions.php. This provided me with the exact functionality I needed without having to include unnecessary elements.

So, the purpose of this post is my attempt to engage you, the reader/admin/developer, to share with me and other here any code bits which you find useful and have added to your theme's function.php file to extend or enhance WordPress without utilizing a plugin.

When you submit a response here please kindly give each code bit a title, let us know if with what version of WordPress you know its compatible with, include whatever description you feel best describes its function and (if applicable) include a link to the original plugin or source where you found the information.

I am looking forward to all your responses and will of course continually add my own new finds whenever I find them.

Please vote on the question and any answers you find useful by clicking on the up arrow on the left hand side of the question or answer.

  • 13
    Considering the first 5 answers were by the OP and the question seems more geared at collecting an array of responses rather than a single, definitive answer, this should be a community wiki.
    – EAMann
    Sep 9 '10 at 14:43
  • 17
    All answers not related to a theme should be removed. This thread is a good example for bad coding practices.
    – fuxia
    Jun 13 '11 at 12:09
  • 17
    I think it'd be better to encourage people to create a custom functionality plugin instead of using their theme's functions.php
    – Ian Dunn
    Jan 16 '12 at 18:49
  • 3
    @NetConstructor.com The pure number of page views is not an indicator for quality. We should encourage specific questions with specific answers and good coding practices. This thread is the opposite.
    – fuxia
    Feb 22 '12 at 2:44
  • 6
    @NetConstructor.com Discuss it on Meta where people can see your arguments better. :)
    – fuxia
    Feb 24 '12 at 17:10

108 Answers 108

1 2 3

Exclude default category from public pages

Excludes the default category from the front-facing side of the website.
Code excludes the admin area, else you'll have no way to manage posts assigned with the default category.

add_filter( 'list_terms_exclusions', 'exclude_default_cat' );

function exclude_default_cat( $exclusions ) {
    if( !is_admin() )
        $exclusions .=  "AND t.term_id != " . get_option( 'default_category' ) . " ";
    return $exclusions;

Custom Logos for Login page and Admin

/*  Custom logos
function custom_admin_logo() {
    echo '
        <style type="text/css">
            #header-logo { background-image: url('.get_bloginfo('template_directory').'/path/to/images/admin-logo.png) !important; }
add_action('admin_head', 'custom_admin_logo');

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

add_action('login_head', 'custom_login_logo');
  • 2
    Please take a look at this gist. There are even better options than shown in the gist. You could also try to participate on the trac ticket (link in gist plugin header).
    – kaiser
    Jun 13 '11 at 14:01

Remove Admin (User #1) from User list

function your_pre_user_query($user_search) {
  $user = wp_get_current_user();
  if ($user->ID!=1) {
    global $wpdb;
    $user_search->query_where = str_replace('WHERE 1=1',
      "WHERE 1=1 AND {$wpdb->users}.ID<>1",$user_search->query_where);
  • Again: user 1 may be a non-admin. See Roles and Capabilities.
    – fuxia
    Jun 13 '11 at 11:59
  • It's an example. Plus in default installations the user 1 is Admin - the first user created. This is why I emphasized (User #1) Jun 13 '11 at 12:05
  • It is an example showing how not to check for administrative capabilities. You should not use this code in a real website.
    – fuxia
    Jun 13 '11 at 12:08
  • Exactly. This code doesn't check for capabilities, toscho, but for specific user. This code has nothing to do with capabilities and I haven't mentioned capabilities anywhere. I don't see why this can not be used on production sites. Jun 13 '11 at 12:21
  • @Daniel Sachs If you're searching for the first ever added administrator, please check the roles of all users first, then sort them by their ID and take the first one. As @toscho said: Currently it's "how you should not do it example". Reasons: a) the actual Admin might not be the one with the lowest ID b) If someone else would work on this, she/he wouldn't search for this functionality in a theme.
    – kaiser
    Jun 13 '11 at 13:56

Get Attributes of Given Thumbnail

Use this function with the loop to determine width, height and URL of a thumbnailed image. Very handy for assigning a thumbnailed image as a background element via inline CSS.

* Fetches width, heigth and URI of a thumbnail.
* @author Philip Downer <philip@manifestbozeman.com>
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @version v1.0
* @param string $return Accepts 'path', 'width', or 'height'.
* @param string $size The thumbnail size corresponding to {@link add_image_size() WP core function}.
* @return mixed Returns the requested info, or if no 'Featured Image' assigned, returns 'false'.
function get_thumb_attr($return,$size='thumbnail') {
    global $post;

    if (has_post_thumbnail($post->ID)) {
      $thumb = wp_get_attachment_image_src(get_post_thumbnail_id(), 'intro');
      if ( $return == 'path' ) { return $thumb[0]; }
      if ( $return == 'width' ) { return $thumb[1]; }
      if ( $return == 'height' ) { return $thumb[2]; }
    } else {
        return false;
}//end function

Output the contents of a widget outside the context of a sidebar using it's ID. The wrapping before/after HTML is not included. You need to know the specific ID of the widget you're angling for (ie 'text-5').

function widget_contents($id) {
    list($type,$number) = explode('-',$id);
    global $wp_registered_widgets;

You can peek at the output of wp_get_sidebars_widgets() if you aren't sure of the precise ID you need.

A more complete example lifted from /wp-includes/widgets.php under the dynamic_sidebar() function:

function render_widget($id) {
    global $wp_registered_widgets;
    $params = array_merge(
            array( array('widget_id' => $id, 'widget_name' => $wp_registered_widgets[$id]['name']) ),
            (array) $wp_registered_widgets[$id]['params']
    $classname_ = '';
    foreach ( (array) $wp_registered_widgets[$id]['classname'] as $cn ) {
            if ( is_string($cn) )
                    $classname_ .= '_' . $cn;
            elseif ( is_object($cn) )
                    $classname_ .= '_' . get_class($cn);
    $classname_ = ltrim($classname_, '_');
    $params[0]['before_widget'] = sprintf($params[0]['before_widget'], $id, $classname_);

    if ( is_callable($wp_registered_widgets[$id]['callback']) )
            call_user_func_array($wp_registered_widgets[$id]['callback'], $params);

Custom smilies (plugin)

 * Smilies.
function filter_smilies_src($img_src, $img, $siteurl) {
    return plugins_url('', __FILE__) . '/img/smilies/' . $img;
add_filter('smilies_src', 'filter_smilies_src', 1, 10);

Custom smilies (theme)

 * Smilies.
function filter_smilies_src($img_src, $img, $siteurl) {
    return get_bloginfo('stylesheet_directory') . '/images/smilies/' . $img;
add_filter('smilies_src', 'filter_smilies_src', 1, 10);

Cross Taxonomy Tags Query

A cached query that outputs a get_tags() like HTML string of all tags for a given Taxonomy parameter defaulting to a Category. You can use $where_slug and $where_tax to get post tags filtered by any other taxonomy. SQL tested for WP 3.1 to WP 3.3.1.

function tags_by_other_taxonomy($where_slug,$where_tax = 'category',$bust_cache = false) {
    $cache_key = "{$where_slug}:{$where_tax}";
    $cache = get_transient('tags_by_other_taxonomy');
    $html = '';
    if( true !== $bust_cache and false !== $cache and isset($cache[$cache_key]) and !empty($cache[$cache_key]) ) {
            $html = $cache[$cache_key];
    } else {
        global $wpdb;
        $cat_id = $wpdb->get_var("SELECT tt.term_taxonomy_id FROM $wpdb->terms t INNER JOIN $wpdb->term_taxonomy tt ON t.term_id = tt.term_id WHERE t.slug = '{$where_slug}' AND tt.taxonomy = '{$where_tax}' LIMIT 1");
        if( !empty($cat_id) ) {
            $cat_posts = $wpdb->get_col("SELECT tr.object_id FROM $wpdb->term_relationships tr inner join $wpdb->posts p ON p.ID = tr.object_id WHERE term_taxonomy_id = {$cat_id} AND p.post_status = 'publish' AND p.post_type = 'post'");
            if( count($cat_posts) ) {
                $tags = $wpdb->get_results("SELECT DISTINCT t.name,t.slug FROM $wpdb->term_taxonomy tt
                                INNER JOIN $wpdb->term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
                                INNER JOIN $wpdb->terms t ON t.term_id = tt.term_id
                                WHERE tt.taxonomy = 'post_tag' and tr.object_id IN (".implode(',',$cat_posts) .')');
                $html = '<ul class="post-tags-'.$where_slug.'">';
                if( count($tags) ) {
                    foreach($tags as $tag)
                        $html .= '<li><a href="/tag/'.$tag->slug.'/" title="Posts tagged with '.$tag->name.'">'.$tag->name.'</a></li>';
                $html .= '</ul>';
                if( !is_array($cache) )
                    $cache = array();
                $cache[$cache_key] = $html;
                set_transient('sc_cross_tax', $cache, 86400);
    echo $html;

For example, get all tags for Published Posts in the news Category slug:

<?php echo tags_by_other_taxonomy('news'); ?>

Automatically close missing tags from the WYSIWYG editor

Tested on: Wordpress 3.0.1

This code will automatically close any missing tags when using the WYSIWYG editor.

   function clean_bad_content($bPrint = false) {
 global $post;
 $szPostContent  = $post->post_content;
 $szRemoveFilter = array("~<p[^>]*>\s?</p>~", "~<a[^>]*>\s?</a>~", "~<font[^>]*>~", "~<\/font>~", "~style\=\"[^\"]*\"~", "~<span[^>]*>\s?</span>~");
 $szPostContent  = preg_replace($szRemoveFilter, '', $szPostContent);
 $szPostContent  = apply_filters('the_content', $szPostContent);
 if ($bPrint == false) return $szPostContent; 
 else echo $szPostContent;
  • Just to let you know there is an option of doing that in WordPress itself. IT can be useful if one needs to force it for multiple users irrespective of their setting. But I would force saving that setting instead.
    – Ashfame
    Apr 20 '11 at 17:11

Reposition the WYSIWYG Editor through JQUERY

Tested on: Wordpress 3.0.1

This code will allow you to remove specific meta boxes which wordpress adds by default to the POST and PAGES screens.

   function admin_head_hook() {
 ?><style type="text/css">
  #postdiv.postarea, #postdivrich.postarea { margin:0; }
  #post-status-info { line-height:1.4em; font-size:13px; }
  .custom-wysiwyg-editor-container { margin:2px 6px 6px 6px; }
  #ed_toolbar { display:none; }
  #postdiv #ed_toolbar, #postdivrich #ed_toolbar { display:block; }

   function admin_footer_hook() {
 ?><script type="text/javascript">
  jQuery('#postdiv, #postdivrich').prependTo('.custom-wysiwyg-editor-container');

Remove role="search" attributes for get_search_form()

function remove_role_search($role)
    $result = array();
    preg_match_all('|role="[^"]*"|U', $role, $result);
    foreach ($result[0] as $role_tag) {
        $role = str_replace($role_tag, '', $role);
    return $role;
add_filter('get_search_form', 'remove_role_search');

Add a Login Link to wp_nav_menu

add_filter('wp_nav_menu_items', 'add_login_logout_link', 10, 2);

function add_login_logout_link($items, $args) { 

        $loginoutlink = wp_loginout('index.php', false); 

        $items .= '<li>'. $loginoutlink .'</li>'; 

    return $items; 
  • 3
    Do not use output buffering. wp_loginout() has a second parameter $echo to make your life easier.
    – fuxia
    Feb 23 '11 at 19:30

Changing "Posts" menu name in admin to whatever you wish (e.g. "Articles")

// hook the translation filters

function change_post_to_article( $translated ) {
$translated = str_ireplace('Post','Article',$translated );// ireplace is PHP5 only
return $translated;

Credits to smashingmagazine.com


Remove Links Menu Item

Many of my WordPress installs don't require that users have access to the 'Links' menu item. This function removes it from view.

add_action( 'admin_menu', 'custom_admin_menu' );
function custom_admin_menu() 
    global $menu;
    // var_dump($menu); // use this to identify the key for the menu item you want to remove
    unset( $menu[15] ); //key 15 is links
    if ( !current_user_can('manage_options') ) { unset( $menu[75] ); } //key 75 is tools ... but only for non super admins

Disable Upgrade Now Message for Non-Administrators

I'm actually a big fan of NOT using this code. Instead, I prefer to allow customers to update their own WordPress installs. This helps keep the site up-to-date and forces me to write better code.

if ( !current_user_can( 'manage_options' ) ) {
  add_action( 'init', create_function( '$a', "remove_action( 'init', 'wp_version_check' );" ), 2 );
  add_filter( 'pre_option_update_core', create_function( '$a', "return null;" ) );

Automatically add a hidden custom field and associating value to a post when the post is published

add_action('publish_page', 'add_custom_field_automatically');
add_action('publish_post', 'add_custom_field_automatically');
function add_custom_field_automatically($post_ID) {
global $wpdb;
if(!wp_is_post_revision($post_ID)) {
    add_post_meta($post_ID, 'field-name', 'custom value', true);

Add custom post types to archives page

function namespace_add_custom_types( $query ) {
if( is_category() || is_tag() && empty( $query->query_vars['suppress_filters'] ) ) {
$query->set( 'post_type', array(
 'post', 'your-custom-post-type-here'
      return $query;
add_filter( 'pre_get_posts', 'namespace_add_custom_types' );

Add a custom class to the next and previous links

add_filter('next_posts_link_attributes', 'posts_link_attributes');
add_filter('previous_posts_link_attributes', 'posts_link_attributes');
function posts_link_attributes(){
    return 'class="styled-button"';

Call bloginfo using shortcode...

function digwp_bloginfo_shortcode($atts) {
            'key' => '',
            ), $atts));
    return get_bloginfo($key);

add_shortcode('bloginfo', 'digwp_bloginfo_shortcode');


[bloginfo key='name']
  • Can you add some examples of where this could be useful? Feb 1 '20 at 19:05
1 2 3

Not the answer you're looking for? Browse other questions tagged or ask your own question.