Complete Setup for this Website - Part 1

Create a smart and simple website for free in a record time πŸš€

Credit: Hugo Game

1. Overview

So I’ve finally decide to have a blog-like website πŸ†. And no, the Hugo that we are going to talk about in this first post is not from Hugo Game πŸ˜‚

Whatever… I do like tech, travel, beers, and a couple of other stuff, I think that I can share a bit of this experience with anybody that wants to take some time to read about it πŸ€“

As my first post, I want to share my personal experience with Hugo, for this you can find the complete source code on my GitHub (pay attention to the branch πŸ˜‰).

2. The Goal

For me blogging shouldn’t be so complex to setup, and actually it isn’t. For complex blog providers which brings a lot of fancy features and also has no manage multiple blogs in the same structure, it’s obviously going to be way more complex to maintain the entire application and it’s infrastructure.

That’s not my case.

What I need is just a place to put my notes, share some content that may be useful and start nice talks about technology (mainly, but not only).

So I did some research and I finally choose Hugo. You can find a lot of posts comparing different static website generators (for blog or general purposes like Hugo), but I’m not going too much into it here. If you want to go a bit deeper you can find some nice comparisons here and here just to start.

So, let’s blog πŸ€“

3. Setup

  • To install Hugo you can follow this steps from Hugo docs;
    • I choose to install with brew;
  • To setup the initial environment I have followed this steps from Academics docs;
    • I decided to use the ‘Install with Git’ option just to keep the credits on the original repo via forked from mentioning πŸ˜„

After doing the basic installation steps according to Hugo’s and Academic’s websites, I’ve entered on the website root folder and ran this command to test locally:

hugo server
Running hugo server on command line

Then accessing localhost you can find something like this:

Initial home page

Nice, we have a complete blog-template running locally 😬

4. Ok, so.. Where am I?

Yes! It’s alive! But, then.. Now what? There is dozens of files everywhere and a lot of pages and things that actually I don’t need at all. I found a good post about this here and indeed, it’s quite overwhelming.

But ok, first things first: let’s clean up the code and define the MVP, right?

4.1. config.toml & params.toml

Not much to do, just url, mail contacts and basic information (also some minimal theme configuration). The documentation in the files itself is pretty good and self explanatory, but you can also see extra features on Academic docs.

4.2. Minimum Pages and Content Organization

According to Hugo’s docs the base organization is directory/file based, as you can see in their sampe:

.
└── content
    └── about
    |   └── index.md  // <- https://example.com/about/
    β”œβ”€β”€ posts
    |   β”œβ”€β”€ firstpost.md   // <- https://example.com/posts/firstpost/
    |   β”œβ”€β”€ happy
    |   |   └── ness.md  // <- https://example.com/posts/happy/ness/
    |   └── secondpost.md  // <- https://example.com/posts/secondpost/
    └── quote
        β”œβ”€β”€ first.md       // <- https://example.com/quote/first/
        └── second.md      // <- https://example.com/quote/second/

So I decided to try to bring some sense to this chaos using simple pattern: on posts folder I’m going to organize the posts using the date structure year/month/day and put all related data to that post in this folder, if I want to add multiple posts in the same day I can also control it using post-path/index.md pattern. I’m also going to rename folder posts to blog (in my sense it is more meaningful, also url-wise). So the blog content will be organized like that:

.
└── content
    └── blog
        └── 2019
            └── 11
            |   └── 30
            |       └── developing_this_blog_with_hugo.md // <- https://jjbeto.com/blog/2019/11/30/developing_this_blog_with_hugo/
            β””-- 12
                β””-- 01
                    └── following_awesome_post.md // <- https://jjbeto.com/blog/2019/12/05/following_awesome_post/

This way it’s possible to aggregate related content in one place, track down by date and maybe in the future create some plugin to deal better with the content per directory (who knows?).

Aside of the post organization, I need to decide also about general content, so initially I’m going to prepare the following:

PageMotivation
About (Hugo’s default author’s page)Too Long To Read resume
ResumeIt’s good to have it online and also test features πŸ˜„
ContactEr, to get in touch via social media
Posts Root Page /blogTo has a root page for blog posts

Next is to add more featured pages like:

  • Courses: for tutorial-like purposes like this one πŸ€”
  • Talks: for meetups and/or talks that I find interesting to track

All basic plan is defined. Let’s start to work on it πŸ˜„

5. First Page: Resume

The default Academic’s home page is just too crowded (obviously, they want to show off as much features as possible, right?), and as this theme is more related to academic’s in general, there is a lot of really good tools/pages to help you to show yourself, but I want a cleaner homepage, with only latest news and a quick presentation about myself.

So I decided to create a resume folder and see how it looks like to use Academic’s features, and also learn a bit of page builder and content organization. This can clean up my home page but maintaining a lot of cool features in the website anyway for who is interested: you can fork my website’s repo on GitHub and update the resume folder according to your needs and just add this folder to your Hugo’s website.

  1. Create folder ./content/resume
  2. Create file ./content/resume/index.md to define the widget: in my case it’s just an empty page where I want to add sections like the homepage does

    ---
    title: "Resume"
    date: "2019-11-30T12:00:00Z"
    type: "widget_page"
    ---
    
  3. Copy ./content/home/about.md to .content/resume/ to work as the homepage’s ref

  4. Move ./content/home/accomplishments.md, ./content/home/skills.md and ./content/home/experience.md to .content/resume/

  5. Duplicate ./content/resume/accomplishments.md to ./content/resume/certifications.md to reuse the feature, separating certificates from on-line courses

  6. Fullfil the data! Changing the data on ./content/authors/admin/_index.md (which I renamed to ./content/authors/jjbeto/_index.md) and updating the other pages on .content/resume/ with custom data is enought to have a really nice page already

Resume initial page

Another small CSS trick is here: creating a small tag cloud for my experience stack list:

Cloud tags

How to do it here? You can check the source code, but to make it easier, you will need 2 things:

<!-- The HTML for the cloud -->
<div class="cloud_wrapper">
    <ul class="cloud">
        <li>Item 01</li>
        <li>Item 02</li>
    </ul>
</div>

...

<!-- The CSS for the cloud -->
<style>
.cloud_wrapper { text-align: center; }
.cloud { display: inline; list-style-type: none; width: 80%; margin: auto; }
.cloud li { list-style: none; display: inline; margin: 2px; }
.cloud li:nth-of-type(3n+1) { font-size: 1.25em; }
.cloud li:nth-of-type(4n+3) { font-size: 1.5em; }
.cloud li:nth-of-type(5n-3) { font-size: 1em; }
</style>

Another thing that I want to add is devicons so that I can list the tech stack that I’m using!

To do so, I’ve added to the end of ./content/resume/skills.md the ref style:

<link rel="stylesheet" href="https://cdn.rawgit.com/konpa/devicon/df6431e323547add1b4cf45992913f15286456d3/devicon.min.css">

So that I can use the icon this way:

[[feature]]
  icon = "apache-plain"
  icon_pack = "devicon"
  name = "Apache"
  description = ""

There should be a way to add this style to the root page and reuse it everywhere in the website, but I didn’t look into it for now because for now I just want to use it inside ./content/resume/skills.md (so, no need to download this css elsewhere).

Awesome, right?! Now we can play around with the current page list on the .content/resume/ folder and change everything that may be useful (and remove pages that don’t match with your needs).

6. Home Page: Review

So with the resume page settled, we can finish off the home page:

  • Activate ./content/home/hero.md to use as a first welcome;
  • Disable the following pages (not removing because I may use some of then soon):
    • ./content/home/featured.md;
    • ./content/home/projects.md;
    • ./content/home/publications.md;
    • ./content/home/tags.md;
    • ./content/home/talks.md;

I’ve renamed the base folder ./content/post to ./content/blog previously, because of that the homepage widget ./content/home/posts.md stops to work! No, actually the type of items to list on the default page is marked to be post, so I just changed it to blog instead (my new folder name) and that’s it.

[content]
  # Page type to display. E.g. post, talk, or publication.
  page_type = "blog"

Another small change that I’ve done was about the favicon (that small icon set for your page). To change that first I needed to find where it is set: ./themes/academic/layout/partials/site_head.html at line 125:

<link rel="icon" type="image/png" href="{{ "img/icon-32.png" | relURL }}">

Academics theme has it’s own Icon set at ./themes/academic/static/img/icon-32.png, so everything that I need to do is overwrite this with my own file on my root static folder .static/img, adding a PNG with the same name πŸ₯‡

But which icon should I use? πŸ€”

I’ve decided to not go too much into it for now, so I went to this cool website and generate an icon based on Devicons! Just placing the PNG at .static/img/icon-32.png is enough!

Ok, completely clean home page and also a nice Resume page is settled!

7. Blogging

To create a post we just need to write a lot of cool stuff and post it, right?

The answer is: no, not really.

I’m kind of methodic, I don’t like to read blogs or sites that looks too flooded with information and mainly: I hate to look at a content and fill confused to follow up. Well I’m sure that I’m not a good writer myself, and English is not my mother language too, so it’s kinda complicated to get things done without too much mess.

For that I did some research about how to organize my posts in a way that somebody else can understands it and… No lucky πŸ˜…

So as a first try out, I’ve decided to post as mini-publications, like one of my favorite Java-related blogs (Baeldung) does:

  1. Create a base structure for a post:
    • Overview
    • Items
    • Conclusion
  2. Use all possible tools to show examples
  3. Give a repository link in the end to show a running demo

As an extra tool, I’m going to create a Table of Contents as a fist item in each post to make it easier going around it.

It’s possible to check in the source code of this page, but I’ll list some points that took me a fill extra time to figure it out how to do:

7.1. Anchors and Table of Content

I didn’t find an easy way to create a Table of Contents for Hugo or Academic Theme, but I’ve found in this post a helpful link to make it to work.

Now every post will start with:

<aside>
    <div class="ox-hugo-toc toc">
        <header>
            <h2>Table of Contents</h2>
        </header>
        - [1. Overview](#overview)
        - [2. Item](#item)
        - [3. Conclusion](#conclusion)
    </div>
</aside>
<!--endtoc-->

This way is very simple to follow the actual Table of Contents in the post and also in the code. If somebody see this post and have other ideas to make it better, please let me know!

If you don’t know what a HTML Anchor is, you should search more about it πŸ˜„

7.2. Handling Images

As a folder-centric framework, I’m going to store related files all together in the same folder. You can check this on this post source code), and by the end it was incredibly easy to show the image:

![This is an image](featured.jpg)

The only problem is that this way you will have a static image directly on the post body, also depending on the image size you can have problems to see it properly. Then I found interesting sample folder with nice image handling, for more about this go to the documentation.

You can also point to the real url, it’s also fine πŸ˜„

8. Publish

TL;TR

Execute the following command to generate your final website:

hugo --gc --minify

This way, a folder public will be generated with the static site in it, what you need to do is commit/push all the files in a GitHub Repository called <your github user>.github.io.

That’s all, you can already access <your github user>.github.io and be happy ⭐️

There are plenty of content about how to setup Hugo Websites on GitHub Pages, for example on Hugo’s docs.

But to be honest, I think that it should be done automatically by some CI/CD tool. It’s a bit more complex and I’m going to talk more about it in a next post!

9. Conclusion

It was a looooong first post, wow! Next time I’ll try to be more concise (maybe).

Hugo is very helpful, has a big community, really good themes/plugins and extensive documentation. It’s obviously a great tool to use, very intuitive and easy to get used to.

I’m looking forward to use other features, like Google Analytics and Comments integration with social media! Stay tuned for next posts where I’m going to talk about web performance at Hugo, CI/CD (with GitHub Actions), Google Analytics, Comments and more.

Avatar
Beto Fonseca
Java Developer & Tech Enthusiast

My research interests includes Solution & Architecture Design, automation & DevOps and Cryptocurrency & Technical Analysis.