RelatedPages

Table of contents
No headers
/***
    USAGE:

    RelatedPages(pages, exclude, limit, parents)
        Show pages related to current page by hierarchy and by see: and keyword: tags.

    PARAMETERS:

    (optional) pages : list (default: child pages of current page)
        List of pages to organize based on their tags.

    (optional) exclude : list (default: none)
        List of pages to exclude from the related list.

    (optional) limit : num (default: 5)
        Limit of related pages to use to determine if additional pages need to be discovered and included in the related list.

    (optional) parents : bool (default: true)
        Show link to parent page if no other links are shown.

***/

// Redirect to custom page, if any
var template_custom = wiki.inclusions(true)[-1].path .. 'Custom';
if (wiki.pageexists(template_custom)) {
    return template(template_custom, $);
}

var pages = $0 ?? $pages;
var exclude = $1 ?? $exclude ?? [ ];
var limit = $2 ?? $limit ?? 5;
var parents = $3 ?? $parents ?? true; 

//--- Aggregate Pages ---

// if no pages were provided, enumerate child pages
if(pages is nil) {
    let pages = [ 
        wiki.getpage(id)
        foreach 
            var id in [ num.cast(xml.text(id)) foreach var id in wiki.tree(_, 1)["//@pageid"] ] 
    ];
}

// find tags with the 'see:' prefix (or no prefix) and include the definition page or related pages
let pages ..= [
    p .. { origin: 'tags' }
    foreach
        var tag in page.tags where (tag.type === 'text') && (string.startswith(tag.name, 'see:', true) || !string.contains(tag.name, ':')),
        var def = tag.definition,
        var p in ((def && (def.id != page.id)) ? [ def ] : tag.pages) where p.id != page.id
];

// find tags with the 'keyword:' prefix and include search results for them
if(#pages < limit) {
    var terms = [
        '"' .. string.escape(string.substr(tag.name, 8)) .. '"'
        foreach
            var tag in page.tags where (tag.type == 'text') && string.startswith(tag.name, 'keyword:')
    ];
    if(#terms) {
        var searchString = string.join(terms, ' ');
        var defaultSearch = 'type:wiki AND namespace:main';

        // find main guide (tagged article:topic-guide), if any
        var pathSearch = '';
        foreach (var parent in page.parents) {
            var isTopic = #[tag foreach var tag in parent.tags where (tag.type == 'text' && string.endswith(tag.name, 'topic-guide'))] > 0;
            if (isTopic) {
                let pathSearch = ' AND path:' .. parent.path .. '/*';
                break;
            }
        }

        // keyword must appear in title
        var titleSearch = ' AND title:' .. searchString;
        var searchQuery = defaultSearch .. titleSearch .. pathSearch;

        let pages ..= [
            p .. { origin: 'keyword' }
            foreach 
                var p in wiki.getsearch(searchString, limit - #pages, _, searchQuery)
        ];
    }
}

// de-duplicate pages
var uniquepages = [ ];
var pageids = [ ];
foreach(var p in pages) {
    if((p.id != page.id) && (p.id not in pageids) && (p.id not in exclude)) {
        let pageids ..= [ p.id ];
        let uniquepages ..= [ p ];
    }
}
let pages = list.sort(uniquepages, 'path');

// trim to limit
if (#pages > limit) {
   let pages = list.splice(pages, limit - #pages);
}

<div class="noindex">
    <div class="mt-related-pages">
        
    if (#pages > 0) {    
        template("MindTouch/Controls/ListPages", {
                pages: pages,
                style: "bullets",
                sort: "path"
            });
     }
     else if (parents) {
         template("MindTouch/Controls/ListPages", {
                pages: [ page.parent ],
                style: "bullets",
                sort: "path"
            });
     }
    </div>
</div>
 
Page statistics
53 view(s), 1 edit(s) and 3995 character(s)

Tags

This page has no custom tags set.

Comments

You must to post a comment.

Attach file

Attachments