Labarum

Creating Labarum (Part 4): Initiating the Index

In the beginning of this series, we started off with an index page that was just a static page with one line that stated you were on the index page. When it comes to implementing this, I looked at the Hugo Themes Free as well as the theme gallery that Micro.blog provides.

Ultimately, I went with a simple structure that took advantage of the simplicity that I had in the Pure theme and the fact that we had already extracted the logic for articles into the partials.

{{- range ( .Paginate (where .Site.RegularPages "Type" "post")).Pages }}
{{ partial "article.html" . }}
{{ end }}

After that, we remove all the static <article> tags that we placed into our index to see how it renders. This looks ok, but the design that I have in mind calls for pagination1(being able to go to older posts).

Paging the index

I admit that I went down a rabbit hole of different examples of how to create the navigation that you see at the bottom of the page. A lot of the examples that I came across where hard coded or I couldn’t understand.

Ultimately, I went with the example that I had from my previous theme. I took the code and placed it into a file name partial\site-navigation.html so that I can track it later.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
{{ "<!-- Site Pagination -->" | safeHTML }}
{{ $paginator := .Paginate (where .Data.Pages.ByDate.Reverse "Type" "post") (index .Site.Params "archive-paginate" | default 10) }}
<nav class="pagination">
	{{- if $paginator.HasPrev -}}
	<p class="nav_prev">
		<a href="{{ $paginator.Prev.URL }}" title="Previous Page" rel="prev">
		← Newer Posts
		</a>
	</p>
	{{- end }}

	{{ if $paginator.HasNext -}}
	<p class="nav_next">
		<a href="{{ $paginator.Next.URL }}" title="Next Page" rel="next">
		Older Posts →
		</a>
	</p>
	{{- end }}
</nav>

On the first line, I’m adding a line that will show up in the final output of the generated site so I can see where Hugo is inserting the code.

The second line calls the default paginator to go over all the posts that the site has by whatever parameter that is given. If none is given, it will use 10.

Line 3 defines our semantic element for the navigation and give it a class for styling it later.

Line 4-10 tests to see if there is a previous page and then creates a link to the page when it exists.

Line 12-18 tests to see if there is a next page and creates everything that’s needed.

The navigation was another thing that I spent a lot of time looking into, but ultimately went with a simple ordered list of items.

The initial design did not have a link to the home page because I thought that anyone how came across the page would only be interested in that page and not the additional content, but after having to go to the address bar multiple times to navigate between the different pages, I decided to add it as the first item.

I placed this into a separate file called site-nav.html like I did for pagination for better tracking.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{{ "<!-- site-nav.html -->" | safeHTML }}
<nav>
	<menu>
		{{ if ne .IsHome true }}
		<li><a href="{{ .Site.BaseURL }}" title="{{ .Site.Title }}">Home</a></li>
		{{ end }}
		{{- range .Site.Menus.main }} 
		<li><a href="{{ .URL | relLangURL | safeURL }}">{{ .Name }}</a></li>
		{{ end -}}
		<li><a href="{{ "feed.xml" | absURL }}" rel="feed" type="application/rss+xml" title="{{ $.Site.Title }}">RSS</a></li>
	</menu>
</nav>

On line 3, I used the <menu> semantic tag to give it some more meaning. It definitely felt that it took some time to On line 3, I used the <menu> semantic tag to give it some more meaning. It definitely felt that it took some time to get a consensus on whether I needed to add a <ul> or <ol> to make the syntax valid.

Line 4 does a test to see if the generated page is the home page. This is working to an extent, but fails when moving to the second index page.

Line 7 sorts through the different menu items. I had an issue trying to understand how Hugo puts together a menu on my local copy and what was being used in Micro.blog.

Line 10 gives a direct link to the RSS feed for the site. The RSS feed is inherited from the base blank theme that underlies of Micro.blog.

The next segment of this tutorial will be focused on the schema tags followed by accessibility and then a grab bag of different things.

Please let me know if you have any questions about the design so that I can make this better. I think I might put this all together in one LARGE post at the end.


  1. I’ve come across a couple sites that only have the index and then has the user search or go through an archive to find older material. The argument being that most users only want to read your most current entries or have something specific that they are looking for.

    I’m going to go with what I feel is a classic approach and revisit this later. ↩︎

Categories: Labarum

Published:

Debug

Site Properties

		&hugolib.SiteInfo{Authors:page.AuthorList(nil), Social:hugolib.SiteSocial(nil), hugoInfo:hugo.Info{CommitHash:"1798bd3f", BuildDate:"2021-12-23T15:33:34Z", Environment:"production"}, title:"Mandaris", RSSLink:"https://mandarismoore.com/feed.xml", Author:map[string]interface {}{"avatar":"https://micro.blog/mandaris/avatar.jpg", "name":"Mandaris Moore", "username":"mandaris"}, LanguageCode:"en", Copyright:"", permalinks:map[string]string{}, LanguagePrefix:"", Languages:langs.Languages{(*langs.Language)(0xc00080dba0)}, BuildDrafts:false, canonifyURLs:false, relativeURLs:false, uglyURLs:(func(page.Page) bool)(0x163ea20), owner:(*hugolib.HugoSites)(0xc0000ed600), s:(*hugolib.Site)(0xc000592d80), language:(*langs.Language)(0xc00080dba0), defaultContentLanguageInSubdir:false, sectionPagesMenu:""} 

		

site.Params Properties

		maps.Params{"description":"Follow <a href=\"https://micro.blog/mandaris\">@mandaris on Micro.blog</a>.", "feeds":maps.Params{"bookmarks_json":"https://micro.blog/feeds/mandaris/bookmarks/08117195b525afe4a55f.json"}, "github_username":"mandaris", "include_conversation":true, "instagram_username":"mandaris", "itunes_author":"Mandaris", "itunes_category":"Society & Culture", "itunes_cover":"https://micro.blog/mandaris/podcast.png", "itunes_description":"A High-quality stranger. I've considered myself a digital gofer. Y'know, go for this and go for that. I'm using micro.blog now to par down my technical projects and be part of an outstanding community.  Apple Game Center: MrMandaris  Email: Contact@MandarisMoore.com", "itunes_email":"podcast@mandarismoore.com", "itunes_subcategory":"Personal Journals", "mainSections":[]string{"replies"}, "mainsections":[]string{"replies"}, "paginate_categories":true, "paginate_home":true, "paginate_replies":true, "plugins_css":[]interface {}{}, "plugins_html":[]interface {}{}, "plugins_js":[]interface {}{}, "site_id":"661", "theme_seconds":"1675089916", "twitter_username":"mandaris"}
		

Permalink

		"https://mandarismoore.com/2023/01/11/creating-labarum-part.html" 

		

Params

		map[categories:[Labarum] date:2023-01-11 11:02:30 -0800 -0800 draft:%!s(bool=false) guid:http://mandaris.micro.blog/2023/01/11/creating-labarum-part.html iscjklanguage:%!s(bool=false) lastmod:2023-01-11 11:02:30 -0800 -0800 layout:post microblog:%!s(bool=false) publishdate:2023-01-11 11:02:30 -0800 -0800 title:Creating Labarum (Part 4): Initiating the Index type:post url:/2023/01/11/creating-labarum-part.html]
		

All variables scoped to the current context

		&hugolib.pageState{pageOutputs:[]*hugolib.pageOutput{(*hugolib.pageOutput)(0xc00273a6c0), (*hugolib.pageOutput)(0xc00273a7e0), (*hugolib.pageOutput)(0xc00273a900), (*hugolib.pageOutput)(0xc00273aa20), (*hugolib.pageOutput)(0xc00273ab40), (*hugolib.pageOutput)(0xc00273ac60), (*hugolib.pageOutput)(0xc00273ad80), (*hugolib.pageOutput)(0xc00273aea0)}, pageOutput:(*hugolib.pageOutput)(0xc00273a6c0), pageCommon:(*hugolib.pageCommon)(0xc00194c000)}	
		

Creating Labarum (Part 3): Implementing post footer

In my initial design, I had footer that would show the categories, tags, date published, and date modified. All of these values are things, I had seen in previous sites and I could easily get to this information. I thought it would be 15-20 minutes to get this information. The fact that I felt that the footer deserves it’s own discussion should let you know that it ultimately wasn’t.

Start!

The first thing I did was move my current static footer from my example into it’s own template file partials/article-footer.html. I’m going to spare you the boring details of how I searched and searched through examples of what I thought it should look like versus what Hugo provides. A lot the issues that I ran into was whether I was using tag, tags, category, or categories. Do I write the code I write have to parse a comma separate list or an array?

My mental model originally had it so that a post could have one category and multiple tags.

Tag to multiple categories

Unfortunately, after a couple hours I realized that a lot of this was moot because I was going to send this template to Micro.blog and I didn’t know what they used.

Getting more information about Micro.blog

The ultimate goal for this theme is that I’d use it on the Micro.blog service. Although Micro.blog uses Hugo, it has a significant amount of customization that I do not know about. Honestly, I do not want to know exactly how it is put together, but I do want to know what it is sending to the theme to get rendered.

So, this is the point in the process where I deploy all the changes that I’ve made to GitHub and then use the instructions on how to set up with a custom theme.

I took some information from the  Hugo page on debugging a theme and then placed that in a <detail> item nested in the  footer. This made the article.html template pretty long, so I decided to make the footer into its own file (article-footer.html) for easier management.

Ultimately, this allows me to see if Micro.blog supports tags or categories and whether it’s stores in a string or array. I’m going to include the code in this post below.

{{ "<!-- Debugging Details --> " | safeHTML }}
	<details>
		<summary>Debug</summary>
		<h1>Site Properties</h1>
		<pre>
		{{ printf "%#v \n" $.Site  }}
		</pre>

		<h1>site.Params Properties</h1>
		<pre>
		{{ printf "%#v" site.Params }}
		</pre>

		<h1>Permalink</h1>
		<pre>
		{{ printf "%#v \n" .Permalink }}
		</pre>
		
		<h1>Params</h1>
		<pre>
		{{ printf "%s" $.Params }}
		</pre>

		<h2>All variables scoped to the current context</h2>
		<pre>
		{{ printf "%#v" . }}	
		</pre>
	</details>

After that, I’ll set the display of the debug information to hidden in the CSS.

article footer details {
    display: none;
}

I then deploy it to the test blog to see what is going on, I can see that categories is used in templates and is stored in an array.

Opening and closing of detail/summary debug information

If we parse through the debug information, we can find the information about whether Micro.blog uses tags or categories.

Categories defined on a specific post

Categories and Tags

As you have seen, I spend a lot more time of what the different elements make up the different pages. From here, I borrowed1 some code from the internet and rewrote it so that I can hopefully remember what it does in the future.

{{ with .Param "categories" }}
	Categories:

	{{ range $CategoryArray, $Category := (. | sort) }}
		{{ if gt $CategoryArray 0 }}
			<span>•</span>
		{{ end }}
		<a href="/categories/{{ $Category | urlize }}">{{ $Category }}</a>
	{{ end }}
	
{{ end }}

I also included code for tags that I saw in another example to future proof the theme in case we add tags later on with Micro.blog.

{{- with .Param "tags" }}
{{ with $.Param "categories"}}
<br />
{{ end }}
	Tags: <span itemprop="keywords">
  	{{ range $index, $tag := (. | sort) }} 
  		{{ with $.Site.GetPage (printf "/%s/%s" "tags" $tag) }}
  			<a href="{{ .Permalink }}" class="tag">{{ $tag | urlize }}</a>
  		{{ end }}
	{{ end }}
	</span>
{{- end }}

I didn’t do much with this portion because we don’t use them with Micro.blog, and I’ve got a lot of other things to get working before coming back to this.

Remember the time

Another piece of information that we can get from the debug output is date information from the post. We actually get three different dates: date, publishdate, and lastmod.

On my local server instance, I played with the different logic for if a date was different than another and learned about how Go did comparisons of dates for about an hour.

Then I found out that Micro.blog use the same time for all three…

Labarum raw date format in debug information

You can then put this information into our template.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<p>Published: 
	<a href="{{ .Permalink }}" class="u-url">
	<time class="dt-publised" itemprop="dateCreated datePublished"
		{{ 
		printf `datetime="%s"` (.Date.Format "2006-01-02T15:04:05Z07:00") 
		| safeHTMLAttr }}>
		{{- .Date.Format (default "January 2, 2006" .Site.Params.date_format) }}
	</time>
	</a>
</p>

On line 2, I create a link to the article because this footer will be used single pages and the index and we don’t know if every post will have a title.

Line 5 makes sure that the date is formatted in ISO 8601 so that it can be parsed properly.

Line 7 shows the date in a more human readable way. I made a mental note to look into how I can make it output “6th” but all the examples that I’ve seen do not show in like that.

I wanted the footer to have two separate sections of information; one for categories and tags and the other for dates.

Footer detail mental model

I used a css grid to make the two sections and made sure that the data I add was grouped in a <p> tags.

article footer {
    display: grid;
    grid-template-columns: 2;
}

article footer p:last-of-type {
    grid-column: 2;
    text-align: right;
}

After doing my testing and getting the debug information, I hid the details in the footer.

article footer details {
    display: none;
}

I plan to cover more css when I discuss accessibility later on in the series.


  1. I took this from Pete Moore’s implementation of Tufte. You can read Moore about it here↩︎

Categories: Labarum

Published:

Debug

Site Properties

		&hugolib.SiteInfo{Authors:page.AuthorList(nil), Social:hugolib.SiteSocial(nil), hugoInfo:hugo.Info{CommitHash:"1798bd3f", BuildDate:"2021-12-23T15:33:34Z", Environment:"production"}, title:"Mandaris", RSSLink:"https://mandarismoore.com/feed.xml", Author:map[string]interface {}{"avatar":"https://micro.blog/mandaris/avatar.jpg", "name":"Mandaris Moore", "username":"mandaris"}, LanguageCode:"en", Copyright:"", permalinks:map[string]string{}, LanguagePrefix:"", Languages:langs.Languages{(*langs.Language)(0xc00080dba0)}, BuildDrafts:false, canonifyURLs:false, relativeURLs:false, uglyURLs:(func(page.Page) bool)(0x163ea20), owner:(*hugolib.HugoSites)(0xc0000ed600), s:(*hugolib.Site)(0xc000592d80), language:(*langs.Language)(0xc00080dba0), defaultContentLanguageInSubdir:false, sectionPagesMenu:""} 

		

site.Params Properties

		maps.Params{"description":"Follow <a href=\"https://micro.blog/mandaris\">@mandaris on Micro.blog</a>.", "feeds":maps.Params{"bookmarks_json":"https://micro.blog/feeds/mandaris/bookmarks/08117195b525afe4a55f.json"}, "github_username":"mandaris", "include_conversation":true, "instagram_username":"mandaris", "itunes_author":"Mandaris", "itunes_category":"Society & Culture", "itunes_cover":"https://micro.blog/mandaris/podcast.png", "itunes_description":"A High-quality stranger. I've considered myself a digital gofer. Y'know, go for this and go for that. I'm using micro.blog now to par down my technical projects and be part of an outstanding community.  Apple Game Center: MrMandaris  Email: Contact@MandarisMoore.com", "itunes_email":"podcast@mandarismoore.com", "itunes_subcategory":"Personal Journals", "mainSections":[]string{"replies"}, "mainsections":[]string{"replies"}, "paginate_categories":true, "paginate_home":true, "paginate_replies":true, "plugins_css":[]interface {}{}, "plugins_html":[]interface {}{}, "plugins_js":[]interface {}{}, "site_id":"661", "theme_seconds":"1675089916", "twitter_username":"mandaris"}
		

Permalink

		"https://mandarismoore.com/2023/01/04/creating-labarum-part.html" 

		

Params

		map[categories:[Labarum] date:2023-01-04 06:08:50 -0800 -0800 draft:%!s(bool=false) guid:http://mandaris.micro.blog/2023/01/04/creating-labarum-part.html images:[https://mandarismoore.com/uploads/2022/3148c5bdea.png https://mandarismoore.com/uploads/2022/abf540b26c.gif https://mandarismoore.com/uploads/2022/ff7084b629.png https://mandarismoore.com/uploads/2023/9aed865d81.png https://mandarismoore.com/uploads/2023/1ee7438c9d.png] iscjklanguage:%!s(bool=false) lastmod:2023-01-04 06:08:50 -0800 -0800 layout:post microblog:%!s(bool=false) photos:<nil> photos_with_metadata:<nil> publishdate:2023-01-04 06:08:50 -0800 -0800 title:Creating Labarum (Part 3): Implementing post footer type:post url:/2023/01/04/creating-labarum-part.html]
		

All variables scoped to the current context

		&hugolib.pageState{pageOutputs:[]*hugolib.pageOutput{(*hugolib.pageOutput)(0xc002713440), (*hugolib.pageOutput)(0xc002713560), (*hugolib.pageOutput)(0xc002713680), (*hugolib.pageOutput)(0xc0027137a0), (*hugolib.pageOutput)(0xc0027138c0), (*hugolib.pageOutput)(0xc0027139e0), (*hugolib.pageOutput)(0xc002713b00), (*hugolib.pageOutput)(0xc002713c20)}, pageOutput:(*hugolib.pageOutput)(0xc002713440), pageCommon:(*hugolib.pageCommon)(0xc0018faa00)}	
		

Creating Labarum (Part 2): Creating the individual posts

For this part, we’re going to be setting up the basic page used for our post and make sure that it can be reached from the index page. We’re going to be switching between different files to show the iterative process that I went through in order to see results quickly.

We’re going to edit the single.html to show the content by using the &#123;&#123; .Content }} tag from Hugo. We also add the &#123;&#123; .Title }} to the header and link it using the &#123;&#123; .Permalink }} tag to get the following.

<article class="h-entry">
<header>
<h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
</header>

<section class="e-content post-body">
{{ .Content }}
</section>

It renders to the following:

Simple article header with title

Let’s go back to our index.html to make it link to our post and show it on the main page.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
{{ range ( .Paginate (where .Site.RegularPages "Type" "post")).Pages }}

<article>
	<header>
		<h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
	</header>
	<section>
		{{ .Content }}
	</section>
	<footer>
		<p>
		Category: <a href="#">Some Category</a><br/>
		Tags: One Two Three
		</p>
	
		<p>Published: Some Date</p>
		</footer>
</article>
	
{{ end }}

The first line in the above code instructs hugo to iterate over all pages marked for the post type. On our local system, this isthe post directory and is in a database when using Micro.blog. The Permalink points to the individual post.

Links between index and post

We can test this by adding more content in the post folder to see what it looks like.

Multiple posts on index

But this highlights, we’re currently writing code in two places: the index.html and the single.html to render our content.

Note the forth line of the code which makes the assumption that we’re using a title for this post.

This is how I envision a post’s composition.

Mental model of post composition

We’d check if a post has a title and from there show a header or not before displaying the content and ultimately the footer.

Abstracting the article from the page

Let’s create partials/article.html and we’ll put all the content that we placed in _default/single.html in it.

<article class="h-entry">
<header>
<h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
</header>

<section class="e-content post-body">
{{ .Content }}
</section>

<footer>
	<p>Category: <a href="#">Some Category</a><br/>
		Tags: One Two Three</p>
	
		<p>Published: Some Time</p>
</footer>
</article>

Then we replace the contents of default/single.html with the following.

{{ define "main" }}
{{ partial "article.html" . }}
{{ end }}

When we render the page and there shouldn’t be any errors at this point.

Let’s add the conditional for the header of the article.

{{ if .Title }}
<header>
<h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
</header>
{{ end }}

Then let’s make a post without a header to test out that this is working without an error in our logs.

Simple article without a header

Next, we can work on the article footer which I’ll make into a separate component in the next installment.

Categories: Labarum

Published:

Debug

Site Properties

		&hugolib.SiteInfo{Authors:page.AuthorList(nil), Social:hugolib.SiteSocial(nil), hugoInfo:hugo.Info{CommitHash:"1798bd3f", BuildDate:"2021-12-23T15:33:34Z", Environment:"production"}, title:"Mandaris", RSSLink:"https://mandarismoore.com/feed.xml", Author:map[string]interface {}{"avatar":"https://micro.blog/mandaris/avatar.jpg", "name":"Mandaris Moore", "username":"mandaris"}, LanguageCode:"en", Copyright:"", permalinks:map[string]string{}, LanguagePrefix:"", Languages:langs.Languages{(*langs.Language)(0xc00080dba0)}, BuildDrafts:false, canonifyURLs:false, relativeURLs:false, uglyURLs:(func(page.Page) bool)(0x163ea20), owner:(*hugolib.HugoSites)(0xc0000ed600), s:(*hugolib.Site)(0xc000592d80), language:(*langs.Language)(0xc00080dba0), defaultContentLanguageInSubdir:false, sectionPagesMenu:""} 

		

site.Params Properties

		maps.Params{"description":"Follow <a href=\"https://micro.blog/mandaris\">@mandaris on Micro.blog</a>.", "feeds":maps.Params{"bookmarks_json":"https://micro.blog/feeds/mandaris/bookmarks/08117195b525afe4a55f.json"}, "github_username":"mandaris", "include_conversation":true, "instagram_username":"mandaris", "itunes_author":"Mandaris", "itunes_category":"Society & Culture", "itunes_cover":"https://micro.blog/mandaris/podcast.png", "itunes_description":"A High-quality stranger. I've considered myself a digital gofer. Y'know, go for this and go for that. I'm using micro.blog now to par down my technical projects and be part of an outstanding community.  Apple Game Center: MrMandaris  Email: Contact@MandarisMoore.com", "itunes_email":"podcast@mandarismoore.com", "itunes_subcategory":"Personal Journals", "mainSections":[]string{"replies"}, "mainsections":[]string{"replies"}, "paginate_categories":true, "paginate_home":true, "paginate_replies":true, "plugins_css":[]interface {}{}, "plugins_html":[]interface {}{}, "plugins_js":[]interface {}{}, "site_id":"661", "theme_seconds":"1675089916", "twitter_username":"mandaris"}
		

Permalink

		"https://mandarismoore.com/2022/12/29/creating-labarum-part.html" 

		

Params

		map[categories:[Labarum] date:2022-12-29 19:09:58 -0800 -0800 draft:%!s(bool=false) guid:http://mandaris.micro.blog/2022/12/29/creating-labarum-part.html images:[https://mandarismoore.com/uploads/2022/0a0dc4df16.png https://mandarismoore.com/uploads/2022/a4b66784cd.png https://mandarismoore.com/uploads/2022/bf4479aaed.png https://mandarismoore.com/uploads/2022/978e2e8cd2.png https://mandarismoore.com/uploads/2022/9fa69be141.png] iscjklanguage:%!s(bool=false) lastmod:2022-12-29 19:09:58 -0800 -0800 layout:post microblog:%!s(bool=false) photos:<nil> photos_with_metadata:<nil> publishdate:2022-12-29 19:09:58 -0800 -0800 title:Creating Labarum (Part 2): Creating the individual posts type:post url:/2022/12/29/creating-labarum-part.html]
		

All variables scoped to the current context

		&hugolib.pageState{pageOutputs:[]*hugolib.pageOutput{(*hugolib.pageOutput)(0xc0026f46c0), (*hugolib.pageOutput)(0xc0026f47e0), (*hugolib.pageOutput)(0xc0026f4900), (*hugolib.pageOutput)(0xc0026f4a20), (*hugolib.pageOutput)(0xc0026f4b40), (*hugolib.pageOutput)(0xc0026f4c60), (*hugolib.pageOutput)(0xc0026f4d80), (*hugolib.pageOutput)(0xc0026f4ea0)}, pageOutput:(*hugolib.pageOutput)(0xc0026f46c0), pageCommon:(*hugolib.pageCommon)(0xc0018c0a00)}	
		

Creating Labarum (Part 1): Design and initialization

I wanted to create a new theme for Micro.blog, and I thought I would document all the steps that I went through. The creation of the theme was an iterative process for me and this tutorial works in that way. I’m also not a web designer and I’ve focused mostly on the technical aspect of this theme. This theme and tutorial were put together over the span of a couple months and things changed both in some of the technical aspect and how I thought of the theme.

Design Goals

The first thing I wanted to make sure of was that my theme would be accessible. I want people who use a screen reader to be able to navigate the site without a problem and meet the latest standards as defined by WCAG.

Secondly, I wanted the site design to be semantically correct. I understand that many designers used dev tags for a lot of their design and architecture, but I wanted people who come to my website to be able to read the source and learn from it.

Third, I want to be able to make the design that has been siting in the back of my mind for a while. I’ve been enjoying minimal designs for years. I think this is mostly in part from my years experiencing dial-up and having to sit there and wait for the site to render because whoever paid for it needed me to see their huge logo and hero images.

This is what I’ve been picturing for the main page.

The first sketch of what I wanted the site to look like.

This is what I’d like to have for individual pages.

Sketch of the individual page

Understanding Micro.blog

To make it clear, I do not want to know what the secret sauce that Manton applies to make the whole site work. I know I would continually want to dabble. Manton has really done some magic to make Micro.blog work as both a blogging platform and social network. I feel that it offers an exciting mix of features without me having to spend a lot of time doing a lot of the technical configuration that I both equally hated and enjoyed.

But old habits tend to die hard and I found myself wanting to customize my own site and Micro.blog allows you to do that. When I look at new projects, I tend to visualize how the different components come together. For me - as it is near Christmas at the time of this writing - I think of Micro.blog as a Christmas tree.

Mental model of Micro.blog components

I do want to have an understanding of how themes are put together so that I can customize it. The beauty of working with this system is that every thing that I’ll be doing to customize will be backed by the Blank theme. I also only want to focus on how the site is generated. Every thing else, I leave to Manton Magic.

Setting up my local environment

The first thing that I did was make sure that I had Hugo installed on my machine using Homebrew. I did this to get an understanding of Hugo which is a big part of Micro.Blog. At the beginning of this project, you had to make changes to the Git repository that your theme was hosted on and then add it as a new theme in Micro.blog to see it refresh. I thought that if I do most of the initial development on my system, I could save time with doing smaller iterations on my home system.

Terminal window running hugo command

It’s a slightly older version than what Micro.blog (v91) is using, but I didn’t want to spend too much time in getting the versions to match up after spending some time reading what the key differences were.

From there I used the standard Hugo command to create a new environment.

hugo new site labarum-hugo

I create a project in GitHub called Labarum and cloned it in the themes directory of the new Hugo site. The was mostly to the .gitignore and README without making my own, but I see that it didn’t include the .DS_Store so I’ll add that as my first local commit1.

I then created smaller repository to host a little html and css experiments called tryout so that could iterate on the design with a static site.

Basic Structure

For the first iteration, I took a lot of the structure from my previous projects2 and just made the basics of what I wanted to be the following.

<html>

<head>
	<meta charset="utf-8">
    <meta name="viewport" content="width=device-width initial-scale=1">

    <title>Boxes</title>
	<link rel="stylesheet" href="./css/normalize.css" />
	<link rel="stylesheet" href="./css/style.css">
    <link rel="stylesheet" href="./css/custom.css">
</head>


<body>

<nav>
	<menu>
		<li><a href="#">Home</a></li>
		<li><a href="#">About</a></li>
		<li><a href="#">Contact</a></li>
		<li><a href="#">Toggle</a></li>
	</menu>
</nav>

<main>
<article>
	<header>
		<h1><a href="#">First Article Title</a></h1>
	</header>
	<section>
		<p>This is the main body of the article.</p>
	</section>
	<footer>
		<p>This is the article footer</p>
	</footer>
</article>
</main>
<footer>
	<p>Footer for the site</p>
</footer>
</body>

</html>

Please note that I added a note to normalize.css. I thought it was interesting that a lot of the themes that I see in the Hugo theme library link to a version of normalize, but it didn’t seem like it was the latest. I don’t know if they are just optimizing for classes that aren’t in most sites, but I thought I would take the version from the GitHub repository and make it part of my theme. I feel that you never know what the end user of this theme is going to use it for and this will cover most cases and they can change the rest.

Initial Designs and Iterations

I also took some of the colors from the Pure project I was working on to help me figure out how I wanted some of the colors to look.

This is the first iteration of light mode.

This actually took me a lot more time than I thought.

Then I thought I’d put some time into the dark theme.

Labarum first draft dark mode

During the first iteration, I also decided to drop the heading for the page as I felt that if someone came to my page they would be more interested in the articles than what the title was.

For the second iteration on the design, I added places more information about the categories, tags, and the dates something was published and modified. I played around with using a details and summary tag, but it was getting a little too much outside of my abilities and I wanted to move on to other portions of the design.

This should give the user quick access to pertinent information.

If you noticed, I haven’t put any work towards the navigation yet. I thought that I would see what the site looks like when some test content before I decide on it.

But first it’s important to start moving this into a template.

For Hugo, you need to have layouts/_default/baseof.html. We’ll take the entire example that we were working on and put it in the same format that Hugo is expecting.

Folder structure of theme in bbedit

In the baseof.html, we’ll add the following block.

{{ block "main" .}}{{ end }}

Then we create a layouts\index.html file for later version of Hugo with the following content:

{{ define "main" }}
<p>This is the index page</p>
{{ end }}

Then when we run hugo server -D on the command line, the page will render and you might see something like the following.

~/Code/labarum-hugo
❯ hugo server -D
Start building sites …
hugo v0.94.2+extended darwin/amd64 BuildDate=unknown
WARN 2022/06/16 21:11:52 found no layout file for "HTML" for kind "taxonomy": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN 2022/06/16 21:11:52 found no layout file for "HTML" for kind "taxonomy": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.

The site should look like the following at this point.

Index page with an article on it

Pretty plain. And -again- this is mostly the static content that I created.

Let’s get rid of the warnings first, that way, we can focus on anything that pops up as we build the rest of the template.

Creating taxonomy/list pages

Let’s go to the Hugo’s documentation on template lookup order and search for taxonomy, and it lists different options. I think we’ll make layouts/_defaults/list.html which matches what we see with the base template that blank template that micro.blog provides.

We’ll just stub it for now.

{{ define "main" }}
<p>This is the basic list.html file</p>
{{ end }} 

Now we have a “clean” build of our site that shows pretty much nothing other than the box example that we created.

We can start the Hugo server and go to /posts/ to see the new posts page.

Labarum list html with no css

Notice that it doesn’t have the css linked properly. This is because our css used ./css and we have to remove the dot so that Hugo serves in properly. There are other ways of referencing this that we’ll look into later in this series.

We can now get really started!

Let’s make our first post by using the “Add Some Content” step from the Hugo Quick start.

After creating the content, we run the hugo -D command if the server isn’t running to get the output. At this point, we see another warning about pages.

❯ hugo -D
Start building sites …
hugo v0.94.2+extended darwin/amd64 BuildDate=unknown
WARN 2022/07/05 18:19:20 found no layout file for "HTML" for kind "page":
You should create a template file which matches Hugo Layouts Lookup Rules for this combination.

We go back to the template look up and find the information on making a page. We’ll just make a simple stub for now.

{{ define "main" }}
<article>
<header>
<h2>Article Title</h2>
</header>

<section>
{{ .content }}
</section>

</article>

{{ end }}

Now when we run, we don’t see any warning!

But.

It doesn’t do anything dynamic at this point and all we see is a page with just one line of text.

We’ll have to do that in the second part. Please give me some feed back before I push out the next part two days from now.


  1. This is part of my global ignores but I wanted to make sure that it’s there for people cloning the project in the future of if I forget. ↩︎

  2. I was luckily enough to work on the Pure theme. ↩︎

Categories: Labarum

Published:

Debug

Site Properties

		&hugolib.SiteInfo{Authors:page.AuthorList(nil), Social:hugolib.SiteSocial(nil), hugoInfo:hugo.Info{CommitHash:"1798bd3f", BuildDate:"2021-12-23T15:33:34Z", Environment:"production"}, title:"Mandaris", RSSLink:"https://mandarismoore.com/feed.xml", Author:map[string]interface {}{"avatar":"https://micro.blog/mandaris/avatar.jpg", "name":"Mandaris Moore", "username":"mandaris"}, LanguageCode:"en", Copyright:"", permalinks:map[string]string{}, LanguagePrefix:"", Languages:langs.Languages{(*langs.Language)(0xc00080dba0)}, BuildDrafts:false, canonifyURLs:false, relativeURLs:false, uglyURLs:(func(page.Page) bool)(0x163ea20), owner:(*hugolib.HugoSites)(0xc0000ed600), s:(*hugolib.Site)(0xc000592d80), language:(*langs.Language)(0xc00080dba0), defaultContentLanguageInSubdir:false, sectionPagesMenu:""} 

		

site.Params Properties

		maps.Params{"description":"Follow <a href=\"https://micro.blog/mandaris\">@mandaris on Micro.blog</a>.", "feeds":maps.Params{"bookmarks_json":"https://micro.blog/feeds/mandaris/bookmarks/08117195b525afe4a55f.json"}, "github_username":"mandaris", "include_conversation":true, "instagram_username":"mandaris", "itunes_author":"Mandaris", "itunes_category":"Society & Culture", "itunes_cover":"https://micro.blog/mandaris/podcast.png", "itunes_description":"A High-quality stranger. I've considered myself a digital gofer. Y'know, go for this and go for that. I'm using micro.blog now to par down my technical projects and be part of an outstanding community.  Apple Game Center: MrMandaris  Email: Contact@MandarisMoore.com", "itunes_email":"podcast@mandarismoore.com", "itunes_subcategory":"Personal Journals", "mainSections":[]string{"replies"}, "mainsections":[]string{"replies"}, "paginate_categories":true, "paginate_home":true, "paginate_replies":true, "plugins_css":[]interface {}{}, "plugins_html":[]interface {}{}, "plugins_js":[]interface {}{}, "site_id":"661", "theme_seconds":"1675089916", "twitter_username":"mandaris"}
		

Permalink

		"https://mandarismoore.com/2022/12/28/creating-labarum-part.html" 

		

Params

		map[categories:[Labarum] date:2022-12-28 07:45:02 -0800 -0800 draft:%!s(bool=false) guid:http://mandaris.micro.blog/2022/12/28/creating-labarum-part.html images:[https://mandarismoore.com/uploads/2022/3c18076a20.jpg https://mandarismoore.com/uploads/2022/4d4de77c69.jpg https://mandarismoore.com/uploads/2022/1cb7ade360.png https://mandarismoore.com/uploads/2022/89b400aa03.png https://mandarismoore.com/uploads/2022/bd8973bc38.png https://mandarismoore.com/uploads/2022/fdf751c16b.png https://mandarismoore.com/uploads/2022/21ac283916.png https://mandarismoore.com/uploads/2022/3d54b6f92e.png https://mandarismoore.com/uploads/2022/f412e85c54.png https://mandarismoore.com/uploads/2022/0c92f4e707.png] iscjklanguage:%!s(bool=false) lastmod:2022-12-28 07:45:02 -0800 -0800 layout:post microblog:%!s(bool=false) photos:[https://mandarismoore.com/uploads/2022/3c18076a20.jpg https://mandarismoore.com/uploads/2022/4d4de77c69.jpg] photos_with_metadata:[map[height:%!s(int=300) url:https://mandarismoore.com/uploads/2022/3c18076a20.jpg width:%!s(int=232)] map[height:%!s(int=0) url:https://mandarismoore.com/uploads/2022/4d4de77c69.jpg width:%!s(int=232)]] publishdate:2022-12-28 07:45:02 -0800 -0800 title:Creating Labarum (Part 1): Design and initialization type:post url:/2022/12/28/creating-labarum-part.html]
		

All variables scoped to the current context

		&hugolib.pageState{pageOutputs:[]*hugolib.pageOutput{(*hugolib.pageOutput)(0xc0026eb440), (*hugolib.pageOutput)(0xc0026eb560), (*hugolib.pageOutput)(0xc0026eb680), (*hugolib.pageOutput)(0xc0026eb7a0), (*hugolib.pageOutput)(0xc0026eb8c0), (*hugolib.pageOutput)(0xc0026eb9e0), (*hugolib.pageOutput)(0xc0026ebb00), (*hugolib.pageOutput)(0xc0026ebc20)}, pageOutput:(*hugolib.pageOutput)(0xc0026eb440), pageCommon:(*hugolib.pageCommon)(0xc0018c0000)}