murklinstest (murklinstest) wrote in component_help,
murklinstest
murklinstest
component_help

Bi-level Tags in Sidebar

This is code to display your tags in a sidebar component. Similar to my multi-level component, but simpler, designed for those who anticipate never needing more than two levels of tags. By naming your tags using a delimiter, for example animals:cats or animals:dogs, where the colon is the delimiter, you can display a two-level list of tags. If more than one delimiter is used (animals:cats:tabbies) all delimiters after the first are ignored. If you feel your tags list will take up too much space in the sidebar, there is example styling provided to limit the component'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.

function print_free_text(Page p)
{

#####   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 string list = ""; 
    # mt:20050627
    # Replaced erroneous return code with if statement (otherwise any 
    # additional free text components placed below this code would not print!).
    if (size $p->visible_tag_list() > 0) 
    {
        # mt:20050624
        # Can't use delimiter longer than one char, so truncate if necessary.
    	if ($delimiter->length() > 1)    
        {
            $delimiter = $delimiter->substr(0, 1);
        }
        
        var bool list_started = false;
        var string list_item = "";
        var string[] prev_tags = ["", ""];
        
        # mt:20050624: Start the list.
        $list = """<ul class="tagList">"""; 
        
        foreach var TagDetail t ($p->visible_tag_list()) 
        {        
            var string[] tags;
         
            if ($t.name) 
            {  
                # mt:20050624
                # Split tags into a 1- or 2-element array on delimiter. Oh god, my
                # kingdom for a function.  Adapted from lj-user rane500's explode 
                # function to only care about first instance of the delimiter.
                var int array_counter = 0;
                var string buffer = "";
                var bool found_delimiter = false;
                foreach var string char ($t.name) 
                {
                    if (($found_delimiter == false) and ($char == $delimiter))
                    {
                        $found_delimiter = true;
                        $tags[$array_counter] = $buffer;
                        $array_counter = $array_counter + 1;
                        $buffer = "";
                    }
                    else 
                    {
                        $buffer = $buffer + $char;
                    } 
                }  
                $tags[$array_counter] = $buffer;
                
                # mt:20050624: Now examine the tags array to determine how to display the tag.
                if (size $tags == 1)
                {
                    # mt:20050624: This tag has no subtag.
    
                    if ($list_started)
                    {
                        # mt:20050624: Previous tag had a subtag, so must close its outstanding list.
                        $list = $list + """</ul>""";
                        $list_started = false;
                    }
                    if ($prev_tags[0] != "")
                    {
                        # mt:20050624: This is not the very first tag in the list, so close off previous tag.
                        $list = $list + """</li>""";
                    }
                    # mt:20050624: Now add the new tag.
                    $list = $list + """<li class="tagItem"><a href="$t.url">$tags[0]</a>""";
                }
                else
                {   
                    # mt:20050624: This tag has a subtag.
            
                    $list_item = """<li class="tagItem"><a href="$t.url">$tags[1]</a></li>""";
               
                    if (($tags[0] == $prev_tags[0]) and ($list_started))
                    {
                        # mt:20050624
                        # This tag fits under the previous tag's tier, and it is not the first item in that tier.
                        $list = $list + $list_item;
                    }
                    elseif (($tags[0] == $prev_tags[0]) and ($list_started == false))
                    {
                        # mt:20050624
                        # This tag fits under the previous tag's tier, and it is the very first item in that tier.
                        $list = $list + """<ul class="tagList">""" + $list_item;
                        $list_started = true;
                    }       
                    elseif (($tags[0] != $prev_tags[0]) and ($list_started))
                    {
                        # mt:20050624: This tag initializes a new tier and must also close off the previous tag's list.
                        # $list_started retains its true state. 
                        $list = $list + """</ul></li><li class="tagItem">$tags[0]<ul class="tagList">""" + $list_item;
                    }
                    elseif (($tags[0] != $prev_tags[0]) and ($list_started == false))
                    {
                        # mt:20050624: This tag initializes a new tier but does not have to close off a list.
                        
                        if ($prev_tags[0] != "")
                        {
                            # mt:20050624: This is not the very first tag in the list, so close off previous tag.
                            $list = $list + """</li>""";
                        }
                    
                        # mt:20050624: Now add the new tag.
                        $list = $list + """<li class="tagItem">$tags[0]<ul class="tagList">""" + $list_item;
                        $list_started = true;
                    }
                }
                $prev_tags = $tags;           
            }        
            # mt:20050623: Next tag in the list!
        }  
    
        # mt:20050624: Close any outstanding lists, including the surrounding tagbox list.
        if ($list_started)
        {
            $list = $list + """</ul>""";
        }
        $list = $list + """</li></ul>""";
    
        # mt:20050624: Add surrounding div tag for styling purposes.
        $list = """<div class="tagBox">""" + $list + """</div>""";
    }

    # mt:20050627: This adds the Tags component, if there are visible tags.
    if ($list != "")
    {
        print_comp_header($tag_title);
        """$list""";
        print_comp_footer();
    }  
}

# mt:20050623
# If you're like me, you'll want to tighten up the default list formatting, and maybe you 
# want to scroll your long tag list.  The tag list is enclosed in a div called tagBox, 
# the ul list items are all classed as tagList, and the list items are classed as tagItem.
# Alter the styles below however you like.
function Page::print_custom_head() {
    """
    <style media="screen" type="text/css">

    /* Tighter lists */
    ul.tagList {padding-left: 0; margin-left: 0; list-style: none; line-height: normal;}
    li.tagItem {padding-left: 15px; list-style: none; line-height: normal;}

    /* Vertical Scroll */
    /* Need to shrink the list width to prevent horizontal scrollbar in Firefox. */
    /* Note this won't prevent it if your tags are super long, it will only */
    /* prevent it from displaying unnecessarily. For the pleasure of IE users */
    /* you can also colour any resulting scrollbars as you desire. */ 
    ul.tagList {width: 90%;}
    .tagBox {
      height: 200px;
      overflow: auto;
      scrollbar-arrow-color: #dae3b2;
      scrollbar-base-color: #ffffcc;
      scrollbar-face-color: #ffffcc;
      scrollbar-highlight-color: #dae3b2;
      scrollbar-darkshadow-color: #dae3b2;
      scrollbar-shadow-color: #dae3b2;
    }

    </style>
    """;
}

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!

Subscribe

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

  • 25 comments