Catalog your books with Go Templates, Library of Congress style

Have been cataloging my books during the holiday and gradually put together a Hugo template file that largely automates things. Now first off, a JSON file stores all the books like the following (I’m not using all the keys yet):

{
	"title": "The Desert Fathers",
	"subtitle": "Sayings of the Early Christian Monks",
	"publishyear": "2003",
	"publisher": "penguin",
	"author": "Benedicta Ward (tr.) ",
	"subject": "BR1705",
	"booktags": [
		"Orthodoxy",
		"monasticisim",
		"desert fathers",
		"penguin"
	]
}

And with the template, each newly added book gets in line following these steps:

  1. it tries to go under the main LCC (Library of Congress Classification) class, i.e., the first letter of the call number (“B” for <The Desert Fathers>);
  2. if that main class has too many books already, goes to the subclass instead (“BR” for <The Desert Fathers>);
  3. after being classified, it’s sorted according to the author name;
  4. for the same author, it’s sorted again according to the subtitle. This is so that multiple volumes of a book are displayed orderly.

The template finishes things off with a hyperlinked table of contents of the subject areas on the side. The result is here.

The full template file

{{ $lcc_dict := dict
	"A" "General works"
	"B" "Philosophy (General)"
	"BC" "Logic"
	"BD" "Speculative philosophy"
	"BF" "Psychology"
	"BH" "Aesthetics"
	"BJ" "Ethics"
	"BL" "Religions. Mythology. Rationalism"
	"BM" "Judaism"
	"BP" "Islam. Bahaism. Theosophy, etc."
	"BQ" "Buddhism"
	"BR" "Christianity"
	"BS" "The Bible"
	"BT" "Doctrinal theology"
	"BV" "Practical theology"
	"BX" "Christian Denominations"
	"C" "Auxiliary Sciences of History"
	"D" "History (General)"
	"DA" "History of Great Britain"
	"E" "History of America"
	"F" "History of the Americas"
	"G" "Geography, Anthropology, and Recreation"
	"H" "Social Sciences"
	"J" "Political Science"
	"K" "Law"
	"L" "Education"
	"M" "Music"
	"N" "Fine Arts"
	"P" "Language and Literature"
	"Q" "Science"
	"R" "Medicine"
	"S" "Agriculture"
	"T" "Technology"
	"U" "Military Science"
	"V" "Naval Science"
	"Z" "Bibliography, Library Science, and General Information Resources" }}
<main>

	{{ $lccs := slice }}
	{{ range .Site.Data.library }}
		{{ $lcc_this_book := (index (findRE `^[A-Z]+` .subject) 0) }}
		{{ if isset $lcc_dict $lcc_this_book }}
			{{ $lccs = $lccs | append $lcc_this_book }}
		{{ else }}
			{{ $lccs = $lccs | append (substr $lcc_this_book 0 1) }}
		{{ end }}
	{{ end }}
	{{ $lccs = $lccs | uniq | sort }}

	{{ $authors := slice }}
	{{ range .Site.Data.library }}
		{{ $authors = $authors | append .author  }}
	{{ end }}
	{{ $authors = $authors | uniq | sort }}

	<aside>
		<div>
			<ul>
			{{ range $lccs }}
				<li>
					<a href="#{{.}}">{{ index $lcc_dict . }}</a>
				</li>
			{{ end }}
			</ul>
		</div>
	</aside>

	<h1>Library</h1>
	{{ range $lccs }}
		<h2 id={{.}}>{{ print . }} - {{ index $lcc_dict . }}</h2>
		{{ $lcc_list_now := . }}
		<ul>
			{{ range $authors }}
				{{ range where (sort $.Site.Data.library "subtitle" "asc") "author" . }}
					{{ $lcc_this_book := (index (findRE `^[A-Z]+` .subject) 0) }}
					{{ $lcc_this_book_main := (substr $lcc_this_book 0 1) }}
					{{ $lcc_this_book_isset := (isset $lcc_dict $lcc_this_book) }}
					{{ if or (eq $lcc_this_book $lcc_list_now) (and (not $lcc_this_book_isset) (eq $lcc_this_book_main $lcc_list_now)) }}
						<li>
							{{ with .author }}
								{{ . }}
							{{ end }}
							-
							<b>{{ .title }}</b>
							<i>
								{{ with .subtitle }}
									: {{ . }}
								{{ end }}
							</i>
						</li>
					{{ end }}
				{{ end }}
			{{ end }}
		</ul>
	{{ end }}

</main>