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, 2010 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, 2011 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, 2012 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, 2012 at 2:44
  • 6
    @NetConstructor.com Discuss it on Meta where people can see your arguments better. :)
    – fuxia
    Feb 24, 2012 at 17:10

108 Answers 108


Remove default fields contact info user profile and replace them with something more usable

The second part of this function has already been mentioned above, but removing the default fields - AIM, Yahoo IM and Jabber/Google Talk - not yet:

function update_contact_methods( $contactmethods ) {

// Remove annoying and unwanted default fields  

// Add new fields  
$contactmethods['phone'] = 'Phone';  
$contactmethods['mobile'] = 'Mobile';  
$contactmethods['address'] = 'Address';  

return $contactmethods;
add_filter('user_contactmethods', 'update_contact_methods');

Of course you can add as many fields as you want (see previous examples earlier in this thread) under "Add new fields"


Add "Next-page"-button in WYSIYG-editor

function wysiwyg_editor($mce_buttons) {
    $pos = array_search('wp_more',$mce_buttons,true);
    if ($pos !== false) {
        $tmp_buttons = array_slice($mce_buttons, 0, $pos+1);
        $tmp_buttons[] = 'wp_page';
        $mce_buttons = array_merge($tmp_buttons, array_slice($mce_buttons, $pos+1));
    return $mce_buttons;

Change default Author Slug

Put this in your functions to change the default Author Slug to whatever you want,
just change the "sellers" to the slug you want.

// Change URL Slug from Author to Sellers
function new_author_base() {
    global $wp_rewrite;
    $author_slug = 'sellers';
    $wp_rewrite->author_base = $author_slug;
add_action('init', 'new_author_base');
  • 4
    You'd not want to run that code on every page load however.
    – t31os
    Dec 21, 2010 at 20:27
  • Yeah, flushing roles on every load saves you a lot of sellers. :) Better use the plugin Edit Author Slug.
    – fuxia
    Dec 22, 2010 at 3:21
  • I have update the function!!! Thanks for your input:)
    – Philip
    Jan 12, 2011 at 21:37

Add custom styles to TinyMCE editor

Sometimes users and clients get confused about how their content is displayed in the editor versus how it is displayed on the front-end. Copying just a few relevant lines from your main stylesheet into your new tinymce.css can help a lot:

function custom_mce_css($wp) {
    return $wp .= ',' . get_bloginfo('stylesheet_directory') . '/css/tinymce.css';
add_filter( 'mce_css', 'custom_mce_css' );
  • Nice. Ive just discoverd there is a solution by Seamus Leahy that extends all this one step further by adding a body class to tinymce. digwp.com/2010/11/actual-wysiwyg
    – Michal Mau
    Jan 20, 2011 at 2:03
  • Isn't this already covered by core & editor styles?
    – kaiser
    Feb 1, 2011 at 7:52
  • I prefer to create a stylesheet for both front-end and TinyMCE in one go. Then I use core functionality of the add_editor_style() function to include the stylesheet and ensure it's loaded when TinyMCE loads. Codex article at codex.wordpress.org/Function_Reference/add_editor_style Sep 13, 2011 at 20:42

Add auto-update/plugin-installer on you localhost

define ('FS_METHOD', 'direct');

Put this in your wp-config.php.

  • so this automatically updates any/all of your plugins whenever something new is available? Nov 5, 2010 at 15:44
  • Nope, you just don't need a ftp login to update your core or plugins locally
    – Horttcore
    Nov 9, 2010 at 8:11

Auto Include Google Analytics Code

Tested on: Wordpress 3.1 RC3

I've been using this script on all of my sites since WordPress 2.3.0 ... it just adds the standard Google tracking scripts to the footer.

// Add Google Analytics Tracking Code
function add_google_analytics() {
<script type="text/javascript">
    var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
    document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
<script type="text/javascript">
    try {
        var pageTracker = _gat._getTracker("UA-XXXXXXX-X");
    } catch(err) {}</script>

add_action('wp_footer', 'add_google_analytics');

Just be sure to replace UA-XXXXXXX-X with your own Google tracking code...

  • thanks for the share. I have been using this one as well but I would be curious to know if you are aware how this can be modified so that specific tags, post type pages or even posts themself can be passed additional values automatically making use of the campaign tracking var capabilities google provides. Additionally, what would need to be added if we wanted to add this to the footer of all admin pages to track admin activity? Sep 17, 2010 at 6:53
  • 1
    Not sure about adding campaign tracking variables only because I haven't had a need for that yet. But to add the same scripts to admin pages, you'd just use add_action('admin_footer', 'add_google_analytics'); to hook on to the footer of admin pages.
    – EAMann
    Sep 17, 2010 at 13:08

Resize large image on upload

Image will be resize according to the large size in your media settings.

/**resize on upload to the largest size in media setting */

function replace_uploaded_image($image_data) {
// if there is no large image : return
if (!isset($image_data['sizes']['large'])) return $image_data;

// path to the uploaded image and the large image
$upload_dir = wp_upload_dir();
$uploaded_image_location = $upload_dir['basedir'] . '/' .$image_data['file'];
$large_image_location = $upload_dir['path'] . '/'.$image_data['sizes']['large']['file'];

// delete the uploaded image

// rename the large image

// update image metadata and return them
$image_data['width'] = $image_data['sizes']['large']['width'];
$image_data['height'] = $image_data['sizes']['large']['height'];

return $image_data;
  • Does this mean that the original large file uploaded is actually replaced? My php is not great, but the answer seems to be yes?
    – davemac
    Feb 20, 2011 at 1:26
  • @davemac I realise this is very old now, but from what I understand of the code, the original image file is resized to the same dimensions as the 'large' image size set in the WordPress settings screen. Which is great but then you just end up with 2 images of the same size. I'd suggest manually setting the values to make the original image only as big as the largest file you will ever realistically use on your site. Then you have an almost original image to work with in future. Nov 25, 2016 at 19:22

Use figure and figcaption for captions

Tested on: WordPress 3.1.3

(Credits to WP Engineer: http://wpengineer.com/917/filter-caption-shortcode-in-wordpress/)

function mytheme_caption( $attr, $content = null ) {
    $output = apply_filters( 'img_caption_shortcode', '', $attr, $content );
    if ( $output != '' )
        return $output;

    extract( shortcode_atts ( array(
    'id' => '',
    'align' => 'alignnone',
    'width'=> '',
    'caption' => ''
    ), $attr ) );

    if ( 1 > (int) $width || empty( $caption ) )
        return $content;

    if ( $id ) $id = 'id="' . $id . '" ';

    return '<figure ' . $id . 'class="wp-caption ' . $align . '" style="width: ' . $width . 'px">'
. do_shortcode( $content ) . '<figcaption class="wp-caption-text">' . $caption . '</figcaption></figure>';

add_shortcode( 'wp_caption', 'mytheme_caption' );
add_shortcode( 'caption', 'mytheme_caption' );

List all constants for information and debugging

Tested on: Wordpress 3.0.1

Will only display the information if you are a logged in user

if ( is_user_logged_in() ) {
    print_r( @get_defined_constants() );

Here is version with optional filter that will partially match constant names and values:

function constants($filter = false) {

        $constants = get_defined_constants();

        if( $filter ) {

            $temp = array();

            foreach ( $constants as $key => $constant )
                if( false !== stripos( $key, $filter ) || false !== stripos( $constant, $filter ) )
                    $temp[$key] = $constant;

            $constants = $temp;

        ksort( $constants );
        var_dump( $constants );

Here are some nice shortcodes for you to use:

1. Easy-to-add Twitter and Facebook share button shortcode

function shreplz() {
   return '
    <div class="sharebox">
    <div class="twittme"><a href="https://twitter.com/share" class="twitter-share-button" data-count="horizontal">Tweet</a><script type="text/javascript" src="//platform.twitter.com/widgets.js"></script></div>
    <div class="shareface"><a name="fb_share"></a> <script src="http://static.ak.fbcdn.net/connect.php/js/FB.Share" type="text/javascript"></script></div>
    <br style="clear: left;" />
add_shortcode('sharethis', 'shreplz');
// How to use: [sharethis]

2. Easy remote site snapshot using WordPress API shortcode

function wpr_snap($atts, $content = null) {
            "snap" => 'http://s.wordpress.com/mshots/v1/',
            "url" => 'http://www.sagive.co.il',
            "alt" => 'My image',
            "w" => '400', // width
            "h" => '300' // height
        ), $atts));

    $img = '<img src="' . $snap . '' . urlencode($url) . '?w=' . $w . '&h=' . $h . '" alt="' . $alt . '"/>';
        return $img;

add_shortcode("snap", "wpr_snap");
// How to use: [snap url="http://www.example.com" alt="Cool Site!" w="300px" h="200px"]

3. Easy to use & embed iFrame shortcode

function GenerateIframe( $atts ) {
    extract( shortcode_atts( array(
        'href' => 'http://the-url',
        'height' => '550px',
        'width' => '600px',
    ), $atts ) );

    return '<iframe src="'.$href.'" width="'.$width.'" height="'.$height.'"> <p>Your Browser does not support Iframes.</p></iframe>';
add_shortcode('iframe', 'GenerateIframe');
// How to use: [iframe href="http://www.exmaple.com" height="480" width="640"]

4. Easy-to-include remote file / doc with shortcode

function getfile_content( $atts ) {
  extract( shortcode_atts( array(
    'fileurl' => ''
  ), $atts ) );

  if ($fileurl!='')
    return @file_get_contents($fileurl);

add_shortcode( 'getfile', 'getfile_content' );
// How to use: [getfile fileurl="http://www.exmaple.com/somepage.html"]

. Here are some comments related snippets:

1. Close the ability to comment globally

function closeCommentsGlobaly($data) { return false; }
add_filter('comments_number', 'closeCommentsGlobaly');
add_filter('comments_open', 'closeCommentsGlobaly');

2. Give the administrator a different CSS class for the administrator's comments

if (1 == $comment->user_id)
    echo 'siteadmin'; // Pick your class here

3. A really cool rich with a data list of comments - gr8 for custom locked page

$comments = get_comments( array(
    'number'    => 10, // How many comments
    'status'    => 'approve' // Type of comments
) );

foreach($comments as $eachComment){

    // Collect the data and assign it
    $commentID = comment_ID;
    $commentAuthorEmail = $eachComment->comment_author_email;
    $commentPostId = $eachComment->comment_post_ID;
    $commentPostTitle = get_the_title( $commentPostId );
    $commentPostUrl = get_permalink( $commentPostId );
    $comment_sidebarnumber = get_comments_number( $commentPostId );

    global $wpdb;
    $userCommentCount = $wpdb->get_var('SELECT COUNT('.$commentID.') FROM ' . $wpdb->comments. ' WHERE comment_author_email = "' . $commentAuthorEmail . '"');

    echo '<div style="border: 1px solid #ccc; padding: 10px;">';
    echo '<ul style="margin: 0px;">';
    echo '<li>Name: '. $eachComment->comment_author .'</li>';
    echo '<li>Commented about: <a href="'.$commentPostUrl.'">'. $commentPostTitle .'</a></li>';
    echo '<li>Commented On: '. $eachComment->comment_date .'</li>';
    echo '<li>Commneter Site: '. $eachComment->comment_author_email .'</</li>';
    echo '<li>Commenter Email: '. $eachComment->comment_author_email .'</</li>';
    echo '<li>This Commenter'. $eachComment->comment_author .' Commented '. $userCommentCount .' on your site</</li>';
    echo '</ul>';
    echo '<p style="padding: 10px;"><strong>'. $eachComment->comment_author .' wrote</strong>: '. $eachComment->comment_content .'</p>';
    echo '</div>';

Conditional to check for hierarchy descendant

A conditional function to check if the current page is a descendant of the ID given to it. Useful for determining if a page is a grandchild, great-grandchild or father down the hierarchy tree.

function is_tree($pid) {      // $pid = The ID of the page we're looking for pages underneath
    global $post;         // load details about this page

    $anc = get_post_ancestors( $post->ID );
    foreach($anc as $ancestor) {
        if(is_page() && $ancestor == $pid) {
            return true;
               return true;   // we're at the page or at a sub page
               return false;  // we're elsewhere
  • I've been looking for this for awhile. Thanks for putting it together! Can I ask for a bit of clarification on use case. Ideally, I would like to use this in my menu listings so that if i have a top level parent menu across the top of the site that only shows Gen 1 elements. When I'm on a Gen 2-3 element, the Gen1 element can be highlighted via a "current-parent" css attribute. Is this possible?
    – Scott B
    Feb 11, 2011 at 5:48

Create a conditional tag for custom taxonomies

In this example, 'student' was a custom post type, and 'stud_cat' was the custom taxonomy. Use has_student(null) for the conditional

    function has_student( $student, $_post = null ) {
    if ( !empty( $student ) )
        return false;
    if ( $_post )
        $_post = get_post( $_post );
        $_post =& $GLOBALS['post'];
    if ( !$_post )
        return false;
    $r = is_object_in_term( $_post->ID, 'studcat', $student );
    if ( is_wp_error( $r ) )
        return false;
    return $r;
  • 2
    I think this gets replaced with has_term() now that 3.1 is released?
    – Rarst
    Feb 25, 2011 at 23:32

Easy WordPress Security Fixes

Security through obscurity is the name of the game here. These functions do three different things.

  1. Remove the version string from the code. No point in telling folks what version we're running.
  2. Removes any error messages (Wrong Password, No Such User, etc.) from admin login screens
  3. When the admin posts a comment, a CSS class is added. This removes the admin name in comments.

    remove_action('wp_head', 'wp_generator');
    //HIDE LOGIN ERROR MESSAGES (Wrong Password, No Such User etc.)
    add_filter('login_errors',create_function('$a', "return null;"));
    // Remove admin name in comments class
    // Source: http://www.wprecipes.com/wordpress-hack-remove-admin-name-in-comments-class
    function remove_comment_author_class( $classes ) {
        foreach( $classes as $key => $class ) {
            if(strstr($class, "comment-author-")) {
                unset( $classes[$key] );
        return $classes;
    add_filter( 'comment_class' , 'remove_comment_author_class' );
  • Removing the Wordpress version number is bad practice. It is much safer to keep your Wordpress updated with the latest security fixes AT ALL TIMES. Added bonus: wanna-be script kiddies will move along to older versions.
    – knutole
    Jan 12, 2014 at 16:30
  • 2
    @knotole, it is not bad practice. It is your opinion... albeit this is pretty standard.
    – Jeremy
    Oct 20, 2014 at 20:13

Replace Default Gravatar with Custom Image

All you'll need to customize is the path to your default image.

function custom_gravatar($avatar_defaults) {
    $logo = get_bloginfo('template_directory') . '/images/icons/gravatar_logo.jpg'; //Change to whatever path you like.
    $avatar_defaults[$logo] = get_bloginfo('name');
    return $avatar_defaults;
add_filter( 'avatar_defaults', 'custom_gravatar' );

Automatically create a new page upon activating a theme

if (isset($_GET['activated']) && is_admin()){
    $new_page_title = 'This is the page title';
    $new_page_content = 'This is the page content';
    $new_page_template = ''; //ex. template-custom.php. Leave blank if you don't want a custom page template.

//don't edit under this line
$page_check = get_page_by_title($new_page_title);
$new_page = array(
    'post_type' => 'page',
    'post_title' => $new_page_title,
    'post_content' => $new_page_content,
    'post_status' => 'publish',
    'post_author' => 1,
    $new_page_id = wp_insert_post($new_page);
        update_post_meta($new_page_id,'_wp_page_template', $new_page_template);

Exclude child categories of a specific category.

Pretty straight forward, but I couldn't find anyone doing exactly what I needed. Also it will display the post if the parent category is selected, except if that post has a child category of that parent selected.

   /* this code excludes all of the children of (category id = 20) posts
       on the HOME page, but allows parent (category id = 20) to be shown. */

    function exclude_category_children($query) {
        $child_cats = (array) get_term_children('20', 'category');
        if ( $query->is_home ) {
        $query->set('category__not_in', $child_cats);
        return $query;
    add_filter('pre_get_posts', 'exclude_category_children');

Make WordPress Editor Allow iFrames

// make TinyMCE allow iframes
add_filter('tiny_mce_before_init', create_function( '$a',
'$a["extended_valid_elements"] = "iframe[id|class|title|style|align|frameborder|height|longdesc|marginheight|marginwidth|name|scrolling|src|width]"; return $a;') );

Auto Clean SEO Slugs without removing functionality

Tested on: Wordpress 3.0.1

By adding this code to your functions.php file wordpress will automatically clean up the slug URL title by removing all unnecessary words. I have also extended the capabilities with additional customizations which hide the screen option for slug as well as the metabox. By including the code below any new post you create will automatically get shortened and you will still have the ability to manually edit the slug by clicking on the url under the post title and saving the post.

   add_filter('name_save_pre', 'seo_slugs', 0);
   function seo_slugs($slug) {
    // We don't want to change an existing slug
 if ($slug) return $slug;
 global $wpdb;
 $seo_slug = strtolower(stripslashes($_POST['post_title']));
 $seo_slug = preg_replace('/&.+?;/', '', $seo_slug); // kill HTML entities
    // kill anything that is not a letter, digit, space or apostrophe
 $seo_slug = preg_replace ("/[^a-zA-Z0-9 \']/", "", $seo_slug);
    // Turn it to an array and strip common words by comparing against c.w. array
 $seo_slug_array = array_diff (split(" ", $seo_slug), seo_slugs_stop_words());
    // Turn the sanitized array into a string
 $seo_slug = join("-", $seo_slug_array);
 return $seo_slug;
   function seo_slugs_stop_words () {
   return array ("a", "able", "about", "above", "abroad", "according", "accordingly", "across", "actually", "adj", "after", "afterwards", "again", "against", "ago", "ahead", "ain't", "all", "allow", "allows", "almost", "alone", "along", "alongside", "already", "also", "although", "always", "am", "amid", "amidst", "among", "amongst", "an", "and", "another", "any", "anybody", "anyhow", "anyone", "anything", "anyway", "anyways", "anywhere", "apart", "appear", "appreciate", "appropriate", "are", "aren't", "around", "as", "a's", "aside", "ask", "asking", "associated", "at", "available", "away", "awfully", "b", "back", "backward", "backwards", "be", "became", "because", "become", "becomes", "becoming", "been", "before", "beforehand", "begin", "behind", "being", "believe", "below", "beside", "besides", "best", "better", "between", "beyond", "both", "brief", "but", "by", "c", "came", "can", "cannot", "cant", "can't", "caption", "cause", "causes", "certain", "certainly", "changes", "clearly", "c'mon", "co", "co.", "com", "come", "comes", "concerning", "consequently", "consider", "considering", "contain", "containing", "contains", "corresponding", "could", "couldn't", "course", "c's", "currently", "d", "dare", "daren't", "definitely", "described", "despite", "did", "didn't", "different", "directly", "do", "does", "doesn't", "doing", "done", "don't", "down", "downwards", "during", "e", "each", "edu", "eg", "eight", "eighty", "either", "else", "elsewhere", "end", "ending", "enough", "entirely", "especially", "et", "etc", "even", "ever", "evermore", "every", "everybody", "everyone", "everything", "everywhere", "ex", "exactly", "example", "except", "f", "fairly", "far", "farther", "few", "fewer", "fifth", "first", "five", "followed", "following", "follows", "for", "forever", "former", "formerly", "forth", "forward", "found", "four", "from", "further", "furthermore", "g", "get", "gets", "getting", "given", "gives", "go", "goes", "going", "gone", "got", "gotten", "greetings", "h", "had", "hadn't", "half", "happens", "hardly", "has", "hasn't", "have", "haven't", "having", "he", "he'd", "he'll", "hello", "help", "hence", "her", "here", "hereafter", "hereby", "herein", "here's", "hereupon", "hers", "herself", "he's", "hi", "him", "himself", "his", "hither", "hopefully", "how", "howbeit", "however", "hundred", "i", "i'd", "ie", "if", "ignored", "i'll", "i'm", "immediate", "in", "inasmuch", "inc", "inc.", "indeed", "indicate", "indicated", "indicates", "inner", "inside", "insofar", "instead", "into", "inward", "is", "isn't", "it", "it'd", "it'll", "its", "it's", "itself", "i've", "j", "just", "k", "keep", "keeps", "kept", "know", "known", "knows", "l", "last", "lately", "later", "latter", "latterly", "least", "less", "lest", "let", "let's", "like", "liked", "likely", "likewise", "little", "look", "looking", "looks", "low", "lower", "ltd", "m", "made", "mainly", "make", "makes", "many", "may", "maybe", "mayn't", "me", "mean", "meantime", "meanwhile", "merely", "might", "mightn't", "mine", "minus", "miss", "more", "moreover", "most", "mostly", "mr", "mrs", "much", "must", "mustn't", "my", "myself", "n", "name", "namely", "nd", "near", "nearly", "necessary", "need", "needn't", "needs", "neither", "never", "neverf", "neverless", "nevertheless", "new", "next", "nine", "ninety", "no", "nobody", "non", "none", "nonetheless", "noone", "no-one", "nor", "normally", "not", "nothing", "notwithstanding", "novel", "now", "nowhere", "o", "obviously", "of", "off", "often", "oh", "ok", "okay", "old", "on", "once", "one", "ones", "one's", "only", "onto", "opposite", "or", "other", "others", "otherwise", "ought", "oughtn't", "our", "ours", "ourselves", "out", "outside", "over", "overall", "own", "p", "particular", "particularly", "past", "per", "perhaps", "placed", "please", "plus", "possible", "presumably", "probably", "provided", "provides", "q", "que", "quite", "qv", "r", "rather", "rd", "re", "really", "reasonably", "recent", "recently", "regarding", "regardless", "regards", "relatively", "respectively", "right", "round", "s", "said", "same", "saw", "say", "saying", "says", "second", "secondly", "see", "seeing", "seem", "seemed", "seeming", "seems", "seen", "self", "selves", "sensible", "sent", "serious", "seriously", "seven", "several", "shall", "shan't", "she", "she'd", "she'll", "she's", "should", "shouldn't", "since", "six", "so", "some", "somebody", "someday", "somehow", "someone", "something", "sometime", "sometimes", "somewhat", "somewhere", "soon", "sorry", "specified", "specify", "specifying", "still", "sub", "such", "sup", "sure", "t", "take", "taken", "taking", "tell", "tends", "th", "than", "thank", "thanks", "thanx", "that", "that'll", "thats", "that's", "that've", "the", "their", "theirs", "them", "themselves", "then", "thence", "there", "thereafter", "thereby", "there'd", "therefore", "therein", "there'll", "there're", "theres", "there's", "thereupon", "there've", "these", "they", "they'd", "they'll", "they're", "they've", "thing", "things", "think", "third", "thirty", "this", "thorough", "thoroughly", "those", "though", "three", "through", "throughout", "thru", "thus", "till", "to", "together", "too", "took", "toward", "towards", "tried", "tries", "truly", "try", "trying", "t's", "twice", "two", "u", "un", "under", "underneath", "undoing", "unfortunately", "unless", "unlike", "unlikely", "until", "unto", "up", "upon", "upwards", "us", "use", "used", "useful", "uses", "using", "usually", "v", "value", "various", "versus", "very", "via", "viz", "vs", "w", "want", "wants", "was", "wasn't", "way", "we", "we'd", "welcome", "well", "we'll", "went", "were", "we're", "weren't", "we've", "what", "whatever", "what'll", "what's", "what've", "when", "whence", "whenever", "where", "whereafter", "whereas", "whereby", "wherein", "where's", "whereupon", "wherever", "whether", "which", "whichever", "while", "whilst", "whither", "who", "who'd", "whoever", "whole", "who'll", "whom", "whomever", "who's", "whose", "why", "will", "willing", "wish", "with", "within", "without", "wonder", "won't", "would", "wouldn't", "x", "y", "yes", "yet", "you", "you'd", "you'll", "your", "you're", "yours", "yourself", "yourselves", "you've", "z", "zero");

When adding the additional code below to your functions.php file it will remove/hide the slug option for the screen options dropdown as well as the metabox.

   function hide_slug_options() {
 global $post;
 global $pagenow;
 $hide_slugs = "<style type=\"text/css\">#slugdiv, #edit-slug-box, [for=\"slugdiv-hide\"] { display: none; }</style>\n";
 if (is_admin() && $pagenow=='post-new.php' OR $pagenow=='post.php') print($hide_slugs);
   add_action( 'admin_head', 'hide_slug_options'  );

List all SubCategories

Tested on: Wordpress 3.0.1

$echo = '<ul>' . "\n";
$childcats = get_categories('child_of=' . $cat . '&hide_empty=1');
foreach ($childcats as $childcat) {
    if (1 == $childcat->category_parent) {
        $echo .= "\t" . '<li><a href="' . get_category_link($childcat->cat_ID).'" title="' . $childcat->category_description . '">';
        $echo .= $childcat->cat_name . '</a>';
        $echo .= '</li>' . "\n";
$echo .= '</ul>' . "\n";
echo $echo;

also here, more informations and functins in the post http://wpengineer.com/2025/list-all-subcategories/


Remove Admin Backend Menus for all users, except User #1 (usually the first Admin)

/*  Restrict access
function remove_menus () {
global $menu;
$user = wp_get_current_user();
    if ($user->ID!=1) { // Is not administrator,

        $restricted = array(__('Dashboard'), __('Posts'), __('Media'), __('Links'), __('Pages'), __('Appearance'), __('Tools'), __('Users'), __('Settings'), __('Comments'), __('Plugins'));
        end ($menu);
        while (prev($menu)){
            $value = explode(' ',$menu[key($menu)][0]);
            if(in_array($value[0] != NULL?$value[0]:"" , $restricted)){unset($menu[key($menu)]);}
add_action('admin_menu', 'remove_menus');
  • User 1 may be the first admin. But after adding new administrators the first one may be just a regular user. Ask for capabilities, not for numbers. Plus, this code belongs into a plugin, not in the functions.php. There is zero relation to the theme.
    – fuxia
    Jun 13, 2011 at 11:55
  • This way you can allow all admins to act as normal but at the same time hide the first admin and reserve it to system administrator / support team. I disagree that this code belongs to a plugin. Functions.php is a plugin. This file basically acts like a plugin Theme_Development#Functions_File Jun 13, 2011 at 12:12
  • But the functions.php contains logic which is tied to the theme, because if you switch themes the whole code is gone. So, unless the code depends on the theme and vice versa – do not use the functions.php as a mu-plugin.
    – fuxia
    Jun 13, 2011 at 13:00
  • Yes. But let's consider this: You are developing a website for a client. This website will always use only one theme, the one designed by the designer. The theme is the website. You add custom post types, metaboxes, load additional functions, etc. Now you do want to give some users the admin capabilities, but you want to hide some sections of the site that your client will never use or confuse them (Links, Tools, Comments, are the best examples) and to give the support team a sort of "SuperAdmin" so they can see the whole admin area. Jun 13, 2011 at 13:24
  • 2
    If you look at the linked plugin, then it allows you to set access groups per "whatever a user offers (login name, role, ID)". Relying on IDs generally is a "not best practice" concept. That's all i wanted to point out.
    – kaiser
    Jun 13, 2011 at 14:32

Disable browser upgrade warning in wordpress 3.2

enter image description here

//Disable browser upgrade warning in wordpress 3.2
function disable_browser_upgrade_warning() {
    remove_meta_box( 'dashboard_browser_nag', 'dashboard', 'normal' );
add_action( 'wp_dashboard_setup', 'disable_browser_upgrade_warning' );
  • Pure plugin material.
    – fuxia
    Aug 19, 2011 at 16:51
  • @toscho So what? Still its working. Isn't it? Aug 19, 2011 at 16:55
  • 4
    Not after switching themes. Themes are for frontends.
    – fuxia
    Aug 19, 2011 at 17:29

Show template files being included

Display inline comment with Template File and get_template_part files being included when rendering pages. Handy for troubleshooting multipart templates.

function template_snoop(){
    $args = func_get_args();
    if( !is_admin() and $args[0] ){
        if( $args[0] == 'template_include' ) {
            echo "<!-- Base Template: {$args[1]} -->\n";
        } elseif( strpos($args[0],'get_template_part_') === 0 ) {
            global $last_template_snoop;
            if( $last_template_snoop )
                echo "\n\n<!-- End Template Part: {$last_template_snoop} -->";
            $tpl = rtrim(join('-',  array_slice($args,1)),'-').'.php';
            echo "\n<!-- Template Part: {$tpl} -->\n\n";
            $last_template_snoop = $tpl;

is_tree() conditional Function

/* Adapted from csstricks with addition of
ancestors .... use = if(is_tree($id)) { // do stuff } ... Returns true if the
page is  = $id OR any of it's children OR descendants */

function is_tree($pid) {      // $pid = The ID of the page we're looking for pages underneath
  global $post;         // load details about this page
  $ancestors = get_post_ancestors($post);
    return true;   // we're at the page or at a sub page
    return false;  // we're elsewhere 

Display the users that have submitted the most comments without a plugin

function top_comment_authors($amount = 5) {
global $wpdb;
$results = $wpdb->get_results('
    COUNT(comment_author_email) AS comments_count, comment_author_email, comment_author, comment_author_url
    FROM '.$wpdb->comments.'
    WHERE comment_author_email != "" AND comment_type = "" AND comment_approved = 1
    GROUP BY comment_author_email
    ORDER BY comments_count DESC, comment_author ASC
    LIMIT '.$amount
$output = "<ul>";
foreach($results as $result) {
    $output .= "<li>".$result->comment_author."</li>";
$output .= "</ul>";
echo $output;

Other options you can call: $result->comment_author_email $result->comments_count $result->comment_author_url


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;

Get the Users Real IP Address whenever possible

Tested on: Wordpress 3.0.1

If you're using a proxy or load balancer, adding this to your wp-config.php file or functions.php

// Gets the user's real IP address

$_SERVER['REMOTE_ADDR'] = getRealIpAddress();
function getRealIpAddress( $validate = true ) {
    if ( isset($_SERVER['HTTP_X_FORWARDED_FOR']) && !empty($_SERVER['HTTP_X_FORWARDED_FOR']) ) {
        $ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        $ip = trim($ips[count($ips) - 1]);
    } elseif ( isset($_SERVER['HTTP_X_REAL_IP']) && !empty($_SERVER['HTTP_X_REAL_IP']) ) {
        $ip = $_SERVER['HTTP_X_REAL_IP'];
    } elseif ( isset($_SERVER['HTTP_CLIENT_IP']) && !empty($_SERVER['HTTP_CLIENT_IP']) ) {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    } else {
        $ip = $_SERVER['REMOTE_ADDR'];
    if ( $validate && function_exists('filter_var') &&  filter_var($ip, FILTER_VALIDATE_IP, array('flags' => FILTER_FLAG_IPV4, FILTER_FLAG_NO_PRIV_RANGE, FILTER_FLAG_NO_RES_RANGE)) )
        return $ip;
    elseif ( $validate )
        return long2ip(ip2long($ip));

    return $ip;
  • 1
    what does this do exactly? Sep 14, 2010 at 2:21
  • When a user is behind a proxy or load balancer, then anything that grabs that user's IP address using the superglobal $_SERVER['REMOTE_ADDR'] will see the proxy or load balancer's IP address. The proxy/lb in return puts the user's original IP address in the X-Forwarded-For X-Real-Ip, or Client-Ip headers (depending on the proxy/lb configuration). Thus, when commenting (or posting, but that's less relevant) WP will see a lot of users coming from the same IP address. This fixes that by replacing $_SERVER['REMOTE_ADDR'] with the original IP.
    – gabrielk
    Sep 19, 2010 at 18:02
  • Those are easy to trick by adding the HTTP_X_FORWARDED_FOR header manually into each browser request. My favorite is to set it which will then set $_SERVER['REMOVE_ADDR'] to an empty value with that example.
    – hakre
    Nov 5, 2010 at 21:41

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' );

Adds a custom dropdown option to WP_NAV_MENUS where the user can select a predefined css class for each menu item

<?php function menu_item_class_select(){
    global $pagenow;
    if ($pagenow == "nav-menus.php"){

    function create_dd(v){
        //create dropdown
        var dd = jQuery('<select class="my_class"></select>');
        //create dropdown options
        //array with the options you want
        var classes = ["","class1","class2","class3"];
        jQuery.each(classes, function(i,val) {
            if (v == val){
                dd.append('<option value="'+val+'" selected="selected">'+val+'</option>');
                dd.append('<option value="'+val+'">'+val+'</option>');
        return dd;
    jQuery(".edit-menu-item-classes").each(function() {
        //add dropdown
        var t = create_dd(jQuery(this).val());
        //hide all inputs
    //update input on selection
    jQuery(".my_class").bind("change", function() {
        var v = jQuery(this).val();
        var inp = jQuery(this).next();

<?php } }

source: https://wordpress.stackexchange.com/a/33816/479


Remove WordPress 3.3 Admin Bar Menu Items

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

Reference: http://pastebin.com/Wrk0JPxw


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'); ?>

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