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>

Comments