Hugo - Power On
Before we start, we need to understand how Hugo works from top to bottom, at least, to get a full picture first. These checkpoints are what we called "power-on" checkpoints: we learn through experience. This guide will leads you to setting a basic understanding and usable Hugo repository until you hit the wrapping up checkpoint (which indicates you already achieve the minimum requirement for understanding how Hugo works.
Objectives
- We create a scaffold version of the hugo site, without external themes or any new magic.
- Once attaining that version, version control the result as a vanilla version.
Run the setup command
This will create a directory containing the Hugo structure.
$ hugo new site <name>
Example:
$ hugo new site mysite
Initialize the Development Server
Once we're done, we'll launch the server for development. There are a number of parameters to pass in to make it a development friendly server. This terminal will be busy with this server
$ cd <name>
$ hugo server -D -b <address> -p <port number> \
--disableFastRender
Example:
$ cd mysite
$ hugo server -D -b localhost -p 8080 \
--disableFastRender
-D
means build the draft version together.-b
means bind to an address. In our case,localhost
is good.-p
means bind to a port. In our case, we use standard8080
port.--disableFastRender
means to always freshly build after changes instead of using caching.
Open a New Terminal
The existing server is not occupied for serving the website. Hence, you'll need to open a new terminal and head back to the same directory for editing.
# in new terminal
$ cd path/to/mysite
Create the First 2 Posts
Now that we have a server to run, we should write 2 posts to test out our server. Proceed to create those posts in the following sequence in the new terminal.
$ hugo new posts/my-first-post.md
$ echo "# My First Post" >> ./content/posts/my-first-post.md
$ hugo new posts/my-second-post.md
$ echo "# My Second Post" >> ./content/posts/my-second-post.md
If you watch the server activity, it is now rebuilding the site for each changes you made to it.
Create the BaseOf Layout
Hugo needs the html layouts to build your contents. Otherwise, it won't be able to render any site at all. To do this, we need to create a directory called _default
inside layouts
directory. Then we create the baseof.html
layout, which is root of all layouts.
$ mkdir layouts/_default
$ echo '<!DOCTYPE html>
<html>
<head>
<title>{{ .Title }} | {{ .Site.Title }}</title>
</head>
<body>
<h2>Using Baseof Layout</h2>
{{ block "main" . }}{{ end }}
</body>
</html>
' > layouts/_default/baseof.html
We'll go through the theory and specification in the later topic. For now, let's focus on powering-on.
Create the Single Page Layout
Now that we have our base layout. It's time to create the single page layout. Each markdown files are rendered using this single page layout. To do this, we create the single.html
layout inside the same _default
directory.
$ echo '{{ define "main" }}
<h2>Using Single Layout</h2>
{{- .Content -}}
{{ end }}
' > layouts/_default/single.html
Check the Post Links
With the layouts are set to render, it's time to visit the page. Open up your web browser and visit the following site:
http://localhost:8080/posts/my-first-post
http://localhost:8080/posts/my-second-post
You should see something as such on the website, depending on which post you're visiting. Here is an example for second post:
Using Baseof Layout
Using Single Layout
my second post
If you're not seeing the pages, you might want to delete the folder and try again.
Git Commit This Vanilla Version
Since the site is now working. You should perform your git version control over the current version. We'll expand it in the following topics. To do so, you will need git software and perform the git commit.
$ git init
$ git add .
$ git commit -s
<fill in your commit message>
Congratulations! You now have the vanilla version of the hugo site. It is a crude html codes illustrating how thing works. The following section is explaining what's going on during this phase.
Theory and Explanations
Hugo Rendering Process (basic flow)
If you read the hugo documentations in detailed fashion, you'll notice that Hugo is very flexible, which is a reason why it is complex at first glance. Based on what we did in this section, we should observe clearly how hugo works its way for us:
- Hugo first read the
content
folder and structure the necessary site pages. - Hugo read each markdown file, the
my-first-post.md
andmy-second.post.md
in the posts sub-folder and built the website path based on thefilename
andsub-folder
name (also known as section). In our case, the URL are:/posts/my-first-post
/post/my-second-post
- Hugo then reaches the
layouts
folder and look for the base layout (baseof.html
) and single page layout (single.html
) to construct the html files for all the contents.- From here, we observe that the
baseof.html
layout is the most underlying base template. Another word, this is our base. - Then, it seeks the
single.html
layout to render each posts.
- From here, we observe that the
How Single Page Layout and Base Layout Works Together
Using Baseof Layout
Using Single Layout
my second post
Let's use back our output for second post as our analysis sample. If you observes carefully on both baseof.html
and single.html
layouts, you'll notice that we included both the lines Using X Layout
to indicate the layout is being used.
If we read the lookup order specification, Hugo first look for baseof.html
and then seek single.html
at the last point. That's why both Using Baseof Layout
and Using Single Layout
appeared.
<body>
<h2>Using Baseof Layout</h2>
{{ block "main" . }}{{ end }}
</body>
For baseof.html
to call single.html
to build its content, it uses what we called template shortcodes to process it. The specific shortcode is:
{{ block "<name>" . }}{{ end }}
Keep in mind that you can name any code block with any sensible name as long as the responder has the code block to respond for it.
This "block" shortcode here, calls the "main" layout block offered from the following layout. In our case, it is from single.html
. Otherwise, it will fills in as blank.
{{ define "main" }}
<h2>Using Single Layout</h2>
{{- .Content -}}
{{ end }}
For single.html
to fulfill baseof.html layout request, we facilitate them using the define shortcode.
{{ define "<name>" }}{{ end }}
This wrap all the codes inside the definition as "main" code block and then proceed to construct the content.
To write the content out, we use the .Content shortcode:
{{- .Content -}}
This shortcode will dump all contents currently being processed. In the example, it is the header my second post
from the second post.
If you work backwards from here now, you'll see that you can reconstruct the 2nd post output easily.