Themes and Templates
This post was started on 2020-12-18. It was published on 2020-12-18.
With the most recent refactoring, Colophon has a basic, but functional theming system. Since Colophon is a system for building websites, themes are written as CSS (though in the future themes could be written in something like CSS-expressions).
For now, Colophon themes only allow for customizing the colors of various elements using CSS variables. In the future, this could be extended to customize fonts and other layout elements. But to properly understand how these themes work, we need to know a little about how Colophon handles styling and CSS in general.
The default <head>
tag for an HTML page generated by Colophon contains a
number of <link>
tags for CSS stylesheets. In particular, there is a
fonts.css
(that we will ignore for now), a stylesheet.css
and a
theme.css
. The stylesheet.css
file contains most of the styling
for the page: margins, padding, fonts, everything that defines the basic look
and feel of the page. However, most of the time a color is required, this file
uses CSS variables instead of direct hex or RGB values. The values corresponding
to these variables are defined in theme.css
. To change the colors in use,
we just need to provide a different CSS file with the colors of our choice.
But there’s more! Each theme can have any number of variants by providing a
different set of these values for these variables. For example, the default
Grayscale theme that this site uses has both a light and a dark variant (since
dark mode is the new hotness these days). The theme.css
file for
Grayscale provides selectors for .theme-light
and .theme-dark
as
follows:
.theme-light {
--bg-color: #f7f7f7;
--bg-alt-color: #222222;
--bg-sel-color: #cce3ee;
--text-color: #333333;
--text-alt-color: #f7f7f7;
--text-sel-color: #222222;
--text-hdr-color: #000000;
--code-text-color: #222222;
--code-bg-color: #fbfbfb;
--link-color: #0077aa;
--link-visited-color: #66adcc;
--link-bg-color: #f7f7f7;
--border-color: #0077aa;
}
.theme-dark {
--bg-color: #333333;
--bg-alt-color: #f7f7f7;
--bg-sel-color: #cce3ee;
--text-color: #f7f7f7;
--text-alt-color: #333333;
--text-sel-color: #222222;
--text-hdr-color: #66adcc;
--code-text-color: #222222;
--code-bg-color: #fbfbfb;
--link-color: #66adcc;
--link-visited-color: #0077aa;
--link-bg-color: #333333;
--border-color: #0077aa;
}
So far so good, but how does one go about using these themes and theme variants?
This is where Colophon’s templating system comes in. Really, this is
Pollen’s
template system, but Colophon provides some handy functions to make writing
them easier. In particular, Colophon provides the head-with
and
body-with
functions for generating HTML <head>
and <body>
tags, but with Colophon-specific components. The head-with
takes a
#:theme
argument that is a URL to a CSS file, and body-with
has a
#:theme-variant
that lets you specify a theme variant (light
or
dark
in the case of the Grayscale theme). The template for these post
pages looks like this:
<!DOCTYPE html>
<html lang="en">
◊(->html (head-with #:theme "/css/grayscale.css"))
◊(->html (body-with
#:navigation (navbar)
#:theme-variant "light"
#:contents
`(article ((id "content"))
,@(make-top metas)
,@(remove-tag more-tag (select* 'root doc)))))
<footer>
<!-- Copyright notice goes here -->
</footer>
</html>
As you can see, the post template is HTML with some Pollen code sprinkled in to
do the heavy lifting. The body-with
function lets you build up the page
by providing a navigation bar (with "#:navigation"
) and the main contents
(with #:contents
). In this case, we’re using a navbar
we defined
elsewhere and then used some Colophon utility functions to put the contents of a
post inside an <article>
tag, automatically generate some top-matter and
remove the more
tag that tells Colophon where to stop when generating an
excerpt.
Right now, the theme and templating system is admittedly a little inelegant. It
readily exposes the fact that we’re just hooking up various pieces of HTML and
CSS. It also has quirks like requiring the theme to be part of the <head>
tag, but the variant to be in the <body>
. Changing a theme also requires
editing (possibly multiple) templates, which is going to be a pain if you want
lots of different types of pages. These are all things I’d like to address once
Colophon’s core functionality is a little more fleshed out. But for now, it gets
the job done, and I think the basic ideas of how it works and is implemented are
solid, while allowing for future user-facing improvements.