This website has been created with the Hugo static site generator. This page documents the creation steps in more detail.
Install git, go, hugo, and npm
-
sudo apt install git -
Go
-
wget https://go.dev/dl/go1.23.0.linux-amd64.tar.gz orwget https://go.dev/dl/go1.23.0.linux-arm64.tar.gz -
rm -rf /usr/local/go; tar -C /usr/local -xzf go1.23.linux-amd64.tar.gz - Fixing the PATH. Edit
$HOME/.profile and addexport PATH=$PATH:/usr/local/bin. May need tosource ~/.profile to apply the PATH changes. -
go version
-
-
npm
-
sudo apt install npm
-
-
Hugo
-
wget https://github.com/gohugoio/hugo/releases/download/v0.118.2/hugo_extended_0.118.2_linux-amd64.tar.gz -
wget https://github.com/gohugoio/hugo/releases/download/v0.118.2/hugo_extended_0.118.2_linux-arm64.tar.gz -
tar xvf hugo_extended_0.118.2_Linux-64bit.tar.gz -
sudo cp hugo /usr/local/bin
-
Initial setup
-
git clone https://github.com/razonyang/hugo-theme-bootstrap-skeleton sagar.se -
cd sagar.se -
rm -rf .git;git init -b main -
Modify the
go.mod and change the contents tomodule github.com/sagarbehere/sagar.se go 1.18 require github.com/razonyang/hugo-theme-bootstrap v1.7.0 // indirect -
The
.gitignore file has the following content# Created by https://www.toptal.com/developers/gitignore/api/hugo # Edit at https://www.toptal.com/developers/gitignore?templates=hugo ### Hugo ### # Generated files by hugo /public/ /resources/_gen/ /assets/jsconfig.json hugo_stats.json # Executable may be added to repository hugo.exe hugo.darwin hugo.linux # Temporary lock file while building /.hugo_build.lock # End of https://www.toptal.com/developers/gitignore/api/hugo # npm assets package-lock.json node_modules/ # ignore system files .DS_Store -
git add -A; git commit -m 'First commit'; git remote add origin [email protected]:sagarbehere/sagar.se; git push origin main -
hugo mod npm pack -
npm install -
hugo server
Theme Configuration
-
Change
config/_default/config.yaml,config/_default/params.yaml,config/_default/languages.yaml, andconfig/_default/menu.en.yaml as needed.- The setting
mainSections inconfig/_default/params.yaml is no intuitive, but important. The default is-posts, -docs which I have changed to-posts only. The way I understand it, if theType of a post is not specified, but the Recent Posts sidebar widget will be present, then the widget contents will be of the type inmainSections.
- The setting
-
The above gets you most of the way there. The rest of the customization is done as per the Additional Customization section below.
Content
Landing page
The landing page is the content/_index.md file. It’s content is as follows
1+++
2title = "Sagar Behere"
3type = "landing"
4sidebar = true
5+++
6
7The rest of the landing page content.
My landing page content is raw HTML. To get hugo to process it, there is a need to create and use the rawhtml shortcode. Create file layouts/shortcodes/rawhtml.html with content
<!-- raw html -->
{{.Inner}}
Blog
For the Blog section of this website, create folder content/blog and in content/blog/_index.md add
1+++
2title = "Blog"
3[menu.main]
4 title = "Blog"
5 weight = 10
6[cascade]
7 type = "posts"
8+++
Static pages
This website has pages like ‘Talks’, and ‘Publications’. For those, create folder content/pages and in content/pages/_index.md add
1+++
2title = "Pages"
3[[cascade]]
4 sidebar = false
5+++
Notes
The Notes section of this website is a Digital Garden, built using the docs layout of the Hugo Bootstrap Theme. Create folder content/notes and in content/notes/_index.md add
1---
2cascade:
3 type: docs
4date: 2023-11-24 09:42:06
5lastmod: 2023-12-05 12:29:17
6menu:
7 main:
8 title: Notes
9 weight: '45'
10publish: true
11title: Notes
12---
13The content to show on the page main /notes/ page.
Additional Customization
Block quotes
Add the following to assets/main/scss/_custom.scss to have a nicer font appearance for block quotes
1blockquote {
2 font-size: 1.5em;
3 font-style: italic;
4}
Change URL color
The URL color at various places on the site is not distinct from the color of non-URL text. This makes it difficult to visually distinguish URLs from non-URLs. This can be fixed by adding the following to assets/main/scss/_custom.scss
1.post-list li a, .post-summary a, .post-content a, .post-nav a, p a, .card-body li a {
2 color: var(--hbs-primary);
3}
Table of contents
- The ToC consists of links to sections of the post. Let’s keep the color of the links consistent with the color of other URLs across the site.
- Additionally, I think it is more visually pleasing if the font-size of the ToC content is a bit smaller than the font size of the posts.
All of this can be accomplished by adding the following to assets/main/scss/_custom.scss
1#TableOfContents {
2 font-size: 0.9rem;
3 color: var(--hbs-primary) !important;
4}
5
6.post #TableOfContents {
7 font-size: 0.9rem;
8 color: var(--hbs-primary) !important;
9}
Font color of post summaries
The HBS theme by default uses a gray-ish color for the text of post summaries on a list page. To change this to a darker color, add the following to assets/main/scss/_custom.scss
1.post-summary {
2 color: var(--hbs-primary-text-on-surface);
3}
Full-size images in summaries
For some reason, images are resized to a width of 180px in the post summaries on a list page. To enable full-sized images, the following addition to assets/main/scss/_custom.scss fixes this.
1.posts .post img {
2 float: left;
3 width: 95%;
4 height: auto;
5 padding-bottom: 1rem;
6 max-height: unset;
7 max-width: 700px;
8}
9.post-summary p {
10clear:both
11}
Notes: I don’t exactly know why this fix works. Noticed in firefox dev console that the image width was being set to 180px. Setting width to a %age and a max-width seems to fix it. Adding the padding-bottom to get some separation between image and following text. The .post-summary ppart is needed because without it, the text will float to the right of the image and not start from below the image. All of this wouldn’t be needed if the theme did not already include css for .posts .post img that set the image width to 180px and float: left, which we are overriding here with width:auto, and resetting the float:left with clear:both.
Menu items
To add a link to a page to e.g. the top menu bar, add the following to the frontmatter of the page
1[menu.main]
2 Title = "Foo"
3 weight = 10
Links are arranged left to right by increasing values of the weight parameter.
Favicon
- Create and copy a favicon.png file to
static/images/icons - Use imagemagick’s
convert command to create icons of different size
1convert -resize 192x192 favicon.png icon-192x192.png
2convert -resize 180x180 favicon.png icon-180x180.png
3convert -resize 150x150 favicon.png icon-150x150.png
4convert -resize 32x32 favicon.png icon-32x32.png
5convert -resize 16x16 favicon.png icon-16x16.png
6convert favicon.png favicon.ico
Generate every size the theme asks for: 16, 32, 150, 180 and 192. The theme resizes
assets/favicon.webp / assets/favicon.png for any size that has no matching
static/images/icons/icon-<size>.png, so a missing size silently falls back to whatever
image sits in assets/ - which, after a theme upgrade, may be the theme’s own sample
picture. Keep an assets/favicon.png copy of the icon there too, as a safe fallback.
The filename matters: the theme looks for icon-150x150.png, not favicon-150x150.png.
Customize font
The site uses PT Serif, self-hosted from static/fonts/ so that no request goes to
a third party. (An earlier version of these notes linked Google Fonts through
customCSS in config/_default/params.toml. That worked, but the config has since
moved to YAML, and the font is now self-hosted instead.)
1. Fetch the woff2 files. Ask the Google Fonts CSS API for the stylesheet, then
download the files it references, keeping only the subsets the site needs
(latin and latin-ext; PT Serif also ships cyrillic):
1curl -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \
2 "https://fonts.googleapis.com/css2?family=PT+Serif:ital,wght@0,400;0,700;1,400;1,700&display=swap" \
3 -o ptserif.css
4# then download each url(...) from the latin / latin-ext blocks into static/fonts/
Eight files (regular/bold x roman/italic, each in latin and latin-ext) come to ~91 KB. PT Serif is SIL Open Font License 1.1, so self-hosting is permitted.
2. Declare the faces in assets/main/scss/_custom.scss, one @font-face per file.
Copy the unicode-range values from the Google stylesheet verbatim - they are what makes
the browser fetch latin-ext only when a page actually uses those characters:
1@font-face {
2 font-family: 'PT Serif';
3 font-style: normal;
4 font-weight: 400;
5 font-display: swap;
6 src: url('/fonts/pt-serif-400-latin.woff2') format('woff2');
7 unicode-range: U+0000-00FF, U+0131, U+0152-0153, /* ... */;
8}
3. Point the theme at it, in the same file:
1:root {
2 --hbs-body-font-family: 'PT Serif', serif;
3 --hbs-body-font-size: 1.1rem;
4}
--hbs-body-font-size is optional; omit it to keep the theme’s 1rem.
4. Preload the one face used above the fold, in
layouts/partials/hooks/head-end.html:
1<link rel="preload" href="/fonts/pt-serif-400-latin.woff2" as="font" type="font/woff2" crossorigin>
The crossorigin attribute is required even for same-origin fonts - without it the
browser fetches the file twice.
Verify after a production build (hugo --minify --gc), because PurgeCSS runs only in
production and can strip @font-face rules as unused:
1# Note: use -o | wc -l, not grep -c. The bundle is minified onto a single line,
2# so grep -c reports 1 whether there are eight @font-face rules or one.
3grep -o "@font-face" public/assets/main/bundle.min.*.css | wc -l # expect 8, not 0
4grep -c "fonts.googleapis" public/index.html # expect 0
Tweaking the layouts
Some more tweaking has been done to various layout files. Do tree layouts to see the added files. The files in this folder override their default counterparts in the theme. I have tweaked
-
layouts/blog/list.html: Make Hugo use thelayouts/partials/blog/list.html partial below -
layouts/partials/blog/list.html: Remove the childsections that pop up before the list of posts -
layouts/partials/docs/list.html: Remove subsections and child page summaries from being displayed -
layouts/partials/footer/main.html: Removed the site title and tagline and row of social icons at the bottom. -
layouts/partials/footer/powered-by.html: Modified the Powered by statement at the end of the blog. -
layouts/partials/hooks/docs/sidebar-end.html: Introduced the ‘Recent Posts’ widget in the sidebar in the docs layout -
layouts/partials/hooks/head-end.html: Added Plausible analytics script
Analytics
This uses the self-hosted version of Plausible. The documentation notes I made while self-hosting Plausible are Plausible.
The tracking script needs to be added to layouts/partials/hooks/head-end.html. In that file, add the following:
1<script defer data-api="https://visits.sagar.se/api/event" data-domain="sagar.se" src="https://visits.sagar.se/js/script.js"></script>
And that’s all that is needed for recent versions of Plausible (As of August 2024).