Wrap up this blog post
This commit is contained in:
parent
3d96dcf0c8
commit
8dbd68a3d8
1 changed files with 32 additions and 14 deletions
|
@ -1,9 +1,10 @@
|
|||
---
|
||||
title: "Hugo Dictionary API"
|
||||
title: "Hugo's Dictionary API"
|
||||
date: 2022-10-13T10:19:02-07:00
|
||||
draft: true
|
||||
categories: ["Tech"]
|
||||
tags: ["Hugo", "Web"]
|
||||
tags: ["Hugo", "Web", "API Design"]
|
||||
series: "Erynwells.me Development"
|
||||
---
|
||||
|
||||
Hugo's templating system has support for dictionaries. Unfortunately the API for
|
||||
|
@ -17,8 +18,10 @@ Here's a quick summary of what I found.
|
|||
## Creating Dictionaries
|
||||
|
||||
The function to create a dictionary is called [`dict`][dict] and it takes a
|
||||
variable number of arguments that alternate between keys and values. Keys must
|
||||
be strings (or string slices) and values can be anything. So this:
|
||||
variable number of arguments that alternate between keys and values. It reminds
|
||||
me of this [bizarre and backwards NSDictionary API][nsdictionary-init] in Apple's
|
||||
Foundation framework. Keys must be strings (or string slices) and values can be
|
||||
anything. So this:
|
||||
|
||||
{{< figures/code >}}
|
||||
```go-html-template
|
||||
|
@ -34,8 +37,7 @@ creates a structure that looks like this JSON object:
|
|||
```
|
||||
{{< /figures/code >}}
|
||||
|
||||
For completeness, you can also create an empty dictionary by calling `dict` with
|
||||
no arguments.
|
||||
You can also create an empty dictionary by calling `dict` with no arguments.
|
||||
|
||||
{{< figures/code >}}
|
||||
```go-html-template
|
||||
|
@ -60,14 +62,16 @@ If you want to get a value with a key you get at render time, you can use the
|
|||
|
||||
{{< figures/code >}}
|
||||
```go-html-template
|
||||
{{ $item := index "b" (dict "a" 1 "b" 2 "c" 3) }}
|
||||
{{ $key := "b" }}
|
||||
{{ $item := index $key (dict "a" 1 "b" 2 "c" 3) }}
|
||||
```
|
||||
{{< /figures/code >}}
|
||||
|
||||
`index` doesn't make much sense to me as a verb for accessing values in a
|
||||
dictionary. It sounds more like an array function. I would like to see another
|
||||
function with a more dictionary-sounding name, like `get` or `value` or `item`,
|
||||
even if it were just an alias for `index` underneath.
|
||||
dictionary. It sounds more like an array function, and indeed it's the function
|
||||
that gives you access to items in arrays. I would like to see another function
|
||||
with a more dictionary-sounding name, like `get` or `value` or `item`, even if
|
||||
it were just an alias for `index` underneath.
|
||||
|
||||
## Adding Items to a Dictionary
|
||||
|
||||
|
@ -100,9 +104,8 @@ For the previously mentioned template changes I was making, I was updating the
|
|||
one section per tag, and a list of all the posts with that tag underneath.
|
||||
|
||||
My categories are high level groups like "Tech," "Music," and "Travel." Tags are
|
||||
more specific topics for the post like "Web" or "Compositions." By my own
|
||||
policy, pages should only ever have one category but they can have multiple
|
||||
tags.
|
||||
more specific topics for the post like "Web" or "Compositions." Pages only ever
|
||||
have one category but they can have multiple tags.
|
||||
|
||||
A `terms` template lets you access an array of terms, and the pages associated
|
||||
with those terms. You can access the tags attached to a page with the
|
||||
|
@ -111,7 +114,7 @@ with those terms. You can access the tags attached to a page with the
|
|||
{{< figures/code >}}
|
||||
```go-html-template
|
||||
{{- $pagesByTag := dict -}}
|
||||
{{- range $page := .Pages }}
|
||||
{{- range $page := .Pages -}}
|
||||
{{- range $tag := .GetTerms "tags" -}}
|
||||
{{- $tagName := $tag.Name -}}
|
||||
{{- if not (in $pagesByTag $tagName) -}}
|
||||
|
@ -128,7 +131,22 @@ with those terms. You can access the tags attached to a page with the
|
|||
```
|
||||
{{< /figures/code >}}
|
||||
|
||||
`$pagesByTag` is my empty dictionary. It will hold tag names as keys, each
|
||||
pointing to a slice (array) of page objects. For each page, I get its list of
|
||||
tags. For each tag, I check `$pagesByTag` to see if it already has a key/value
|
||||
pair for that tag. If not, I create a new entry in `$pagesByTag` with `merge`.
|
||||
If it does already, I get the slice for that tag with `index`, add the Page to
|
||||
the slice with `append`, and then merge the updated slice back into
|
||||
`$pagesByTag` with `merge`.
|
||||
|
||||
It's not too bad once it's all spelled out, but it does feel like more work than
|
||||
it should take for such simple operations.
|
||||
|
||||
I think this API could be improved substantially with some new functions that
|
||||
operate specifically on dictionaries and that have clear names that describe
|
||||
what they do.
|
||||
|
||||
[dict]: https://gohugo.io/functions/dict/
|
||||
[index]: https://gohugo.io/functions/index-function/
|
||||
[merge]: https://gohugo.io/functions/merge/
|
||||
[nsdictionary-init]: https://developer.apple.com/documentation/foundation/nsdictionary/1574181-dictionarywithobjectsandkeys?language=objc
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue