How to Create a Website with Hugo Academic Theme: Blog Setup
Getting your blog setup right.
Academic is one of the most popular Hugo themes for good reason. It’s flexible, clean, and easy to use and set up. It supports many widgets and allows you to display a wide range of content types, including biographies, accomplishments, experiences, projects, posts, talks, and publications (it is called Academic after all). However, while it’s able to handle all of them adequately, it does lack some desirable features and characteristics that a dedicated blog theme might provide. This post outlines the changes I made, and how, to improve the theme’s ability to function as a blog.
Rename section from “post” to “blog”
One thing that may have bugged you, I know it did me, is that everything is called “post” instead of “blog”, especially for the URL. I wanted it to be eliaszwang.com/blog
instead of eliaszwang.com/post
. I know it may seem like a small detail, but I cared enough to figure out how to change it. And now I’ll show you how too.
Website repo changes
Starting off with the easy changes, you’ll need to change the name in the menus. So in config/_default/menus.toml
replace the two lines with,
name = "Blog"
url = "#blog"
If you want the menu to take you directly to the section page for your posts you can use url = "/blog"
instead. Next, rename the post
subdirectory in the content
folder to blog
and change the title
in the front matter of content/blog/_index.md
to “Blog”, or whatever you want to name your blog. Also rename content/home/posts.md
to content/home/blog.md
. In that file you’ll also need to change the page_type
from “post” to “blog”. Some important notes:
- The name of the
*.md
file incontent/home
determines the HTMLid
attribute on the homepage, i.e. the anchor link used in the menu. Seelayouts/partials/widget_page.html
in the theme repo. - The
page_type
determines the folder name in thecontent
directory where content (e.g. single posts) is pulled from. Seelayouts/partials/widgets/pages.html
.
Subdomain redirect
At this stage, you can also set up subdomain redirects through Netlify to make your blog accessible from a subdomain, e.g. blog.domain.com
. Just add the following lines to the netlify.toml
file, replacing domain.com
with your own domain:
[[redirects]]
from = "https://blog.domain.com"
to = "/blog"
status = 200
force = true
[[redirects]]
from = "https://blog.domain.com/blog/*"
to = "/blog/:splat"
status = 200
force = true
[[redirects]]
from = "https://blog.domain.com/css/*"
to = "/css/:splat"
status = 200
force = true
The last redirect rule for the css
subdirectory ensures that the pages on the new subdomain will be formatted correctly without any addtional changes. The final thing to do is add the subdomain as a domain alias in Netlify under “Domain settings>Custom domains”. To fully understand how these redirect rules work take a look at the documentation on
general redirects,
proxy redirects, and
splats.
Summary of changes in the website repo:
- In
config/_default/menus.toml
changename
to “Blog” andurl
to “#blog” or “/blog” - Rename
content/post
tocontent/blog
, and changetitle
incontent/blog/_index.md
to “Blog” - Rename
content/home/posts.md
tocontent/home/blog.md
, and changepage_type
to “blog” - Change redirects accordingly in
netlify.toml
Theme repo changes
This part is pretty short. Start by renaming two files: layouts/post/single.html
to layouts/blog/single.html
and layouts/section/post.html
to layouts/section/blog.html
. This mostly just reflects the renaming that you did earlier in the website repo. Finally, there are a couple of changes in the layout files. In layouts/partials/widgets/pages.html
(i.e. the pages widget) in the two lines where $items_type
and "post"
appear change “post” to blog. The new lines should look something like,
...
{{ $items_type := $st.Params.content.page_type | default "blog" }}
...
{{ if eq $items_type "blog" }}
...
Also in layouts/partials/page_metadata.html
change the $page.Type
check (near the end of the file) from “post to “blog”,
...
{{ if and (eq $page.Type "blog") (not (or (eq site.Params.reading_time false) (eq $page.Params.reading_time false))) }}
...
This will ensure that the estimated reading time for posts continues to be displayed, if you have it enabled in params.toml
. For some more information about content types in Hugo take a look
here.
Summary of changes in the theme repo:
- Rename
layouts/post/single.html
tolayouts/blog/single.html
- Rename
layouts/section/post.html
tolayouts/section/blog.html
- In
layouts/partials/widgets/pages.html
changepage_type
/$items_type
processing from “post” to “blog” - In
layouts/partials/page_metadata.html
change$page.Type
check from “post to “blog”
Change subdirectory to submodule
Another useful thing to do is setting up your content/blog
subdirectory into a git submodule. The benefit of doing this is that you can still use git for version control of your posts while keeping them in a private repo, even if your website repo is public. If you’re not familar with git submodules, check out
my other post that explains more.
Splitting a subdirectory into a new repo
In case you’ve already added some posts and want to keep the git history, it’s pretty easy to do with just a few git commands. Just follow the steps outlined in the GitHub docs
here. Once you have this new repo set up with just your blog posts it’s time to add it as a submodule to the original repo. First delete the original content/blog
folder, then replace it with a submodule by running the following command in the root directory: git submodule add https://github.com/USERNAME/REPOSITORY-NAME.git content/blog
(this assumes you renamed post to blog, if not use content/post
as the path). Note: If you are planning to keep the blog repo private you’ll need to use ssh instead of https: git submodule add git@github.com:USERNAME/REPOSITORY-NAME.git content/blog
and follow the additional steps in
“Configure Netlify for private submodules”. After adding the submodule run git submodule update --init
to finish the setup.
Configure Netlify for private submodules
Netlify provides nice documentation for setting up deploy keys when using private repos here. In short, you’ll first need to go to the Netlify site and generate a public key by going to Settings > Build & deploy > Continuous deployment > Deploy key, and select Generate public key. Copy this public key. Next you’ll go to the GitHub page for you blog repo and go to Settings > Deploy keys, and select Add deploy key and paste the public key you copied from Netlify (no need to give it write access). This should now give Netlify read access to the private repo and will allow it to build your site.