8 fun & useful shortcode functions for wordpress

shortcodes

‘Shortcodes’ are a feature of wordpress used for executing custom functions by inserting a small snippit of code into a post. For example, my download monitor plugin now uses shortcodes; by entering [download id="1"] into a post, the plugin will output a download link.

The shortcode syntax varies, here are some examples:

  • [shortcode]
  • [shortcode atribute="value"]
  • [shortcode]Text[/shortcode]

Shortcodes can be created to perform a handful of useful functions. To use any of the shortcodes in this post I recommend adding the functions to your functions.php theme file (create it if it does not exist!). Ill show shortcodes ranging from showing adsense to speaking pirate! (written for wordpress 2.7)

1. Get some bloginfo

Need to get your wordpress url or template url? Try this on for size:

1
2
3
4
5
6
7
function bloginfo_shortcode( $atts ) {
    extract(shortcode_atts(array(
        'key' => '',
    ), $atts));
    return get_bloginfo($key);
}
add_shortcode('bloginfo', 'bloginfo_shortcode');

Now you can output some bloginfo using [bloginfo key=""], for example [bloginfo key="template_url"] will output the path to your template directory. This page highlights the data you can grab using this custom shortcode.

Example output: http://blue-anvil.com/wp-content/themes/blueanvil


2. Integrate some Adsense Ads

Want to output some adsense ads in posts? Try this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function adsense_shortcode( $atts ) {
	extract(shortcode_atts(array(
	    'format' => '1',
	), $atts));
 
	switch ($format) {
		case 1 :
			$ad = '<script type="text/javascript"><!--
			google_ad_client = "pub-6928386133078955";
			/* 234x60, created 16/09/08 */
			google_ad_slot = "0834408702";
			google_ad_width = 234;
			google_ad_height = 60;
			//-->
			</script>
			<script type="text/javascript"
			src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
			</script>';
		break;
	}
	return $ad;
}
add_shortcode('adsense', 'adsense_shortcode');

Remember to replace the adsense code with your own from google. Now you can output an ad simply using [adsense].

Add additional ad formats to the switch statement and you can output other ad formats using, for example,  [adsense format="2"]. Nice eh?

3. Obfuscate an email address

This simple shortcode will munge/create a link to an email address to help prevent spam. Not 100% foolproof but better than nothing (and a good basis to expand upon if you want to enhance it).

1
2
3
4
5
6
7
8
function munge_mail_shortcode( $atts , $content=null ) {
 
	for ($i = 0; $i < strlen($content); $i++) $encodedmail .= "&#" . ord($content[$i]) . ';'; 
 
    return '<a href="mailto:'.$encodedmail.'">'.$encodedmail.'</a>';
 
}
add_shortcode('mailto', 'munge_mail_shortcode');

Use: [mailto]email@yourdomain.com[/mailto].

email@yourdomain.com

In the source the mail is shown as:

&amp;#101;&amp;#109;&amp;#97;&amp;#105;&amp;#108;&amp;#64;&amp;#101;&amp;#109;&amp;#97;&amp;#105;&amp;#108;&amp;#46;&amp;#99;&amp;#111;&amp;#109;

4. Show related posts (uses tags)

How about showing some related posts in your current post based on it’s tags? Lets do it!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
function related_posts_shortcode( $atts ) {
 
	extract(shortcode_atts(array(
	    'limit' => '5',
	), $atts));
 
	global $wpdb, $post, $table_prefix;
 
	if ($post->ID) {
 
		$retval = '
<ul>';
 
		// Get tags
		$tags = wp_get_post_tags($post->ID);
		$tagsarray = array();
		foreach ($tags as $tag) {
			$tagsarray[] = $tag->term_id;
		}
		$tagslist = implode(',', $tagsarray);
 
		// Do the query
		$q = "
			SELECT p.*, count(tr.object_id) as count
			FROM $wpdb->term_taxonomy AS tt, $wpdb->term_relationships AS tr, $wpdb->posts AS p
			WHERE tt.taxonomy ='post_tag'
				AND tt.term_taxonomy_id = tr.term_taxonomy_id
				AND tr.object_id  = p.ID
				AND tt.term_id IN ($tagslist)
				AND p.ID != $post->ID
				AND p.post_status = 'publish'
				AND p.post_date_gmt < NOW()
			GROUP BY tr.object_id
			ORDER BY count DESC, p.post_date_gmt DESC
			LIMIT $limit;";
 
		$related = $wpdb->get_results($q);
 
		if ( $related ) {
			foreach($related as $r) {
				$retval .= '
	<li><a title="'.wptexturize($r->post_title).'" href="'.get_permalink($r->ID).'">'.wptexturize($r->post_title).'</a></li>
';
			}
		} else {
			$retval .= '
	<li>No related posts found</li>
';
		}
		$retval .= '</ul>
';
		return $retval;
	}
	return;
}
add_shortcode('related_posts', 'related_posts_shortcode');

Magic. Now use [related_posts] to show 5 related posts, or [related_posts limit="x"] to show a number of your choosing. Example:

5. Add a simple paypal donation link

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function donate_shortcode( $atts ) {
    extract(shortcode_atts(array(
        'text' => 'Make a donation',
        'account' => 'REPLACE ME',
        'for' => '',
    ), $atts));
 
    global $post;
 
    if (!$for) $for = str_replace(" ","+",$post->post_title);
 
    return '<a class="donateLink" href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business='.$account.'&item_name=Donation+for+'.$for.'">'.$text.'</a>';
 
}
add_shortcode('donate', 'donate_shortcode');

Replace the default ‘account’ with your paypal email address, and output using [donate]. Remember you can override the default ‘text’ too in the shortcode. You can style this link with css (as ive done) easily.

Make a donation

6. Output a google powered chart

Pass this shortcode some data and it will convert it into a graph generated by google charts api. First I’ll show it in action. I want to show some info about my traffic to Blue Anvil from analytics; I will show it in a pie chart:

Traffic Sources

Code: [chart data="41.52,37.79,20.67,0.03" bg="F7F9FA" labels="Reffering+sites|Search+Engines|Direct+traffic|Other" colors="058DC7,50B432,ED561B,EDEF00" size="488x200" title="Traffic Sources" type="pie"]

The shortcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
function chart_shortcode( $atts ) {
	extract(shortcode_atts(array(
	    'data' => '',
	    'colors' => '',
	    'size' => '400x200',
	    'bg' => 'ffffff',
	    'title' => '',
	    'labels' => '',
	    'advanced' => '',
	    'type' => 'pie'
	), $atts));
 
	switch ($type) {
		case 'line' :
			$charttype = 'lc'; break;
		case 'xyline' :
			$charttype = 'lxy'; break;
		case 'sparkline' :
			$charttype = 'ls'; break;
		case 'meter' :
			$charttype = 'gom'; break;
		case 'scatter' :
			$charttype = 's'; break;
		case 'venn' :
			$charttype = 'v'; break;
		case 'pie' :
			$charttype = 'p3'; break;
		case 'pie2d' :
			$charttype = 'p'; break;
		default :
			$charttype = $type;
		break;
	}
 
	if ($title) $string .= '&chtt='.$title.'';
	if ($labels) $string .= '&chl='.$labels.'';
	if ($colors) $string .= '&chco='.$colors.'';
	$string .= '&chs='.$size.'';
	$string .= '&chd=t:'.$data.'';
	$string .= '&chf='.$bg.'';
 
	return '<img title="'.$title.'" src="http://chart.apis.google.com/chart?cht='.$charttype.''.$string.$advanced.'" alt="'.$title.'" />';
}
add_shortcode('chart', 'chart_shortcode');

Other examples:

Code: [chart data="0,12,24,26,32,64,54,24,22,20,8,2,0,0,3" bg="F7F9FA" size="200x100" type="sparkline"]

Macbook Fund

Code: [chart data="40" bg="F7F9FA" labels="Mula" colors="058DC7,50B432,ED561B,EDEF00" size="488x200" title="Macbook Fund" type="gom"]

7. Show a google map with a marker on it

Want to show a map and/or a marker on it? You’ll need a Google Maps API key for this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function googlemap_shortcode( $atts ) {
    extract(shortcode_atts(array(
        'width' => '500px',
        'height' => '300px',
        'apikey' => 'REPLACEME',
        'marker' => '',
        'center' => '',
        'zoom' => '13'
    ), $atts));
 
    if ($center) $setCenter = 'map.setCenter(new GLatLng('.$center.'), '.$zoom.');';
    if ($marker) $setMarker = 'map.addOverlay(new GMarker(new GLatLng('.$marker.')));';
 
    $rand = rand(1,100) * rand(1,100);
 
    return '
    	<script src="http://maps.google.com/maps?file=api&v=2.x&sensor=false&key='.$apikey.'" type="text/javascript"></script>
 
	    <script type="text/javascript">
		    function initialize() {
		      if (GBrowserIsCompatible()) {
		        var map = new GMap2(document.getElementById("map_canvas_'.$rand.'"));
		        '.$setCenter.'
		        '.$setMarker.'
		        map.setUIToDefault();
		      }
		    }
		    initialize();
	    </script>
    ';
 
}
add_shortcode('googlemap', 'googlemap_shortcode');

To display a map just enter [googlemap] replacing center/marker/zoom co-ordinates with whatever you like.

Code: [googlemap zoom="13" center="52.66389056542801, 0.1641082763671875" marker="52.66389056542801, 0.1641082763671875" width="488px"]

8. Talk like a pirate

Just for fun we can convert a section of text into pirate speak using the following shortcode (inspired by/taken from Pirate for drupal and the text filter suite pirate filter).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
function pirate_talk_shortcode( $atts , $content=null ) {
 
      $patterns = array(
        '%\bmy\b%' => 'me',
        '%\bboss\b%' => 'admiral',
        '%\bmanager\b%' => 'admiral',
        '%\b[Cc]aptain\b%' => "Cap'n",
        '%\bmyself\b%' => 'meself',
        '%\byour\b%' => 'yer',
        '%\byou\b%' => 'ye',
        '%\bfriend\b%' => 'matey',
        '%\bfriends\b%' => 'maties',
        '%\bco[-]?worker\b%' => 'shipmate',
        '%\bco[-]?workers\b%' => 'shipmates',
        '%\bpeople\b%' => 'scallywags',
        '%\bearlier\b%' => 'afore',
        '%\bold\b%' => 'auld',
        '%\bthe\b%' => "th'",
        '%\bof\b%' =>  "o'",
        "%\bdon't\b%" => "dern't",
        '%\bdo not\b%' => "dern't",
        '%\bnever\b%' => "no nay ne'er",
        '%\bever\b%' => "e'er",
        '%\bover\b%' => "o'er",
        '%\bYes\b%' => 'Aye',
        '%\bNo\b%' => 'Nay',
        '%\bYeah\b%' => 'Aye',
        '%\byeah\b%' => 'aye',
        '%\bare\b%' => 'be',
        '%\bDrupalists\b%' => 'Bucaneers',
        '%\bthere\b%' => 'thar',
        '%b\bnot\b%' => 'nay',
        '%\bdesign\b%' => 'bounty',
        '%\bonline\b%' => 'on the plank',
        '/and\b/' => "an'",
        '/ious\b/' => "i'us",
        "%\bdon't know\b%" => "dinna",
        "%\bdidn't know\b%" => "did nay know",
        "%\bhadn't\b%" => "ha'nae",
        "%\bdidn't\b%"=>  "di'nae",
        "%\bwasn't\b%" => "weren't",
        "%\bhaven't\b%" => "ha'nae",
        '%\bfor\b%' => 'fer',
        '%\bbetween\b%' => 'betwixt',
        '%\baround\b%' => "aroun'",
        '%\bto\b%' => "t'",
        "%\bit's\b%" => "'tis",
        '%\bwoman\b%' => 'wench',
        '%\bwomen\b%' => 'wenches',
        '%\blady\b%' => 'wench',
        '%\bwife\b%' => 'lady',
        '%\bgirl\b%' => 'lass',
        '%\bgirls\b%' => 'lassies',
        '%\bguy\b%' => 'lubber',
        '%\bman\b%' => 'lubber',
        '%\bfellow\b%' => 'lubber',
        '%\bdude\b%' => 'lubber',
        '%\bboy\b%' => 'lad',
        '%\bboys\b%' => 'laddies',
        '%\bchildren\b%' => 'little sandcrabs',
        '%\bkids\b%' => 'minnows',
        '%\bhim\b%' => 'that scurvey dog',
        '%\bher\b%' => 'that comely wench',
        '%\bhim\.\b%' => 'that drunken sailor',
        '%\bHe\b%' => 'The ornery cuss',
        '%\bShe\b%' => 'The winsome lass',
        "%\bhe's\b%" => 'he be',
        "%\bshe's\b%" => 'she be',
        '%\bwas\b%' => "were bein'",
        '%\bHey\b%' => 'Avast',
        '%\bher\.\b%' => 'that lovely lass',
        '%\bfood\b%' => 'chow',
        '%\bmoney\b%' => 'dubloons',
        '%\bdollars\b%' => 'pieces of eight',
        '%\bcents\b%' => 'shillings',
        '%\broad\b%' => 'sea',
        '%\broads\b%' => 'seas',
        '%\bstreet\b%' => 'river',
        '%\bstreets\b%' => 'rivers',
        '%\bhighway\b%' => 'ocean',
        '%\bhighways\b%' => 'oceans',
        '%\binterstate\b%' => 'high sea',
        '%\bprobably\b%' => 'likely',
        '%\bidea\b%' => 'notion',
        '%\bcar\b%' => 'boat',
        '%\bcars\b%' => 'boats',
        '%\btruck\b%' => 'schooner',
        '%\btrucks\b%' => 'schooners',
        '%\bSUV\b%' => 'ship',
        '%\bairplane\b%' => 'flying machine',
        '%\bjet\b%' => 'flying machine',
        '%\bmachine\b%' => 'contraption',
        '%\bdriving\b%' => 'sailing',
        '%\bunderstand\b%' => 'reckon',
        '%\bdrive\b%' => 'sail',
        '%\bdied\b%' => 'snuffed it',
        '/ing\b/' => "in'",
        '/ings\b/' => "in's",
      );
      foreach ($patterns as $pattern_search => $pattern_replace) {
        $content = preg_replace($pattern_search, $pattern_replace, $content);
      }
      return $content;
 
}
add_shortcode('pirate', 'pirate_talk_shortcode');

Wrap any content you want to translate in [pirate][/pirate].

The sky’s the limit!

Usin' shortcodes ye can write yer own functions an' output pretty much anythin' ye want. Go play!

The wordpress documentation for the shortcode API can be found here. Smashing magazine also had a useful post on shortcodes you can read.

Found this post useful? Why not buy me a coffee!

Related Entries

20 Responses to “8 fun & useful shortcode functions for wordpress”

RSS feed for comments on this post.

  1. Will says:

    Aha, me hearties! Excellent post Mike. I particularly enjoyed the pirate shortcode if you couldn’t tell :P

    ReplyReply

    Comment made on March 14, 2009 at 9:22 pm

  2. Many says:

    Great post indeed ! Funny and useful as you said :D

    Thanks for those.

    ReplyReply

    Comment made on March 15, 2009 at 12:57 pm

  3. Clemens says:

    Congratulations, awsome post! Especially the related posts and the Google interfaces are very useful.
    I don’t like the idea of putting the functions into your theme’s function.php, though – if you switch to a different theme, the shortcodes aren’t parsed anymore, but I guess that’s more of a wordpress design problem than your fault.

    ReplyReply

    Comment made on March 15, 2009 at 2:41 pm

  4. Mike Jolley says:

    @Clemens: Not so much a problem unless you change themes all the time; although I don’t think theres anything to stop you from writing your own special plugin containing all the shortcode functions – that will work across all themes.

    ReplyReply

    Comment made on March 17, 2009 at 12:48 pm

  5. George Serradinho says:

    Thanks for the shortcodes, I have added the donate one. I somehow thought it would be more technical but you made it so easy.

    ReplyReply

    Comment made on March 19, 2009 at 9:23 am

  6. BeyondRandom says:

    Very nice resource! I like the donate one and will probably have to integrate that in my blog this weekend. Thanks for sharing.

    ReplyReply

    Comment made on March 26, 2009 at 3:40 pm

  7. Elliot says:

    Great shortcode, I’m using it at http://www.ilovecolors.com.ar/ilc-thickbox-wordpress-plugin-to-display-images/
    I’ve added a bit of markup and text to the $retval variable.
    I like the fact that it is a shortcode so I’m free to apply it whenever I want. However, when I get sometime off I will create a meta checkbox for the sidebar in order to enable/disable related posts for a particular post instead of writing the shortcode.

    ReplyReply

    Comment made on March 30, 2009 at 8:22 pm

  8. Kampanye Damai Pemilu Indonesia 2009 says:

    Glad I stumbled into this article! I have you bookmarked to check out new stuff you post.

    ReplyReply

    Comment made on April 14, 2009 at 1:42 am

  9. Kate Mag says:

    Love this post, especially pirate shortcode :-) . Thank you so much

    ReplyReply

    Comment made on April 22, 2009 at 4:24 am

  10. Ashley says:

    That is pretty cool, i wasn’t aware we could do all this with short codes. Thanks for the quick tut, i will sure look to find more!

    ReplyReply

    Comment made on June 1, 2009 at 4:31 am

  11. will says:

    Shortcodes are just too cool for school!!!

    ReplyReply

    Comment made on July 6, 2009 at 12:48 pm

  12. .Phibez says:

    Man I love your site.. great article on shortcodes.. I am no programmer, just know enough to do some damage.. more of a conceptual designer.. anyhow the information you provided here will make my life a lot easy.. thanks for sharing and keep up the uber site development..

    Peace

    ReplyReply

    Comment made on July 9, 2009 at 5:02 am

  13. LCDHDTV says:

    Thanks for the shortcodes, I have added the donate one. I somehow thought it would be more technical but you made it so easy.

    :)

    ReplyReply

    Comment made on August 15, 2009 at 5:39 pm

  14. Anthony says:

    Just tried all these, shortcodes rock! That pirates hot – can I have his phone number?

    ReplyReply

    Comment made on November 5, 2009 at 12:32 pm

  15. Short Code says:

    Thanks for the short codes!

    ReplyReply

    Comment made on November 18, 2009 at 7:56 pm

  16. DailyManila says:

    Excellent post! Thank you for the short codes! I love the Google Chart and AdSense integration.

    ReplyReply

    Comment made on December 22, 2009 at 4:14 am

  17. Mihai O. says:

    Great article! I like the one with the pirate language :) )

    ReplyReply

    Comment made on February 8, 2010 at 11:49 pm

  18. Special Tips .co.cc says:

    how to make 2 different adsense shortcode?

    coz I don’t know how to make the second adsense shortcode. Thanks

    ReplyReply

    Comment made on March 2, 2010 at 12:20 am

Leave a Reply

Why ask?

About this site

Blue Anvil is the online web design journal & portfolio of , a web designer from Norfolk, England. Read More »
ThemeSlice
  • Featured work - More

    • Beefjack
    • Integrity
    • theotaku.com
  • Latest Tweet - More

    • Phew, rabbit was found in the school.
  • Out of the blue - More

    • MiniCard 1.1.7 Update

      I have just uploaded 1.1.7 of MiniCard here and to the WordPress theme directory. This updates includes:

      • New networks; xing, gowalla, yelp, foursquare, mobileme, google buzz
      • A way to change link text and define multiple links of the same network
      • A way to define your own custom links + icons
      • Improved admin panel

      Hope you like it, and don’t forget you can show your support by purchasing the premium pack from here.

    • Switched: From Shared to VPS

      It’s been about two weeks now since I made the transition from a shared reseller hosting account to a VPS (Virtual Private Server) account – impressions so far, excellent performance but fiddly to configure.

      The reason I wanted to change from shared hosting was the fact the server was always being hacked (even though ALL my scripts were secure), there was frequent downtime, support blamed me for problems every time, and it was slow as hell.

      Those used to a shared hosting environment would probably not know where to start when faced with configuring a VPS. Luckily, a lot of it was pre-configured when I received my account – certainly some of the major security holes were patched. I was not satisfied with those however. As a victim of hacking in the past (previous host swears it was not there fault, something I don’t believe) I took extra care to secure it as a much I could – configuring brute force detection, the firewall, installing mod security (excellent rules for that here: http://www.atomicorp.com/wiki/index.php/Atomic_ModSecurity_Rules) and going though multiple guides (like this one: http://www.webhostingtalk.com/showthread.php?t=468168) with a fine-tooth comb.

      The result? My pages are loading at least 6 times faster, I have had no down time (or at least have not noticed any), and I feel in control and happy. No longer am I at the mercy of shared hosts :)

      If your interested, I chose ServInt as my provider as they offered a great deal, as well as being a managed service (so I’m not on my own if I screw things up). I was tempted by the bells and whistles of Media Temple, but felt the ServInt service was better value.

    • Download Monitor 3.2.2 Maintenance Release

      Download Monitor has received some more love and has been updated. Here’s the change log from the new version:

      • Small bugfix in uploader.php – cat ID
      • Changed stats graph calculation – thanks lggemini
      • Changes to headers in download.php to avoid caching
      • File Browser fixes – $root was clashing with something….
      • exclude_cat works in all sections of download_page now
      • Removed hardcoding of /uploads/
      • Added action to download.php – should be able to use it to stop a download if you want – maybe limiting downloads per day or something? Whatever you want…
      • Made it so if you post new file on ‘edit’ screen, the post date is updated.
      • Fixed the ‘blank meta’ section which blanks out custom field values when nothing is set.
      • Moved ‘allow_url_fopen’ check.
      • Someone said downloads don’t work with spaces in the name. They do! Wasting my time sonny…
      • All work and no play make jolley a dull boy
      • Had to rename capabilities so they work. Apologies if you have to set this up again! Cheers to Mark Dingemanse.
      • {category_ID} custom format tag added. Useful if you want to send someone to its category on the DL page I guess. Also added {category_other} so when no category is set “other” is shown – this is because the download page can show an ‘other’ section if you want it to.
      • You can now manually edit the post date on the edit download screen.

      If you have edited capabilities for download monitor user permissions, you’ll have to again sorry! This is because I named them too long. Also, you should check your forced downloads still work because there was a logic error meaning they may not have been forced after-all…

      Enjoy.

    • Mahousive update to Download Monitor (3.2)

      Today I completed the update for the Wordpress Download Monitor Plugin – many tweaks, fixes, and features added. There were no changes to the database structure so people upgrading should be fine. Here is the list from the change log:

      • {user} tag added for custom formats
      • ‘autop’ option fix
      • Download page buttons applied with CSS so they are easier to customise/translate.
      • Fix for pagination bug after editing a download
      • Category output fix on edit downloads screen
      • Category urls on download page use ID rather than name to prevent errors when cats have the same names.
      • exclude_cat added to download_page shortcode
      • Localised ‘hits’ ‘date’ ‘title’ on download page
      • Option to disable the download logging
      • Read file ‘chunked’ some people found large files were corrupted so this should help (fingers crossed)
      • Added show_tags option to download page – displays x amount of tags on the download page.
      • File Browser root setting and download.php logic/mime types modified thanks to Jim Isaacs (jidd.jimisaacs.com)
      • Interface Improvements
      • Bulk edit categories, custom fields, tags, member only downloads
      • Added roles for download monitor admin – should be able to use with a role manager plugin if you want anyone other than admin to access the admin section e.g. http://wordpress.org/extend/plugins/capsman/
      • Change redirect after add
      • Edit Cat names/parents
      • Dedicated tags and thumbnails fields (they still use meta table though)

      And yes, those category link bugs are fixed at long last, and you can edit category names finally. Phew!