Blogging with hugo & netlify
Here is a great tutorial on how to host hugo on netlify
Other examples using the exact same theme:
- Tomas Westlake: r-mageddon.netlify.com
- Sascha Wolfer: rcrastinate.rbind.io
Creating the hugo site
In order to create a new hugo site simply go:
hugo new site [path] [flags]
Create a new repository via git
init
the git repo and push
it to the guthub repo:
echo "# website2" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/thomaslaber/website2.git
git push -u origin master
# Push an existing repository from the command line
# Alternatively you could link it to an already existing git repo:
git remote add origin https://github.com/thomaslaber/website2.git
git push -u origin master
Theme as git submodule
This is the theme I decided to go for Mainroad. Now you could add a theme of your choice git simply cloning it. However, it is more elegant to add it as a submodule.
Submodules allow you to include or embed one or more repositories as a sub-folder inside another repository.
git submodule add https://github.com/vimux/mainroad themes/mainroad
git submodule init
git submodule update
# This means it can be updated by running:
git submodule update --remote themes/mainroad
Adapting the theme
Now we simply copy the config.toml in order to immediately have a running config for the theme.
cp themes/mainroad/exampleSite/config.toml .
We also could copy the examplesite folder from the theme folder in order to have some sample content to display. However, for now we refrain from doing that. We start the hugo server by:
hugo server -D
Add custom CSS
We do not want to change anything in the theme folder as it will be updated and thus overwritten at some point of time. Therefore, we have to persist all our changes in the
Inside the config file we assign the path to an css file which can be found in static/css
:
[params]
custom_css = ["css/tl.css"]
{{ range .Site.Params.custom_css -}}
<link rel="stylesheet" href="{{ . | absURL }}">
{{- end }}
Changing colors
Unfortunately, the mainroad theme does not come with a built-in color-theme-support. Therefore, we have to replace color codes manually:
I chose to go from ███ #e64946
███ to ███ #191970
███. This can easily be done by runnnig a search and replace in the style.css
after it was copied to the static/css
folder.
Remember: No changes in the theme folder!
Adding Particles background
In order to set a simple but important optical highlight, I decided to include the particle.js.
This is done by adding the scripts in the static/js
folder.
<div id="particles-js"> </div>
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script>
<script src="{{ .Site.BaseURL }}js/particles.js"></script>
#particles-js {
/* position: absolute; */
height: 100px;
background-image: linear-gradient(to bottom right, black, navy,#aaa);
}
Main menu
A big upset was the possibility to add new menu items: It only works by adding the following code directly into menu.html
(\layouts\partials) and not into the template file. A more elegant way would include an option in the config file, i.e. config.toml
.
<li class="menu__item">
<a class="menu__link" href="/categories/book/">Books</a>
</li>
<li class="menu__item">
<a class="menu__link" href="/categories/project/">Projects</a>
</li>
Adding highlight.js
We are adding a few options to our config file:
highlight = true
highlightStyle = "monokai-sublime"
highlightLanguages = ["r", "sql", "bash", "css"]
Using these parameter we are loading them in the <head>
of baseof.html
:
{{ if .Site.Params.highlight | default false }}
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
{{ range .Site.Params.highlightLanguages }}
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/languages/{{ . }}.min.js"></script>
{{ end }}
<script>hljs.initHighlightingOnLoad();</script>
{{ end }}
Adding a custom search function
Following a tutorial we again start by adding some parameters to config.toml
.
[outputs]
home = [ "HTML", "RSS", "JSON"]
Note: Make shure to locate the required index.json
file in the layouts folder. Once the file exists, hugo is going to dump the index to file. It should look like:
[{{ range $index, $page := .Site.Pages }}
{{- if ne $page.Type "json" -}}
{{- if and $index (gt $index 0) -}},{{- end }}
{
"uri": "{{ $page.Permalink }}",
"title": "{{ htmlEscape $page.Title}}",
"tags": [{{ range $tindex, $tag := $page.Params.tags }}{{ if $tindex }}, {{ end }}"{{ $tag| htmlEscape }}"{{ end }}],
"description": "{{ htmlEscape .Description}}",
"content": {{$page.Plain | jsonify}}
}
{{- end -}}
{{- end -}}]
Once this is done, hugo generates a lunrjs
-index.json
at the root of your public folder. If you encounter some problems run: hugo --verbose
and check messages and warnings.
We add another css file css/auto-complete.css
to our <head>
.
Finally, we need to load lunr.
Please note: as lunr.js
is based on jquery, make sure jquery.js
gets loaded first.
<body>
...
<!-- custom search -->
{{ if not .Site.Params.disableSearch }}
<script type="text/javascript" src="{{ .Site.BaseURL }}js/lunr.min.js"></script>
<script type="text/javascript" src="{{ .Site.BaseURL }}js/auto-complete.js"></script>
<script type="text/javascript">
var baseurl = "{{ .Site.BaseURL }}";
</script>
<script type="text/javascript" src="{{ .Site.BaseURL }}js/search.js"></script>
{{ end }}
...
</body>
and finally, we add a search entry box somewhere in your webpage layout:
{{ if not .Site.Params.disableSearch }}
<li class="dropdown">
<a>
<i class="fa fa-search"></i>
<div class="searchbox pull-right">
<input data-search-input id="search-by" type="text">
</div>
</a>
</li>
{{ end }}
Finally, we delete Â
in »
in search.js
at line 80. I do not know what purpose is served.
Custom sidebar
I had to create a new widget in layouts\partials\widgets and called it toc.html
:
{{ if eq .Kind "page" }}
<div class="widget-toc" id="sticker">
<h4 class="widget__title">Table of Content</h4>
<div class="toc__menu">
{{ .TableOfContents }}
</div>
</div>
{{ end }}
Please not that {{ .TableOfContents }}
virtually does all of the work.
The new widget has to be added to the site via the config.toml
. Please not the right section:
[Params.sidebar]
widgets_page = ["toc"]
I added some javascript for two toggle effects for the table of content:
- Make the toc sticky.
- Make the toc disappear.
$(document).ready(function(){
$("#sticker").sticky({topSpacing:10});
});
var clicked = false;
function toggleBtnClick() {
if (clicked) {
$("#sticker").sticky({topSpacing:10});
$("#pin_button img").removeClass("deactivated");
$("#pin_button img").addClass("activated");
clicked = false;
} else {
$("#sticker").unstick();
$("#pin_button img").removeClass("activated");
$("#pin_button img").addClass("deactivated");
clicked = true;
}
}
var clicked2 = false;
function toggleBtnClick2() {
if (clicked2) {
$("aside").show();
$("#hide_button img").removeClass("deactivated");
$("#hide_button img").addClass("activated");
clicked2 = false;
} else {
$("aside").hide();
$("#hide_button img").removeClass("activated");
$("#hide_button img").addClass("deactivated");
clicked2 = true;
}
}
I pushed the table of content in the sidebar and made it sticky using stickyjs.com. This means I also have to add a custom javascript-file to get loaded: custom.js
. I did this by adding the following lines to baseof.html
in \layouts_default. I also added to small icons to be execute the javascript commands:
<script type="text/javascript" src="{{ .Site.BaseURL }}js/jquery.sticky.js"></script>
<script type="text/javascript" src="{{ .Site.BaseURL }}js/custom.js"></script>
...
</head>
<body class="body">
{{ if eq .Kind "page" }}
<div class="sidebar_menu">
<span onclick="toggleBtnClick()" id="pin_button"><sup><img src="{{ .Site.BaseURL }}img/pin.png" width="25px" class="activated"></sup></span>
<span onclick="toggleBtnClick2()" id="hide_button"><sup><img src="{{ .Site.BaseURL }}img/eye.png" width="25px" class="activated"></sup></span>
</div>
{{ end }}
External link open a new tab
The usual target="_blank"
is not really supported in markdown, only a few subversions do. Therefore, you can add this line of jquery code to let javascript do the work:
//add target="_blank" to all external links
$('.content a[href^="http"').attr('target', '_blank');