plugin-category-cloud (A README Experience)
A plugin for Micro.blog that creates a page displaying links to your categories layed out as a category cloud. Its code lives here.
If you feel like viewing its use out in the wild, you can mosey on over to my category cloud:
Where It's At
Once installed, the generated page will be found at [SCHEME]://[HOSTNAME]/cloud/
. By default, the content file, content/cloud.md
, registers a menu item for the page:
+++
title = "Cloud"
description = "A category cloud weighted by posts per category."
type = "cloud"
[menu.main]
name = 'Cloud'
title = 'Cloud'
identifier = 'cloud'
url = '/cloud/'
weight = 110
+++
{{< plugin-category-cloud >}}
If you'd rather use the native Micro.blog page interface, locate this file and make it look like this:
+++
title = "Cloud"
description = "A category cloud weighted by posts per category."
type = "cloud"
+++
{{< plugin-category-cloud >}}
If you'd rather not have a dedicated page for your category cloud, feel free to delete content/cloud.md
entirely. You can stick the cloud anywhere you like by invoking the partial from a template like so:
{{ if templates.Exists "partials/plugin-category-cloud/category-cloud.html" }}
{{ partial "plugin-category-cloud/category-cloud.html" . }}
{{ end }}
If you do invoke the partial from a template, be sure to include the relative page path in Config.PagePaths per the parameter's documentation.
Parameters, Where TF are the Parameters?
The parameters live in data templates under the data/plugin_category_cloud
directory.
data/plugin_category_cloud/Config.toml
contains debug and build related parameters:
# Debug and build related parameters.
#####################################
# Theme version, printed to HTML comment when the plugin loads.
#
Version = '6.0.9'
# Whether to print HTML comments for debugging purposes.
#
DebugPrint = false
# Whether to provide subresource integrity by generating a
# base64-encoded cryptographic hash and attaching a .Data.Integrity
# property containing an integrity string, which is made up of the
# name of the hash function, one hyphen and the base64-encoded hash sum.
#
Fingerprint = true
# Output style for /assets/sass/category-cloud.scss.
# Valid options are nested, expanded, compact and compressed
#
SassOutput = 'compact'
# The relative paths of pages that should link to the stylesheet.
# Leave the array empty to always link to the stylesheet. The stylesheet
# is always linked for the page generated at /cloud/. If you want to
# remove the generated page from the menu and/or insert the cloud elsewhere
# you can enter the relative page path(s) here to ensure the stylesheet
# is linked for pages wherein you've inserted an invocation of the partial
# (i.e. {{ partial "plugin-category-cloud/category-cloud.html" . }}).
#
# For example, the relative path of the home page would be '/'. The
# relative path for a page like https://my.blog/archive/ would be '/archive/'.
# The relative path for a page like https://my.blog/some/random/page.html would
# be '/some/random/page.html'
#
PagePaths = []
data/plugin_category_cloud/Names.toml
containers parameters relating to how category names will be displayed:
# Configuring the way the cloud displays category names.
########################################################
# 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 (perhaps by 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
# 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
#
[DisplayNames]
# 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'
#
data/plugin_category_cloud/Style.toml
contains mostly stylesheet-related parameters:
# Parameters for styling the cloud.
###################################
# ID to set on the wrapper.
#
WrapperID = 'category-cloud'
# Sass (or CSS) to apply to the wrapper.
#
Wrapper = ''
# Sass (or CSS) to apply to links.
#
Link = ''
# Max font size to use in the cloud in rem units.
#
MaxSize = 2.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
# Whether to display parenthesized page counts along
# with the category names.
#
DisplayPageCounts = false
# Whether to wrap category links with <nobr>
#
UnbreakableLinks = true
Read the comments in the files, I took the time to write them. As far as parameters go, this bunch is fairly straight forward. Setting DisplayPageCounts = true
, for example, would land you a cloud kinda like:
Set Humanize = false
, and you may end up with a cloud kinda like:
So You're Unhappy with the Style
I knew you would be. That is why I stuck those two hooks in data/plugin_category_cloud/Style.toml
, Wrapper and Link. You can stick whatever Sass or CSS you want between the quotes and the plugin will inject it into the build like so…
@import "vendor/rfs";
#category-cloud {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-content: center;
align-items: baseline;
@include rfs(10px, gap);
@include padding(0 20px);
@include margin(40px auto);
/* Wrapper */
a {
line-height: 1;
padding: 0;
margin: 0;
/* Link */
span {
display: none;
}
@for $i from 1 through /* TotalSteps */ {
&.step-#{$i} {
@include font-size((/* MinSize */rem + $i * /* SizeIncrement */rem));
font-weight: /* MinWeight */ + $i * 100;
}
}
}
}
where TotalSteps is equal to (MaxWeight - MinWeight) ÷ 100
and SizeIncrement is equal to (MaxSize - MinSize) ÷ TotalSteps
.
Planning for Persistence
The downside of ensuring the plugin receives good data by running through Hugo's data template API is that the files in data/plugin_category_cloud
will be overwritten every time the plugin is updated. The solution is to move the files outside of the plugin's directory. All my plugins resolve their parameter values by merging what they find in two specific locations. For this plugin these two locations happen to be data/plugin_category_cloud
and data/plugin-category-cloud
. Files in the dash-cased directory take precedence during the merge. If you have a custom theme, simply create new templates that replicate the plugin files … changing the underscores in the path into dashes.
As an alternative for folks that feel like custom themes are bit much to wrap the head around, I created a plugin solely for the purpose of housing all my plugin's configuration files (with all the values commented out so that overriding parameter values is opt-in (by uncommenting)). The files in that plugin will also be overwritten whenever that plugin updates, but I should hardly ever need to update that repository (at least bump the version of it prompting you to update). If this sounds like the way you want to go, you'll need to create a new plugin and paste the repository address in for cloning (for whatever reason that plugin does not want to register). The process is simple:
- Go to the Design section.
- Click Edit Custom Themes
- Click New Plug-in
- Enter whatever title you like.
- Enter the repository's URL:
https://github.com/moonbuck/plugin-configuration-files
. - Make sure the correct blog is selected.
- Click Add Plug-in
- Locate your new plugin in the list and edit the files to your heart's content.