Publishing your own website with Emacs and hugo
2021-09-29
I wanted to present some things to the public. To do so, a personal blog and a
static website is the weapon of choice (maybe 15 years to late). And what is a good start
for a personal blog? A post about the setup and workflow of the blog itself. I start with the
prerequisites for a personal website and afterwards explain the usage of Emacs org-mode
and hugo
for blogging. I expect some technical understanding and the will to google.
Prerequisites
There are many ways to publish your own site but the fundamental things are a domain and public available webspace. I got my domain from godaddy which are cheaper than some other providers. Don’t mix up the upfront costs (You pay the first year) with the long-time costs (You pay yearly). A normal domain costs between one and two euro a month.
For the webspace I use uberspace which is a shared webhoster with a good pricing model
and easy customization through the ssh
access and many detailed description.
Why a shared webhoster and not a root server? I have my own NAS at home which can serve
the same purpose but I don’t have a static IP address until I pay more for my ISP.
I decided against a root server (e.g. IONOS) because the setup of e-mail, certificates
and some other basic things are doable (if you’re experienced enough) but tedious and
one underestimates the regulary maintenance time.
So we’ve the most important parts: a Domain and a Webspace. Now point set a dns record for
your domain which points to your webspace and the prerequisites are done.
Next, we can go one step further and talk about using Emacs org-mode
for your new website.
Using Emacs org-mode
for building your own website
First, why emacs? I’m using emacs since 8 years for coding, note taking and
some other things. So using emacs for website building was naturally to me.
The org-mode
from emacs is one the best organization systems I’ve seen in the wild.
Well it doesn’t have a fancy webapp or shiny buttons but it is plain text and can
be edited and exchanged within every operating systems. It allows code to live alongside
its documentation and has many more outstanding features. So check out yourself.
The worg
(Community driven manuals) provides a list of framework for publishing.
The range lasts from using the internal capabilities to using static-site generators
or other tools written in other languages.
To choose the correct framework we need to know what we want to do:
- Maintain static websites alongsite the blogroll (e.g. About, Main, Impressum)
- Have an easy system to publish new blog post with Date and Tags
- Let the user comment on blog posts
- Maybe maintain some sort of public wiki which are not real blog posts (but this is something for the future)
- Preview posts without publishing them
- Traffic analysis
Let’s see what frameworks exists. Follow the links if you want more details about the frameworks.
Name | Last Udpate | Description |
---|---|---|
o-blog | 7 years ago | Stand-alone system in org but outdated and archived. |
org-jekyll | current | Uses Jekyll for publishing and org project with hand-made conversion rules. |
Projects | current | The internal publishing management system of org. |
Blorgit | 9 years ago | Based on Ruby for publishing exported org files. |
org2blog | current | Uses Wordpress for publishing org-files. |
org-page | 4 years ago | The project is unmaintained. |
lazyblorg | current | Written in Python and build for simplicity. |
ox-hugo | current | Uses Hugo for publishing with ox-hugo as exporter for org files. |
These are not all frameworks but it gives a good overview of the used approaches. Search for yourself for other frameworks since they come and go or write something yourself. Elisp is right under your finger-tips. ;)
I would prefer a system under active development and I dislike Wordpress from a personal perspective.
This leaves us with org-jekyll
, Projects
, lazyblorg
and ox-hugo
.
Projects
is the internal publishing software for emacs and I think it requires the most manual configration.
lazyblorg
sounds nice but is under development and some general features like comment section or analysis are more complicated
to get to work. This keeps me away from using this at the moment. This leaves us with org-jekyll
and ox-hugo
. Both depends
on well-known static-site generators with many feature. I would prefer ox-hugo
simply from the fact that
it has a better documentation than the org-jekyll
project. So, let’s setup hugo
and ox-hugo
.
Setup
To get this up and running we need hugo and emacs running somewhere. My shared hosting provder allows many applications on the backend site which includes hugo. This means I could write my blog on my local machine let emacs convert the org-files and then upload them to he hosting provider. There hugo does the static-site generation and it gets served. I found this type of workflow has some drawbacks. First, if I switch my hoster and the new one only allows static files (like the classic ones), it would break the workflow. Second, I like some sort of preview step before publishing something to the wild. Running a local hugo instance and only uploading the generated files seemed to me a better controlled workflow. Additionally, this allows a tighter integration between emacs and hugo which we see later. It’s time to setup hugo.
Hugo
Hugo can be installed on many distributions from the package manager (e.g. pacman -S hugo
).
Another option is to grab the binary directly from Github.
Download the latest version with:
|
|
Place the binary located in hugo
in your directory of choice.
If you choose the manual way of installation check the github page of hugo for the latest release.
Afterwards, I followed the quickstart guide from the hugo documentation and created a new website and added a theme.
|
|
The last line should start the server with only warnings and no errors. The new website can be found under http://localhost:1313.
To build the final website run hugo
in the website directory or hugo -D
if your want draft pages to be included.
The result ends up in the public folder of the website. In my case this is ~/rtzptz.xyz/public/
.
To deploy the site to my shared hoster I use rsync
with:
|
|
Depending on the hoster other options than ssh
must be used. Now you should see the website served by your domain.
If this succeds, you can start changing your website further and make it more of your own one.
A good starting point is the config.toml
. If your theme provides an exampleSite
copy the config file
and start adjusting it to your needs.
Some other possible adjustments are:
- Use another theme
- Configure your theme
- Create content, e.g. “about”, “interests”, “a post about your setup”
If you only wanted to know something about hugo, you can leave now and skip the emacs part but this is the more interesting one.
ox-hugo
Now we have hugo running on your local machine creating static websites and we manually upload
the generated website to your hoster. Next is to setup emacs with ox-hugo.
ox-hugo
has an extensive documentation which you can refer if stuck.
I use use-package
for managing my emacs configuration. So the I paste the following into
my init-file and hit C-x C-e
to evaluate the code. [Ref]
|
|
This install the package ox-hugo
and loads it into emacs scope.
The package provides two types of writing styles with org-mode
. One can either
have one org-file for each post or one org-file where each subtree can be a blog post.
I prefer the mixed style at the moment and created a new directory for the blog within
my org folder (mkdir ~/org/website
). For blog posts I use an org file called posts.org
where the posts resides in the org subtree and for special sites I use a single file.
I use a private Nextcloud instance to backup my org-files to another machine thus the original
content of our new website is already save. Ensure some sort of backup for the hugo
stuff without the /public
folder.
Frontmatter and Properties
Hugo is a static site generator which uses a fixed directory layout with special
meanings assinged to the folders. The content generated by emacs gets converted from org
to Markdown and resides under <website-name>/content/
. The other special folders are:
archetypes
: Stores templates when generating new content.assets
: Stores all files which are preprocessed by hugo before website creation.config
: Can be used to store additional configuration files used by hugo.data
: Stores configuration files used by hugo when generating the website.layout
: Stores.html
files that specify how parts of the content gets rendered, for example list pages, homepage.static
: Location of all static content. It gets copied into the final side as-is.resources
: Some sort of cache directory.themes
: The theme template for the current websites. It is possible to store multiple themes here.
Most of the directories are only useful if a more complex website is needed.
Hugo uses Markdown files with a frontmatter to generate the correct html page. The
frontmatter consists out of properties which are evaluated either during creation
or processing of the Markdown file. Emacs org-mode
provides properties to store advanced
and metainformations for special processing. A good overview about emacs properties and the
possibillites can be found here.
So, create your first “real” post with C-x C-f
and point to ~/org/website/posts.org
.
Paste the following properties at the beginning of the buffer and save it.
|
|
This tells ox-hugo
the location of the exported file and its name. The hugo section corresponds
to the hugo archetypes and the base dir to the website base dir. The post can now
be exported with C-c C-e H H
and the Markdown file is written to your posts
directory.
One can toggle the draft state of a post with the classic emacs TODO
and DONE
state.
Than the done date is taken instead of the creation date.
Additionally, I followed the hint from the documentation and added the following to the website config.toml
:
|
|
Tags
To get support for tags or categories add to the post file header #+filetags: emacs hugo
.
Now the tags cann be applied to the subtrees with C-c C-q
.
Categories can be defined in the same way with a @
as prefix like #+filetags: @coding
Polish and release
After the last part you can release whatever and whenever you want but there are some things to make your life easier.
Auto-Export
ox-hugo
provides an auto export mode to speed up the workflow.
I only use this setup in posts file and appended to the end of the file the following:
|
|
Now, when you save your file it gets directly exported.
Emacs workflow
I further tweaked my workflow with the following helpers:
Shortcut to open files directly
|
|
Generate the static website
|
|
Sync the generated site
|
|
Replace paths used in the functions with your own ones. You can tweak the functions further if you like.
Matomo a libre Google Analytics alternative
Now, we’ve a running website with emacs integration. As a last step I want to know how many people are accessing my new website. Google analytics may be the platzhirsch but I prefer open-source tools. So, I decided to use Matomo which is a open-source and user-friendly alternative to Google analytics.
First we need a Matomo instance up and running. Uberspace provides a short tutorial.
|
|
Now, open the website <your-domain>/matomo
and follow the installation steps.
In your new installation go to settings->plattform->marketplace and search for
the AjaxOptOut
plugin and install it.
For the integration into the website Matomo is provided as a hugo component. Install it beside your normal theme:
|
|
Afterwards, add your Matomo beside your theme with theme = ["cactus", "matomo"]
and to your website template. The footer.html
partial is recommended which is
located in your theme or your layout
folder if you wrote it yourself. The opt-out
can be placed anywhere but the privacy page is recommended. I my case the original
Google Analytics stuff was placed in the head.html
.
|
|
Change the config.toml
and add the following lines:
|
|
You can further change the opt-out messages in the config.toml
with:
|
|
You can configure the Opt-Out style by overriding the provided one with a new asset file assets/css/matomo-optout.css
.
Conclusion
We have setup a workflow for a personal webpage and blog driven by emacs. I’ve found the handling fairly easy and hugo as a good tool for creating static websites.
From here on, you can tweak our webiste further by modifying the theme or using modules provided by hugo. For a comment section I can recommend cactus.
So, go further and leave me a comment.