Building Micro.blog Custom Themes That Work with Plug-ins
Assumed audience: Micro.blog users who have written or are interested in writing their own custom theme and are familiar with Hugo/Go Templates or other, similar static site generators.
With the introduction of plug-ins, it has become much easier to share ways to expand the functionality of a Micro.blog. Users with custom designs should keep these tips in mind to ensure their themes are compatible with all community plug-ins.
Anatomy of a Plug-in
Plug-ins provide four components that are common in most Hugo themes.
- Static files, such as CSS for styling elements specific to that theme or custom Javascript to add interactivity and interact with external APIs to embed data. See GLightbox.
- Partial templates, which for plug-ins are meant to embed content in a page’s
<head>
. See Twitter Cards. - Custom page templates to add new pages to your Micro.blog site. See Category Cloud.
- Shortcodes, which are special partial templates that can be invoked in the content of posts or pages. See Bookshop.
Plug-ins that use the first three of these components may require some modification to your custom theme to work.
Static Files and Partials
In order to include the static files and partial templates in your design, you’ll want to add the following snippet to where you define <head>
in your theme:
{{ range .Site.Params.plugins_css }}
<link rel="stylesheet" href="{{ . }}" />
{{ end }}
{{ range $filename := .Site.Params.plugins_html }}
{{ partial $filename $ }}
{{ end }}
You’ll always want
{{ range .Site.Params.plugins_js }}
<script src="{{ . }}"></script>
{{ end }}
probably in the <footer>
.
This code iterates over all the listed parameters in the includes
parameter in the plugin.json
configuration that each plug-in sets up and ensures the CSS, JS, and partials are all included and rendered in your templates.
Custom Pages
Plug-ins that add a new page to your site, like say a page with a wordcloud for blog categories, have to make some assumptions about your Hugo theme. It’s not unusual, especially with older themes, to use something like this in layouts/post/single.html
(which is what pages render as in Micro.blog):
{{ partial "header.html" . }}
<article class = "h-entry">
{{ if .Title }}
<h2 class = "p-name post-title">
<a class = "u-url" href = "{{ .Permalink }}">{{ .Title }}</a>
</h2>
{{ end }}
<time class = "date dt-published"
datetime = "{{ .Date.Format "January 02, 2006 15:04:05 -0700" }}">
<a href = "{{ .Permalink }}" class = "u-url">
{{ .Date.Format "January 02, 2006 3:04PM" }}
</a>
</time>
<div class = "post-content e-content">
{{ .Content }}
</div>
</article>
{{ partial "footer.html" . }}
When creating a new page template as a plug-in author, however, there is no way to know how someone has structured the “frame” of their site and where to put the page content. What if you have a partial for your header, then a partial for navigation, then a partial for featured posts, then a partial for content, then a partial for pagination, then a partial for the page footer? This is not only quite common, but a plug-in author would need to know the names of each of these partials to render a page that fits with your theme.
New pages assume that you are using a relatively new feature of Hugo– base templates and blocks. I highly recommend reading the documentation, but in essence, Hugo allows you to define the framing of all of your templates in a new layouts/*/baseof.html
special template. In that template (which I recommend defining in _default
), you can put all the content for your page header, navigation, and footer. What used to be several partials to avoid code duplication can now live in one template.
In baseof.html
, you can define a named block
and then your other templates, such as layouts/post/single.html
can define the contents of that block. How does this help plug-ins with pages? Micro.blog has largely standardized themes around taking everything that is contained within the <article>
element in the example above and replacing it with:
{{ block "main" . }}
{{ end }}
inside the baseof.html
template. So your _default/baseof.html
might look like this:
```html
{{ partial "header.html" . }}
{{ block "main" . }}
{{ end }}
{{ partial "footer.html" . }}
Then your page templates, like post/single.html
might look like this:
{{ define "main" }}
<article class = "h-entry">
{{ if .Title }}
<h2 class = "p-name post-title">
<a class = "u-url" href = "{{ .Permalink }}">{{ .Title }}</a>
</h2>
{{ end }}
<time class = "date dt-published"
datetime = "{{ .Date.Format "January 02, 2006 15:04:05 -0700" }}">
<a href = "{{ .Permalink }}" class = "u-url">
{{ .Date.Format "January 02, 2006 3:04PM" }}
</a>
</time>
<div class = "post-content e-content">
{{ .Content }}
</div>
</article>
{{ end }}
By standardizing on the page contents being in the block named main
, plug-in authors can redefine the main
block safely for their custom pages, and you can be rest assured that the page will still look like it’s on your blog.
Hopefully these tips are helpful to custom theme authors who want compatibility with the community contributed plug-ins on Micro.blog.
Item contributed by Jason Becker.