Macros in Go Templating

Hi, I’m just starting out with Hugo and want to build a living component library into a web project I’m working on. Normally I work with Nunjucks and build up a simple component library with Nunjucks Macros ( I can’t find how to do this with the Go Templating, but this could be my fault. I hope someone can help to lead the way or can show me an other way how to do this. :slight_smile: Thanks.

We refer to those as shortcodes in hugo. Look in the docs to see how to make custom shortcodes

Shortcodes are used for in markdown, but I want to use macros to use in mij templates and not in my content. See them as partials with options, something like this:

{{ partial “‘components/button’, ‘type=primary’, ‘size=large’” . }}

In Nunjucks it would be like this:

{% call button(type=‘primary’, size=‘large’) %}

I don’t think go html template has that but you can dig through to see if you’d find anything like that as it’s what hugo uses

I am not as familiar with components in Nunjucks, but if I can make an inference from the pseudo code you provided above, I think your best bet is partials with the dict function.

Thanks for your help, I’m not very technical, so I don’t really understand the dict documentation at the moment. :frowning:

The combination of macros and the dict template function should be a good alternative for Nunjucks macros.

Thanks for your help, I’m not very technical, so I don’t really understand the dict documentation at the moment.

It’s not as hard as it might looks like. A dictionary, or dict for short, maps a keyword to a value; similar to a real dictionary that maps a word to a description of it.

Within a template you can create a dict as follows:

{{ dict "key1" "value1" "key2" "value2" }}

Here we’re mapping the string key1 to the value value1. You always define a mapping as a key-value-pair. By the way: you’re not limited to use strings for the value. It can be anything.

Now, let’s have a look at partials. You provide the partial function the name of the partial you want to include and a context to add data, aka the .

You can create your own context by creating a dict where the key is the parameter’s name and the value is simply the value of the parameter. Those are essentially the information that you pass to a Nunjucks macro (which act like functions).

Within a template you can do something like this:

{{ partial "example.html" (dict "key1" "value1" "key2" "value2") }}

In the template file for the partial you can access the values with .key1 and .key2.

1 Like

Thank you, this is great help, I’ve got it to work! Now I can build small reusable components in Hugo.
Another question, is there a way to ‘nest’ partials into each other? Like a card with an image and button:

{{ partial "card" (dict "key1" "value1" "key2" "value2") }}
  {{ partial "image" (dict "key1" "value1" "key2" "value2") }}
  {{ partial "button" (dict "key1" "value1" "key2" "value2") }}
{{ end partial }}

This way I could combine small reusable components and still be very flexible. I’m using this in larger projects, maybe not extremely important in a smaller Hugo project, but it could be very helpful.

I know the method below could be an option, but I don’t want to do that:

{{ partial "card" (dict "image" "/image.jpg" "button" "primary" "button-url" "" button-text" "Send") }}

Yes, you can nest partial templats as you like, i.e. calling a partial within a partial. The posted example looks fine.

1 Like

Ok, this is what I have right now.

Index.html template:

{{ $type := "warning" }}
{{ $size := "small" }}
{{ $url := "" }}
{{ $text := "Send" }}

{{ partial "components/card/card" (dict "type" "white") }}

  {{ partial "components/button/button" (dict "type" $type "size" $size "url" $url "text" $text) }}

{{ end partial }}

Button.html partial:

{{ $type_class := printf "c-button--%s" .type }}
{{ $size_class := printf "c-button--%s" .size }}

<a class="c-button {{ $type_class }} {{ $size_class }}" href="{{ .url }}">{{ .text }}</a>

Card.html partial:

{{ $type_class := printf "c-card--%s" .type }}

<div class="c-card {{ $type_class }}">
  {{ . }}

It looks like I can not end a partial this way. This is my error message: ‘index.html:18: unexpected “partial” in end’. So it should be done otherwise?

And I don’t know in the Card.html if the {{ . }} is correct.

I’m so close, I hope you can tell me what I am doing wrong! :slight_smile:

There is no {{ end partial }} in Hugo.

It’s just {{ end }}

Also you need to use the above for your nested “button” partial.

A partial needs to be closed in the end always.

Ah ok, I didn’t know that, but with your solution I still get the same error (template: index.html:18: unexpected {{end}}) :frowning:

{{ partial "components/card/card" (dict "type" "white") }}

  {{ partial "components/button/button" (dict "type" $type "size" $size "url" $url "text" $text) }}{{ end }}

{{ end }}

There is a missing dot in your partials syntax. It should be like this
{{ partial "components/card/card" (dict "type" "white") . }}
{{ partial "components/button/button" (dict "type" $type "size" $size "url" $url "text" $text) . }}

Remove both {{ end }} tags. Sorry my above comment was wrong. I was a bit absent minded.
Partials don’t need this tag in this case.

Anyway see if the corrected syntax with the dot works. If not come back here.

But also read the Docs about partials:
I don’t think you have.

As an end note I’m not sure that what you’re trying to do is the proper way to call a partial from within another. If “card” is the container partial then “button” I think that it should be called from within card.html (but take this with a grain of salt I haven’t used this, since I never had a need to nest partials this way).