QuickGlossary wordpress plugin

I am curious with the ongoing discussion on LSI in search, how Googlebot responds to using the Datalist and it’s DFN definition element on page. Maybe it helps if we provide the search engines with more on page context. So I built a Quick Glossary WordPress plugin. It puts the single post tags with description as a Glossary in the sidebar and uses jQuery to shorten the displayed text and add a [more] link, so visitors can choose to read a full description but it does not dominate the page, whilst Googlebot and Slurp get the full context of the content according to my tag definitions.

PIYF
Acronym : Panda Is Your Friend

First the basic widget code, I’ll call it Quick Glossary :

  1. function widget_QuickGlossary($args) {
  2.         extract($args);
  3.  
  4.         //preparation : scope, css, javascript
  5.  
  6.         echo $before_widget;
  7.         echo $before_title . 'Quick Glossary' . $after_title;
  8.  
  9.         //output  
  10.  
  11.         echo $after_widget;
  12. }
  13.  
  14. register_sidebar_widget('Quick Glossary', 'widget_QuickGlossary');

the preparation

scope

I want my widget to only show on single posts, and only if the post has tags :

if(!is_single()) return
  1.     global $post;
  2.     $tags = get_the_tags($post->ID);
  3.     if(!$tags) return;

layout

I want a double column layout with the term (tag) linking to the tag page, and the definition itself only part visible, with a fancy [more] link like on Facebook.

First some css for a double column data list :

  1. and then some jQuery : I want the whole definition on the page but only part visible to the reader. <a href="&lt;br /&gt;
  2. http://viralpatel.net/blogs/2010/12/dynamically-shortened-text-show-more-link-jquery.html">Viralpatel</a> list a nice cut and paste jQuery snippet. That requires I add a class "more" to the DD element, and add some css for it and for the link :
  3. <pre lang="php">

I put the extra CSS script in it’s own function :

function quickGlossary_scripts() {
  1. //css for doyble column
  2. //css hooks for jquery
  3. }

…and make sur the jquery script only loads when thr query is loaded :

add_action('init', 'register_QuickGlossary_script');
  1. add_action('wp_footer', 'print_QuickGlossary_script');
  2.  
  3. function register_QuickGlossary_script() {
  4.  wp_register_script('QuickGlossary', plugins_url('QuickGlossary.js', __FILE__), array('jquery'), '1.0', true);
  5. }
  6.  
  7. function print_QuickGlossary_script() {
  8.  global $add_QuickGlossary_script;
  9.   if ( ! $add_QuickGlossary_script ) return;
  10.   wp_print_scripts('QuickGlossary');
  11. }
  12.  
  13. //nb.: requires setting the global var to true in the widget function
  14.     global $add_QuickGlossary_script;
  15.     $add_QuickGlossary_script = true;

…and proceed to generating the output, the data list :

the output

Straight forward, using DL as list container, tagname and description as list of DT DD elements, with an added class=”more” to the DD description as hook for jQuery.

function QuickGlossary_datalist($tags) {
  1.    $html = '
  1. ';
  2.   return $html;
  3. }

You can edit your tag description under Admin-Posts-Post Tags menu.

Now my main widget function is :

function widget_QuickGlossary($args) {
  1.     extract($args);
  2.  
  3.     if(!is_single()) return;
  4.  
  5.     global $post;
  6.     $tags = get_the_tags($post-&gt;ID);
  7.     if(!$tags) return;
  8.  
  9.     global $add_QuickGlossary_script;
  10.     $add_QuickGlossary_script = true;
  11.  
  12.     quickGlossary_scripts();
  13.  
  14.     echo $before_widget;
  15.     echo $before_title . 'Glossary' . $after_title;
  16.  
  17.     echo QuickGlossary_datalist($tags);
  18.  
  19.     echo $after_widget;
  20. }

Activate the widget, drag and drop it from Admin-Appearance-Widgets menu and it is a Quick Glossary, if you want to play with it, code is overhere as zip.

spot the bot

I have some overhead scripts fetching data that can cost a few seconds extra loading time. Having traffic trigger tasks saves me the trouble of using cron-jobs, but I don’t want to run overhead scripts with visitors or googlebot on the site. Apart from that, some routines can use a lot of resources which are wasted on some crawlers.

I actually want the crawlers to come around, so I will make an array with bots and allowed_bots. Whatever is not on the white-list gets a meager page with overhead jobs attached to it, the rest (iow visitors and the big search engines) get the standard page.

There are truckloads of bots (see crawltrack), for my purposes a few regulars will do.

  1.  
  2. //hook it into 'init', run when calling script
  3. add_action( 'init', 'spotabot' );
  4.  
  5. /**
  6.  * checks if visitor is a bot
  7.  *
  8.  * This method checks the http_user_agent string
  9.  * to see if the visitors is a non-essential bot
  10.  *
  11.  * @param void
  12.  * @return void
  13.  */
  14.  
  15. /*
  16.    if(IS_A_BAD_BOT) {}
  17. */
  18. function spotabot()
  19. {
  20.     $bot_list = array("Teoma", "betaBot", "alexa", "froogle", "Gigabot", "inktomi",
  21.     "looksmart", "URL_Spider_SQL", "Firefly", "NationalDirectory",
  22.     "Ask Jeeves", "TECNOSEEK", "InfoSeek", "WebFindBot", "girafabot",
  23.     "crawler", "www.galaxy.com", "Googlebot", "Scooter", "Slurp",
  24.     "msnbot", "appie", "FAST", "WebBug", "Radian6", "Spade", "ZyBorg", "rabaz",
  25.     "Baiduspider", "Feedfetcher-Google", "TechnoratiSnoop", "Rankivabot",
  26.     "Mediapartners-Google", "Sogou web spider", "WebAlta Crawler");
  27.  
  28.     $bot_allowed = array("Googlebot", "Feedfetcher-Google", "Mediapartners-Google", "Slurp", "Baiduspider", "msnbot");
  29.  
  30.     foreach($bot_list as $bot) {
  31.         if(strpos(strtolower("x".$_SERVER['HTTP_USER_AGENT']), strtolower($bot))>0)
  32.         {
  33.             foreach($bot_allowed as $okbot) {
  34.                  if($okbot==$bot) {
  35.                     define("IS_A_BAD_BOT", false);
  36.                     return;
  37.                  }
  38.            
  39.             define("IS_A_BAD_BOT", true);
  40.             return;
  41.             }
  42.         }
  43.     }
  44.    
  45.     define("IS_A_BAD_BOT", false);
  46.     return;
  47. }

In templates and functions i can use some simple code to run stuff conditional :

  1. if (defined('IS_A_BAD_BOT')) {
  2.    if(IS_A_BAD_BOT)
  3.    {
  4.     echo "hi bot<br />";
  5.                                 run_time_consuming_overhead_tasks();
  6.                                 and_omit_the_sidebar();  
  7.    } else {
  8.     echo "hello wonderful visitor<br />";
  9.    }
  10.   }
  11. //if it is not defined it is not a bot or the function ain't present,
  12. //I am lazy and sloppy and don't want a code-break

It would be nice if WordPress built in a switch to run plugins conditional.

one related smart plugin is the chennai central plugin that sends 304 not modified headers on conditional GETs, so crawlers don’t fetch the page. That can save some bandwidth and serverload.

quick note : serp plugin beta

I am developing a new google serp plugin for wordpress. I developed it over the weeknd on wp2.8, it should run on anything with a ‘shutdown’ hook and jquery. I will be adding some other stuff to it over the next few weeks, but I thought I’d put a beta on the blog. If you try it, I hope it runs, send some feedback.

If you have some ideas about cool features drop me a note, I might put it in there. I was pondering on a rest service to pool sem-data and develop some competitor analysis functionality, but that is just a vague idea.