Arquivo da tag: theme reviews

Caching any custom query using transients

Caching any custom query using transients

Is your theme using custom queries? If yes, you should definitely use the transients API to cache the queries. The following code shows how to cache a custom query. As you can see, there’s nothing complicated at all.

< ?php // Get any existing copy of our transient data if ( false === ( $special_query_results = get_transient( 'special_query_results' ) ) ) { // It wasn't there, so regenerate the data and save the transient $special_query_results = new WP_Query( 'cat=5&order=random&tag=tech&post_meta_key=thumbnail' ); set_transient( 'special_query_results', $special_query_results ); }// Use the data like you would have normally... ?>

Cached Tag cloud

Cached Tag cloud

Thanks to WordPress transients API, caching almost anything is definitely. The following example shows how to cache the good old tag cloud. Simply paste this code wherever you want you tag cloud to be displayed.

$tag_cloud = get_transient( ‘tag_cloud’ );
if ( false === $tag_cloud || ” === $tag_cloud ){
$args = array(‘echo’ => false);
$tag_cloud = wp_tag_cloud( $args );
set_transient( ‘tag_cloud’, $tag_cloud, 60*60*12 );
}
echo $tag_cloud;

Cached navigation menu

Cached navigation menu

Introduced in WordPress 3.0, the new menu system is definitely an improvement to WordPress. But using transients, we can even do something better, a menu with the same functionality but without the huge database requests.

< ?php /** * Wrapper function around wp_nav_menu() that will cache the wp_nav_menu for all tag/category * pages used in the nav menus * @see http://lookup.hitchhackerguide.com/wp_nav_menu for $args * @author tott */ function hh_cached_nav_menu( $args = array(), $prime_cache = false ) { global $wp_query;$queried_object_id = empty( $wp_query->queried_object_id ) ? 0 : (int) $wp_query->queried_object_id;

// If design of navigation menus differs per queried object use the key below
// $nav_menu_key = md5( serialize( $args ) . ‘-‘ . $queried_object_id );

// Otherwise
$nav_menu_key = md5( serialize( $args ) );

$my_args = wp_parse_args( $args );
$my_args = apply_filters( ‘wp_nav_menu_args’, $my_args );
$my_args = (object) $my_args;

if ( ( isset( $my_args->echo ) && true === $my_args->echo ) || !isset( $my_args->echo ) ) {
$echo = true;
} else {
$echo = false;
}

$skip_cache = false;
$use_cache = ( true === $prime_cache ) ? false : true;

// If design of navigation menus differs per queried object comment out this section
//*
if ( is_singular() ) {
$skip_cache = true;
} else if ( !in_array( $queried_object_id, hh_get_nav_menu_cache_objects( $use_cache ) ) ) {
$skip_cache = true;
}
//*/

if ( true === $skip_cache || true === $prime_cache || false === ( $nav_menu = get_transient( $nav_menu_key ) ) ) {
if ( false === $echo ) {
$nav_menu = wp_nav_menu( $args );
} else {
ob_start();
wp_nav_menu( $args );
$nav_menu = ob_get_clean();
}
if ( false === $skip_cache )
set_transient( $nav_menu_key, $nav_menu );
}
if ( true === $echo )
echo $nav_menu;
else
return $nav_menu;
}

/**
* Invalidate navigation menu when an update occurs
*/
function hh_update_nav_menu_objects( $menu_id = null, $menu_data = null ) {
hh_cached_nav_menu( array( ‘echo’ => false ), $prime_cache = true );
}
add_action( ‘wp_update_nav_menu’, ‘hh_update_nav_menu_objects’ );

/**
* Helper function that returns the object_ids we’d like to cache
*/
function hh_get_nav_menu_cache_objects( $use_cache = true ) {
$object_ids = get_transient( ‘hh_nav_menu_cache_object_ids’ );
if ( true === $use_cache && !empty( $object_ids ) ) {
return $object_ids;
}

$object_ids = $objects = array();

$menus = wp_get_nav_menus();
foreach ( $menus as $menu_maybe ) {
if ( $menu_items = wp_get_nav_menu_items( $menu_maybe->term_id ) ) {
foreach( $menu_items as $menu_item ) {
if ( preg_match( “#.*/category/([^/]+)/?$#”, $menu_item->url, $match ) )
$objects[‘category’][] = $match[1];
if ( preg_match( “#.*/tag/([^/]+)/?$#”, $menu_item->url, $match ) )
$objects[‘post_tag’][] = $match[1];
}
}
}
if ( !empty( $objects ) ) {
foreach( $objects as $taxonomy => $term_names ) {
foreach( $term_names as $term_name ) {
$term = get_term_by( ‘slug’, $term_name, $taxonomy );
if ( $term )
$object_ids[] = $term->term_id;
}
}
}

$object_ids[] = 0; // that’s for the homepage

set_transient( ‘hh_nav_menu_cache_object_ids’, $object_ids );
return $object_ids;
}

RSS subscribers count using WordPress transients

RSS subscribers count using WordPress transients

Using exactly the same technique as demonstrated above, we can grab RSS subscribers and store the result in WordPress database. Don’t forget to update the code with your own feedburner url on line 2. Then, paste the code where you’d like to display how many RSS feed readers you have.

function feed_subscribers(){
$feed_url = ‘http://feeds.feedburner.com/yourname’;
$count = get_transient(‘feed_count’);
if ($count != false) return $count;
$count = 0;
$data = wp_remote_get(‘http://feedburner.google.com/api/awareness/1.0/GetFeedData?uri=’.$feed_url.”);
if (is_wp_error($data)) {
return ‘error’;
}else{
$body = wp_remote_retrieve_body($data);
$xml = new SimpleXMLElement($body);
$status = $xml->attributes();
if ($status == ‘ok’) {
$count = $xml->feed->entry->attributes()->circulation;
} else {
$count = 300; // fallback number
}
}
set_transient(‘feed_count’, $count, 60*60*24); // 24 hour cache
echo $count;
}

Twitter followers count using WordPress transients

Twitter followers count using WordPress transients

Many blogs, including this one, are displaying how many people are following them on Twitter. It’s quite easy to grab some json data, but it takes a significant amount of time. Using transients allow you to grab the json data from Twitter once a day, and store it in your database for future uses.

Simply paste the function below into your functions.php file:

function my_followers_count($screen_name = ‘kovshenin’){
$key = ‘my_followers_count_’ . $screen_name;

// Let’s see if we have a cached version
$followers_count = get_transient($key);
if ($followers_count !== false)
return $followers_count;
else
{
// If there’s no cached version we ask Twitter
$response = wp_remote_get(“http://api.twitter.com/1/users/show.json?screen_name={$screen_name}”);
if (is_wp_error($response))
{
// In case Twitter is down we return the last successful count
return get_option($key);
}
else
{
// If everything’s okay, parse the body and json_decode it
$json = json_decode(wp_remote_retrieve_body($response));
$count = $json->followers_count;

// Store the result in a transient, expires after 1 day
// Also store it as the last successful using update_option
set_transient($key, $count, 60*60*24);
update_option($key, $count);
return $count;
}
}
}

echo “I have ” . my_followers_count(‘kovshenin’) . ” followers”;

List sites from your network

List sites from your network

Let’s start with an interesting snippet for those who run networks of many blogs. The code below display a general menu of all sites from your networks. In this case, transients are used to store the data for a defined time (which can be set using the $expires variable on line 1) so you’ll not make huge database calls each time your menu have to be displayed.

To use this snippet, first you have to paste the function into your functions.php file.

function wp_list_sites( $expires = 7200 ) {
if( !is_multisite() ) return false;

// Because the get_blog_list() function is currently flagged as deprecated
// due to the potential for high consumption of resources, we’ll use
// $wpdb to roll out our own SQL query instead. Because the query can be
// memory-intensive, we’ll store the results using the Transients API
if ( false === ( $site_list = get_transient( ‘multisite_site_list’ ) ) ) {
global $wpdb;
$site_list = $wpdb->get_results( $wpdb->prepare(‘SELECT * FROM wp_blogs ORDER BY blog_id’) );
// Set the Transient cache to expire every two hours
set_site_transient( ‘multisite_site_list’, $site_list, $expires );
}

$current_site_url = get_site_url( get_current_blog_id() );

$html = ‘

    ‘ . “n”;

    foreach ( $site_list as $site ) {
    switch_to_blog( $site->blog_id );
    $class = ( home_url() == $current_site_url ) ? ‘ class=”current-site-item”‘ : ”;
    $html .= “t” . ‘

  • ‘ . get_bloginfo(‘name’) . ‘
  • ‘ . “n”;
    restore_current_blog();
    }

    $html .= ‘

‘ . “nn”;

return $html;
}

Once done, the following code will display all sites from your network. Simply paste it on any of theme files, where you want the list to be displayed.

< ?php // Multisite Network Menu $network_menu = wp_list_sites(); if( $network_menu ): ?>

< ?php echo $network_menu; ?>

< ?php endif; ?>

Remove dashboard widgets according to user role

Remove dashboard widgets according to user role

If you’re owning a multi-user blog, it may be useful to know how to hide some dashboard widgets to keep confidential information in a safe place.
The following code will remove the postcustom meta box for “author” (role 2). To apply the hack on your own blog, just copy the code below and paste it in your functions.php file.

function customize_meta_boxes() {
//retrieve current user info
global $current_user;
get_currentuserinfo();

//if current user level is less than 3, remove the postcustom meta box
if ($current_user->user_level < 3) remove_meta_box('postcustom','post','normal'); }add_action('admin_init','customize_meta_boxes');

Monitor your server in WordPress dashboard

Monitor your server in WordPress dashboard

WordPress dashboard API allow you to do many useful things using dashboard widgets. I recently came across this very useful code: a dashboard widget that allows you to monitor your server directly on WordPress’ dashboard.
Paste the code in your functions.php file, and you’re done.

function slt_PHPErrorsWidget() {
$logfile = ‘/home/path/logs/php-errors.log’; // Enter the server path to your logs file here
$displayErrorsLimit = 100; // The maximum number of errors to display in the widget
$errorLengthLimit = 300; // The maximum number of characters to display for each error
$fileCleared = false;
$userCanClearLog = current_user_can( ‘manage_options’ );
// Clear file?
if ( $userCanClearLog && isset( $_GET[“slt-php-errors”] ) && $_GET[“slt-php-errors”]==”clear” ) {
$handle = fopen( $logfile, “w” );
fclose( $handle );
$fileCleared = true;
}
// Read file
if ( file_exists( $logfile ) ) {
$errors = file( $logfile );
$errors = array_reverse( $errors );
if ( $fileCleared ) echo ‘

File cleared.

‘;
if ( $errors ) {
echo ‘

‘.count( $errors ).’ error’;
if ( $errors != 1 ) echo ‘s’;
echo ‘.’;
if ( $userCanClearLog ) echo ‘ [ CLEAR LOG FILE ]’;
echo ‘

‘;
echo ‘

‘;
echo ‘

    ‘;
    $i = 0;
    foreach ( $errors as $error ) {
    echo ‘

  1. ‘;
    $errorOutput = preg_replace( ‘/[([^]]+)]/’, ‘[$1]‘, $error, 1 );
    if ( strlen( $errorOutput ) > $errorLengthLimit ) {
    echo substr( $errorOutput, 0, $errorLengthLimit ).’ […]’;
    } else {
    echo $errorOutput;
    }
    echo ‘
  2. ‘;
    $i++;
    if ( $i > $displayErrorsLimit ) {
    echo ‘

  3. More than ‘.$displayErrorsLimit.’ errors in log…
  4. ‘;
    break;
    }
    }
    echo ‘

‘;
} else {
echo ‘

No errors currently logged.

‘;
}
} else {
echo ‘

There was a problem reading the error log file.

‘;
}
}

// Add widgets
function slt_dashboardWidgets() {
wp_add_dashboard_widget( ‘slt-php-errors’, ‘PHP errors’, ‘slt_PHPErrorsWidget’ );
}
add_action( ‘wp_dashboard_setup’, ‘slt_dashboardWidgets’ );

Provide help messages

Provide help messages

If you’re building a site for a client and they have some problems with some parts of the dashboard, a good idea is to provide contextual help to the client.
The following hack will allow you to add a custom help messages for the blog admin. As usual, you only have to paste the code into your functions.php file.

function my_admin_help($text, $screen) {
// Check we’re only on my Settings page
if (strcmp($screen, MY_PAGEHOOK) == 0 ) {

$text = ‘Here is some very useful information to help you use this plugin…’;
return $text;
}
// Let the default WP Dashboard help stuff through on other Admin pages
return $text;
}

add_action( ‘contextual_help’, ‘my_admin_help’ );

Change WordPress dashboard colors

Change WordPress dashboard colors

If you ever wanted to be able to change WordPress dashboard colors (as well as font or even display) without having to edit WordPress core files, you’ll like this hack for sure.
The following example features a basic style change (grey header is replaced by a blue one) but you can easily add as many styles as you wish within the

tags.

function custom_colors() {
echo ‘

‘;
}

add_action(‘admin_head’, ‘custom_colors’);

Add custom widgets to WordPress dashboard

Add custom widgets to WordPress dashboard

With the previous example, I showed you how easy it is to remove unwanted dashboard widgets. The good news is that creating your own widgets isn’t hard either.
The well-commented code below should be self explanatory. Just insert it in your functions.php, as usual.

function example_dashboard_widget_function() {
// Display whatever it is you want to show
echo “Hello World, I’m a great Dashboard Widget”;
}

// Create the function use in the action hook
function example_add_dashboard_widgets() {
wp_add_dashboard_widget(‘example_dashboard_widget’, ‘Example Dashboard Widget’, ‘example_dashboard_widget_function’);
}
// Hoook into the ‘wp_dashboard_setup’ action to register our other functions
add_action(‘wp_dashboard_setup’, ‘example_add_dashboard_widgets’ );

Remove dashboard widgets

Remove dashboard widgets

Introduced in WordPress 2.7, dashboard widgets can be pretty useful. For example, some can display your Google Analytics stats. Though, sometimes you don’t need it, or at least don’t need some of them.
The code below will allow you to remove WordPress’ dashboard widgets once you paste it in your functions.php file.

function example_remove_dashboard_widgets() {
// Globalize the metaboxes array, this holds all the widgets for wp-admin
global $wp_meta_boxes;

// Remove the incomming links widget
unset($wp_meta_boxes[‘dashboard’][‘normal’][‘core’][‘dashboard_incoming_links’]);

// Remove right now
unset($wp_meta_boxes[‘dashboard’][‘normal’][‘core’][‘dashboard_right_now’]);
unset($wp_meta_boxes[‘dashboard’][‘side’][‘core’][‘dashboard_primary’]);
unset($wp_meta_boxes[‘dashboard’][‘side’][‘core’][‘dashboard_secondary’]);
}

// Hoook into the ‘wp_dashboard_setup’ action to register our function
add_action(‘wp_dashboard_setup’, ‘example_remove_dashboard_widgets’ );

Disable the “please upgrade now” message

Disable the “please upgrade now” message

WordPress constantly release new versions. Although for obvious security concerns you should always upgrade; disabling the “Please upgrade now” message on client sites can be a good idea because the client doesn’t necessarily have to know about this, this is a developer’s job.

One more time, nothing hard: paste the code in your functions.php, save it, and it’s all good.

if ( !current_user_can( ‘edit_users’ ) ) {
add_action( ‘init’, create_function( ‘$a’, “remove_action( ‘init’, ‘wp_version_check’ );” ), 2 );
add_filter( ‘pre_option_update_core’, create_function( ‘$a’, “return null;” ) );
}

Replace dashboard logo with yours

Replace dashboard logo with yours

Just as a client will love to see their own logo on WordPress login page, there’s no doubt that they’ll enjoy viewing it on the dashboard too.
Simply copy the code below and paste it to your functions.php file.

add_action(‘admin_head’, ‘my_custom_logo’);

function my_custom_logo() {
echo ‘

‘;
}

Define your own login logo

Define your own login logo

Although it doesn’t have any importance for the blog performance or usability, most clients will be very happy to see their own logo on the dashboard login page, instead of the classic WordPress logo.
The Custom admin branding plugin can do that for you, as well as the following hack that you just have to paste in your functions.php file.

function my_custom_login_logo() {
echo ‘

‘;
}

add_action(‘login_head’, ‘my_custom_login_logo’);

Remove dashboard menus

Remove dashboard menus

When building a WordPress blog for a client, it can be a good idea to remove access to some dashboard menus in order to avoid future problems such as the client “accidentally” deleting the custom theme they paid for.
Paste the following code in the functions.php file from your theme directory. The following example will remove all menus named in the $restricted array.

function remove_menus () {
global $menu;
$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’);