3 minutes
Written: 2023-06-17 17:29 +0000
Updated: 2024-08-06 00:53 +0000
Dart Sass and Hugo Themes
Quick notes on variables,
dart-sass
andhugo
Background
Recently I decided that it was annoying for me as a user to not know which links on my site were internal and which led off to an external site.
However, since hugo
requires baseurl
for generating meaningful rss
and
sitemap
files, this meant either hardcoding the variable into my theme, or
figuring out how to pass variables from my config.toml
to my theme’s
(generated) css
.
This about the latter, and is heavily based off of this post on the Hugo Discourse.
The CSS
The crux of the implementation is simply the use of attribute selectors:
1a {
2 &[href^="/"],
3 &[href*="rgoswami.me"],
4 &[href^="#"] {
5 border-bottom: #0380ff 0.125em solid;
6 }
7 &:not([href^="/"]):not([href*="rgoswami.me"]):not([href^="#"]) {
8 border-bottom: #9b36ff 0.125em solid;
9 }
10}
Where the main sticking point is being able to pass the name of the site from
the configuration. Although this could be done with libsass
and hugo
as
detailed in the discourse post, it is conceptually clunky, since partials are
not respected when using ExecuteAsTemplate
with hugo-pipes. A better SCSS
processor could probably take in a better configuration option object…. Which
leads to the next section.
Dart Sass
At some point which I didn’t have time to figure out, libsass
got phased out
in favor of Dart Sass and includes (among other features) a nifty math
module. This had a few side effects:
- I could swap my hand-kanged
exp
function formath.exp()
and also had to transition to usingcalc()
more (as in 3938ac2). - I could pass variables from
hugo
toscss
and from there tocss
for attribute selectors (as in 804d417)
CI Updates
For various reasons, hugo
(even the extended version) does not seem to include
dart-sass-embedded
though the snap
package does (as noted here on Discourse).
1- name: Setup Hugo
2 uses: peaceiris/actions-hugo@v2
3 with:
4 hugo-version: '0.111.3'
5 extended: true
6- name: Install Dart Sass Embedded
7 run: sudo snap install dart-sass-embedded
Local Usage
hugo serve
will correctly compile and load the theme if hugo env
recognizes the dart-sass-embedded
installation:
1$ hugo env
2hugo v0.112.3+extended linux/amd64 BuildDate=unknown
3GOOS="linux"
4GOARCH="amd64"
5GOVERSION="go1.20.4"
6github.com/sass/libsass="3.6.5"
7github.com/webmproject/libwebp="v1.2.4"
8github.com/sass/dart-sass-embedded/protocol="1.2.0"
9github.com/sass/dart-sass-embedded/compiler="1.54.8"
10github.com/sass/dart-sass-embedded/implementation="1.54.8"
dart-sass-embedded
is a node package, which means that npm
can be used:
1DART_SASS_VERSION=1.54.8 npm install sass-embedded-linux-x64@${DART_SASS_VERSION}
2PATH=$PATH:./node_modules/sass-embedded-linux-x64/dart-sass-embedded/ hugo env
Personally I ended up using micromamba
to grab dart-sass
as well.
Passing Variables
User Perspective
The theme users simply updates their configuration to include the relevant variables:
1baseurl = "https://rgoswami.me/"
2[params.style]
3site_url = "rgoswami.me" # Same as baseurl
Theme Dev Perspective
With the hugo
asset processing pipeline for dart-sass
, the relevant options need to be (minimally) set:
1{{ $options := (dict "targetPath" "main.css" "transpiler" "dartsass" "vars" site.Params.style) }}
2{{ $style := resources.Get "scss/main.scss" | resources.ToCSS $options | resources.Minify | resources.Fingerprint }}
3<link rel="stylesheet" href="{{ $style.RelPermalink }}">
Where vars
takes a section corresponding to the user-defined section (style
in this case). Usage within scss
partials looks like:
1@use "hugo:vars" as h;
2$site-url: h.$site_url;
3$link-color: #0380ff;
4$external-link-color: #9b36ff;
Which can finally be used to elegantly setup attribute selector based colors:
1a {
2 &[href^="/"],
3 &[href*="#{$site-url}"],
4 &[href^="#"] {
5 border-bottom: $link-color 0.125em solid;
6 }
7 &:not([href^="/"]):not([href*="#{$site-url}"]):not([href^="#"]) {
8 border-bottom: $external-link-color 0.125em solid;
9 }
10}
Conclusions
Of the many maintenance burdens I have accrued over the years, one of the least often discussed is the underlying theme used for the site. Some day that will be rectified. I think web design via vanilla JS, S(CSS) and HTML is a pretty nifty gateway into other languages (interpreted and compiled). The approach could be (and perhaps should be) extended to color other links and sites differently (e.g. all my content on other sites in blue). For now this works well enough at any rate.