Setting up your own free blog


Here's what this post is about:


There are many things I find interesting about the way this blog is deployed:

  • It is only static pages, so you don’t have to worry about huge frameworks, database management etc.
  • Pages are written in Markdown language, so you have a clean and understandable text while writing.
  • You can host it and many different places. I’m choosing the Github Pages, so both my website project and the website itself are under a version control system.
  • I can share my ideas much easily, because the code is already hosted on Github, available to anyone curious enough to sneak a peek.
  • It’s easy!
  • It’s free!

I’m assuming you already have a valid account at Github, installed Git on your machine and downloaded Hugo. No IDE is required for these tasks: everything can be managed just with your favorite text editor (I recommend Notepad++ if you’re in a Windows environment) and a terminal/prompt.

I’ll be using my repositories throughout this post as an example, so anywhere you read otaviokr-blog you may change by source code repository named as you like it while otaviokr.github.io means .github.io. Notice that Github allows you to have a website for a particular repository, but that’s not what we’re aiming here: this is to build the user’s website - while you may have many project websites (one for each project you have), you can only have one user website.

So here’s the steps to create your own blog:

Create 2 different repositories

The source repository is where the website source code will be; you’ll also need a Github Pages default repository. Feel free to name the first one as you like - mine is otaviokr-blog. Now, create another repository, following the pattern <your_username>.github.io, as in otaviokr.github.io. This is the default name used by Github Pages, so when you create this repository, Github will understand that you want to have a website at http://your_username.github.io. If you use a different repository name, it won’t work - at least, not out-of-the-box.

If you need help to create the repositories, you may use Github’s documentation as a guideline.

Setting the source repository

Now it’s time to work with the source repository, where the raw code of your site will be - I’ll be using my repos as example, we’ll handle otaviokr-blog now. First, open the terminal, enter the folder where you want to keep the local repositories and clone the first repository to your machine:

1 git clone otaviokr-blog

There’s nothing there yet, so we’ll add the blog skeleton manually[1]. Just create the following folders:

1 mkdir content
2 mkdir layouts
3 mkdir public
4 mkdir static
5 mkdir themes

Brief explanation about the folders:

  • content: where your raw posts will be;
  • layouts: Hugo demands this folder, but I haven’t use it so far;
  • public: where the compiled site will be generated;
  • static: to keep your static files, like images;
  • themes: where the blog template are stored.

Now, create the configuration file on the root path (otaviokr-blog/) and name it config.yaml. Be careful to use just 2 spaces for identation - YAML does not respond well to tabs. There are other optional parameters you can configure, and the theme you’ll choose probably will have its own settings, but for now, what you need is just this - change the values whenever necessary!

 1 ---
 2 contentdir: "content"
 3 layoutdir: "layouts"
 4 publishdir: "public"
 5 taxonomies:
 6   category: "categories"
 7   series: "series"
 8 baseurl: "http://otaviokr.github.io"
 9 title: "Otaviokr's Blog"
10 canonifyurls: true

Your own local blog

Before sending it to the web, we’ll configure it and test it locally, to see if everything is working as expected. First, you’ll need a theme (aka template) for you blog. Hugo has a great variety of themes already, and you can create your own if you want, but, for now, let’s just pick one to see the magic happening. I’m using hurock, but you can choose your personal favorite.

At the terminal, just enter inside themes/ and clone the theme you want:

1 cd themes
2 git clone https://github.com/TiTi/hurock.git

Then append the parameters required by the theme in your config.yaml file. Hurock gives already a template with everything configured. Hurock also expects your picture saved as static/media/me.jpg.

Now, let’s create a simple post to check our blog. You may simple create a text file and copy the header or use Hugo:

1 hugo new posts/2015/hello.md

File will be created at content/posts/2015/hello.md. Open it, change the configuration header if you want and enter some text after the header. Markdown syntax is enabled, so try to do something nice! When you’re done, save and exit.

Now, run:

1 hugo server --watch

This will compile the website and create a server where you can see your blog. Open you web browser and access localhost:1313. You should see the blog and your first post - if not, check for error messages in the terminal and review all the steps. If the blog is fine, Ctrl+C in the terminal to kill the server and delete everything under public/ folder - don’t worry, we’ll generate it again later. Create an empty file named .gitkeep inside any folder that has no files - I believe it’s layouts/ and public/ - and commit the first version of you website source code:

1 git add -A
2 git commit -m "First commit."
3 git push origin master

Putting the website online

Now we know that public/ is where the website actually is, so let’s clone the webiste repository into public/. That way, we’ll just need to generate the site and push the commit to have the new article online.

1 git clone https://github.com/otaviokr/otaviokr.github.io.git public/

The idea then is to run hugo to generate the site, add all generated files to the website repository and push changes.

1 hugo
2 cd public
3 git add -A
4 git commit -m "First post: Hello."
5 git push origin master

It might take a while before you can check your site for the first time, but it is there! Just open a browser and go to http://your_username.github.io. There you go, now for each new post, just run the last piece of command to add it, commit it and deploy it.

Bonus round: making things easier

Whenever a developer hears the sentence you just need to do this thing again and again, he quickly starts thinking what sort of script could do that automatically, am I right? So, let’s improve a little our project.

First, let’s avoid having source and compiled code in the same repository. If you didn’t created a .gitignore file while creating the otaviokr-blog repository, now it’s the time. You may put anything you find relevant here, but we must algo include public so that folder is not in this project radar anymore.

Now, the automation script. Let’s create a bin/ folder where we’ll keep it and inside it create a script called publish.bat - I’m in a Windows environment, but if you’re in Linux, call it publish.sh and change the code as necessary… I’ll try to create an example later, but you can check the excellent original post on which I based my version.

 1 @echo off
 2 echo "Deploying updates to GitHub..."
 3 
 4 cd ..
 5 
 6 REM Build the project.  If using a theme, and it is not set in config.yaml, 
 7 REM replace by `hugo -t <yourtheme>`
 8 hugo
 9 
10 REM Go To Public folder
11 cd public
12 
13 REM Add changes to git.
14 git add -A
15 
16 REM Commit changes. Count the number of arguments: 
17 REM if user has not given any, use default message.
18 set argC=0
19 for %%x in (%*) do Set /A argC+=1
20 
21 For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c-%%a-%%b)
22 For /f "tokens=1-2 delims=/:" %%a in ('time /t') do (set mytime=%%a%%b)
23 set msg=rebuilding site %mydate%_%mytime%
24 if %argC% equ 1 (
25     set msg=$1
26 )
27 git commit -m "%msg%"
28 
29 REM Push source and build repos.
30 git push origin master
31 
32 REM Come Back
33 cd ../bin

That’s it! Just commit the new changes and now, whenever you create a new post, all you have to do is commit/push otaviokr-blog and, after, run cd bin; publish.bat. Unless, you’re using Windows…

Bonus round 2: The eternal struggle on Windows - LF <=> CRLF

I won’t explain much about line endings conflict because what you need to know is that the return carriage (aka new-line character) is different between Windows and Linux. Because Github favours Linux standard, whenever you try to commit something using Windows end-of-line char, you’ll receive a fatal error and the operation will be aborted. To avoid that, I’m using unix2dos to convert the files to Windows standard (CRLF).

It is important to notice that this is only needed to otaviokr.github.io repository; in theory, all files at otaviokr-blog are already using the correct EOL char. First thing is to modify repository configuration, editing .git/config file:

 1 [core]
 2 	repositoryformatversion = 0
 3 	filemode = false
 4 	bare = false
 5 	logallrefupdates = true
 6 	symlinks = false
 7 	ignorecase = true
 8 	hideDotFiles = dotGitOnly
 9 	eol = native
10 	autocrlf = true
11 [remote "origin"]
12 	url = https://github.com/otaviokr/otaviokr.github.io.git
13 	fetch = +refs/heads/*:refs/remotes/origin/*
14 [branch "master"]

Then download unix2dos program at their official site and extract the zip file at the bin/unix2dos/ folder. I don’t think that’s a good idea to version the unix2dos program, so add to more lines to .git/config file:

1 bin/unix2dos/bin
2 bin/unix2dos/share

You’ll also have to change the auto-publish script, so it converts the files before committing them.

 1 @echo off
 2 REM Created based on script at http://gohugo.io/tutorials/github-pages-blog/
 3 
 4 SETLOCAL
 5 SET PATH=%PATH%; %__CD__%unix2dos/bin/
 6 echo %PATH%
 7 echo "Deploying updates to GitHub..."
 8 
 9 REM Back to root parent dir.
10 cd ..
11 
12 REM Build the project.  If using a theme, and it is not set in config.yaml, 
13 REM replace by `hugo -t <yourtheme>`
14 hugo
15 
16 REM Listing all files to be converted LF-CRLF, if necessary.
17 for /r public\ %%G in (*.*) do unix2dos.exe %%G
18 
19 REM Go To Public folder
20 cd public
21 
22 REM (...) - this original script part remains the same
23 
24 REM Come Back
25 cd ../bin
26 
27 ENDLOCAL

Commit again otaviokr-blog and now you’re really good to go! This is the first post about a series I’m starting to tell about my experiences with this blog. If you wish to know anything in more detail, let me know!