Here's a plugin I wrote that you might be interested in. It displays all
of the categories on a site in a hierarchical format using "%%collapse".
All it needs is the prefix that you use for categories, and it defaults
that to "Category." like Wikipedia uses. Visit
https://encyclopaedia-wot.org/Wiki.jsp?page=Special.Categories to see it
in action.
Gary
--
Gary Kephart
Facebook: gary.kephart
Twitter: @garykephart
"The penalty that good men pay for not being interested in politics is to be
governed by lesser men." -- Plato.
/**
*
*/
package com.jspwiki.extensions.plugin;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.wiki.api.core.Context;
import org.apache.wiki.api.core.Engine;
import org.apache.wiki.api.exceptions.PluginException;
import org.apache.wiki.api.plugin.Plugin;
import org.apache.wiki.references.ReferenceManager;
import org.apache.wiki.render.RenderingManager;
/**
* Displays the category hierarchy for the site.
*
* Usage: [{CategoryHierarchyPlugin page='Category.Contents'
prefix='Category.'}]
*
* @author gary_kephart
*
*/
public class CategoryHierarchyPlugin implements Plugin
{
public static final String DEFAULT_PREFIX = "Category.";
public static final String PARAM_PREFIX = "prefix";
public static final int MAX_LEVELS = 25;
/**
*
*/
@Override
public String execute(
Context context,
Map<String, String> params) throws PluginException
{
Engine engine = context.getEngine();
final ReferenceManager refMgr = engine.getManager(ReferenceManager.class);
final RenderingManager rendMgr = engine.getManager(RenderingManager.class);
String prefix = params.get(PARAM_PREFIX);
StringBuilder result = new StringBuilder(256);
final Set<String> allPageNames = refMgr.findCreated();
List<Category> rootCategories;
if (prefix == null)
prefix = DEFAULT_PREFIX;
if (allPageNames != null)
{
SortedMap<String, Category> categories = findAllCategories(prefix,
allPageNames);
processCategories(refMgr, prefix, categories);
rootCategories = getRootCategories(categories);
result = renderCategories(engine, rootCategories, context);
} // end if there are pages
else
result.append("No pages were found");
return rendMgr.textToHTML(context, result.toString());
}
/**
* @param prefix
* @param allPageNames
* @return
*/
public SortedMap<String, Category> findAllCategories(
String prefix,
final Set<String> allPageNames)
{
SortedMap<String, Category> categories = new TreeMap<String, Category>();
for (String pageName : allPageNames)
{
if (pageName.startsWith(prefix))
{
Category category = new Category(pageName);
categories.put(pageName, category);
}
}
return categories;
}
/**
* @param categories
* @return
*/
public List<Category> getRootCategories(
SortedMap<String, Category> categories)
{
List<Category> rootCategories = new ArrayList<Category>();
for (Category category : categories.values())
{
if (category.isRootCategory())
rootCategories.add(category);
}
Collections.sort(rootCategories);
return rootCategories;
}
/**
* @param refMgr
* @param prefix
* @param categories
*/
public void processCategories(
final ReferenceManager refMgr,
String prefix,
SortedMap<String, Category> categories)
{
for (Category category : categories.values())
{
Collection<String> referrers =
refMgr.findReferrers(category.getPageName());
if (referrers != null && referrers.size() > 0)
{
for (String referrer : referrers)
{
if (referrer.startsWith(prefix))
{
Category subCategory = categories.get(referrer);
if (subCategory != null)
{
category.addSubcategory(subCategory);
subCategory.addParentCategory(category);
}
}
else
{
// Category content
category.incrementContentPageCount();
}
} // end loop through referrers
} // end if there are referrers
} // end loop through categories
}
/**
* @param engine
* @param rootCategories
* @param context
* @param output
*/
public StringBuilder renderCategories(
final Engine engine,
List<Category> rootCategories,
Context context)
{
//final RenderingManager renderingManager =
engine.getManager(RenderingManager.class);
final StringBuilder output = new StringBuilder();
int listLevel = 1;
output.append(System.lineSeparator())//
.append("%%collapse");
for (Category rootCategory : rootCategories)
{
renderCategory(output, rootCategory, listLevel);
}
output.append(System.lineSeparator())//
.append("%%");
return output;
}
public void renderCategory(
StringBuilder output,
Category category,
int listLevel)
{
int pages = category.getContentPageCount();
String pagesLabel = pages == 0 ? "no pages" : (pages == 1 ? "1 page" :
pages + " pages");
output//
.append(System.lineSeparator())//
.append(StringUtils.repeat("#", listLevel))//
.append(" [")//
.append(category.getPageName())//
.append("] (" + pagesLabel + ")");
if (listLevel < MAX_LEVELS)
{
for (Category subCategory : category.getSubCategories().values())
{
renderCategory(output, subCategory, listLevel + 1);
}
}
}
}
package com.jspwiki.extensions.plugin;
import java.util.Map;
import java.util.TreeMap;
public class Category implements Comparable<Category>
{
private int contentPageCount;
private String pageName;
private Map<String, Category> parents;
private Map<String, Category> subCategories;
public Category(String pageName)
{
super();
this.contentPageCount = 0;
this.pageName = pageName;
this.parents = new TreeMap<String, Category>();
this.subCategories = new TreeMap<String, Category>();
}
public void addParentCategory(
Category category)
{
this.parents.put(category.getPageName(), category);
}
public void addSubcategory(
Category subCategory)
{
this.subCategories.put(subCategory.getPageName(), subCategory);
}
@Override
public int compareTo(
Category that)
{
return this.pageName.compareTo(that.pageName);
}
public int getContentPageCount()
{
return contentPageCount;
}
public String getPageName()
{
return pageName;
}
public Map<String, Category> getSubCategories()
{
return subCategories;
}
public void incrementContentPageCount()
{
this.contentPageCount++;
}
public boolean isRootCategory()
{
return this.parents.isEmpty();
}
public void setContentPageCount(
int contentPageCount)
{
this.contentPageCount = contentPageCount;
}
public void setPageName(
String pageName)
{
this.pageName = pageName;
}
public void setSubCategories(
Map<String, Category> subCategories)
{
this.subCategories = subCategories;
}
/**
*
*/
@Override
public String toString()
{
return getPageName();
}
}