Setting Up A Personal Blog
Introduction
In this article, I will explain the steps for creating a blog like mine: static, automatically generated and hosted for free.
Framework
I have built this blog using Hugo and the hello-friend-ng theme, and host it on GitHub Pages.
Workflow
I use a private Git repository to version the development side of the blog
(such that drafts will not be public), and use a public repository named
xphyro.github.io
to host the public web site. I do not use GitHub
Actions or any other external
automations; rather, I set up a client-side pre-push
hook in the
development repository that builds the web site and pushes the build to the
repository acknowledged by GitHub Pages.
Setup
Essentials
The following are the steps to set up a near-exact copy of this blog as of the time of writing this article.
- Complete the quick start to get a basic idea of Hugo.
- Navigate to the root directory of your Hugo project and add the
hello-friend-ng
theme as a sub-module by executing the following.
git submodule add 'git@github.com:rhazdon/hugo-theme-hello-friend-ng.git' themes/hello-friend-ng
- Overwrite your
config.toml
file with the example file by executing the following
cp -f themes/hello-friend-ng/exampleSite/config.toml config.toml
Then, configure your website by filling in or changing the details.
Below are some important changes (for replication purposes) in my configuration. I have omitted changes that are clearly explained in the default configuration, or changes that are obvious.
[permalinks]
posts = "/articles/:year/:month/:day/:filename/"
[taxonomies]
tag = "tags"
category = "categories"
series = "series"
[languages]
[languages.en]
copyright = '<a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank" rel="noopener">CC BY-NC-SA 4.0</a> & <a href="https://opensource.org/licenses/MIT" target="_blank" rel="noopener">MIT</a>'
[menu]
[[menu.main]]
identifier = "posts"
name = "Articles"
url = "/articles"
weight = 20
[[menu.main]]
identifier = "tags"
name = "Tags"
url = "/tags"
weight = 30
[[menu.main]]
identifier = "categories"
name = "Categories"
url = "/categories"
weight = 40
[[menu.main]]
identifier = "series"
name = "Series"
url = "/series"
weight = 50
[[menu.main]]
identifier = "about"
name = "About"
url = "/about"
weight = 200
[markup]
[markup.tableOfContents]
startLevel = 1
If you do not want to call your posts articles as I do, you may replace all
articles
and Articles
you see with posts
and Posts
. When renaming
posts, be sure to keep the identifier as posts
1. Setting
startLevel
to 1 is important to have all sections visible in the table of
contents of an article. Also make sure to not add post = "posts"
as a
taxonomy: it will create duplicate paths and race conditions2.
Having completed the above steps, you can build or preview the website exactly the same way as you did in the quick start, after which you should have a website that looks and behaves very much like mine.
Justification3
If you create a post now, you will see that yours is not justified like this.
To achieve justification, set customCSS = ["/style.css"]
under [params]
in
your configuration and paste
.post-content p {
text-align: justify;
}
into the file static/style.css
.
MathJax4
To typeset $\LaTeX$, you can include MathJax in your posts by appending
{{- if .Params.mathjax -}} {{ partial "mathjax.html" . }} {{- end }}
to themes/hello-friend-ng/layouts/partials/head.html
and pasting the
following into layouts/partials/mathjax.html
.
<script
type="text/javascript"
async
src="https://cdn.jsdelivr.net/npm/mathjax@2.7.4/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
></script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [['$','$'], ['\\(','\\)']],
displayMath: [['$$','$$'], ['\[','\]']],
processEscapes: true,
processEnvironments: true,
skipTags: [
'script', 'noscript', 'style', 'textarea', 'pre', 'code',
],
TeX: {
equationNumbers: { autoNumber: "AMS" },
extensions: ["AMSmath.js", "AMSsymbols.js"]
},
}
});
</script>
Then, you should be able to render in-line and display mathematics using
$\LaTeX$ syntax respectively between single or double dollar signs after
setting mathjax: true
in the frontmatter of your post. Here’s an example:
$$ G_{\mu\nu} + \Lambda g_{\mu\nu} = \kappa T_{\mu\nu} $$
MathJax will only be loaded in posts that sets the mathjax
field to true
.
It will not be loaded in any other case, including on non-post pages.
Eliminating JavaScript
hello-friend-ng
uses
JavaScript for two
purposes: to utilise PrismJS and to allow toggling
between themes.
If you would like to eliminate the above-mentioned unnecessary usages of JavaScript from your website, which I highly recommend you do, follow these steps:
- Navigate to
themes/hello-friend-ng
. - Execute
rm -rf assets/js layouts/partials/javascript.html
. - Open
layouts/_default/baseof.html
in a text editor and remove the line that reads{{ partial "javascript.html" . }}
.
Now, your website should be free of JavaScript. If you have set up MathJax, it will still behave as expected.
You can also add enableThemeToggle = false
under the [params]
section in
your configuration to get rid of the now dysfunctional toggle.
Deployment
After building, Hugo will create a directory named (by default) public
.
Navigate into this directory and execute the following commands to initialise a
Git repository, add all files to the Git index and commit them.
git init
git add -A
git commit -m "Initial commit"
This will be the repository you deploy.
Now, you need to create a repository on GitHub that would be acknowledged by
the GitHub Pages application. Go onto GitHub and
create an empty repository named USERNAME.github.io
where USERNAME
is your
username. Then, switch back to the terminal from before and execute the
following.
git remote add origin "git@github.com:USERNAME/USERNAME.github.io.git"
git push --set-upstream origin master
After a few seconds to a few minutes, GitHub Pages will automatically deploy
your website on https://USERNAME.github.io
.
Alternate Methods
If you would not like to host your website on GitHub Pages, there are many other similar hosting services such as Render. You may use one of those, or even better, host on your own server using your own domain name.
If the exchange rate between your native currency and USD is sufficiently small, hosting should be quite cheap; and, you can get a domain name for free thanks to EU.org.
To learn more about how to host on your own server and set up your own domain name, see the basic courses on LandChad.net.
Automation
Building
To automatically build the website (without drafts) and push it live, paste the
following script into .git/hooks/pre-push
.
#!/usr/bin/env sh
set -e
cd "$(git rev-parse --show-toplevel)"
hugo --path-warnings
cd public
git add -A
GIT_COMMITTER_NAME="hook" GIT_COMMITTER_EMAIL="" git commit \
--author="hook <>" \
-m "#$(($(git rev-list --all --count) + 1)): Automatic build"
git push
If you want the commit to be under your name and be signed normally, replace
the commit line with git commit -m "#$(($(git rev-list --all --count) + 1)): Automatic build"
.
Updating the Last Modification Time
Hugo allows you to set the field lastmod
in the frontmatter of your posts. If
this field has a value later than the field date
, the value is passed onto
themes to be displayed somewhere in the post. This value might not be displayed
depending on the theme you use.
It is quite cumbersome to update this field manually, so, if you would like to
automate it, paste the following script into .git/hooks/pre-commit
.
#!/usr/bin/env sh
time="$(date --iso-8601=seconds)"
git diff --cached --name-status \
| grep "^M" \
| cut -d' ' -f2- \
| grep "^content/.*\.md$" \
| while IFS= read -r file; do
sed -iE "0,/^lastmod:\s*[0-9]{4}-.*/s//lastmod: $time/" -- "$file"
git add -- "$file"
done
-
Atlialp, D. (2021, August 25). Renaming
/posts
makes elements disappear. Github. Retrieved August 25, 2021, from https://github.com/rhazdon/hugo-theme-hello-friend-ng/issues/316#issuecomment-905008401. ↩︎ -
Pedersen, B. E. (2021, July 16) Build Output Is Indeterministic. HUGO. Retrieved July 16, 2021, from https://discourse.gohugo.io/t/build-output-is-indeterministic/33850. ↩︎
-
Mackenzie, D. (2019, May 1). Way to justify posts. GitHub. Retrieved July 15, 2021, from https://github.com/rhazdon/hugo-theme-hello-friend-ng/issues/20#issuecomment-488144749/. ↩︎
-
xuchengpeng. (2018, July 10). Setting MathJax with Hugo. xuchengpeng. Retrieved July 15, 2021, from http://xuchengpeng.com/hexo-blog/2018/07/10/setting-mathjax-with-hugo/. ↩︎