Plugin for a Category Cloud


*Updated for the latest release*

A plugin for that creates a page displaying links to your categories layed out as a category cloud. Once installed, the generated page will be found at [SCHEME]://[HOSTNAME]/cloud/. It is based upon the category cloud plugin you might already know and love that lives here.


Plugin Interface

The plugin’s parameter interface looks like this:

All of the plugin’s simple parameter values are settable via the interface. All of the simple parameters plus two additional parameters may be set via data file. For an understanding of how my plugins use data files, have a look at this post.

Data File

The template data file is located at data/plugin_category_cloud/params.toml and it looks like this (notice the comments describe what the parameters do):

# Max font size to use in the cloud in rem units.
MaxSize = 1.34

# Min font size to use in the cloud in rem units.
MinSize = 0.9

# Max font weight to use in the cloud.
MaxWeight = 800

# Min font weight to use in the cloud.
MinWeigth = 200

# Category names are fetched in their anchorized form.
# Setting this parameter to true will convert anchorized
# forms into capitalized and spaced forms.
#   my-category → My Category
Humanize = true

# The default path to a category page takes the form:
#  /categories/my-anchorized-category
# If the category has been lifted into the main menu,
# and its path has been altered (perhapse dropping /categories)
# the plugin can try to match a category to its menu item and
# use the URL value of the menu item.
MenuItemMatching = true

# Whether to display parenthesized page counts along
# with the category names.
DisplayPageCounts = true

# Class to set on the cloud's category <a> tags.
Class = 'category-cloud-link'

# List of categories to exclude from the category cloud.
# For example: ['Pinned', 'Temporary']
ExclusionList = [ ]

# The plugin fetches the category names in anchorized form.
# The 'Humanize' parameter will return the category names
# to their capitalized and spaced form. The DisplayNames
# parameter allows for direct control over how a category
# name will be displayed

# To define exactly how to display a specific category name 
# enter its value below with its anchorized form as the key.
# My use case for this option is this category:
# stream-of-consciousness = 'Stream of Conscioussness'


ExclusionList is configured to include a Pinned category. None of the screenshots, however, happen to include such a category. The reason is that I have configured the value of ExclusionList like so:

ExclusionList = ['Pinned]


The screenshot at the top shows a category cloud that includes parenthesized page counts. Configure the value of DisplayPageCounts like so:

DisplayPageCounts = false

And you get a category cloud that’s all:

The CSS for the category cloud gets injected into the page head via layouts/partials/category-cloud-style.html:

{{- /* Inject category cloud styling into page head */ -}}

{{- $display_page_counts := true -}}

{{- /* Resolve the data file and check for parameter value */ -}}
{{- $data_file := site.Data.plugin_category_cloud_params -}}
{{- $data_file = $data_file | default site.Data.plugin_category_cloud.params -}}

{{- with $data_file -}}
  {{- if (isset . "DisplayPageCounts") -}}
    {{- $display_page_counts = .DisplayPageCounts -}}
  {{- end -}}
{{- end -}}
{{- /* Check for value set via plugin parameter interface */ -}}
{{- with site.Params.cloud_display_page_counts -}}
  {{- if (in (slice "true" "false") .) -}}
    {{- $display_page_counts = eq . "true" -}}
  {{- end -}}
{{- end -}}
div#category-cloud { 
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-content: center;
  align-items: baseline;
  gap: 10px 10px;
  width: 90%;
  max-width: 900px;
  padding: 0px 20px;
  margin: 40px auto; 

a.category-cloud-link { 
  color: #666; 
  margin: 0px;
  padding: 0px;
  line-height: 1;

a.category-cloud-link > span.category-count {
  display: {{ cond $display_page_counts "initial" "none" }};

a.category-cloud-link:hover { color: #000; }

The page count spans are always included. The value of DisplayPageCounts controls whether span.category-count elements get their display property set to initial or none. I figure this way it would be easy to toggle them on and off using Javascript should I ever feel the desire.


Set Humanize to false and you get a cloud displaying the anchorized category names kinda like:


Setting Humanize to true will only get you so far. Where I to revert DisplayNames to its default value:


I would end up with a category cloud that was all:

By configuring DisplayNames to override a couple of troublesome category names:

microblog = ''
stream-of-consciousness = 'Stream of Consciousness'

I am able to put the period back into and correct the capitalization in the middle of Stream of Consciousness:


By creating content files within a custom theme, it is totally possible to change the path to a category’s page. I happen to create files for all my categories so I am able to control various page level attributes. For categories that I also include in the main navigation menu, I also alter their URLs to remove /categories. Take the category page for Critters, for example:

title = 'Critters'
description = 'All things critter-related.'
url = '/critters/'
aliases = ['/categories/critters/']

name = 'Critters'
title = 'Critters'
identifier = 'critters'
url = '/critters/'
weight = 60
*All things critter-related.*

Since the plugin generates URLs for the categories that include /categories by default, you can tell the plugin to check the main menu item URLs for an item whose URL’s last path component is equal to the category’s anchorized name. When a match is found, the menu item’s URL will be used in place of the default construction.

Page Configuration

The file living at content/ specifies the front matter for the page.

title = 'Cloud'
description = 'A category cloud weighted by posts per category.'
type = 'cloud'
name = 'Cloud'
title = 'Cloud'
identifier = 'cloud'
url = '/cloud/'
weight = 110

Leave the type alone (as that is what points it to layouts/cloud/single.html). You can play with the title and description values. These set the values I would expect your theme to draw from when constructing the page <head>. The menu.main entry creates a menu item to include the page in your navigation. Leave the url alone as it needs to match the value for type. You can change the value of name to change the text displayed in the navigation link. You can adjust the value of weight to slide the menu item up or down your list of navigation items (amongst other weigthed navigaton items). You can remove the menu entry entirely if you do not want the page to show up in your navigation menu.

If you really, really want the page URL to be something other than /cloud/, it isn’t hard to do. You do, however, need to keep things in sync. Whatever this new value is that is meant to replace cloud, it must also be set in the page front matter for type, and urland … you’ll need to rename layouts/cloud/single.html so that cloud is replaced by this new value as well.

would love to try this as chaintya’s doesn’t seem to be working for either of my designs.
@Moondeer do you intend to get onto plugins page?

Yuppers, just working through the READMEs

Update: right when I was about to @manton went and gave me the Hugo update I’d been wanting … so I refactored the sixteen plugins to take advantage and be consistent … then started on the READMEs and the one for plugin-cards has been taking a while. Finally have an updated rough draft worth reading … after I polish and register that one I’ll do plugin-category-cloud next