---
date: '2026-03-23T17:27:50+01:00'
draft: false
title: "Let's start a blog!"
author: "Jirka"
tags: ["hugo", "idea", "guide", "tutorial"]
categories: ["blog", "idea"]
description: "Behind the scenes of the idea and setup."
---

This blog has been created as one of my personal projects, first one released on this page. (Actually, this article, about creating this blog, is being written before creation of the blog and this page).

## How it started

The original idea was simple: **I would like to share my projects and knowledge with others.** But how?

I am big fan of self-hosting and in the same time I hate JavaScript, CSS and anything connected to web development. (A bit embarrassing I know).

So how to self-host simple web/blog without need to write the HTML and all the web things on my own?

The answer is [Hugo](https://gohugo.io/)! I do not feel knowledgeable enough to describe what Hugo is, but I will share with you, how I am going to use it.

## Dreamed solution

Before finding out what Hugo is, I had a pretty complete idea of how this should work:

- Every project shared here should be shared with source files, so anyone can reuse and replicate my journey.
- I am using [Markdown](https://www.markdownguide.org/) for all my notes, so it would be best, if I can write and article in Markdown and then convert it to static page. **And that is exactly what Hugo is going to do for me!**

Those two things connects together like this:
- Self host a Git with project files for Hugo
- Write new articles in `.md` and upload them to the server via git.
- When pushing to `master` branch, build/update the page files and automatically reflect it to the website.

This article is just about how to set up the Hugo for my purpose and how the content in associated repository has been created. More about the self-hosting in the future articles.

## Hugo setup

Work with hugo is super simple, I've start with their official [guide](https://gohugo.io/getting-started/quick-start/), but I will cover basic steps here.

To create empty Hugo project (after installing Hugo), start with:
```bash
hugo new project name_of_new_directory
```

This creates initial `hugo.toml`. Right now, you should know which theme for your side you would like to use. List of example theme can be found (here)[https://themes.gohugo.io/]. As you can see, I have chosen (Minimal Black)[https://themes.gohugo.io/themes/hugo-minimal-black/].

Next step is to download the theme and add it to the `themes` directory. You can clone it from Git repository, or download it. What is right depends just on your target usage.

I am going to download the theme as `.zip`, because I am going to edit some files and would like to reflect the changes in my own repository.

```bash
cd themes
wget 'https://gitlab.com/jimchr12/hugo-minimal-black/-/archive/main/hugo-minimal-black-main.zip?ref_type=heads' -O theme.zip
unzip theme.zip
mv hugo-minimal-black-main minimal-black
rm theme.zip
```

Right now, you should have your theme installed in right directory and follow the directions from theme author.

For me this means I should install `npm` dependencies and copy example `hugo.toml`.
```bash
cd minimal-black/
npm install
cd ../..
cp themes/minimal-black/exampleSite/hugo.toml ./hugo.toml
```

From now on, you should be good to go. Go through the `hugo.toml` file, edit it to your likeness and create some content.

I am not going to explain what changes I've done (you can see them in the repo (Once it is set up #TODO)), neither I am going to talk about writing this how to guide, but I will add changes that I've done to the project. 

## Work with Hugo

When you want to write new article, you create new `.md` file in `content` directory with:
```bash
hugo new blog/01-blog.md
```

This will automatically add header to your file. How the header is going to look like is based on your `archetypes`. Those are `.md` files located in `archetypes` folder.

`default.md` is created by default, and you can look what it contains on your own. I recommend copy it to your specialized `.md` files and add lines which you need (probably based on your theme selection).

For example, I've created `blog.md` file, and it is going to be used for files created under `blog` directory.

It looks like this:
```toml
---
date: '{{ .Date }}'
draft: true
title: '{{ replace .File.ContentBaseName "-" " " | title }}'
author: "Jirka"
tags: ["tag"]
categories: ["documentation"]
description: "..."
---
```
As you can see, it is going to prefill date, author, ... for me and prepares fields where I can specify description, categories, etc. for the article.

> [!NOTE]
> I've switched to `yaml` format, because it looks better (by me) in raw `.md` files rendered in Gitea for example.

Now, when you created your `.md` files (not just archetypes, but some testing article also), you can start your development server and see how it looks like by:
```bash
hugo server # or hugo server -D for preview of draft files
```

And that's it! You've just created new web!

For publication, right now the web can be prepared for publishing just by executing `hugo`. It will generate static files in `public` folder. On how to make web online, you can check [official documentation](https://gohugo.io/host-and-deploy/). I will cover how this website is going to be published in next articles.


## Advanced changes

You do not have to do anything more. I will just cover changes I've made to make publishing for me just a bit easier.

### Use natural Markdown linking between files

Right now, Hugo does not expect me to link articles just how I would link them in plain `.md` files. I do not like that, because it would not work in repo that way.
So I've created `layouts/_default/_markup/render-link.html` will follow content:

```html
{{- $link := .Destination -}}
{{- $isRemote := or (strings.HasPrefix $link "http") (strings.HasPrefix $link "mailto") -}}

{{- if not $isRemote -}}
  {{- $url := urls.Parse .Destination -}}
  {{- $fragment := "" -}}
  {{- with $url.Fragment }}{{ $fragment = printf "#%s" . }}{{ end -}}
  
  {{- /* Try to find the page by its path */ -}}
  {{- with .Page.GetPage $url.Path -}}
    {{- $link = printf "%s%s" .RelPermalink $fragment -}}
  {{- else -}}
    {{- /* If the page is not found, throw a warning during build. */ -}}
    {{- warnf "Broken link to page: '%s' found in file %s" .Destination .Page.File.Path -}}
  {{- end -}}
{{- end -}}

<a href="{{ $link | safeURL }}"{{ with .Title }} title="{{ . }}"{{ end }}>{{ .Text | safeHTML }}</a>
```

It creates correct links just from file links and will warn me if anything will go wrong.
