Was this page helpful?

TagDirectory

     

    Introduction

    The TagDirectory template creates a multi-column display of a list of pages based on their tags.  The directory can include all non-prefixed tag or only those with a given prefix (e.g. "category:dog").  The TagDirectory uses the ListPages template to list each tag group.  The caller can specify the options used by ListPages for full control on how the results are displayed.

    History

    Version Date Author Description
    1.0 6/09/2009 SteveB first version
    1.1 9/29/2009 SteveB fixed an issue with not showing untagged pages as "(unclassified)"

    Requirements

    • This template requires MindTouch version 9.02
    • This template requires the ListPages template

    How do I install it?

    1. Create a template, call it "Template:TagDirectory" (or rename as you desire).  You must have UNSAFECONTENT permission for this to work.
    2. Create a "DekiScript" block on the template page (use the "Style" menu in the editor")
    3. Copy the code from the end of this page and paste it into the DekiScript block.  To copy, click "expand source", then mouse over the top right corner of the source code, and click the "view source" button.  This will pop up a window with the source code.  Select all, then copy to clipboard.
    4. Make sure there isn't an extra blank paragraph after the DekiScript block! Do this every time you edit!!!  
    5. Save.

     

    A quick note about the examples on this page

    For all the examples on this page, the code is shown before the working example.  The code is shown with the syntax extension, and looks like this:

    TagDirectory()

    This means that the actual code on the page should be enclosed in a DekiScript block.  If you want to copy the code from this page, then use the same procedure as described in steps 2-4 above. 

    How do I use it?

     

    Arguments

    Name
    Type
    Default
    Description
    pages map/list/str subpages of current page List or map of pages to show in the list.  If the parameter is of type str, then it is used as the parent page of the pages to list.
    tagPrefix str only unprefixed tags Only use tags with given prefix (e.g. 'category:dog').  The prefix is automatically stripped.
    columnCount num 2 Number of columns to display.
    listPagesOptions map { sort: 'viewcount', reverse: true, style: 'bullets' } Options passed into the ListPages template for listing each column entry.

    Examples

    Show the 10 most popular pages for each tag prefixed with "type:".

    TagDirectory{ pages: 'Deki/Extensions', tagPrefix: 'type', columnCount: 3, listPagesOptions: { limit: 10 }}
    
    App
    Template
    (Unclassified)
    Script
    Native
    Php

     

    Reference(s)

     

    Credits/Special Thanks

     

    Template/Extension Source Code

    /***
        USAGE:
    
        TagDirectory(pages, tagPrefix, columnCount, listPagesOptions) 
            build a multi-column tag directory for a list of pages
    
        PARAMETERS:
    
        (optional) pages : list/map/str
            list/map of pages to list; if pages is a str, then it is used as a path to a parent page to list all subpages; 
            defaults to list of subpages of current page
    
        (optional) tagPrefix : str
            only use tags with given prefix (e.g. 'category:dog'); defaults to using only unprefixed tags
    
        (optional) columnCount : num
            number of columns to display; defaults to 2
    
        (optional) listPagesOptions : map
            options passed into the ListPages template for listing each column entry; 
            defaults to { sort: 'viewcount', reverse: true, style: 'bullets' }
    
    ***/
    
    var pages = $0 ?? $pages ?? page.subpages;
    if(pages is str) let pages = wiki.getpage(pages).subpages;
    if(pages is map) let pages = map.values(pages);
    var tagprefix = $1 ?? $tagprefix;
    var columns = num.max($2 ?? $columnCount ?? 2, 1);
    var listPagesOptions = { sort: 'viewcount', reverse: true, style: 'bullets' } .. ($4 ?? $listPagesOptions ?? { });
    
    // build map of all tags in pages
    var tagmap = { }; 
    foreach(var p in pages) { 
        var tags = p.tags; 
    
        // check if page has no tags; if so make up a default list
        if(!#tags) {
            let tags = [ { name: (tagprefix ? tagprefix .. ':' : '') .. '(unclassified)', type: 'text' } ];
        }
    
        // for each tag on the page, append the page to that tag's list
        foreach(var t in tags where t.type == 'text') {
    
            // check if either the tag prefix matches or there is no tag prefix
            var parts = string.split(t.name, ':', 2);
            if(tagprefix && (#parts == 2) && (string.compare(parts[0], tagprefix, true) == 0)) {
                let tagmap ..= { (parts[1]) : tagmap[parts[1]] .. [ p ] };
            } else if(!tagprefix && (#parts == 1)) {
                let tagmap ..= { (parts[0]) : tagmap[parts[0]] .. [ p ] };
            }
        } 
    }
    
    if(#tagmap) {
    
        // count how many pages each tag has
        var tag_count = [ { tag: tag, count: #tagmap[tag] } foreach var tag in map.keys(tagmap) ]; 
    
        // balance columns so that their heights are as equal as possible
        var column_tags = list.new(columns, [ ]);
        var column_sums = list.new(columns, 0);
    
        foreach(var t in list.sort(tag_count, 'count', true)) { 
    
            // find shortest column
            var column = list.indexof(column_sums, list.min(column_sums));
    
            // update column
            let column_tags = list.splice(column_tags, column) .. [ column_tags[column] .. [ t.tag ] ] .. list.splice(column_tags, 0, column + 1);
            let column_sums = list.splice(column_sums, column) .. [ column_sums[column] + (listPagesOptions.limit ?? t.count) + 2 ] .. list.splice(column_sums, 0, column + 1);
        }
    
        // emit the table with N columns
        <table width="100%" cellspacing="0" cellpadding="5" border="0" style="table-layout: fixed;">
            <tr valign="top">
    
                // loop over each column
                foreach(var column in column_tags) {
                    <td style="padding-right: 20px;">
    
                        // loop over all tags in column, sorted alphabetically
                        foreach(var tag in list.sort(column)) {
                            <h5> string.tocamelcase(tag) </h5>
                            template("ListPages", listPagesOptions .. { pages: tagmap[tag] });
                        }
                    </td>
                }
            </tr>
        </table>
    }
    

     

    Disclaimers

    None.

    Was this page helpful?
    Tag page
    Viewing 6 of 6 comments: view all
    Hello,

    Thanks for this feature :-)

    How can I get a list of all tags on my site ? Take all tags (all recursive)

    Thanks
    Posted 00:52, 18 Feb 2010
    @dranakan This template doesn't support that. You'd have use to modify it to use site.tags, which gives a list of all tags without needing to load all pages ahead of time (much, much faster).
    Posted 04:26, 18 Feb 2010
    Thanks SteveB,

    Bad but fast : replace line 34 "foreach(var p in pages) { " by " foreach(var p in wiki.getsearch('type:wiki',10000)) {"
    This is bad code (using site.tags should be better)
    Posted 05:22, 18 Feb 2010
    so is it possible to simply create a list that shows pages with a specific tag? edited 19:05, 4 Mar 2010
    Posted 19:04, 4 Mar 2010
    @kochm yes, you can feed in an arbitrary list of pages using wiki.getsearch()
    Posted 04:14, 5 Mar 2010
    Is there any way to sort the entries so they are ascending from top to bottom, starting from column 1?

    ie: 2 columns with A-P in the first, then Q-Z in the 2nd column, in that order.
    Posted 22:22, 17 May 2010
    Viewing 6 of 6 comments: view all
    You must login to post a comment.

    Copyright © 2011 MindTouch, Inc. Powered by