WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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
@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. – toscho Feb 22 '12 at 2:44
@NetConstructor.com Discuss it on Meta where people can see your arguments better. :) – toscho Feb 24 '12 at 17:10

108 Answers 108

Make your Shortlinks Shorter by Removing WWW

Tested on: Wordpress 3.0.1

Make your shortlinks shorter if you include www. in your domain. Via scratch99.com:

function sjc_alter_shortlink($shortlink) {
    $shortlink = preg_replace('/^(https?:\/\/)?(www\.)/','$1',$shortlink);
    return $shortlink;
share|improve this answer
A check should be added to make sure the string "www." is only removed if it is found at the very beginning of the domain part of the original URL. Naively replacing it anywhere in the URL will lead to bugs if it had been used on a domain like owww.com (which actually appears to be running WordPress) :) – Ingve May 28 '12 at 21:30
@Ingve I fixed it, now it will remove only the initial www – bfred.it Jan 11 '14 at 1:04

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
share|improve this answer
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 '11 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;
share|improve this answer
I think this gets replaced with has_term() now that 3.1 is released? – Rarst Feb 25 '11 at 23:32

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

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

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');
share|improve this answer
You'd not want to run that code on every page load however. – t31os Dec 21 '10 at 20:27
Yeah, flushing roles on every load saves you a lot of sellers. :) Better use the plugin Edit Author Slug. – toscho Dec 22 '10 at 3:21
I have update the function!!! Thanks for your input:) – Philip Jan 12 '11 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' );
share|improve this answer
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 '11 at 2:03
Isn't this already covered by core & editor styles? – kaiser Feb 1 '11 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 – manifestphil Sep 13 '11 at 20:42

Add auto-update/plugin-installer on you localhost

define ('FS_METHOD', 'direct');

Put this in your wp-config.php.

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

Enable Numeric Pagination

Tested on: Wordpress 3.0.1

/* Numeric Pagination ********************************************/

function numeric_pagination ($pageCount = 9, $query = null) {

 if ($query == null) {
  global $wp_query;
  $query = $wp_query;

 if ($query->max_num_pages <= 1) {

 $pageStart = 1;
 $paged = $query->query_vars['paged'];

 // set current page if on the first page
 if ($paged == null) {
  $paged = 1;

 // work out if page start is halfway through the current visible pages and if so move it accordingly
 if ($paged > floor($pageCount / 2)) {
  $pageStart = $paged - floor($pageCount / 2);

 if ($pageStart < 1) {
  $pageStart = 1;

 // make sure page start is
 if ($pageStart + $pageCount > $query->max_num_pages) {
  $pageCount = $query->max_num_pages - $pageStart;

 <div id="archive_pagination">
 if ($paged != 1) {
 <a href="<?php echo get_pagenum_link(1); ?>" class="numbered page-number-first"><span>&lsaquo; <?php _e('<< First', 'global'); ?></span></a>
 // first page is not visible...
 if ($pageStart > 1) {
  //echo 'previous';
 for ($p = $pageStart; $p <= $pageStart + $pageCount; $p ++) {
  if ($p == $paged) {
  <span class="numbered page-number-<?php echo $p; ?> current-numeric-page"><?php echo $p; ?></span>
<?php } else { ?>
  <a href="<?php echo get_pagenum_link($p); ?>" class="numbered page-number-<?php echo $p; ?>"><span><?php echo $p; ?></span></a>

 // last page is not visible
 if ($pageStart + $pageCount < $query->max_num_pages) {
  //echo "last";
 if ($paged != $query->max_num_pages) {
  <a href="<?php echo get_pagenum_link($query->max_num_pages); ?>" class="numbered page-number-last"><span><?php _e('>> Last', 'global'); ?> &rsaquo;</span></a>
<?php } ?>

share|improve this answer
There's a function in WordPress for doing numeric pagination already, see codex.wordpress.org/Function_Reference/paginate_links – t31os Nov 11 '10 at 17:09

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...

share|improve this answer
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? – NetConstructor.com Sep 17 '10 at 6:53
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 '10 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;
share|improve this answer
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 '11 at 1:26

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' );
share|improve this answer
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 '14 at 16:30
@knotole, it is not bad practice. It is your opinion... albeit this is pretty standard. – Jeremy Oct 20 '14 at 20:13

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

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

Here are some nice shortcodes for you to use:

1. Easy to add twitter & 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 globaly

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

2. Give admin a different Css Class for he's comments

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

3. a really cool rich with 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>';

share|improve this answer

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

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

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

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

share|improve this answer

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

Automatically adding header images from directory location

Within the default them which comes with wordpress you will notice an additional theme menu which gets activated that lets you select a header image to be utilized. Within the default theme code these images are hardcoded into the functions.php file. The code below allows wordpress to automatically pick up new images based upon a specific header image directly you can create on your server (or within your themes folder).

It will automatically include any .jpg or .jpeg files. Every image must have a associating thumbnail file but this can just be a copy of the original with a different name with a file name that has to end in "-thumbnail". The associating name is used as the description in the headers appearance settings and underscores are automatically replaced with spaces. (e.g. My_Header_Image_A.jpg, My_Header_Image_A=thumbnail.jpg will have a description automatically presented a “My Header Image A”)

if ($handle = opendir( TEMPLATEPATH . '/images/headers/') ) {
    $headers = array();
    while (false !== ($file = readdir($handle))) {
        $pos = strrpos( $file, '.' );
        if( $pos !== false && $pos > 0 ) {
            $file_name = substr( $file, 0, $pos );
            if( strpos( $file_name, "-thumbnail" ) === false ) {
                $file_ext = substr( $file, $pos+1 );
                $file_ext_low = strtolower( $file_ext );
                if( $file_ext_low == "jpg" || $file_ext_low == "jpeg" ) {
                    $headers[$file_name] = array (
                    'url' => '%s/images/headers/' . $file,
                    'thumbnail_url' => '%s/images/headers/' . $file_name ."-thumbnail." . $file_ext,
                    'description' => __( str_replace( "_", " ", $file_name ), 'twentyten' )
register_default_headers( $headers );
share|improve this answer

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

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');
share|improve this answer
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. – toscho Jun 13 '11 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 – Daniel Sachs Jun 13 '11 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. – toscho Jun 13 '11 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. – Daniel Sachs Jun 13 '11 at 13:24
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 '11 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' );
share|improve this answer
Pure plugin material. – toscho Aug 19 '11 at 16:51
@toscho So what? Still its working. Isn't it? – Giri Aug 19 '11 at 16:55
Not after switching themes. Themes are for frontends. – toscho Aug 19 '11 at 17:29

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: http://wordpress.stackexchange.com/a/33816/479

share|improve this answer

Displaying information for logged in users

if ( is_user_logged_in() ) {


is not working in functions.php file. You can use this code:

if ( !function_exists('is_user_logged_in') ) :

 function is_user_logged_in() {
$user = wp_get_current_user();

if ( $user->id == 0 ){
// This section if user is not logged in
} else {
// This section if user is logged in
share|improve this answer
if( !current_user_can('read') ) should catch guests (ie. non-logged in users) .. – t31os Dec 7 '10 at 10:19
I just tested it and is_user_logged_in() seems to work just fine in functions.php?.. Any background info on why it's not supposed to? – Rarst Jan 26 '11 at 13:48

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;
share|improve this answer
what does this do exactly? – NetConstructor.com Sep 14 '10 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 '10 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 '10 at 21:41

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/

share|improve this answer
Why would you do this when there's a function available specifically for displaying a list of categories..See: codex.wordpress.org/Template_Tags/… – t31os Nov 11 '10 at 17:06

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);
share|improve this answer
Again: user 1 may be a non-admin. See Roles and Capabilities. – toscho 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) – Daniel Sachs 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. – toscho 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. – Daniel Sachs 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
share|improve this answer

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