Some fixes and extensions for Wordpress tags such as a tag cloud using only tags found in a specific category and also tag and category intersection.
Download Plugin Now from Wordpress.org!
Version 0.5 enables true ‘or’ tag intersection when using a category. It wasn’t working prior to this (and no-one noticed). Thanks to Joel Giddey for spotting it.
Wordpress 2.3 introduced native tagging support, which is rather nifty.
But did you know that you can display multiple tags in the one archive and even generate a feed for that?
- “
http://your-blog-uri/?tag=tag1,tag2” this would get all the posts tagged with tag1 or tag2. - “
http://your-blog-uri/?tag=tag1+tag2” this would get all the posts tagged with tag1 and tag2 - “
http://your-blog-uri/?tag=tag1,tag2&feed=rss” this would get you an RSS feed for all the posts tagged with tag1 or tag2
Neat huh? But did you notice that on the generated tag page you see only one tag listed in the header? This function fixes that and displays all tags used to generate that tag archive. It does this by silently modifying the single_tag_title template tag. It’ll even work on the RSS feed generated by that page!
What would be also be cool is to be able to intersect categories and tags so you could grab posts with tags from a specific category for example?
With this plugin you can. It’s not perfect however. It only allows intersection between a single category and one or more tags. Technically Wordpress should be able to support multiple categories and tags intersections but it didn’t work for me in Wordpress 2.3.x and 2.5.
So go to one of your category pages. If your using using fancy permalinks then at the end of the url add “?tdo_tag=a_tag“. If your not using permalinks then you can just use “&tdo_tag=a_tag“. You must use the tag slug, not the full tag name. You can use multiple tags as above using “,” and “+”.
- Example not using fancy permalinks: “
http://your-blog-uri/?cat=35&tdo_tag=tag1,tag2” this would get all posts in category with id 35 and tagged with either tag1 or tag2. - Example using fancy permalinks: “
http://your-blog-uri/category/mycategory/?tdo_tag=tag1+tag2” this would get all posts in the category “mycategory” and tagged with both tag1 and tag2.
This plugin uses this intersection code to automatically modify the built-in tag cloud template tag wp_tag_cloud so that if it is used on a category archive, it shows only the tags within that category. You can then click on a tag in that tag cloud and it will get the posts for in that category that tagged with that tag. (You can disable this and just use the specific template as you need).





This plugin is perfect for my needs, however, I cannot get it to work. Using http://URL/category/catname/?tdo_tag=tagname fails. The title is correct (e.g., Music tagged with ‘concerts’). However, the tag filtering never takes place. It always shows the entire category archive. I’m using WP 2.3.2.
Also, I’m getting the modified tag clouds for categories, even though I set:
$tdotf_fix_tag_cloud_auto = false;
I’m not sure what I’m doing wrong. Thanks in advance.
Oh dear. Looks like $tdotf_fix_tag_cloud_auto isn’t working as I thought. You can try just commenting out the line, like this.
#$tdotf_fix_tag_cloud_auto = false;
As for the tag filtering, is there any chance you could give me a link to have a look?
Thanks Mark, I’ll give that a shot. As for an example, here’s one:
http://philip.yurchuk.com/category/software/?tdo_tag=job-trends
You can see it shows everything for that category, not just the one post tagged “job trends”.
How very odd. I wonder if it’s an issue with WP 2.3.2 as I’m still using 2.3.1. What you might try and do is modify the function tdotf_tag_cat_intersect. You can see it’s wrapped by:
if(isset($tdotf_tag_get_var)) { . . . }If you try commenting those lines out so we can make sure the code is actually being used.
Have you modified “$tdotf_tag_get_var”?
I commented out the if/isset lines as instructed, but that didn’t fix it.
I had not modified $tdotf_tag_get_var, nor did I comment it out.
I commented out:
$tdotf_fix_tag_cloud_auto = true;
and the tag clouds are now the same everywhere, so that worked - thanks.
I noticed a couple code blocks that were commented out, but I’m assuming that’s intentional.
Hi, Your plugin is solving a major problem I had. Thanks. But I had a question about URL structure. Instead of having it output the URL as:
“http://your-blog-uri/category/mycategory/?tdo_tag=tag1+tag2″
Could it output as:
“http://your-blog-uri/category/mycategory/tdo_tag/tag1+tag2″
??
In this way, I can change the “tdo-tag” bit to a general keyword for my niche (for example, I have a games site, so a generic word like “fun” or “play” would be appropriate). Then I’d have SEO-friendly (and human-friendly) URLs for these intersections (I’d like them to be links in my menus).
So the desired URL might be:
“http://my-blog-uri/category/puzzles/fun/adventure″
where “puzzles” is the category and “adventure” is the tag that I want to produce an interaction of.
And similarly,
“http://my-blog-uri/category/puzzles/fun/adventure+kids″
would be the intersection of the category “puzzles” with the tag “adventure” AND “kids”.
(For the record, for SEO, I’m also renaming the category and tag bases to more relevant keywords).
I’m happy to fiddle the .htaccess if that’s required (but am having difficulty doing so). I just don’t know enough php or javascript to hack your wonderful plugin
Thanking you heaps and heaps in advance,
The Boss
I’m sure there is a nice wordpress way, probably hooking into wp_rewrite stuff… but also I think you can do it with .htaccess easily enough.
If you stick something like this at the top of your .htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^fun/(.*)$ ?td_cat=$1 [L]
</IfModule>
It should allow a url like “http://your-blog-uri/category/mycategory/fun/tag1+tag2″ to act like “http://your-blog-uri/category/mycategory/?td_cat=tag1+tag2″.
I’ve tested this piece of code below and it will redirect “/fun/tag1+tag2/” to “?td_cat=tag1+tag2″.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^fun/(.*)$ ?td_cat=$1 [L,R]
</IfModule>
But this isn’t exactly what you want. Dropping the R should do the trick though.
Thanks for the quick reply! I tried that and it didn’t work for me. It didn’t break anything, just didn’t do the rewrite, and simply returned the 404 page. By the way, I’m assuming you meant “tdo_tag” not “td_cat”. I tried both anyway.
But I did find this in the Codex:
http://codex.wordpress.org/Custom_Queries#Permalinks_for_Custom_Archives
It seems like what I’m after, but not sure where something like that would go (obiously changing the function names etc). I’m thinking the most obvious place is in your plugin somewhere (duh!).
I tried adding a suitably edited version of the above sample just to the end of your plugin, but that didn’t work either (not that I expected it to).
(There’s also http://codex.wordpress.org/Function_Reference/WP_Rewrite).
I think we’re getting closer.
I also had a look at the Search Permalink plugin:
http://wordpress.org/extend/plugins/search-permalink/#post-2433
I think a rejig of that might work also…
I’m playing around with a few ideas and if anything work, I’ll let you know.
cheers and thanks again,
Michelle (The Boss)
this is fabolous thank you.
Thank you very much for your work.
This is great
Hi great plugin, but how to correct or use fixes for
i mean
? php the_tags () ;
Hi pepe, sorry, but the plugin does nothing to
the_tags();template tag. Is there something wrong with it?I fixed the problem I was having. I had a custom query_posts
Can you give some hints if your plug-in calls can be wrapped into the query_posts? I want to set up a static page that and at the bottom grab a set of posts in a category filtered by a tag.
no the plugin is great, i need to use somthing like this
tdotf_cat_the_tags();becouse i need if a sigle post has tags and you choise one of the tags you have to go in tag page with the tags only from category wich the post is. sorry for my bad english
i found a small solution but a the moment a can’t separate every tag with comma:
$posttags = get_the_tags(''); if ($posttags) { foreach((get_the_category()) as $category) foreach($posttags as $tag) {
echo ' cat_ID . ‘&tdo_tag=’ . $tag->slug . ‘” title=”This is single post’.$category->name . ‘, ‘ . $tag->name . ‘”>’ . $tag->name . ‘ ’ ;} } }the problem is if you put comma all tags look like this: tag1, tag2, tag3,
But I need only: tag1, tag2, tag3
the last tag3 has no comma
any suggestions?
I guess, something like this might do the trick for you pepe:
$posttags = get_the_tags('');
if ($posttags) {
$num = count($posttags);
foreach((get_the_category()) as $category) {
$cnt = 0;
foreach($posttags as $tag) {
$cnt++;
echo ' <a href="'cat_ID . '&tdo_tag=' . $tag->slug . '" title="This is single post'.$category->name . ', ' . $tag->name . '">' . $tag->name . '</a> ' ;
if($cnt < $num) {
echo ",";
}
}
}
}
thank you very much the code is working perfect i sugest you to add id to you plugin
it has small error i one sign the right code is
$posttags = get_the_tags('');
if ($posttags) {
$num = count($posttags);
foreach((get_the_category()) as $category) {
$cnt = 0;
foreach($posttags as $tag) {
$cnt++;
echo ' slug . ‘” title=”This is single post’.$category->name . ‘, ‘ . $tag->name . ‘”>’ . $tag->name . ‘‘ ;
if($cnt < $num) {
echo “,”;
}
}
}
}
Has anyone found a way to have tdo_tags and query_posts live together? whenever I use query_posts, to sort or control the number of results on a given page… it breaks the ?tdo_tags= call.
Awesome plugin, really well done.
Do you think you can add seo-friendly links as well
or can you tell me how to rewrite
“?tdo=tag” to “/tag/”
Would appreciate any help with that!
Oliver
Awesome plugin, thanks a lot!
Do you think you can add seo friendly url’s or can
you tell me how to rewrite “?tdo=tag” to “/tag/”?
Any help is appreciated!
Oliver
I sorta figured it out, I can pass the sort order in the URL and it doesn’t break the keyword filter!! I only want to sort things in certain categories… and I the tags I need to link in the sidebar are only a subset anyway… so I am hand-coding it anyway them :(, I changed tdo-tags to keyword
/category/rodents?keyword=bunnies&orderby=title&order=asc
Hi Tobias Ross, that’s quite neat. I should dump that on readme.txt for the plugin.
?keyword=bunnies&orderby=title&order=asc
is not to handy for generating URL’s,
&orderby=title&order=asc?keyword=bunnies
also works
Now if I can just figure out how to create and retrieve groups of tags (States) (Rodents)rats, bunnyies, gophers (Felines) lions, tigers, panthers… I will be styling.
Double drat! All of a sudden tdotf_cat_tag_cloud, and wp_tag_cloud are only returning 11 tags… no matter what I do…
Mr. Deceased Individual,
I’m using WP 2.3.2 … I’m getting a very short list of tags back using your plugin, 11, I have it set to 0, I have tried something small like 20 as well.
When they are both activated sensitive tag cloud gives me the same short list of tags… If I disable tdo tag fixes… sensitive tag cloud returns a big list…
If I have them both active, sensitive tag cloud returns the same trunkated list…
I’m trying both of these:
wp_tag_cloud(’smallest=8&largest=8&unit=pt&number=0&format=flat&orderby=name&order=ASC&exclude=560,562′);
The excluded tags are not getting excluded…
I just did a quick look at the code, the code that grabs the tags from posts in a specific category does not exclude tags listed in the exclude tag list. In fact it does no modification on the tag list. So number/include/exclude etc. are ignored. orderby isn’t though (however ‘rand’ is not support). Would this explain your issue? If so I can attempt to fix it.
As for getting the plugin to work with query_posts… I’d nearly recommend ditching the plugin and using the code for your own work (this was the original intention for the plugin - some example code). The plugin does overwrite the query object so if you try to modify the query object, it’s effect may depend on if it modifies it before the plugin activates or after.
thanks
Help again.
my custom function is
function tagger() {
$posttags = get_the_tags('');
if ($posttags) {
$num = count($posttags);
foreach((get_the_category()) as $category[0]) {
$cnt = 0;
foreach($posttags as $tag) {
$cnt++;
echo ‘ cat_ID . ‘&tdo_tag=’ . $tag->slug . ‘” title=”This is single post ‘.$category->name . ‘, ‘ . $tag->name . ‘”>’ . $tag->name . ‘‘ ;
if($cnt < $num) {
echo “,”;
}
}
}
}
}
it works like
How can i limit category only to parent.
For example i have a post listen in Cat1 and subcat
I want to see tags only for parent Cat1.
May be should use
$category[0]?PLS help.
Hi toto - you want to get the id of the category on a post that is the parent of the other categories on the post?
I’m about to release an new version of tdo-tag-fixes. I’ve tested it on WP2.5, done some fixes to the tag cloud (as requested), added a tdotf_the_tags (to replace the_tags template tag) (as requested) and add some basic fancy permalink stuff (as requested).
Hi admin, yes exactly.
The database I am building on my site would not be possible without this plug-in or a non-existent one that does the same things!?
I think the Wordpress people should roll it back into wordpress! Yes, 2.3 brought tag intersections… but doesn’t exposing category and tag+tag intersections make just as much sense if not more!?
Oh the pretty cloud!
Great work Mark!
Great plugin thank you
My head is spinning too fast with this!!
simple question: how to write tag cloud from specific category?
I mean how to wrote this on home.php for wp_tag_cloud() from specific category only?
Congratulations on a superb plugin idea. I have tried to get t doing what I want it to do but I am struggling! Please help!
I ahve a standard Wordpress2.5 install, a widget enable template showing the tag cloud. I have installed the plugin. the only change that I made to WP2.5 was that in widgets.php then I set the smallest and largest sizes and changed the number of tags to show.
Next step was to edit tdotf.php to:
============================================================
// You can change this if you want. Do not set it to ‘tag’. If you want to
// disable this feature, just comment it out.
//
// $tdotf_tag_get_var = ‘tdo_tag’;
// If you have fancy permalinks turned on, you can use this option to use a
// more fancy form of the tdo_tag. The first paramater is the category_slug
// and the second parameter is the tag_slug. If you want to disable this feature
// just comment it out. (It depends on $tdotf_tag_get_var)
//
// $tdotf_fancy_tag_regex = ‘tdo_cat/(.+)/tdo_tag/(.+)’;
// Set to false if you do not wish tag archive titles to be correctly updated
//
$tdotf_fix_tag_title_auto = true;
// Set to false if you do not wish the built-in tag cloud automatically fixed
//
$tdotf_fix_tag_cloud_auto = true;
// Set to false if you do not wish the category archive title to include tag filter
//
$tdotf_fix_cat_title_auto = false;
// Enable some debug
//
$tdotf_enable_debug = false;
================================================
The idea being that on each category then I would show a list of tags within that category but each tag link would point to the overall top level tag directory set up under my permalinks.
The tag clouds are generated in each category BUT they are the first 50 alphabetically listed and not a cloud of the top 50 tags.
Can anyone advise on where I have gone wrong or is this a bug?
Thanks in advance for the help.
Hi indojepang,
The modified tag cloud works pretty much the same as the built in WP tag cloud with one additional parameter “cat”.
So if you want to use a specific category, find out it’s category ID, say 6 for our example. Then you can just called the tag cloud function like this:
if(function_exists('tdotf_cat_tag_cloud')) {
tdotf_cat_tag_cloud('cat=6');
}
You can use all the normal tag cloud parameters too. Is that what you are looking for?
Hi Confuscius,
From the look of it, you have the settings for the plugin correct.
How are you calling the wp_tag_cloud function? What are the parameters?
What you could try instead is called tdotf_cat_tag_cloud directly on the category archive template and disable the auto replace. By default the orderby is set to “name” so you need to change the orderby to count to list the top X tags. So you could called the tag cloud function like this:
tdotf_cat_tag_cloud('orderby=count&number=50');This would give you the tdotf tag cloud with the tags ordered by count (not alphabetically) and limited to the top 50.
Hi sorry for late reply..
Yes! Your Plugin is Rock man! it works great for WP 2.5.. Thank u..
FYI I tested in WPMU and got Blank screen..
Just for testing..
But it would be great if it works in WPMU too..
Cheers..
Hi Mark
Many thanks for the point in the right direction - I ended up replacing the tag cloud code in widgets.php with your suggested code and the addition of a ‘&order=DESC’ - this gives me a category tag cloud for each category where all tags point back at the global tags sorted high to low on the tag count - just what the doctor ordered. Neat.
Kind regards.
No problem Confuscius!
Hi indojepang, what do you mean a “Blank Screen”? Does it literally kill your MU install?
putting this plugin into mu-plugins directory gets me a blank screen (nothing shows up), unplugged it and back to normal again.. (for a second my heart stopped beating.. lol)
hi mark .thanks of course
to fix the (tdof_)the_tags() on is_single() pages, i added this to your tdof_the_tags()
function tdof_the_tags( $before = '', $sep = '', $after = '' ) {
global $tdotf_tag_get_var,$cat;
// mr.snow - we need to get the category another way if !is_category()
if ( ! $cat ) {
$category = get_the_category();
$cat = $category[0]->cat_ID;
}
// if(is_category() && isset($tdotf_tag_get_var)) {
if(isset($cat) && isset($tdotf_tag_get_var)) {
…
Thanks Queenvictoria,
I was a bit unsure if it made sense to have it point to the category+tag when your on a single page. What happens if you have multiple categories for a post? You’ll only get the 1st category!
I’ll see about rolling in the chance with some additional enhancements (like allow the user to specify what category to use)
hi. Thanks for plugin
perfect.
regards
Hi, it’s me again. I still can’t get the category/tag intersection to work. I’m now using WP 2.5.1, TDO Tag Fixes .4, and SimpleTags 1.5.7 (plus a few non-tag related plugins). Here is an example link:
http://philip.yurchuk.com/category/software/?tdo_tag=rhino
You’ll see there are multiple posts listed when there really should be only one. This feature would be extremely useful for another blog I’ve set up. I have the same exact setup there, and it also doesn’t work, but I don’t mind experimenting on my personal blog if you need more info.
Thanks!
Hi Philip Yurchuk, I’ve just done a small update to the plugin that might solve your problem. Could you try the dev version and tell me if that makes a difference?
Thanks
I really appreciate the effort, but it still isn’t working. Here is an example link:
http://philip.yurchuk.com/category/software/?tdo_tag=rhino
You can see there are a couple posts that don’t have the rhino tag.
Hi Philip, did you try disabling Simple Tags plugin (just in case their is a conflict)? Are you using any plugins that might be modifying WP_Query (i.e. messing with the order of posts in the template)?
Here are the plugins I have activated (latest versions):
Askimet
Simple Tags
Subscribe to comments
Wordpress Database Backup
WP-Footnotes
I have tried disabling each plugin, but that didn’t fix it. I searched for wp_query in my theme (Tarski), but nothing was found. I’m running PHP 4.4.7 and MySQL 4.1.22. Thanks for your help.
Hi,
You got a really great plugin going here, I was about to code something similar myself when I can across it. I’ve had it working quite nicely and added a few enhancements which can be seen at http://www.easymapinfo.com/wordpress25/category/australia/ (still under dev).
The problem that I was having is when intersecting a category and multiple tags expecting an ‘OR’ join to take place and was getting a ‘AND’ join result. eg …/categoryname/?tdo_tag=tag1,tag2. The plugin correctly modifies the title but the result is definitely a ‘AND’ join.
So I threw a virgin WP install at http://easymapinfo.com/virginwordpress/?cat=3 with only your plugin and it does the same thing.
Thoughts?
Hi Joel Giddey,
I wonder is it something to do with the version of Wordpress. It was working correctly on WP2.3 where I did the initial development. I haven’t properly tested it on WP2.5.1 yet, so maybe somethings been broken. Have you checked the bugs list?
I’ve checked the bug list on trac there is one there that is is slightly relevant but not directly to this issue. So I installed a fresh WP 2.3 with a fresh tdotf on http://easymapinfo.com/wordpress23/category/cat1/ and when is use tdo_tag=tag1,tag2 I’m still getting a ‘AND’ join result.
Was thinking it may be as a result of
$args->set_query_var('tag_slug__and',$tags);on line 149 of tdotf.php but when I try tag_slug__in I get no results. I think this may have something do to with query.php around line 1126 where WP seems to only handle intersects with tag_slug__and and not ‘in’.So until I find a solution I think I’m going to modify my changed tdotf to use radio buttons and not checkboxes and limit users to one cat with one tag intersects.
But I am surprised that you had it working with your 2.3 install, was it dependant on any other plugins?
Thanks!
Hi Joel,
I’ve done some digging. Your right. Tags with an OR join do not intersect with categories. This seems true for Wordpress 2.3 too. I’ve gone through the Wordpress code and it’s not supported at all. I think I can make it work though by doing some magic with filters, so I’ll see what I can do.
I’ve got a filter implemented now that correctly updates the intersection query when you have a set of tags that are ORed instead of ANDed. I’ll add it to the SVN later today, but if your in a here, here is the actual code you can add to the plugin:
function tdotf_query_filter($where) { global $tdotf_tag_get_var,$wpdb; $tag_query = tdotf_get_tdo_tag_query(); if(!empty($tag_query) && $tag_query != false && strpos($tag_query,',')) { $tags = split(",",$tag_query); // Grab all posts with these tags $sql = "SELECT p.ID FROM $wpdb->posts p INNER JOIN $wpdb->term_relationships tr ON (p.ID = tr.object_id) INNER JOIN $wpdb->term_taxonomy tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id) INNER JOIN $wpdb->terms t ON (tt.term_id = t.term_id)"; $sql .= " WHERE tt.taxonomy = 'post_tag' AND t.slug IN ('" . implode("', '", $tags) . "')"; $sql .= " GROUP BY p.ID"; $post_ids = $wpdb->get_col($sql); // Pattern and replacement for query $pattern = "AND.*$wpdb->posts\.ID.*IN.*(.*)"; $replacement = "AND $wpdb->posts.ID IN (" . implode(', ', $post_ids) . ")"; // Update query $where = preg_replace('/'.$pattern.'/', $replacement, $where); } return $where; } add_filter('posts_where_request','tdotf_query_filter');The code I posted is slightly incorrect. I’ve done the change and its sitting in the SVN repo, so anyone can grab the dev version right now with the fix. I’ll probably release it officially during the week.
Hi!
I’d love to find out how to emulate the ‘tag surfer’ functionality that wordpress.com users have.
Any ideas? I thought it might be possible to use your plugin and add some php code to change the links associated with the tags that are displayed.
For example, I could change the hyperlink of a tag (e.g. mywebsitestag [+]) so that it will append the tag to the existing url, or I could change the hyperlink (e.g. mywebsitestag [x]) so that on clicking it, it will jump the user to the same url minus the tag selected.
does this make sense?
many thanks
scotjam
Hi Scotjam, what is the “tag surfer” functionality? I’m not familiar with it. If I know what it does, I can see if its doable.
Great work on the fix to the plugin, I was digging through the new code and it really is a clever bit of work with the ‘OR’ joins.
For those interested I’ve finalized my implementation of the plugin over at my site a good url example is http://travel.accommodationsphere.com/earth/south-africa/gauteng-za/ look over at the left for accommodation types which are actually tags using the tdo_tag_fix with a few mods.
Regards
JG
Hi Joel
Brilliant site. Just one question, how did you get to make sub categories work with tags?
I was under the impression that tdo only works with single category intersections with one or more tags. But you’ve got sub categories working which is brilliant!
Also, I like the way the checkboxes are filtered. A very nice touch indeed.
cheers
the plugin is fantastic, thank you.
i am having 2 issues though that i just can’t sort out.
i have included
but when using on a page like
?cat=6&tdo_tag=tagename
is it possible to have the cloud generate links like
?cat=6&tdo_tag=tagename+anothertag
also, i can’t get the permalinks to work, they always show like
tdo_tag=tagname
any ideas?
Joel Giddey: Nothing you can’t do with some regex!
dave: If you want the tag cloud to generate different links, you’ll need to modify the code yourself currently.
Also what do you mean by the permalinks aren’t working?