HUGO

How to get a specific translation?

I’m trying to get the .Page for a specific translation, but somehow this isn’t working as expected:

            {{ warnf "all translations %s" .AllTranslations}}
            {{ warnf "translation %s 1" (where $.AllTranslations "Language" "de") }}
            {{ warnf "translation %s 2" (where .AllTranslations "Language" "de") }}
            {{ warnf "translation %s 3" (where $.AllTranslations ".Language" "de") }}
            {{ warnf "translation %s 4" (where .AllTranslations ".Language" "de") }}
            {{ range .AllTranslations }}
            {{ warnf "%s" .Language }}
            {{ end }}}

Results in:

WARN 2021/04/19 12:13:59 all translations Pages(2)
WARN 2021/04/19 12:13:59 translation Pages(0) 1
WARN 2021/04/19 12:13:59 translation Pages(0) 2
WARN 2021/04/19 12:13:59 translation Pages(0) 3
WARN 2021/04/19 12:13:59 translation Pages(0) 4
WARN 2021/04/19 12:13:59 en
WARN 2021/04/19 12:13:59 de

BTW: Please add to the documentation that warnf will discard duplicated messages by default - thats the reason why I added digits at each end…

{{ range .Translations }}
    <li>
        <a href="{{ .Permalink }}">{{ .Lang }}: {{ .Title }}{{ if .IsPage }} ({{ i18n "wordCount" . }}){{ end }}</a>
    </li>
{{ end }}

The translation is a page in itself. This works inside of the local page with .AllTranslations.

@davidsneighbour Thanks, but I know that - see the range my example. My question, to be more precise, is, why doesn’t work where in this case, might this be a bug? I didn’t want to send it to GitHub without asking here first…

You should add a complete layout-example for that or the whole repo with either some or all content. I think you might be inside of another range and the context (.) is not what you expect it to be (the indentation points to that :wink: ) we need to see the larger picture.

1) Collections

.Translations returns a collection of the current page’s translations, excluding the current page.

.AllTranslations returns a collection of the current page’s translations, including the current page.

2) .Language vs .Language.Lang

{{ printf "%T" .Language }} --> *langs.Language
{{ printf "%T" .Language.Lang }} --> string

In the where function you are comparing a value of type “*langs.Language” to a value of type “string”. That will always be false.

Instead of this:

{{ where .AllTranslations "Language" "de" }}

Do this:

{{ where .AllTranslations "Language.Lang" "de" }}

3) Get the page

The where function returns a collection (in this case with one item), not a page. So, this will not work.

{{ $p := where .AllTranslations "Language.Lang" "de" }}
{{ $p.Title }}

You need to range through the collection to get the page.

{{ $p := slice }}
{{ range where .AllTranslations "Language.Lang" "de" }}
  {{ $p = . }}
{{ end }}
<a href="{{ $p.RelPermalink }}">{{ $p.Title}} ({{ $p.Language.Lang }})</a>

Or use the index function to get the first (and only) item:

{{ $p := index (where .AllTranslations "Language.Lang" "de") 0 }}
<a href="{{ $p.RelPermalink }}">{{ $p.Title}} ({{ $p.Language.Lang }})</a>

4) Supression of duplicate warnings

See https://gohugo.io/functions/errorf/.

errorf or warnf will evaluate a format string, then output the result to the ERROR or WARNING log (and only once per error message to avoid flooding the log).

@jmooring: Many thanks for this long explanantion, the relevant part for me is section 2. Even though I use Hugo for half a year now this stuff still bites me and I might not be the only one who would find this counterintuitive. Why not just evaluating a where clause in the type context it was written in?
I would suspect that .Langauge cast as string results in the value of .Language.Lang, at least the part

{{ range .AllTranslations }}
            {{ warnf "%s" .Language }}
{{ end }}}

implies that. I guess this would also help to avoid some support questions here - not only related to i18n, but where in general. But I’m not sure what else (existing themes etc.) such a change would break. But then again, typing in Hugo isn’t working well at all, so one couldn’t create typed query parameters…

Maybe a long term goal could be to improve the function library…

I guess I can’t disable the suppression of duplicate warnings?

No, you cannot.

That seems like a slippery slope. For example, I would be irritated if this were true:

{{ eq "2" 2 }}

But those coming from loosely typed languages might expect the opposite behavior. For example, you see a lot of lazy comparisons in PHP code such as:

if ("2" == 2) {
  echo "This is true";
}

instead of:

if ("2" === 2) {
  echo "This is false";
}
1 Like

@jmooring: Yes, I expected such objections and understand them. But talking about typing reminds me that there have been some situations I’ve found it frustrating that there isn’t something like $val := nil, or $val := bool "false". That’s what I meant with Hugo’s type system isn’t working well…
It feels likes it’s getting in ones way in certain situations like above and isn’t helping one when needed.

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

EDIT: “feels like” is insufficient data.

1 Like

That’s the reason why I post this here :wink:
I could make up a use case and argue with it’s educational value, to avoid a few typing related questions in the future. But won’t buy that myself either :wink:

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.