[paid accounts] Multilevel Tags (Sidebar and Tags Page)

Jan 26, 2007 12:00

By naming your tags using a delimiter, for example animals:cats:tabbies or animals:cats:siamese, where the colon is the delimiter, this code allows you to display your tags as a hierarchical list.

This is an updated version of this obsolete tutorial. This new version takes advantage of new features in the layout and provides additional instructions for using the code on your Tags Page. If you are interested in knowing the differences between the old code and the new code, they are documented here.

Multilevel Tags in the Sidebar




1. Make sure you have created a theme layer.

2. Do you already have the print_sidebar_tags function in your layer? If so, then you need to delete that existing version from your layer. You can only have one version of a function in a layer, and keeping your old way of showing the sidebar tags list will prevent the multi-level list from showing up. If you need both styles of list to show up, or you are wary of deleting the existing function for some other reason, please make your layer viewable and comment here with the layer id or a link to the layer.

3. Copy and paste the following function into your layer:

function print_sidebar_tags() {

##### Config #####

# Specify your delimiter. One char only -- extra chars get truncated.
var string delimiter = ":";

# Do you want to show the tag use counts? Set to true or false.
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 = """ $tier""";
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.
if (($tag_list_pos == 0) and ($pos == 0)) {
# mt:20061216
# The outermost ul is supplied later by print_sidebar_box,
# so omit it from this stage.
$list = $list + """
  • $tier_code""";
    $closing_html[$pos] = "
  • ";
    }
    else {
    $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 = size $closing_html;
    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++;
    }
    $list = $list + $remaining_html;

    var string list_title = ($*text_sidebar_tags != "") ? "
  • $*text_sidebar_tags
  • " : "";
    print_sidebar_box("""$list_title""", $list, "sidebar_tags");
    }
    }
    4. Look in the ##### Config ##### section of the code you just added. There are several configuration options listed in green:
    • The delimiter: var string delimiter = ":";
      By default, the code looks for colons in your tag names to figure out what the different tag levels are. You can change the blue text to a different character, such as | or ~. You must then use that character in your tag names, for instance the tag animals:cats:tabbies would become animals~cats~tabbies. Use the Tags Management page to rename your tags.
    • Showing the use counts: var bool show_count = true;
      If you would like to show how many times a tag has been used beside each tag name, leave this set to true. To hide the count, change the blue text to false.
    • Text before the use counts: var string pre_count = "[";
      If you chose to show use counts, this is the text that will display to the left of the count number. By default, the use count displays between square brackets. You can remove the blue text completely to get rid of the bracket, or replace it with other text of your choosing.
    • Text after the use counts: var string post_count = "]";
      If you chose to show use counts, this is the text that will display to the right of the count number. By default, the use count displays between square brackets. You can remove the blue text completely to get rid of the bracket, or replace it with other text of your choosing.
    5. Click the Save & Compile button and go check out your journal. Your tags should show up in the sidebar in a multilevel list. If the list is there, but it has only one level, make sure your tags are named using the delimiter you set in the previous step.

    6. You may want to decrease the default indentation of the list or make some other style changes. You can add style code to your journal in a variety of ways. Pick one of the ways outlined in the Adding Custom CSS tutorial and then experiment with the CSS below.
    • Reduced indentation, no bullets

      #sidebar_tags ul.sbarcontent ul {
      padding-left: 0;
      margin-left: 0;
      }

      #sidebar_tags ul.sbarcontent li.sbaritem ul li {
      padding-left: 15px;
      margin-left: 0;
      }
    • Reduced indentation, with bullets

      #sidebar_tags ul.sbarcontent, #sidebar_tags ul.sbarcontent ul {
      padding-left: 15px;
      margin-left: 0;
      }

      #sidebar_tags ul.sbarcontent li.sbaritem {
      list-style: disc;
      padding-left: 0;
      margin-left: 15px;
      }

      #sidebar_tags ul.sbarcontent li.sbaritem ul li {
      padding-left: 0;
      margin-left: 0;
      }
    • Fixed height with vertical scrollbar

      #sidebar_tags ul.sbarcontent {
      height: 200px;
      overflow: auto;
      }
    7. To position your tags list higher or lower in the sidebar, go to the Sidebar section of the Custom Options page and reorder the sidebar boxes as usual. The multilevel tags list will be placed in whatever position you place the Tags box.


    Multilevel Tags in the Tags Page




    1. This code will insert a multilevel tag list in a pseudo-entry on your tag page. You can find the tag page here:

    http://yourusername.livejournal.com/tag/

    2. Make sure you have created a theme layer.

    3. Do you already have the TagsPage::print_body function in your layer? If yes, you'll need to merge it with the new code. If you have difficulties doing that, make your layer viewable and comment here with the layer id or a link to the layer, without forgetting to post your error message.

    4. If not, copy and paste the following code in your layer:

    function TagsPage::print_body {

    ##### Config #####

    # Specify your delimiter. One char only -- extra chars get truncated.
    var string delimiter = ":";

    # Do you want to show the tag use counts? Set to true or false.
    var bool show_count = true;

    # Specify the page title. Defaults to the core layer's value for
    # the Tags Page title. Change to your text, surrounded by quotes, eg:
    # var string page_title = "My Tags List";
    var string page_title = $*text_tags_page_header;

    ##### End Config #####

    var string list = "";

    if (size $this->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 ($this->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""";
    if ($show_count) {
    var string uses = get_plural_phrase($t.use_count, "text_tag_uses");
    $tier_code = $tier_code + """ - $uses""";
    }
    }
    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.
    if (($tag_list_pos == 0) and ($pos == 0)) {
    # mt:20061216
    # The outermost ul is supplied later so omit it from this stage.
    $list = $list + """
  • $tier_code""";
    $closing_html[$pos] = "
  • ";
    }
    else {
    $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 = size $closing_html;
    $i = ($i <= 0) ? 0 : $i - 1;
    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++;
    }
    $list = $list + $remaining_html;
    }

    #### Print the tag list in an entry-like post ####

    print """

    $page_title

      $list


    """;
    }
    4. Look in the ##### Config ##### section of the code you just added. There are several configuration options listed in green:
    • The delimiter: var string delimiter = ":";
      By default, the code looks for colons in your tag names to figure out what the different tag levels are. You can change the blue text to a different character, such as | or ~. You must then use that character in your tag names, for instance the tag animals:cats:tabbies would become animals~cats~tabbies. Use the Tags Management page to rename your tags.
    • Showing the use counts: var bool show_count = true;
      If you would like to show how many times a tag has been used beside each tag name, leave this set to true. To hide the count, change the blue text to false.
    • The tags page title: var string page_title = $*text_tags_page_header;
      The Tags Page title is set to the core layer's tags page header value, Visible Tags. To change it to something else, replace $*text_tags_page_header with your own text in quotes:
      var string page_title = "My Tags List";
    5. Click the Save & Compile button and go check out your journal's Tags Page. Your tags should show up in a multilevel list. If the list is there, but it has only one level, make sure your tags are named using the delimiter you set in the previous step.

    6.You may want to decrease the default indentation of the list or make some other style changes. You can add style code to your journal in a variety of ways. Pick one of the ways outlined in the Adding Custom CSS tutorial and then try the CSS below:

    .ljtaglist, .ljtaglist ul {
    margin-left: 0;
    padding-left: 0;
    }
  • !tutorial, sidebar, tags, paid accounts

    Previous post Next post
    Up