# Blosxom Plugin: FmtCat # Author: Uncle Roger (http://www.sinasohn.net/notebooks/) # Based on: prettycategory by Randall Hand (yerase@yeraze.com) # Version: 1.40 # Date: 01/17/2005 # License: GPL # # This plugin is based heavily on prettycategory by Randall Hand # # FmtCat # # Formats Categories nicely with separators. # # Description # # Here's a quick summary of what fmtcat can do for you: # # - Capitalize the first letter of category names # - Insert a user defined spacer (such as ">" or "-") between # levels of categorization # - Prepend a top-level category name (such as "Home" or "Top") # - Substitute user defined category descriptions for directory # names at each level of categorization # - Turn each category name/description into a link to a # category-level-specific journal page # - Give you the current category (that is, the bottom level of the # current category tree # - Provided access to descriptions for each category # # For more information on each option, read the comments in the # configuration section. # # Usage: # # fmtcat exposes three variables for your use. They provide a nicely # formatted category string, with optional links, the current, bottom- # level category, and a description of the current, bottom-level # category. Perhaps the best way to explain this is by example. # # Consider a post in the category "meat", which is in the categories # "dinner" and "food". The path to this post would be # "/food/dinner/meat". Given this example, fmtcat gives you the # following values (assuming the default settings): # # variable value # -------- ------------------------------------------- # fmtcat Food :: Dinner :: Meat # lastcat Meat # catlevel 3 # catdesc For carnivores only! # # Each of these would be links to the appropriate category (i.e., the # word food would link to your food category, dinner would link to # food/dinner, and meat (in both instances) would link to the # food/dinner/meat category.) # # Most of this behavior is configurable -- see the configuration # section for more info. # # Okay, so how do you actually use this? The simple answer is that # you simply include "$fmtcat::fmtcat" in your story flavour file # where you want the formatted category to show up. If you just want # the last category displayed, you would use "$fmtcat::lastcat". To # get the level number, use "$fmtcat::catlevel" and to get the # category description, use "$fmtcat::catdesc". That's about it. # # As of version 1.30, fmtcat also works in the head flavour file. It # has not been tested in the foot or any other flavour file. # # Configuration: # # There are a number of variables that control what this plugin does # and what the output looks like. See the configuration section # for a complete description of each. # # # Updates, Bug Fixes, and Enhancements # # If you find a bug or have a suggestion for an enhancement, please # let me (Uncle Roger) know via the contact form at: # # http://www.sinasohn.net/contact.html # # Of course, feel free to modify this to suit your own needs. If you # make a change that would benefit the blosxom community at large, # please share your work by letting me know so I can update the # official version. # # Latest Version # # The latest version of fmtcat can always be found at: # # http://www.sinasohn.net/downloads/blosxom/plugins/ # # or via the plugin registry at the Unofficial Blosxom User Group # website: # # http://blosxom.ookee.com/ # # Update History: # # Date Version Pgmr Description # 01.01.2005 V1.0 RLS Initial Released Version # 01.14.2005 V1.1 RLS Added ability to alias category names # 01.17.2005 V1.2 RLS Added ability to turn category levels # into links to category pages. (Thanks # to Jason Bourne for helping me to # figure this one out.) # 01.22.2005 V1.3 RLS Added the lastcat and catdesc variables. # Also added a title attribute to links. # Modified program flow and added a head # subroutine to make it all work in the # head flavour file. (Thanks to Jason # Clark, from whose storystate plugin I # stole the means to do this.) # 01.27.2005 V1.40 RLS Added conditional removal of HTML tags # (defined as a <> pair and anything # between then) for use in the title # attribute of anchors. Also added # another variable, catlevel, which tells # you how many levels down the category # tree you can find the current category. # package fmtcat; use CGI::Carp qw( fatalsToBrowser ); # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Configuration Section # # There are several variables that can be changed to control how # fmtcat works. They are: # # cap_flag - Controls capitalization of categories # spacer - Defines category separator # home_text - Defines a top level category name # cat_flag - Controls directory name replacement # category_names - Lists human readable category names for # directories # link_flag - controls whether or not categories will be # links to the corresponding category page # category_descs - provides descriptions for specified categories # # Each is described in detail below. The default values are # all valid so you don't even have to do anything, if you don't # mind your categories looking the way mine do. # #----------------------------------------------------------------------- # cap_flag controls whether or not each level of the category # tree is to be capitalized. If set to "Y", then the first # letter of each category level will be capitalized. For example, # # food/dinner/meat # # would become # # Food/Dinner/Meat # # If you don't want capitalization, (You know who you are, e. e.) # set this flag to "N" (or, actually, any value other than "Y"). $cap_flag = "Y"; #----------------------------------------------------------------------- # spacer is the text that will separate each level of the # category tree. Possible spacers include: # # Spacer Description Sample # ------ -------------- --------------------------- # " > " Yahoo Style Food > Dinner > Meat # " :: " Arts & Crafts Food :: Dinner :: Meat # " | " Unix Geek Food | Dinner | Meat # ", " Librarian Food, Dinner, Meat # # Feel free to make up your own, of course. Also, there doesn't # seem to be any reason that this couldn't be an tag to # use a graphic as the spacer instead. $spacer = " :: "; #----------------------------------------------------------------------- # home_text is used to add a top level category to the category # tree. If you don't want one, uncomment the first definition # by removing the number sign (#) at the start of the line and # adding one at the start of the second definition (the line # where it is given the value "Home" by default. # # Examples: # # Given a hierarchy of: # # /Food # /Food/Dinner/ # /Food/Dinner/Meat # /Food/Dinner/Veg # /Drink # /Drink/Coffee # /Drink/Coffee/Sumatra # # With a home_text of "Home", and a spacer of " > ", these would be # displayed as follows: # # Home > Food # Home > Food > Dinner # Home > Food > Dinner > Meat # Home > Food > Dinner > Veg # Home > Drink # Home > Drink > Coffee # Home > Drink > Coffee > Sumatra # # With no home_text defined and the same spacer, the categories # would look like this: # # Food # Food > Dinner # Food > Dinner > Meat # Food > Dinner > Veg # Drink # Drink > Coffee # Drink > Coffee > Sumatra # # It's your choice as to what you prefer. It seems to me that if you # never post stories at that top level, you would probably not want a # home_text defined. If you do, then might want one. # Remove the number sign from this line to disable the home category #$home_text; # Put your text in this variable (and leave the previous line alone) # if you want a top level category added. Possible values include # "Home", "Top", your journal name, or whatever you like. $home_text = "Home"; #----------------------------------------------------------------------- # cat_flag controls whether or not to check the directory name against # a list (see Category_Names below) to get a nicer, more natural # category name. Set it to "Y" (the default) to turn on this feature, # "N" to turn it off. Basically, if this flag is on, FmtCat goes # through the list of directories in Category_Names and if it finds any, # swaps them for the nicer description. For example, if the list # included "rovers" which had a description of "Land Rovers": # # 'rovers' => 'Land Rovers' # # then any entries in the rovers directory would have, instead, # "Land Rovers" in the formatted category string. Any directories # not found would be left the same. That is, if "rovers" was the # only directory in the list, then "home" would not be changed. $cat_flag = "Y"; #----------------------------------------------------------------------- # category_names is the list of directories and the text to be # displayed for each. If no change is necessary (that is, you # want "family" to stay "family"), then it need not be included # in this list. Anything, however, that you do want translated # for display should be listed. # # The format is simple: # # '[dir]' => '[display]' # # Separate multiple pairs with a comma: # # 'fred' => 'Fredrick Flinstone', # 'barney' => 'Barney Rubble' # # Note that the last pair should not have a comma. # %category_names = ( 'food' => 'Edibles', 'veggies' => 'Vegetables', ); #----------------------------------------------------------------------- # link_flag is used to control whether or not each level of the category # will be a link to the page for that particular category. For example, # if a post was in the category hierarchy "food/dinner/meat", then if # this flag is turned on, the word "food" would link to "/food/", # "dinner" would link to "/food/dinner/", and "meat" would link to # "/food/dinner/meat/". Set the value to "Y" (the default) to turn this # feature on and "N" to turn it off. $link_flag = "Y"; #----------------------------------------------------------------------- # category_descs contains pairs of categories and descriptions. If the # current category is found in the list (the left side), the description # (on the right side) is returned in the variable catdesc (use # "$fmtcat::catdesc" to get access to it in your flavour files.) This # could be useful in the head file for category-based pages. It is also # returned as the title attribute of category links in the formatted # category strings. # # To define your descriptions, put the categories on the left side in # single quotes (use the actual directory name) and the description on # the right side of the "=>". Separate pairs by commas. %category_descs = ( 'food' => 'More than bread and water', 'breakfast' => 'Morning repast', 'lunch' => 'Midday Munchies', 'dinner' => 'The nighttime meal', 'meat' => 'For carnivores only!', 'veggies' => 'What food eats' ); #----------------------------------------------------------------------- # Chances are, you'll want to leave this one alone. What it does is # control the removal of HTML tags from the category descriptions before # they are put in the title attribute of links. That is, if you have # linking turned on (see $link_flag above), the links for each category # will have the associated description included as a title. For # example, the link for the category "/food" would (given the default # settings) would be: # # food # # The title attribute is commonly used for "tooltips" by web browsers. # If you put HTML tags in your descriptions (which is perfectly # acceptable, btw), they are displayed as part of the tooltip, which # doesn't look so good. (As an example, the descriptions I use at # are mostly quotes and I've # embedded a
(line break) to put the name of the person quoted # on a separate line.) # # So, the rem_tags flag, if set to yes, simply causes fmtcat to remove # any HTML tags when putting the descriptions into the title attributes. # # If that's it, why bother with a flag; why not just do it? Because you # might want to use the "<" and ">" in your descriptions for something # other than HTML (as I did above, to wrap a URL) and would want to turn # this behaviour off. So, long-story-short, leave this alone unless you # know you want to change it. (Set it to "N" to turn it off, btw.) $rem_tags = "Y"; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # use vars qw/ $fmtcat $lastcat $catdesc /; sub start { 1; } sub story { my ($pkg, $path, $filename, $story_ref, $title_ref, $body_ref) = @_; $fmtcat = $path; process($fmtcat); 1; } sub head { my($pkg, $currentdir, $head_ref) = @_; $fmtcat = $blosxom::path_info; $fmtcat =~ s#/[^/]+\.[^/]+$##; $fmtcat = "/" . $fmtcat; process($fmtcat); 1; } sub process { my $mycat = $_[0]; my $mypath = $mycat; $catlevel = ($mycat =~ tr:/:/:); if ($link_flag eq "Y") { $mycat =~ s:\/(\w+):$spacer . &anchor($mycat,$1):eg; } else { $mycat =~ s:\/(\w+):$spacer . &rename_cat(&cap_cat($1)):eg; } $mycat =~ s:^$spacer::g; if ($home_text) { if ($link_flag eq "Y") { my $dirdesc; if ($category_descs{$home_text}) { $dirdesc = " title=\"" . $category_descs{$home_text} . "\""; } else { $dirdesc = " title=\"" . $blosxom::blog_title . "\""; } if ($rem_tags eq "Y") { $dirdesc =~ s/<(.*)>//gs; } $mycat = "" . $home_text . "" . $spacer . $mycat; } else { $mycat = $home_text . $spacer . $mycat; } } $lastcat = lastcat($mypath); $catdesc = getdesc($mypath); $fmtcat = $mycat; } sub lastcat { my $currpath = $_[0]; my $currurl = $blosxom::url . $currpath . "/"; $currpath =~ m:/([^/]*)$:; $currcat = cap_cat(rename_cat($1)); my $dirdesc; if ($category_descs{$1}) { $dirdesc = " title=\"" . $category_descs{$1} . "\""; if ($rem_tags eq "Y") { $dirdesc =~ s/<(.*)>//gs; } } if ($link_flag eq "Y") { return "" . $currcat . ""; } else { return $currcat; } } sub getdesc { my $descpath = $_[0]; $descpath =~ m:/([^/]*)$:; return $category_descs{$1}; } sub anchor { my $mypath = $_[0]; my $mydir = $_[1]; my $dirloc = index($mypath,$mydir); my $dirurl = $blosxom::url . substr($mypath,0,$dirloc + length($mydir)) . "/"; my $dirdesc; if ($category_descs{$mydir}) { $dirdesc = " title=\"" . $category_descs{$mydir} . "\""; if ($rem_tags eq "Y") { $dirdesc =~ s/<(.*)>//gs; } } $dispdir = rename_cat($mydir); $dispdir = cap_cat($dispdir); return "" . $dispdir . ""; } sub rename_cat { my $rename_dir = $_[0]; if ($cat_flag eq "Y") { foreach my $thiskey (keys %category_names) { $rename_dir =~ s/$thiskey/$category_names{$thiskey}/egi; } } return $rename_dir; } sub cap_cat { my $cap_dir = $_[0]; if ($cap_flag eq "Y") { return uc(substr($cap_dir,0,1)) . substr($cap_dir,1); } else { return $cap_dir; } } 1;