Sign up ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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.

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.

share|improve this question

closed as not constructive by Rarst Feb 15 '12 at 12:44

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.If this question can be reworded to fit the rules in the help center, please edit the question.

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
All answers not related to a theme should be removed. This thread is a good example for bad coding practices. –  toscho Jun 13 '11 at 12:09
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
2 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. –  toscho Feb 22 '12 at 2:44
5 Discuss it on Meta where people can see your arguments better. :) –  toscho Feb 24 '12 at 17:10

108 Answers 108

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);
share|improve this answer

Remove WordPress 3.3 Admin Bar Menu Items

function dashboard_tweaks() {
    global $wp_admin_bar;
add_action( 'wp_before_admin_bar_render', 'dashboard_tweaks' );


share|improve this answer

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.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'); ?>
share|improve this answer

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;
share|improve this answer

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;
share|improve this answer

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');
share|improve this answer

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');
share|improve this answer

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; 
share|improve this answer
Do not use output buffering. wp_loginout() has a second parameter $echo to make your life easier. –  toscho Feb 23 '11 at 19:30

Remove "Comments" link from admin bar if comment status is closed

You can set the default comment status to 'closed', but the comments link will stay. Simply drop the following into your functions.php file to get rid of it based on the condition. Offers 2 different approaches.

 * Disable 'Comments' link if default status is _closed_
function remove_comments() 
    $default_comment_status = get_option( 'default_comment_status' );

    if ( $default_comment_status == 'closed' ) 
        remove_action( 'admin_bar_menu', 'wp_admin_bar_comments_menu', 50 );

        // optional solution using the WP_Admin_Bar class from /wp-includes/class-wp-admin-bar.php
        # global $wp_admin_bar;
        # $wp_admin_bar->remove_menu( 'comments' );
share|improve this answer

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

share|improve this answer

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');
share|improve this answer
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 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
share|improve this answer

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;" ) );
share|improve this answer

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);
share|improve this answer

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);
share|improve this answer

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' );
share|improve this answer

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"';
share|improve this answer

Call bloginfo using shortcode...

function digwp_bloginfo_shortcode($atts) {

            'key' => '',
            ), $atts));

    return get_bloginfo($key);

add_shortcode('bloginfo', 'digwp_bloginfo_shortcode');


[bloginfo key='name']
share|improve this answer

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