Find a widget’s current sidebar context

I recently was programming a widget for WordPress that needed to communicate with another widget if it was at a lower priority in the same sidebar. I came up with these nifty little functions to find the current context and sibling widgets of the current widget. You can add this to your functions.php.

function get_current_sidebar($widget_id) {

    $active_sidebars = wp_get_sidebars_widgets();
    $current_sidebar = false;
    
    foreach($active_sidebars as $key => $sidebar)
        if(array_search($widget_id, $sidebar))
            $current_sidebar = $key;    
    
    return $current_sidebar;
}

function get_current_sidebar_widgets($sidebar_id){

    $active_sidebars = wp_get_sidebars_widgets();
    $current_sidebar_widgets = $active_sidebars[$sidebar_id];

    return $current_sidebar_widgets;
}

Add this method to your widget object:

protected function has_widget_siblings(){

    $widget_id = $this->id_base.'-'.$this->number;
    $current_sidebar = get_current_sidebar($widget_id);
    $current_sidebar_widgets = get_current_sidebar_widgets($current_sidebar);
    
    $current_widget_identified = false;
    $current_widget_siblings = false;
    
    foreach($current_sidebar_widgets as $key => $widget){
        if(preg_match("/{$widget_id}/", $widget)){
            $current_widget_identified = true;
        }
        elseif(preg_match("/{$this->id_base}/", $widget)){
            if($current_widget_identified)
                $current_widget_siblings = true;
                return $current_widget_siblings;
        }
    }
}

Read my post about passing data between classes to have your widget communicate with a sibling widget.

WordPress – Search only posts or pages

One annoyance I have with WordPress default searching is that it searches everything and gives no context to the search results. At times you may want to search specifically for pages in a corporate site and other times in the context of a blog, search specifically for posts.

It’s simple to accomplish this by adding a hidden input field in your form tag.

<?php if(is_page()):?>
    <input type="hidden" name="post_type" value="page" />
<?php elseif(is_archive()):?>
    <input type="hidden" name="post_type" value="post" />
<?php endif;?>

You can also use radio buttons to allow your users to decide what results are returned:

<form method="get" action="<?php echo home_url();?>">
    <input type="text" name="s" />
    <label>Search Pages</label>
    <input type="radio" name="post_type" value="page" />
    <label>Search Posts</label>
    <input type="radio" name="post_type" value="post" />
    <button type="submit">Submit</button>
</form>

This works dandy. See my post on Stack Exchange about this topic.

WordPress Login Movable Type Skin

Since there’s still quite a few hold-outs on the Movable Type platform, I decided to make the transition to WordPress a little more palatable. I created this simple plugin to replace the WordPress admin login form with the Movable Type login form.

It is my deepest hope and desire that this plugin will be a life preserver to those drowning in the sea of Movable Type. For those who refuse to migrate, let this plugin be a bait and switch tactic to show them the light of WordPress and the error of their ways.

Enjoy richly!

Download from github.

In case you missed the tongue-in-cheek tone, this plugin should only be used for a practical joke amongst true nerds. Next time your buddy leaves his computer, install this gem and watch the chaos and confusion ensue.

Add columns to a WordPress taxonomy terms table

At times, you might find it useful to add an extra column in the tags table under Posts->Tags.

Here’s how you can insert columns and add content to each term row. Add this to your theme functions.php file.

function add_post_tag_columns($columns){
    $columns['foo'] = 'Foo';
    return $columns;
}
add_filter('manage_edit-post_tag_columns', 'add_post_tag_columns');

function add_post_tag_column_content($content){
    $content .= "Bar";
    return $content;
}
add_filter('manage_post_tag_custom_column', 'add_post_tag_column_content');

You can also replace ‘post_tag’ with your custom taxonomy slug to make this work anywhere.

Change the default WordPress media MIME icons

I recently helped a someone at Stack Exchange with replacing the MIME icons used to identify the type of file for each media item. I decided to post it here for posterity’s sake. Here’s how you can add a little bit of spice to the WordPress admin panel.

This can be accomplished in three easy steps:

1. Create a directory in your theme that will hold all the new icons /themes/theme-name/images/icons/
2. Copy all the images from /wp-includes/images/crystal/ to your new directory
3. Hook into the wp_mime_type_icon filter in your functions.php file

function change_mime_icon($icon, $mime = null, $post_id = null){
    $icon = str_replace(get_bloginfo('wpurl').'/wp-includes/images/crystal/', WP_CONTENT_URL . '/themes/theme-name/images/icons/', $icon);
    return $icon;
}
add_filter('wp_mime_type_icon', 'change_mime_icon');

To verify this is working, open the media library and browse the media gallery. If you see PHP warnings or errors, somethings has gone awry. If you see the icons displayed, you now have control over the images as they are being pulled from your theme directory.

Be careful not to change the names of the image files as they are called specifically in the core.

Once again, I originally posted this on WordPress Answers hosted by Stack Exchange. This is for those who might assume plagiarizing shenanigans.

jQuery in WordPress – The Good, The Bad, The Ugly

When I was an uber noob with jQuery and WordPress, I struggled to get my scripts to work properly. I looked at dozens of plugins and themes and found a varying number of ways others implemented jQuery. The following is my personal opinion from experience using jQuery and WordPress together.

The Good

jQuery(document).ready(function($){
    $('.something').each(function(){
        $(this).doSomething();
    });
});

I’ve found this to be the most elegant jQuery declaration that does not conflict with the WordPress UI or other plugins. Declare the jQuery function to start and feed the dollar sign parameter so the code inside looks neat and clean.

The Bad

$(function(){
    $('.something').each(function(){
        $(this).doSomething();
    });
});

Since several popular Javascript libraries use the dollar sign as their function name, it’s important to not assume the dollar sign is assigned to the jQuery library. By not declaring the jQuery function outright, you are almost certain to break the WordPress UI.

The Ugly

jQuery(function(){
    jQuery('.something').each(function(){
        jQuery(this).doSomething();
    });
});

Technically, this example is absolutely correct, however it’s not pretty. Who wants to write ‘jQuery’ a thousand times in their script? I prefer to declare the jQuery function once and substitute it with the dollar sign. It makes for a better visual and easier read.

The Acceptable

var $i = jQuery.noConflict();
$i(document).ready(function(){
    $i('.something').each(function(){
        $i(this).doSomething();
    });
});

If you’re really struggling to get jQuery working properly, you can use the jQuery.noConflict() function. I steer away from this method because I only use plugins that won’t cause massive conflicts of this nature. I only use this method when I’m backed in a corner with no other options.

WordPress Post Expiration

Here’s a nifty function I built recently for a project that needed to have real-time post expiration. Place this in your functions.php file. This function assumes you are using a custom field called expiration. If the post expiration field has passed, the post status will be set to draft, thus disabling it from the default WordPress query.

For the post expiration custom field, I created a custom meta box and used the jQuery UI datepicker.

function is_post_expired($post_ID = null){
    
    if(!$post_ID) global $post;
    
    $post_ID = $post_ID ? $post_ID : $post->ID;
    
    //Human Friendly Expiration Date
    $expiration = get_post_meta($post_ID, 'expiration', true);
    
    //Adjust server time for your timezone
    date_default_timezone_set('American/New_York');
    
    $expiration_timestamp = strtotime($expiration);
    $time_left = $expiration_timestamp - time();

    if($time_left < 0):
        if(expire_post($post_ID))
            return true;
    endif;
        
}

function expire_post($post_ID){
    
    $args = array(
        'ID' => $post_ID,
        'post_status' => 'draft'
    );
    if(wp_update_post($args))
        return true;
}

Usage

Simply include the following in the loop.

if(!is_post_expired()):
    //Do something awesome here
else:
    continue;
endif;

Final Thoughts

This function works during the loop iteration. The only caveat is the archive listing at times will not show the defined number of posts to display if a post expires during that loop. (i.e. General Settings -> Reading -> “Blog pages show at most”) The next page load will display the correct amount of posts. You technically could hook this into a WordPress action before the post is rendered to maintain the query integrity.

View on github:gist

Add Thickbox to Your WordPress Theme the Easy Way

If you want to add fancy overlays for images and HTML on the front-end of your template, there’s no reason to use wp_enqueue_script and wp_enqueue_style. All you need in your functions file is:

add_thickbox();

That’s it! Boom, you’re theme just got awesome with one line of code.