
Creating The Author Tag Cloud
Posted on June 14th, 2011 by Kyle G
I just released this sites first plugin: Author Tag Cloud, which create a tag cloud by an author containing the tags he or she used on their posts. Beyond that it creates a new permalink structure to drill down into content and find post based on author and tag. It also creates a template tag that creates the author tag cloud. Enough about what it does I think we should see how it actually works!
Why create this plugin
One of the reason why I created this plugin is I read several blogs some which I return to reread a post. But when I return to the site, I find that there has been several posts since I last visited or it has been a year or so since I read it. Well, to be honest I am an idiot and probably should of bookmarked it. Here is the deal, I might know the author or topic of the post but will have to dig, going back several pages will I find what I am looking for.
Since I am lazy and would like some other way to drill down, mainly I know the author and the topic, I figured why not have WordPress do that for me.
Where to Start to create author tag cloud
To begin, I created a new plugin folder in my wp-content/plugins/ folder and named it author-tag-cloud. I then create a new PHP document named author-tag-cloud.php. After that I created the standard information in that file. I am going to create a new class called author_tag_cloud which I first to see if it exists already, which is not a bad practice as there could be a remote possibility someone else developing on WordPress is using that class name. I create the class and then call a new instance of the class. Here is the code so far:
/*
Plugin Name: Author Tag Cloud
Plugin URI:
Description: my description
Author: Kyle G
Author URI :
Version: 1.0
*/
if(!class_exists('Author_tag_cloud')){
class Author_tag_cloud {
}
$author_tag_cloud = new Author_tag_cloud;
}
Adding the new permalink structure
This is where the post on adding permalinks to WordPress will come in handy becuase I want to create a new permalink structure that looks like:
http://www.mysite.com/author/author-slug/tag/tag-slug
But this also needs to accept paging. For example what if the author has 100 posts with a specific tag and the setting only allow for 10 to show on a given page. This mean there are pages and we must account for this in our permalink structure.
To create this new structure I need to import the class from the previous post. I drop that into a new folder called includes. I then need to create a regular expression and query string for how it will work. I will not go into detail how I created it, that is completely separate topic and here is the rules I am going to create:
'rules' => array(
'tag/([^/]+)/author/([^/]+)/?$' => 'index.php?tag=$matches[1]&author_name=$matches[2]',
'tag/([^/]+)/author/([^/]+)/page/?([0-9]{1,})/?$' => 'index.php?category_name=$matches[1]&author_name=$matches[2]&paged=$matches[3]',
'author/([^/]+)/tag/([^/]+)/?$' => 'index.php?author_name=$matches[1]&tag=$matches[2]',
'author/([^/]+)/tag/([^/]+)/page/?([0-9]{1,})/?$' => 'index.php?author_name=$matches[1]&tag=$matches[2]&paged=$matches[3]'
)
Remember Every Regular Expression in Parentheses Is a Query String Match and if are looking to create your own query strings you should know the query vars available to you.
Now that I have the rules done, I going to create a constructor function in my class and a new method call add_rules(). Also in the constructor function, I am going to call this method add_rules(). You could do this in the constructor but I just prefer to do it this way. I import my class that I added to my includes files and call a new instance of my class passing it these rules. Take a look at the constructor method and add_rules methods:
function __construct() {
$this->add_rules();
}
function add_rules(){
include('includes/refactord-add-rewrite-rules.php');
$options = array(
'rules' => array(
'tag/([^/]+)/author/([^/]+)/?$' => 'index.php?tag=$matches[1]&author_name=$matches[2]',
'tag/([^/]+)/author/([^/]+)/page/?([0-9]{1,})/?$' => 'index.php?category_name=$matches[1]&author_name=$matches[2]&paged=$matches[3]',
'author/([^/]+)/tag/([^/]+)/?$' => 'index.php?author_name=$matches[1]&tag=$matches[2]',
'author/([^/]+)/tag/([^/]+)/page/?([0-9]{1,})/?$' => 'index.php?author_name=$matches[1]&tag=$matches[2]&paged=$matches[3]'
)
);
$add_rewrite_rules = new Refactord_add_rewrite_rules($options);
If you activate this plugin, these new permalink structures will be working. Pretty easy right!
Creating the template tag for the author tag cloud
I am not going to go into to much detail about every line of code because it basically takes the wp_tag_cloud function and modifies it to create the author tag cloud. To do it on your own check out the wp_tag_cloud function in the wp-includes/category-template.php. Here is our modified version:
function author_tag_cloud( $args = '' ) {
$defaults = array(
'author_id' => 0,
'smallest' => 8,
'largest' => 22,
'unit' => 'pt',
'number' => 45,
'format' => 'flat',
'separator' => "\n",
'orderby' => 'name',
'order' => 'ASC',
'exclude' => '',
'include' => '',
'link' => 'view',
'taxonomy' => 'post_tag',
'echo' => true
);
$args = wp_parse_args( $args, $defaults );
//get the author slug
$author = get_userdata($args['author_id']);
if(!$author)
return;
$args['author-slug'] = $author->user_nicename;
//$tags = get_terms( $args['taxonomy'], array_merge( $args, array( 'orderby' => 'count', 'order' => 'DESC' ) ) ); // Always query top tags
$tags = author_get_terms($args['taxonomy'], $args);
if ( empty( $tags ) )
return;
foreach ( $tags as $key => $tag ) {
// if ( 'edit' == $args['link'] )
// $link = get_edit_tag_link( $tag->term_id, $args['taxonomy'] );
// else
// $link = get_term_link( intval($tag->term_id), $args['taxonomy'] );
$link = get_bloginfo('url') . "/author/" . $args['author-slug'] . "/tag/" . $tag->slug;
if ( is_wp_error( $link ) )
return false;
$tags[ $key ]->link = $link;
$tags[ $key ]->id = $tag->term_id;
}
$return = generate_author_tag_cloud( $tags, $args ); // Here's where those top tags get sorted according to $args
$return = apply_filters( 'author_tag_cloud', $return, $args );
if ( 'array' == $args['format'] || empty($args['echo']) )
return $return;
echo $return;
}
If you compare wp_tag_cloud with our function, you will first see the author_id parameter which allows us to tell what author we are talking about. Next, we try to get the user_data on this author_id. This is done as a check to see if this ID even exists and if doesn’t just return. Next, we call a new function which we need to create to get the author tags called author_get_terms. The link is then edited to reflect our new permalink structure. We also change out the generate_wp_tag_cloud with another function we will create. Lastly, we change the filter so if needed this can be filtered.
Finding the tags by the author
In the above function, we called a new function that we need to create called: author_get_terms(). This is basically an SQL call to get rows. Take a look at the function:
function author_get_terms($taxonomy, $r){
global $wpdb;
return $wpdb->get_results(
"SELECT posts.ID, taxonomy.term_id, terms.name,terms.slug, terms.term_group,
relationships.term_taxonomy_id, taxonomy.taxonomy, taxonomy.description, COUNT(terms.name) AS count
FROM {$wpdb->prefix}posts AS posts
JOIN {$wpdb->prefix}term_relationships AS relationships
JOIN {$wpdb->prefix}term_taxonomy AS taxonomy
JOIN {$wpdb->prefix}terms AS terms
WHERE posts.post_author = " . $r['author_id'] . "
AND posts.post_status = 'publish'
AND posts.post_type = 'post'
AND relationships.object_id = posts.ID
AND relationships.term_taxonomy_id = taxonomy.term_taxonomy_id
AND taxonomy.taxonomy = '{$taxonomy}'
AND terms.term_id = taxonomy.term_id
GROUP BY terms.name
ORDER BY count DESC"
);
}
It is a pretty complicated SQL statement that involves joining several tables and grouping the results. I am not going to cover how this SQL statement was formulated and more than likely there is a better way to do this, but it works. My recommendation is to read up on joins and try them on your local WordPress install to see what you can come up with.
The generate_author_tag_cloud Function
This is an exact copy of wp_generate_tag_cloud(). The only reason why I did this exact copy is to maybe later work on both to modify these functions even more.
Plugin Complete!
We completed the plugin and actually didn’t really reinvent the wheel. We took preexisting WordPress functions to create our template tags and used our add permalinks class to create our new structure. Thanks for reading and please subscribe to our feed, we will continue to add more and more tutorials.
One Response to “Creating The Author Tag Cloud”
Wes • December 10th, 2011 at 6:06 pm
I just downloaded your plugin, seems great.
I put the author tags in a side bar, when viewing author.php, using the following code:
$tags = $curauth->ID;
author_tag_cloud( array(‘author_id’ => $tags) );