How to get permalink of Taxonomies in templates?

We can set permalink for taxonomy as follows in config.toml:

[permalinks]
tags = "/tag/:slug/"

So that instead of /tags/TAG_NAME, we get /tag/TAG_NAME as the URL of a given tag.

However, some templates hardcoded the link to a tag page with

{{ range .Params.tags }}  
<a href="{{ "/tags/" | relLangURL }}{{ . | urlize }}">{{ . }}</a>
{{ end }}

Therefore, it always points to /tags/TAG_NAME no matter what is the setting for

[permalinks]

This was pointed out here as well:

https://github.com/gohugoio/hugo/issues/4130 .

Are there any ways to retrieve the permalink of a given taxonomy in templates?

Thank you.

Do you have a sample project that shows your issue? If you link to something I can clone, I’ll take a look.

In the meantime, check the example for listing tags in a single page template, which applies urlize, and may solve the issue you are having (it isn’t clear to me what the issue is, as the discussion linked to didn’t have a resolution).

Hi maiki,

If we use this example

<ul id="tags">
  {{ range .Params.tags }}
    <li><a href="{{ "/tags/" | relLangURL }}{{ . | urlize }}">{{ . }}</a> </li>
  {{ end }}
</ul>

The link to a given tag would be /tags/TAG_NAME.

But actually because the setting of permalink, the page would not be found (ERROR 404), because the actual path of the page is /tag/TAG_NAME.

But it’s not okay to hardcode tag into templates either, because the permalink setting could differ site by site. For example, using the following can solve this problem but it breaks sites that do not change the permalink:

<ul id="tags">
  {{ range .Params.tags }}
    <li><a href="{{ "/tag/" | relLangURL }}{{ . | urlize }}">{{ . }}</a> </li>
  {{ end }}
</ul>

BTW, the ability to change the permalink of tag pages was added in this PR: https://github.com/gohugoio/hugo/pull/4061 .

I disagree with your assertion. :slight_smile: It is okay to put the taxonomy patterns your site uses in the templates. Some folks grab themes specifically to use the taxonomies they set up.

Do you have a specific reservation about adding your site’s taxonomies to the single.html template? The general use case is set and forget, meaning when you set up the taxonomies, they don’t change.

Because we use Go templates, we switch contexts when building, and from what I understand, that is why we don’t just pull up a list of URLs and instead we build them as templated, “hardcoded” values. I hope someone knows how to do what you want, though! :slight_smile:

Thanks for the reply. I do agree that the hardcoded path might be okay in certain situations. But I would also like to give some reasoning about why I think it’s better to remove the hardcoded path.

  1. It’s actually possible to have different URLs for different languages:

     [permalinks]
       tags = "/tag/:slug/"
    
     [languages.es.permalinks]
       tags = "/Etiqueta/:slug/"
     ...
    

    To support this, we would have to hardcod each path for each language, which seems far from elegant.

  2. It’s easy to change permalinks for other sections such as post without modifying the theme. It seems preferable to have the same ability for tags.

I think that you need to open a GitHub issue for this.

From what I gather, you are asking about something like a variable for custom taxonomy permalinks configuration. Something like {{ .TaxonomyPermalink }} or even making these available through
{{ .Permalink }}.

It’s better to ask the Devs directly.

Thanks! I will.
I am asking here first because in issue https://github.com/gohugoio/hugo/issues/4130, @bep seems to indicate that doing so might already be possible.
Suppose this is not the case, and the issue is not reopened by others, I will open a new issue for this.

1 Like

If Pull Request #4796 is merged, then you won’t need to hardcode anymore. You could use

{{% relref "tags" %}}

which would be resolved to whatever url tags is published to. Likewise a call to .GetPage "tags" would return you the page object, from which you could query its actual URL, title or whatever.

2 Likes

There is no need to hard-code the path for “tags” page or any taxonomy term page for that matter.

See this for example (Search for taxonomyTerm in that code). See the categories and tags links created at the top of the page here using that template.

@kaushalmodi: When the permalink is modified, the URL structure of the “tag list” page and “individual tag” page could be different. For example, when we set:

 [permalinks]
   tags = "/tag/:slug/"

The “tag list” page would still be /tags/, while the “individual tag” page is /tag/TAG_NAME/.
While your example handles the “tag list” page, it does not seem to address the “individual tag” page.

@vassudanagunta: Does the PR handles the difference described above as well?

The “individual tag” case is possible. See:

3 Likes

Thank you very much! That’s exactly what I need.

I was trying to do the same thing described in this question, and I’m having a hard time following the answers. Using the ghostwriter theme as an example, we see this in layouts/partial/post-footer.html:

    {{ if .Params.tags }}                                                       
        <p class="post-tags">                                                   
            <span>Tagged:</span>                                                
            {{ $len := len .Params.tags }}                                      
            {{ range $index, $tag := .Params.tags }}                            
                <a href="{{ "/tags/" | relLangURL }}{{ . | urlize }}/">{{ . }}</a>
                {{- if lt $index (sub $len 1) -}}, {{ end }}                    
            {{ end }}                                                           
        </p>                                                                    
    {{ end}}                                                                    

It hardcodes the path to tag pages as /tags/. I would like this to automatically select a path that is consistent with the tag permalink settings (using /tags/ or /tag/ or /bob/ or whatever as appropriate). How would modify the template to do this?

In the link I shared earlier, look at this line. Using that, I can use that terms.html tempalte for any taxonomy term… the .Type returns "tags", "categories", whatever.

… and then see how I use that $type in the site.GetPage in this line.

So in a post template, I would use something like this?

{{ range $index, $tag := .Params.tags }}
  {{ $term := . }}
  {{ with .Site.GetPage (printf "/%s/%s" "tags" $term) }}
    <a href="{{ .Permalink }}">{{ $term }}</a>
    {{- if lt $index (sub $len 1) -}}, {{ end }}
  {{ end }}
{{ end }}

That results in:

executing "partials/post-footer.html" at <.Site.GetPage>: can't evaluate field Site in type string

It looks like I need $.Site.GetPage instead. With that change, it seems to work. Thanks!

You are probably on an old Hugo version; I’d suggest updating to the latest release.

I am using 0.55.5, which I believe is current.

OK, I misunderstood; I thought you had issue using site. ... In that case, just replace .Site.foo and $.Site.foo with site.foo everywhere.