[SOLVED] Reference multilingual content from template

Hello,

I’m trying to build a multilingual site and a theme for that site. Most things work quite good but I have some trouble to link to translted content from my theme. I know we have Ref/RelRef but how can I call that function and get the correct link from it?

For example, I have the following file system:

/root
|content
-|about-us.md
-|about-us.en.md
|themes

The about-us files have both a different url set in their front matter so the resulting urls are /ueber-uns and /about-us. Now I try to call RelRef in my template like this:
{{ .RelRef "about-us.md" }}
It finds the file but both languages now contain /ueber-uns as link because german is my default language and it only finds the exact file specified. The excpected result should be /about-us for english and /ueber-unsfor german.
I need this because I have some info boxes in my page footer and I want to link to the correct localized content page. For consistency reasons all my urls are localized so that’s why I simply cannot link statically.

IThanks for your help.

Does no one know any solution to this?

I really do wonder if this is even possible to achieve…
Hugo is a really nice generator but to not be able to link to localized pages if you’re using url overrides is kind of disappointing. This issue will most likely force myself to use some kind of hack to determine the site language and then refer to the correct page. As of now I only have two languages so it will be a simple if/else but imagine I translate my site to more languages, then I would end up with a bunch of if/else (one for each language) only to be able to link to the page and use localized urls.

Are you trying to do something different from the translated content links feature?

Please reference the requesting help topic and share your code. I can’t tell what is happening on your site without seeing the config and running it locally. :slight_smile:

Looks like I did not set the right topic when I created this thread. This is fixed now.

What I want to achieve is to create a static link to a piece of content using it’s url. I have multiple pages which are translated and each translated page has a front matter like this:

page1.md

+++
url = "/meine-seite"
+++

page1.en.md

+++
url = "/my-page"
+++

This already works fine, the content is available under the corresponding url for the respective site language. Now I want to link to page1 but for the href, I want it to be meine-site when visiting the german site and my-page when visiting the english site. As both sites use the same template, they also use the same link. I tried to use the .Reffunction but it wants a direct path to the referenced file and does not accept/see that the file is translated so it uses the same url for all languages.

I hope now it’s better to understand

Where does is the link rendered on your site? Is it in a menu? As a link in the content? Please provide an example of how you’d like it to work. :slight_smile:

Have you configured your Hugo site for multilingual content? It doesn’t look like it.

See: https://gohugo.io/content-management/multilingual/#configure-languages

@internetfreak we can figure this out a lot faster if you share the source of your site with us. We can check all the parts that make multilingual sites work.

My site is configured for multilingual content. When I build the site, hugo creates two versions of the site, one for german and one for english. I want to create/use the link in my page template inside of the footer. Currently one part of the template where I need this function looks like this:

<div class="widget-content">
     <p>
         {{ .Site.Params.about }}
      </p>
      <a href='REF_HERE'>{{ i18n "seeMore" }}</a>
</div>

The REF_HERE marks the spot where the actual reference should be. I tried it like this: {{ .Ref "about-us.md" . }} and the result was /ueber-uns for both languages as it directly referenced the given file and not the language specific file (about-us.en.md for english)

The reason why I want this is because I want to create localized links for my site. Instead of having a link about-us for both languages I want it to be ueber-uns and about-us for consistency with the page

Have you tried the relLangURL function?

Unfortunately this does not work as it doesn’t resolve the url override from the front matter

I’m quoting straight from the Docs.

To support Multilingual mode in your themes, some considerations must be taken for the URLs in the templates. If there is more than one language, URLs must meet the following criteria:

  • Come from the built-in .Permalink or .URL
  • Be constructed with
  • The relLangURL template function or the absLangURL template function OR
  • Prefixed with {{ .LanguagePrefix }}

If there is more than one language defined, the LanguagePrefix variable will equal /en (or whatever your CurrentLanguage is). If not enabled, it will be an empty string and is therefore harmless for single-language Hugo websites.

It seems that what you’re trying to do is not doable out-of-the-box.

That’s the same conclusion as I currently got. Now that hugo has extended support for multilingual websites, I think that would probably be a useful feature. I think it will be worth to raise an issue on github, I will consider doing this.

I know I’m a little late, but I think you’re having the same problem that I did with my English/Japanese site.

As a workaround, I ended up putting every page in the site into a menu called site, and gave each page an identifier the same as its translations. Then I used a shortcode to find the page in the menu, and get the URL, eg:

/layouts/shortcodes/clink.html

{{ $page := index (where .Site.Menus.site "Identifier" (.Get 0)) 0 }}
{{ $text := .Inner | default (delimit (slice $page.Name "...") "") }}
<a href="{{ $page.URL }}">{{ $text | markdownify }}</a>

/content/imprint.md

---
title: Imprint
menu:
    site:
        identifier: imprint

---

/content/imprint.ja.md

---
title: 奥付
slug: okuduke
menu:
    site:
        identifier: imprint
---

/content/a-page.md

...
{{% clink "imprint" %}}go to Imprint{{% /clink %}}<span></span>
...

/content/a-page.ja.md

...
{{% clink "imprint" %}}奥付に行く{{% /clink %}}<span></span>
...

Perhaps that approach is in some way helpful to you?

(Edit: the shortcode as I originally pasted it was two workarounds, I’ve stripped out the unnecessary part)

Thanks for your answer, I don’t mind if it’s “late”. However, the problem for using your solution is, that shortcodes won’t work inside a template. As my links should be referenced inside a template, I still need another solution. At this time, I think I get two options:

  1. Fork hugo and implement a new function for this then create a PR (I don’t know Go, so this could be a bit of a problem)
  2. Get the site language code then create the path to the file via sprintf/format and pass it to ref/relRef

Well, you can always take the code out of the shortcode and use it directly.

Obviously it’s not as compact, but if you’re using it in a template, presumably that won’t be as much of an issue.

Quick and dirty solution:

{{ $id := "about-us.md" }}
{{ $page := index (where .Site.Menus.site "Identifier" $id) 0 }}
{{ $text := "Text for the link" }}
<a href="{{ $page.URL }}">{{ $text | markdownify }}</a>

The code inside the shortcode is pretty simple to adapt. You wouldn’t need to do it over three lines if you didn’t want.

(I’ve actually just realised the shortcode I pasted had an additional hack in it for dealing with untranslated section names too, so it’s actually even simpler than at first glance)

I now worked out a more or less useable solution. It’s not the best solution but it seems to work for my case since I only want to use it for a couple of links (< 10 links for now). Here’s what I did to achieve it:

  1. Add the following at the beginning of the template you want to use my solution:
{{ if ne .Site.Language.Lang "de" }}
    {{ .Scratch.Set "lang" (printf ".%s" .Site.Language.Lang) }}
{{ else }}
    {{ .Scratch.Set "lang" "" }}
{{ end }}
  1. For each link which should be automatically localized, use the following code:
{{ with .Site.GetPage "page" (printf "%v%v.md" "YOUR_FILE_NAME_WITHOUT_LANGUAGE_OR_ENDING" (.Scratch.Get "lang")) }}
<a href='{{ .URL }}'>{{ .Title }}</a>
{{ end }}

Hugo is now able to get the page and pull the url and the title from the content. For this solution, each linked page must be created as page, if you want to link to a section, you would have to use “section” instead of “page”.

I’ll mark this topic as solved now and I hope that it could be useful for someone. If you have any suggestion on how to make it better, please tell me.

In Hugo 0.33 (released today) you can do .Site.GetPage "page" "post/mypost" (i.e. content page name without any language code or extension) and get the current language version.

@Marek_Maurizio1 good luck in your search for an alternative static generator.

3 Likes

Thanks for the post and the release. I tested it and it works beautifully. Now I don’t need my hack anymore and I’m much more flexible when more languages are added.

1 Like