?

Log in

No account? Create an account

Previous Entry | Next Entry

Multi-level Tags in Sidebar

  • Feb. 28th, 2007 at 9:50 PM
This function changes the display of tags in the sidebar into a hierarchical table. In order for it to work, tags must have one or more delimiter in them. For example, you will have to have entries tagged like "animals:pets:cats", "animals:pets:dogs", "cars:toyota", "icons:buffy", "fanfic:harry potter" and so forth. This code will display the tags in a nested unordered list. Original code for Flexible Squares by murklins, so if something isn't working, talk to her. ;)

Instructions: First create your theme layer, if you don't have one already. Copy and paste the code into the layer, and add the following into the Custom CSS section of the Customization area:
.categories-widget .widget-list .item {margin: 0 0 0 20px;}
The variables in blue can be customized to change the delimiter in the tags or to display the tag count.

function print_module_tags(string title) {

#####   Config   #####
  # Specify your delimiter.  One char only -- extra chars get truncated.
  var string delimiter = ":";
  # Do you want to show the tag use counts?
  var bool show_count = true;
  # Specify the text to show just before the use count, if any
  var string pre_count = "[";
  # Specify the text to show just after the use count, if any
  var string post_count = "]";
##### End Config #####

  var Page p = get_page();
  var string list = "";

  if (size $p->visible_tag_list() > 0) {
    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 = """<a href="$t.url">$tier</a>""";
            if ($show_count) {
              $tier_code = $tier_code + """ ${pre_count}${t.use_count}${post_count}""";
            }
          }
          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 + """<ul class="widget-list"><li class="item">$tier_code""";
            $closing_html[$pos] = "</li></ul>";
          }
          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 + """<ul class="widget-list"><li class="item">$tier_code""";
              $closing_html[$pos] = "</li></ul>";
            }
            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 + """</li><li class="item">$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++;
    }
    $list = $list + $remaining_html;
  }

  open_module("categories", $title, "");
  print """$list""";
  var string tags_url = $p.journal->base_url() + "/tag/"; # TODO: Need Page.view_url{"tags"} which doesn't exist yet.
  print """<div class="widget-footer"><a href="$tags_url" title="$*text_sidebar_tags">$*text_sidebar_tags</a></div>\n""";
  close_module();
}
Hit "Save and Compile", ensuring that the code compiles correctly (i.e., without errors).
Set your just-compiled theme layer to be the active one from the Choose Journal Style page by clicking on "Your Custom Layers" in the left sidebar, then selecting "Apply Theme" under the appropriate layer.

Here is a sample image, using grrliz_icons's journal as an example:

A worthwhile modification to the function would be to print the tag tree in the tags page instead of (or in addition to) in the sidebar. The method would be similar to this one for a tag cloud on the tags page.

Comments

( 45 comments — Leave a comment )
nimoloth
Mar. 1st, 2007 03:19 pm (UTC)
Nice! Might try that sometime. I'll need to work up the motivation to re-tag stuff though, and I don't know if I'm enthusiastic enough. I still haven't gone back and locked early entries.
av8rmike
Mar. 1st, 2007 03:41 pm (UTC)
Yeah, it requires a tremendous amount of organization to use something like this properly. But with all the icon/banner/fanfic/etc. communities out there, I figured someone would be interested and organized enough to warrant posting this.
harmonatrix
Mar. 1st, 2007 05:52 pm (UTC)
Nice!!!! Will "Memorize" this post and see about doing this this weekend.

Thanks for the info!
wistfuljane
Mar. 2nd, 2007 05:01 am (UTC)
murklins has coded one for Expressive here if you're interesting in checking & comparing.
wistfuljane
Mar. 2nd, 2007 05:07 am (UTC)
D'oh, never mind - I noticed from the comments that you were already aware of the post. Ignore this. *scuffles away*
427
May. 22nd, 2007 07:43 pm (UTC)
Thank you ever so much!!!!!
agneson9
Aug. 20th, 2007 01:44 am (UTC)
is it possible to truncate the number of tags displayed?
av8rmike
Aug. 20th, 2007 02:39 am (UTC)
In what way?
[Please edit and title your post!] - agneson9 - Aug. 22nd, 2007 07:19 am (UTC) - Expand
[Please edit and title your post!] - agneson9 - Aug. 22nd, 2007 07:43 am (UTC) - Expand
[Please edit and title your post!] - av8rmike - Aug. 23rd, 2007 12:46 pm (UTC) - Expand
brown_betty
Sep. 3rd, 2007 07:48 pm (UTC)
Hi, I used your tutorial, with some modifications, to give myself a tag-list in Opal. Do you know if there's a way to suppress empty tags?
av8rmike
Sep. 4th, 2007 02:25 am (UTC)
There might be, but why not delete the unused tags at the Manage Tags page?
[Please edit and title your post!] - brown_betty - Sep. 4th, 2007 02:27 am (UTC) - Expand
[Please edit and title your post!] - av8rmike - Sep. 4th, 2007 02:59 am (UTC) - Expand
[Please edit and title your post!] - brown_betty - Sep. 4th, 2007 04:54 pm (UTC) - Expand
agneson9
Oct. 7th, 2007 03:58 pm (UTC)
i'd like to apply tiered tags to the tags page. what changes should be made to the code for tiered tags in sidebar?



i also use a code to count the number of tags and number of times tags are used
av8rmike
Oct. 7th, 2007 11:31 pm (UTC)
Change
function print_module_tags(string title){
to
function TagsPage::print_body(){
Unless you want to use the multi-level tags on both the tags page and sidebar, in which case you'd need to have identical code for both separate functions.
agneson9
Oct. 8th, 2007 01:58 pm (UTC)
just having some problems

Error compiling layer:

Compile error: line 489, column 27: Unknown local variable $title
S2::NodeVarRef, S2/NodeVarRef.pm, 178
S2::NodeTerm, S2/NodeTerm.pm, 162
S2::NodeTerm, S2/NodeTerm.pm, 66
S2::NodeExpr, S2/NodeExpr.pm, 46
S2::NodeArguments, S2/NodeArguments.pm, 61
S2::NodeTerm, S2/NodeTerm.pm, 181
S2::NodeTerm, S2/NodeTerm.pm, 66
S2::NodeExpr, S2/NodeExpr.pm, 46
S2::NodeExprStmt, S2/NodeExprStmt.pm, 35
S2::NodeStmtBlock, S2/NodeStmtBlock.pm, 101
S2::NodeFunction, S2/NodeFunction.pm, 230
S2::Checker, S2/Checker.pm, 353
S2::Compiler, S2/Compiler.pm, 34

open_module("categories", $title, "");
av8rmike
Oct. 9th, 2007 12:29 pm (UTC)
Oh, I see. If this is for the TagsPage, delete the five lines that start with open_module("categories", $title, ""); and replace it with these:

print safe """<h2 class="asset-name page-header2">$*text_tags_page_header</h2>""";
print """$list""";


You could also change the names of the CSS classes in this function to style the TagsPage differently than the sidebar, if you wanted.
[Please edit and title your post!] - agneson9 - Oct. 9th, 2007 12:57 pm (UTC) - Expand
onlysayinghello
Dec. 2nd, 2007 04:56 am (UTC)
lollobrigida using the journal she's in the middle of fixing here.

I'm trying to see if I can use a text-transform: uppercase; in here, but use it only to change the main category on the list of tags. So that it would be on this journal, I already just sort of slapped it in there once, but it changed all the text to uppercase, and I'd like the subTag to still be lowercase if possible.

00 OUT OF CHARACTER
* contact [2]
* information [3]
av8rmike
Dec. 2nd, 2007 07:29 pm (UTC)
Would the headings only be tags that have zero uses? I think there may be a way to specify a format for the plain-text top-level tags, but if those tags have any uses, it may not work.
[Please edit and title your post!] - lollobrigida - Dec. 2nd, 2007 09:56 pm (UTC) - Expand
[Please edit and title your post!] - av8rmike - Dec. 3rd, 2007 01:59 pm (UTC) - Expand
[Please edit and title your post!] - onlysayinghello - Dec. 11th, 2007 04:47 am (UTC) - Expand
[Please edit and title your post!] - av8rmike - Dec. 11th, 2007 05:39 am (UTC) - Expand
[Please edit and title your post!] - onlysayinghello - Dec. 11th, 2007 05:50 am (UTC) - Expand
[Please edit and title your post!] - av8rmike - Dec. 11th, 2007 06:02 am (UTC) - Expand
[Please edit and title your post!] - onlysayinghello - Dec. 11th, 2007 06:32 am (UTC) - Expand
[Please edit and title your post!] - av8rmike - Dec. 11th, 2007 01:09 pm (UTC) - Expand
[Please edit and title your post!] - lollobrigida - Dec. 11th, 2007 06:25 pm (UTC) - Expand
[Please edit and title your post!] - onlysayinghello - Dec. 11th, 2007 06:27 am (UTC) - Expand
danielefton
Jun. 4th, 2008 10:30 am (UTC)
headdesk
I can't sleep and decided I wanted to alter my tags for this, but first wanted to get this implemented.

I designed my current layout using custom css on an unstyled expressive style.

When I create a custom theme layer and apply that style everything shifts to the right and nothing in my sidebars shift to the second one (using twt layout) this also increases the space between the first sidebar and the alpha column.

Adding the source code from the unstyled expressive theme layer to my custom theme layer leaves most of my custom css intact, but the space between the sidebar and the alpha column still exists, and the second sidebar doesn't exist.

I'd prefer not to have to redo my css. In looking at my custom layers I notice that a user layer is created with the contents of the custom CSS. How do the custom layers interact?

Thanks for your help!
av8rmike
Jun. 5th, 2008 01:00 pm (UTC)
Re: headdesk
There's a tutorial for setting up a theme layer in Expressive here; I'd suggest you read through that as it'll probably answer most of your questions.
leixela
Jul. 28th, 2008 09:54 pm (UTC)
Is it possible to do this with a 3-column layout? I would like my tags to show up on the right as a tiered list. I have tried a tinkering with the CSS for the past few hours and looking through the posts here but nothing has worked so far. Thanks in advance to anyone who can shed some light on this.
av8rmike
Jul. 28th, 2008 10:13 pm (UTC)
It works with all of the column arrangements.
[Please edit and title your post!] - leixela - Jul. 28th, 2008 10:26 pm (UTC) - Expand
orexisbella
May. 15th, 2010 07:01 am (UTC)
I'm having a minor issue with this -- for some reason, when I change show tag use count to true, it wraps the tag counts underneath each tag. (I've turned it back to false for now, but see here for a screenshot.) I've been digging around with Web Dev and Firebug, but can't figure out which bit of my stylesheet could possibly be causing it.

If possible, I'd also like to align the tag list so that the top layer is flush left with the edge of the widget (ie no indent for the top layer). Again, I can't figure out which bit of my CSS it is and it's driving me nuts. <_<

Layer source is here; live preview of the style is here.
av8rmike
May. 25th, 2010 03:39 am (UTC)
Wow, I'm sorry I let this go without a reply for so long. Are you still having problems? Can you re-enable the tag usage counts?
[Please edit and title your post!] - orexisbella - May. 25th, 2010 02:27 pm (UTC) - Expand
[Please edit and title your post!] - av8rmike - May. 25th, 2010 03:14 pm (UTC) - Expand
[Please edit and title your post!] - orexisbella - May. 25th, 2010 04:45 pm (UTC) - Expand
[Please edit and title your post!] - av8rmike - May. 25th, 2010 06:30 pm (UTC) - Expand
noyj189
Feb. 17th, 2013 05:53 am (UTC)
I'm alone and online Go Here welcomemyhomecat.blogspot.com
( 45 comments — Leave a comment )

Latest Month

March 2016
S M T W T F S
  12345
6789101112
13141516171819
20212223242526
2728293031  

S2 Help Communities

Tags

Powered by LiveJournal.com
Designed by chasethestars