// SiteTagCloud template, by neilw and maphew, 2009
// Versions
// 1.0.0 10/06/09 neilw Quick hack based on maphew's TagCloud template
// 1.0.1 11/05/09 neilw Small bug fix
// 1.1.0 11/06/09 neilw Refactored arguments, added "align" arg and error messages
// 1.2.0b 12/02/09 neilw Added ability to search only within specified subtree
// 1.2.1 12/11/09 neilw Added "exclude" capability back in (whoops)
// 1.3.0 3/4/2010 neilw Made "path" parameter case-insensitive
// Gracefully handle case when there are no tags
//
// This template is derived from maphew's TagCloud template. It is optimized for
// providing a tag cloud for an entire site; performance is reasonable even with a large number
// of tags on the site. I have refactored the way the arguments work to my own taste, and also
// added extensive error checking and reporting on the args.
//
// USAGE: SiteTagCloud( order, max, color, size, sizeUnits, exclude, showCount, align, path );
// order: str (valid values: "name" or "count") (default "count")
// Specifies how the tags are sorted in the list
// max: num (default:50)
// Specifies the maximum number of tags to be displayed. 0 ==> show all tags
// color: list (default: [ [50,200,50], [50,100,50] ])
// Specifies the color range for displayed tags. May be either a single list of [r,g,b]
// (in which case all tags will be that color) or a list of two [r,b,g] lists, where tags
// with the fewest occurrences will be shown in the first color, and tags with the most
// occurrences will be shown with the second color. Other numbers of occurrences will be
// interpolated between the two.
// size: num or list (default: [80,240])
// Specifies the size range for displayed tags. If a single number is specified, all tags
// will shown in that size. If a list of two numbers is specified, then the tags with fewest
// occurrences will be shown in the first size, and those with the most will be shown in the
// second. Others will be interpolated in between.
// sizeUnits: str (default: "%")
// CSS units for the size argument.
// exclude: str or list (default: [])
// Tag(s) to exclude from the cloud. May be either a single tag given as a string, or a
// list of tags given as a list of strings.
// showCount: bool (default:false)
// Show the number of hits on each tag as a superscript next to the tag
// align: str (default: "left")
// Specifies the text alignment for the tag cloud. Standard CSS values are available.
// path: str (default: "")
// Specifies root of subtree to look in. Defaults to entire site.
var errors = [];
//**************
// Process Args
//**************
// order
var defaultOrder = "name";
var tagOrder = string.tolower($0 ?? $order ?? defaultOrder);
if (tagOrder != "name" && tagOrder != "count") {
let errors ..= [ "ORDER must be either 'name' or 'count' (using default)" ];
let tagOrder = defaultOrder;
}
// max
var defaultMax = 50;
var tagsLimit = $1 ?? $max ?? defaultMax;
if (tagsLimit is not num || tagsLimit < 0) {
let errors ..= [ "MAX must be a number >= 0 (using default)" ];
let tagsLimit = defaultMax;
}
// color
var defaultColor = [ [50,200,50], [50,100,50] ];
var color = $2 ?? $color ?? defaultColor;
if (color is list && #color == 3) let color = [ color,color ];
if (color is not list || #color != 2 ||
color[0] is not list || #color[0] != 3 || color[1] is not list || #color[1] != 3 ||
#list.select(color[0]..color[1], "$ is not num || $ < 0 || $ > 255"))
{
let errors ..= [ "COLOR must be a list of 3 numbers, or list of two lists of three numbers;" ..
" each number must be in the range 0-255 (using default)" ];
let color = defaultColor;
}
// size and sizeUnits (processing these together)
var defaultSize = [ 80,240 ];
var defaultUnits = "%";
var sizeMinMax = $3 ?? $size ?? defaultSize ;
var sizeUnits = $4 ?? $sizeUnits ?? defaultUnits;
if (sizeMinMax is num) let sizeMinMax = [ sizeMinMax, sizeMinMax ];
if (sizeMinMax is not list || sizeMinMax[0] is not num ||sizeMinMax[1] is not num) {
let errors ..= [ "SIZE must be a number or list of two numbers (using default)" ];
let sizeMinMax = defaultSize;
let sizeUnits = defaultUnits;
}
// exclude
var defaultExclude = [];
var tagsToExclude = $5 ?? $exclude ?? defaultExclude;
if (tagsToExclude is str) let tagsToExclude = [ tagsToExclude ];
if (tagsToExclude is not list) {
let errors ..= [ "EXCLUDE must be a string or list of strings (using default)" ];
let tagsToExclude = defaultExclude;
}
// showcount
var hitShow = $6 ?? $showCount ?? false;
// align
var align = $7 ?? $align ?? "left";
// path
var path = $8 ?? $path;
if (path is not str) {
if (path is not nil) let errors ..= [ "PATH must be a string" ];
let path = "";
}
let path = string.replace(path," ","_");
// bail out if errors, to give quick feedback
if (#errors)
<div style="color:red">
<strong> "SiteTagCloud encountered errors:" </strong>;
<ul> foreach (var e in errors) <li> e </li>; </ul>;
</div>;
else {
//****************************************
// Pre-process font size and color values
//****************************************
var minSize = sizeMinMax[0];
var sizeRange = sizeMinMax[1] - minSize;
var colorMin = { r:color[0][0], g:color[0][1], b:color[0][2] };
var colorRange = { r:color[1][0]-colorMin.r, g:color[1][1]-colorMin.g, b:color[1][2]-colorMin.b };
//******************
// Process the tags
//******************
// convert list of excluded tags into a map (easier to check if tag is excluded)
let tagsToExclude = { (t): true foreach var t in tagsToExclude };
// compute map of tags based on site data and excluded tags
var tagMap = {};
foreach (var t in site.tags) {
var tag = string.startswith(t.name, "define:") ? string.substr(t.name, 7) : t.name;
if (tagsToExclude[tag]) continue;
var count = #path ?
#[ 0 foreach var p in t.pages where string.startswith(p.path,path,true) ] :
#t.pages;
let tagMap ..= { (tag) : count + (tagMap[tag] ?? 0) };
}
// compute list of tags sorted by occurrence count
var tagListofMaps = [ { name: string.tocamelcase(t), count: tagMap[t] }
foreach var t in map.keys(tagMap) where tagMap[t] > 0 ];
var tagsTotal = #tagListofMaps;
let tagListofMaps = list.sort(tagListofMaps, 'count', true);
if ((tagsLimit > 0) && !__request.args.alltags)
let tagListofMaps = list.splice(tagListofMaps, tagsLimit);
//****************
// emit tag cloud
//****************
<div id="tagCloud">
<div style=("text-align:" .. align)>
if (#tagListofMaps) {
// pre-calculate some shortcut variables
var maxValue = tagListofMaps[0].count;
var minValue = tagListofMaps[#tagListofMaps-1].count;
var minLog = num.log(minValue);
var logRange = num.log(maxValue) - minLog;
// Re-sort the list
let tagListofMaps = list.sort(tagListofMaps, tagOrder, (tagOrder == "count"));
// Output the cloud!
foreach (var tm in tagListofMaps) {
var tagURI = site.uri & "Special:Tags" & { tag:tm.name };
var weight = ( num.log(tm.count) - minLog ) / logRange;
var size = minSize + num.round(sizeRange * weight);
var color = "color:rgb(" ..
num.min(colorMin.r + num.round(weight*colorRange.r),255) .. "," ..
num.min(colorMin.g + num.round(weight*colorRange.g),255) .. "," ..
num.min(colorMin.b + num.round(weight*colorRange.b),255) .. ");";
<span style=("padding-right:5px; font-size:" .. size .. sizeUnits)>
<a href=(tagURI) style=(color)> tm.name </a>;
if (hitShow)
<sup style=(color.."font-size: x-small")> "(" .. tm.count .. ")" </sup>;
" ";
</span>;
}
}
else "(no tags)";
</div>;
if (!__request.args.alltags && (tagsLimit > 0) && (tagsTotal > tagsLimit)) {
"Showing top " .. tagsLimit .. " tags. ";
<a href=((page.uri & { alltags: "_" }).."#tagCloud")> "See all "..tagsTotal.." tags »" </a>;
}
</div>;
}
| Images 0 | ||
|---|---|---|
| No images to display in the gallery. |
Copyright © 2011 MindTouch, Inc. Powered by
Best TagCloud ever!
But is it possible to include a path argument, so I can use that template to show the tags of a subpage.
Or maybe just include page.path, so where ever I use the template, only the tags of this page with subpage will be shown. edited 06:40, 2 Dec 2009
In case you haven't seen it yet, the functionality has been added. Enjoy!
Oh, hadn't seen it yet.
Thanks a lot!
Is it possible to exclude all chronotags by using something like that:
SiteTagCloud(exclude:"Date:*")
I can't get the exclude function work!
I tried the following with no success:
SiteTagCloud{max:25, exclude: "tag1", align: "center" }
What Syntax do I need for the excluding tags?
I enter SiteTagCloud{path: "User:<username>"} and get a TagCloud of all pages from the user. edited 23:17, 23 Feb 2010
Is it possible to exclude types of tags or tags with prefixes? I have a lot of chronotags and don't want them shown up in the TagCloud.
Sorry for my slow response, I forgot to put this page on my watchlist. Suggest you take further discussion to this forum thread: http://forums.developer.mindtouch.com/showthread.php?t=6558.
You're using the exclude param correctly: you provide it either a string or a list of strings. I'll check into that. I'll also look into how to exclude chronotags and such. I have an idea, but need to see how to implement.
I guess i need to put together a proper documentation page for this template!