Multi-Level Tags in Sidebar

Jun 26, 2005 00:48


This is code to display your tags in a sidebar box. By naming your tags using a delimiter, for example animals:cats:tabbies or animals:cats:siamese, where the colon is the delimiter, you can display a heirarchical list of tags. If you feel your tags list will take up too much space in the sidebar, there is example styling provided to limit the box's length and display a scrollbar.

While I wanted badly to make this code cleaner with functions, I read that that is technically not allowed in user and theme layers and can only be done by creating a new class. So I didn't do that. That means it's ugly. Since Flexible Squares is open source, if you're feeling more ambitious I suggest creating a new layout based on the Flexi-Squares code and adding this code to your layout as a separate function. That would allow you to extract some of the more repitious code in here into global utility functions, giving you a much cleaner solution.

This code needs way more testing so if you decide to take a chance and use it, but experience problems, let me know, please. I will hunt those bugs down! This is my very first attempt at s2 customization so please be kind.

Colour coding:
  • Comments
  • Variables
  • Code that can be deleted to remove the scrollbar option.


function print_sidebar() { ##### Config ##### # Specify your delimiter! One char only -- extra chars get truncated. # Making the delimiter an empty string will result in an un-tiered list, # which may be what you prefer. but this code is serious overkill for # that purpose. var string delimiter = ":"; # Specify the title of your tag box! var string tag_title = "Tags"; ##### End Config ##### var Page p = get_page(); var string list = ""; # mt:20050627 # Replaced erroneous return code with if statement (otherwise # sidebar not printed at all if no visible tags!). if (size $p->visible_tag_list() > 0) { # mt:20050625 # Can't use delimiter longer than one char, so truncate if necessary. if ($delimiter->length() > 1) { $delimiter = $delimiter->substr(0, 1); } var string[] closing_html; var string[] prev_tags; var int tag_list_pos = 0; var string tier_code = ""; $closing_html[0] = ""; $prev_tags[0] = ""; foreach var TagDetail t ($p->visible_tag_list()) { var string[] tags; if ($t.name) { # mt:20050623 # Split tags into array on delimiter. Oh god, my kingdom # for a function. Stolen shamelessly from lj-user rane500. var int array_counter = 0; var string buffer = ""; foreach var string char ($t.name) { if($char == $delimiter) { $tags[$array_counter] = $buffer; $array_counter = $array_counter + 1; $buffer = ""; } else { $buffer = $buffer + $char; } } $tags[$array_counter] = $buffer; var int pos = 0; foreach var string tier($tags) { if (size $closing_html <= $pos) { # mt:20050623 # $closing_html keeps track of html that is used to close off open # lists. Its length must be kept >= to that of the current tag. $closing_html[$pos] = ""; } if (size $prev_tags <= $pos) { # mt:20050625 # The current tag has more tiers than the previous tag. To avoid array # ref errors when comparing the current tier to the previous one (which # is non-existent, of course) add empty string to $prev_tags. $prev_tags[$pos] = ""; } # mt:20050623 # If we're on a tag's last tier, we need to return a link to the tag, # otherwise plain text is returned. if (size $tags == ($pos + 1)) { $tier_code = """ $tier"""; } else { $tier_code = """$tier"""; } # mt:20050625 # $prev_tags stuffed with dummy empty string when it has fewer tiers than # current tag. if ($prev_tags[$pos] == "") { # mt:20050623 # The current tag has more tiers than the previous tag, so a new # list must be opened. $list = $list + """
  • $tier_code"""; $closing_html[$pos] = "
"; } elseif ($tags[$pos] != $prev_tags[$pos]) { # mt:20050623 # The current tag's tier is not the same as the previous tag's tier of # the same level. This means we may need to close some lists. var int i = 0; foreach var string html ($closing_html) { if ($i > $pos) { $list = $list + $closing_html[$i]; # mt:20050623: As we append the closing code, pop it off the array. $closing_html[$i] = ""; } $i++; } if ($closing_html[$pos] == "") { # mt:20050623 # This is the first tier at this level, so open list. $list = $list + """
  • $tier_code"""; $closing_html[$pos] = "
"; } else { # mt:20050623 # There have already been tiers added at this level, so just close the previous # list item before adding the new tier. $list = $list + """
  • $tier_code"""; } } else { # mt:20050623 # The current tag's tier is exactly the same as the previous tag's tier at # this same level. It has already been included in the list, so do nothing. } # mt:20050623: Moving on to next tier in this tag! $pos++; } $prev_tags = $tags; } # mt:20050623: Next tag in the list! $tag_list_pos++; } # mt:20050623 # All the tags have been added so close all outstanding lists. var int i = 0; var string remaining_html = ""; foreach var string html ($closing_html) { if ($html != "") { $remaining_html = $html + $remaining_html; $closing_html[$i] = ""; } $i++; } # mt:20050624: Enclose the entire list in an li tag as required by the layout. $list = """
  • """ + $list + $remaining_html + """
  • """; # mt:20050623: Add styling to box title. $tag_title = """
  • $tag_title
  • """; } ##### Specify Box Order ##### # mt:20050627 # Okay, now that's done, just print out all your sidebar boxes in the order you # want, including a call for this one -- print_sidebar_box($tag_title, $list) -- # nested within an if statement to prevent tags box from printing in the event # of no visible tags. print_userpic(); print_sidebar_blurb(); if ($list != ""){print_sidebar_box($tag_title, $list);} print_sidebar_linklist(); print_sidebar_calendar(); ##### End Box Order ##### } function Page::print_custom_head() { """ """; } Screenshots

    Here's what you get without scrollbars:



    Here's what you get with scrollbars (in Firefox):



    Caveat

    If you use the scrollbox styling and you have long tag names that don't employ enough whitespace to break over several lines, browsers other than IE will show a hideous horizontal scrollbar along the bottom.

    July 28, 2005: Adjusted for new TagDetail class in Core Layer.

    June 27, 2005: This code was edited to fix a bug. Heartfelt thanks go to lab_brat for detecting the problem and anchan218 for pinpointing the source of the trouble. Thanks also go out to all of you who are using this crazy experimental code!

    !old, sidebar, tags

    Previous post Next post
    Up