How to build and deploy static site in GitLab with Hugo?
Hugo GitLab Blogging about blogging
Table of contents:
The intention of this post is to document the process of building this web site and outline some great resources I used along the journey. This is a static site based on Hugo and runs using GitLab pages. I have been fan of static sites for a while.
Back few years earlier I used Ruby on Rails framework, Docker Compose and lots of other technologies to run this site. π€¦ββοΈ This is no longer needed as we can easily publish content without all thes complexities …
Bookmark this link to access full series. π
Getting started #
These are the bare minimums I needed to get started:
- Git for source code (I use GitLab, from where I also deploy this site to GitLab Pages)
- Visual Studio Code
- Hugo
And to generate new site and structure for the new theme:
1hugo new site mysite
2cd mysite
3hugo new theme mytheme
4
5# Now let's see what the actual theme looks like:
6
7tree themes
8themes
9βββ mytheme
10 βββ LICENSE
11 βββ archetypes
12 βΒ Β βββ default.md
13 βββ layouts
14 βΒ Β βββ 404.html
15 βΒ Β βββ _default
16 βΒ Β βΒ Β βββ baseof.html
17 βΒ Β βΒ Β βββ list.html
18 βΒ Β βΒ Β βββ single.html
19 βΒ Β βββ index.html
20 βΒ Β βββ partials
21 βΒ Β βββ footer.html
22 βΒ Β βββ head.html
23 βΒ Β βββ header.html
24 βββ static
25 βΒ Β βββ css
26 βΒ Β βββ js
27 βββ theme.toml
28
298 directories, 11 files
The theme of this site is here. I have it slightly extend from its default state and this is available in the repo.
I use bootstrap 5.0 framework.
Features #
This block contains some of the most interesting features that I have implemented (or plan to implement).
Tags cloud #
Main page, left hand side there is tags cloud. I use the following approach to achieve this effect: iterating through all available tags on the site (with at least 1 reference from post/page) and making calculation of the font size for the certain tags. The more references the certain tag has the bigger its bootstrap badge.
1{{ if not (eq (len $.Site.Taxonomies.tags) 0) }}
2 {{ $fontUnit := "rem" }}
3 {{ $largestFontSize := 2.0 }}
4 {{ $largestFontSize := 2.5 }}
5 {{ $smallestFontSize := 1.0 }}
6 {{ $fontSpread := sub $largestFontSize $smallestFontSize }}
7 {{ $max := add (len (index $.Site.Taxonomies.tags.ByCount 0).Pages) 1 }}
8 {{ $min := len (index $.Site.Taxonomies.tags.ByCount.Reverse 0).Pages }}
9 {{ $spread := sub $max $min }}
10 {{ $fontStep := div $fontSpread $spread }}
11
12 <div class="tag-cloud" style="padding: 5px 15px">
13 {{ range $name, $taxonomy := $.Site.Taxonomies.tags }}
14 {{ $currentTagCount := len $taxonomy.Pages }}
15 {{ $currentFontSize := (add $smallestFontSize (mul (sub $currentTagCount $min) $fontStep) ) }}
16 {{ $count := len $taxonomy.Pages }}
17 {{ $weigth := div (sub (math.Log $count) (math.Log $min)) (sub (math.Log $max) (math.Log $min)) }}
18 {{ $currentFontSize := (add $smallestFontSize (mul (sub $largestFontSize $smallestFontSize) $weigth) ) }}
19 <!--Current font size: {{$currentFontSize}}-->
20 <a href="{{ "/tags/" | relLangURL }}{{ $name | urlize }}" style="font-size:{{$currentFontSize}}{{$fontUnit}}"><span class="badge bg-primary">{{ $name }}</span></a>
21 {{ end }}
22 </div>
23{{ end }}
Shortcodes #
Shortcodes are simple snippets inside my content files calling built-in or custom templates.
If I want to embed the following tweet in my content.
My kids: papa, your door looks lonely, it needs some decorationsβ¦
— Evgeny Rudinsky π§ (@evgenyrudinsky) November 3, 2022
Me: pic.twitter.com/wyV1Q8MMqD
… I use doc.
If I want to get current year
In the footer I use pure JavaScript:
1document.write(new Date().getFullYear());
… but in the content I can use shortcodes and say current year via: 2024
… I use doc.
Masonry - Bootstrap 5 grid #
Masonry is the way to build certain structure from individual units, often with bricks / blocks / parts etc. There is also cascading grid layout library called Masonry written on JavaScript which I used a lot on my sites. For something like this:
Panel title
Some quick example text to build on the panel title and make up the bulk of the panel's content.
Card link Another linkPanel title
Panel subtitle
Some quick example text to build on the panel title and make up the bulk of the panel's content.
Card link Another linkLorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.
- Cras justo odio
- Dapibus ac facilisis in
- Vestibulum at eros
Panel title
Some quick example text to build on the panel title and make up the bulk of the panel's content.
- Cras justo odio
- Dapibus ac facilisis in
- Vestibulum at eros
Special title treatment
With supporting text below as a natural lead-in to additional content.
Button 1<div class="container">
2
3 <h1 class="my-4 font-weight-bold">Masonry - Bootstrap 4 grid</h1>
4
5 <div class="grid">
6 <div class="grid-sizer col-md-3"></div>
7 <div class="grid-item col-md-6 mb-4">
8 <div class="card">
9 <div class="card-body">
10 <h5 class="card-title">Panel title</h5>
11 <p class="card-text">Some quick example text to build on the panel title and make up the bulk of the panel's content.</p>
12 <a class="card-link">Card link</a>
13 <a class="card-link">Another link</a>
14 </div>
15 </div>
16 </div>
17 <div class="grid-item col-md-3 mb-4">
18 <div class="card">
19 <div class="card-body">
20 This is some text within a panel body.
21 </div>
22 </div>
23 </div>
24 <div class="grid-item col-md-3 mb-4">
25 <div class="card">
26 <div class="card-body">
27 <h5 class="card-title">Panel title</h5>
28 <h6 class="card-subtitle mb-2 text-muted">Panel subtitle</h6>
29 <p class="card-text">Some quick example text to build on the panel title and make up the bulk of the panel's content.</p>
30 <a href="#!" class="card-link mr-3">Card link</a>
31 <a href="#!" class="card-link ml-0">Another link</a>
32 </div>
33 </div>
34 </div>
35 <div class="grid-item col-md-6 mb-4">
36 <div class="card">
37 <div class="card-header">
38 Quote
39 </div>
40 <div class="card-body">
41 <blockquote class="blockquote mb-0">
42 <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
43 <footer class="blockquote-footer">Someone famous in <cite title="Source Title">Source Title</cite></footer>
44 </blockquote>
45 </div>
46 </div>
47 </div>
48 <div class="grid-item col-md-3 mb-4">
49 <div class="card">
50 <ul class="list-group list-group-flush">
51 <li class="list-group-item">Cras justo odio</li>
52 <li class="list-group-item">Dapibus ac facilisis in</li>
53 <li class="list-group-item">Vestibulum at eros</li>
54 </ul>
55 </div>
56 </div>
57 <div class="grid-item col-md-3 mb-4">
58 <div class="card">
59 <div class="card-body">
60 <h5 class="font-weight-bold mb-3">Panel title</h5>
61 <p class="mb-0">Some quick example text to build on the panel title and make up the bulk of the panel's content.</p>
62 </div>
63 <ul class="list-group list-group-flush">
64 <li class="list-group-item">Cras justo odio</li>
65 <li class="list-group-item">Dapibus ac facilisis in</li>
66 <li class="list-group-item">Vestibulum at eros</li>
67 </ul>
68 <div class="card-body">
69 <a href="#!" class="card-link mr-3">Card link</a>
70 <a href="#!" class="card-link ml-0">Another link</a>
71 </div>
72 </div>
73 </div>
74 <div class="grid-item col-md-3 mb-4">
75 <div class="card">
76 <div class="card-header">
77 Featured
78 </div>
79 <div class="card-body">
80 <h5 class="card-title">Special title treatment</h5>
81 <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
82 <a href="#!" class="btn btn-primary btn-sm">Button</a>
83 </div>
84 </div>
85 </div>
86 </div>
87
88</div>
Masonry has to be added to scripts and initialized (including page check):
1$(document).ready(function() {
2 $('.grid').masonry({
3 itemSelector: '.grid-item',
4 columnWidth: '.grid-sizer',
5 percentPosition: true
6 });
7});
Example of masonry in bootstrap
GitLab Pages #
To publish this static site I use GitLab Pages. This doc helps to understand Markdown. There is also group of pages examples. I used this ci as foundation:
1image: registry.gitlab.com/pages/hugo:latest
2
3variables:
4 GIT_SUBMODULE_STRATEGY: recursive
5
6pages:
7 script:
8 - hugo
9 artifacts:
10 paths:
11 - public
12 only:
13 - master
The site is available under <project_name>.gitlab.io
domain. There is also possibility to have custom domain.
Later #
- Some music from here
- Speaker decks of @mdo
- Cubernetes?
- Readme.md and this
- Tips and Tricks for Hugo
- An example of building theme from scratch
- Theme
- Hugo’s SEO
- Git Submodules
- Blogging about blogging
- Search and search
- TOC
- TOC and syntax highlight
- RSS