Hello, 🐯🐶! startup chime

The main site has finally been moved over to Hugo, and it feels great. I can write directly from the GitHub web interface, or draft things locally and drop them in later. Updates happen automatically, deployment happens automatically, and overall it’s a much more relaxing setup.
Now I’m just waiting for the GitHub mobile app to support code editing properly.
Notes from the migration pit
A few things broke along the way.
Broken post summaries
The old more tag stopped working if there was a space in the middle. Replacing <!-- more --> in bulk with <!--more--> fixed it.
Post list order was a mess
This turned out to be caused by inconsistent date formats in the front matter. Once everything was normalized to the same year-month-day format, like date: 2020-03-21, sorting worked again.
HTML inside posts disappeared
It was being replaced with <!-- raw HTML omitted -->. The reason is that Hugo 0.60 and later disables this by default. Adding the following to config.toml solved it:
[markup]
[markup.goldmark]
[markup.goldmark.renderer]
unsafe = true
Random tinkering guide
A full migration setup is absolutely worth it: article TOC, breadcrumb navigation, seamless URL migration, built-in search, and so on.
After poking around with the theme, I also made a few custom changes.
Changing the default RSS address
By default, the RSS feed lives at index.xml, which is... strange. The workaround was to place list.atom.xml in layouts/_default inside the theme, then add this to config.toml:
rssLimit = 5 # 控制输出数量,不然默认是全站
[outputs]
home = ["Atom", "HTML"] # <domain>/atom.xml
[outputFormats.Atom]
mediatype = "application/rss"
baseName = "atom"
Adding a TOC for posts
Create layouts/partials/toc.html, then reference it from layouts/_default/single.html like this:
{{ if .Params.toc }}
<div class="tocify">目录:{{- partial "toc.html" . -}}</div>
{{ end }}
Then enable it in a post’s front matter with toc: true. The related CSS and jQuery are as follows:
/* tocify */
.tocify {width: 20%; max-height: 90%; overflow: auto; margin-left: 2%; position: absolute; right:2%; border-radius: 6px;}
.tocify ul, .tocify li {list-style: none; margin: 0; padding: 0; border: none; line-height: 30px; }
.tocify li a {display: inline-block; text-indent:10px; font-size: 14px; text-decoration: none; }
.tocify ul ul li a:before {content: "- "}
@media only screen and (max-width:683px) {
.tocify {display: none;}
}
//文章 toc 跟随
var nav = $(".tocify");
nav.removeClass("hide");
var navTop = $(".post-content").offset().top;
var w = $(window).width()/2 + 400;
nav.css("left", w);
nav.css("top", navTop);
$(window).scroll(function() {
var scrolls = $(this).scrollTop();
if (scrolls > navTop) {
nav.css({"top":0,"position":"fixed"});
} else {
nav.css({"top":navTop,"position":"absolute"});
};
});
Adding Douban pages
Create page templates at layouts/_default/books.html and layouts/_default/movies.html, then update the secret value yourself.
Next, add content/books.md and content/movies.md. When visiting your-domain/books/, Hugo will match and render it with books.html.
Building in search
Important detail: remember to create a page at content/search.md. That empty entry in content is needed so the search page can render.
Search is handled on the front end with fuse.js, using a site-wide JSON index of posts.
Add this to config.toml:
[outputs]
home = ["Atom", "HTML", "JSON"] #加上 JSON 支持
Then create layouts/index.json, a search template at layouts/_default/search.html, a search script at static/search.js, and add the following CSS:
/* searchBoxInput */
.menu .search-box-icon {margin-top: 11px; }
.searchPage{min-height:300px}
.search-box {position: relative; margin-bottom: 20px; } #searchBoxInput {padding: 0.5rem 2rem 0.5rem 1rem; width: 16rem; background:#eaeaea; border-radius: 1rem; outline: 0; font-size: 1rem; color: inherit; border: 0px; box-sizing: border-box; }
.dark-theme .search-box #searchBoxInput {background: #3b3d42; }
#searchBoxButton {display: inline; background: none; margin: 0rem; border:0 none; border-radius: 0; padding: 0.4rem 0.6rem 0.4rem; }
.search-box-icon {color: inherit; fill: currentColor; width: 1.1rem; height: 1.1rem; }
Matching Valine to dark mode
Use Valine.Pure.min.js, which comes without the default styles, then add dark-theme styles like these (from the full style.css):
.dark-theme .v .vwrap{border:1px solid #4a4b50;}
.dark-theme .v .vwrap input{background:#dcdcdc;}
.dark-theme .v .veditor{color:#fff;}
.dark-theme .v .vbtn{color:#dcdcdc;background:#4a4b50;}
One last complaint, and some gratitude
Not knowing English makes this stuff hard. Knowing a little English and still not being able to understand the official docs is somehow even worse. 😭