Variables not pulled from config file

Hello,

In config.toml I have this:

[Params]
  Title = "test title"
  Tagline = "An example tag line"

In the theme (Lanyon) I have this:

<a href="/" title="Home">{{ .Site.Params.Title }}</a>
<small>{{ .Site.Params.Tagline }}</small>

However, both the title and tagline parameter are not outputted. I searched the forum and looked through the documentation, and this page suggests the params configuration is correct while this page says the use of Site.Params is correct also.

And yet the generated HTML is:

<a title="Home" href="/"> </a>
<small></small>

Do you might know what I’m doing wrong?

It’s hard to say without further context.

So in a template for a page there are two sets of params, Site’s and Page’s:

{{ .Site.Params.Tagline }}

{{ .Params.Tagline }}

The above constructions kind of depends on the context, but the last one is params defined in the page’s front matter.

As I said earlier, what’s wrong in your case is hard to say without the full picture. It could be that your TOML file contains none-map types after the params (according to the spec, only a map can follow a map) … But that is a wild guess.

I know this will sound utterly stupid, but try it with lower case parameter names e.g.:

[Params]
  title = "test title"
  tagline = "An example tag line"

…and then:

<a href="/" title="Home">{{ .Site.Params.title }}</a>
<small>{{ .Site.Params.tagline }}</small>
1 Like

Lower case parameters did indeed work. But today, after a fresh start of Hugo the regular params (.Site.Params.Title and .Site.Params.Tagline) also work. I guess there was an old file in the /public/ that wasn’t rebuild/purged when working with Hugo yesterday (or I made a beginners mistake somewhere else that I don’t recall).

So it works correctly now. Thanks for responding Josh and Bep.

@bep

I tackled this just yesterday. Is it a bug?

Why does params need to be lower case in config.toml? But the use convention of the same is Camel case ( .Site.Params.Foo )?

@kaushalmodi please don’t mention my name for general support questions.

OK, I will not tag you in future. But can you please explain why the params needs to be lower case in config.toml but the convention is to refer it using camel case in all the examples that I have seen?

The Camel casing is a feature of Go. Variables that start with an uppercase letter are “public” or “exported.” You can only access exported fields and methods from templates.

I am trying to understand this but am confused because params needs to be all lowercase in config.toml.

From some more testing, here are the different outcomes:

params in config.toml

[params]
foo = "bar"

This gets accessed by .Site.Params.foo.
This does not get accessed by .Site.Params.Foo. That’s expected for the Foo portion because of case sensitivity. But why is is that we need Params to access params?

If variables need to start with uppercase to be made “public”, why do we need to make params lowercase.

Params in config.toml (invalid!)

[Params]
foo = "bar"

On the other hand,

This does not get accessed by .Site.Params.foo. Even though the cases for both Params and foo match with that in the config.toml. This feels very counter-intuitive in general and also in relation to:

Variables that start with an uppercase letter are “public” or “exported.”

Params IS uppercase in config.toml and still it cannot be accessed in the templates.


My observation is as follows:

  • The TOML table names (params here for example) are always lowercase. Is that a rule?
  • The .Site keys are named inconsistently (probably not?).
  • Some are all lowercase: archetypedir, config, …
  • Some are lower camel case: defaultLayout, disableLiveReload, …
  • Some are upper camel case: DefaultContentLanguage, DefaultContentLanguageInSubdir.
  • Do these differences in cases signify anything special about these 3 categories of variables? Or did that just happen by chance?
  • Usually always the key names in params table are in upper camel case. So that seems to be the convention for keys or variables that are directly not under .Site, but are in .Site.Params.

If there are a few set of rules for these casing, can that please be added to the docs?

I don’t know go but looks like this is the problem?:https://github.com/spf13/hugo/blob/8fa871a05f46295beef1f460bca28cb21ce42d2b/hugolib/site.go#L228

Does that mean than the keys are forced to lower case inside site.go and that is used to fetch data from toml parsed database?

I could be totally shooting in the wrong direction here, please forgive my go ignorance.

Update: Actually scratch that. That code probably deals with the keys inside [params].

But I believe somewhere else, what I explain below is happening. I am still trying to understand/grep where that is happening.


Basically, from what I understood, the [params] is stored as .Site.Params in go as you want that object to be public. But then it should not impose the limitation on the config.toml to have that as all lowercase [params].

So somewhere, when .Site.Params is seen in the user template, the code looks for something like “ToLower(Params)” inside the toml database. Again, toml is case sensitive. So if that code in hugo used something like “ToLower”, the toml database has to have [params], and so [Params] will not do. But why is that needed? Can’t hugo treat [Params] or [params] as the same thing?

This is what’s creating this apparent inconsistency from the view point of a first time go and toml user.


If someone has time, can they please review this? I create a bare mininum working environment for hugo to demonstrate this…

https://gitlab.com/kaushalmodi/hugo_config_idiosyncrasies

Here is how I interpret the rules for naming stuff in config.toml and using them in templates:

Rules for naming variables in config.toml and accessing them in templates

  1. Custom variables or table names are not allowed directly inside config.toml.
  • You can only use the inbuilt variables outside TOML tables… like title or supported table names like params.
  1. If you want to use custom variables for theme configuration, etc, put them inside params table. These variables can be named as per user’s liking, in any letter case. But they have to be referenced with the exact case inside the templates.
  • If table params has Abc key or variable, it has to be referenced as .Site.Params.Abc.
  • If table params has aBc key or variable, it has to be referenced as .Site.Params.aBc.
  1. Direct variables or TOML table names in config.toml must be all lower case.
  • If the variable is title, it has to be referenced in UpperCamelCase inside the templates with the .Site. prefix, like .Site.Title.
  • If the table name is params, it has to be referenced in UpperCamelCase inside the templates with the .Site. prefix, like .Site.Params.

Relevant files to look at in this mini project:

  1. config.toml
  2. Test case to try out various combinations of cases for keys and tables.

That said, this project is ready-to-run. So you can also git clone it and hugo to see it in action and play with commenting/uncommenting different things in the test case.

Experiencing the same problem in Hugo 0.18-dev, which wasn’t present in 0.17-stable.

[params]
  DateForm = "2 January, 2006"
  Description = "Hello"

And yet calling .Site.Params.Description has no output, and {{ dateFormat .Site.Params.DateForm .Date }} just throws errors (was expecting a string).

+1!

My earlier letter case inconsistency research was for a separate issue. What you posted used to work when I posted that example project. But now that is failing as well. I confirm that failure too. Looks like some recent changes (2-3 days) made in the hugo master caused this.

@bep I hope I am tagging you for the right cause this time. Looks like the recent ToLowerMap changes are causing this.

My site builds correctly on version 0.17 but fails on the latest hugo build (as of now) with these errors:

Started building sites ...
ERROR: 2016/10/17 10:38:29 general.go:236: theme/_default/summary.html is an incomplete or empty template
ERROR: 2016/10/17 10:38:29 general.go:236: theme/_default/li.html is an incomplete or empty template
ERROR: 2016/10/17 10:38:29 general.go:236: Error while rendering page post/generating-a-transparent-favicon.md: template: /home/kmodi/hugo/kaushalmodi.gitlab.io/themes/lanyon/layouts/_default/baseof.html:5:49: executing "main" at <.Site.Params.DateFor...>: invalid value; expected string
ERROR: 2016/10/17 10:38:29 general.go:236: Error while rendering page post/how-i-created-this-blog.md: template: /home/kmodi/hugo/kaushalmodi.gitlab.io/themes/lanyon/layouts/_default/baseof.html:5:49: executing "main" at <.Site.Params.DateFor...>: invalid value; expected string
ERROR: 2016/10/17 10:38:29 general.go:236: Error while rendering page post/elisp-meta-characters-in-string.md: template: /home/kmodi/hugo/kaushalmodi.gitlab.io/themes/lanyon/layouts/_default/baseof.html:5:49: executing "main" at <.Site.Params.DateFor...>: invalid value; expected string

https://github.com/spf13/hugo/issues/2597

I will check this Params casing issues … probably my mistake.

May not be the last commit in this story, but have a look at this:

https://github.com/spf13/hugo/commit/58f31d2769ec63aa8dfd4eaad47703ce09b57a96

Thanks. Looks like this is working:

    <span class="left post-date">
        {{ .Date.Format (.Site.Param "dateform") }}
    </span>

While that is working, is that the canonical way to call methods within templates?

A note about the commit message:

* Use `.Param "someKey" ` if you want page param with fall back to site param if not found on page.
* Use `.Site.Param "someKey"` to get a site param

If the message is to have lowercase args, why write it in lower camel case? It should be .Site.Param "somekey", correct?

A followup question to the new style of accessing params:

If I have this in config.toml:

[params]
bar = "params.bar0"

[params.temp1]
var1= "params.temp1.var1"

Following in template:

    <li>.Site.Params.Temp1 = {{ (.Site.Param "temp1") }}</li>
    <li>.Site.Params.Temp1.var1 = {{ (.Site.Param "temp1.var1") }}</li>

returns

.Site.Params.Temp1 = map[var1:params.temp1.var1]
.Site.Params.Temp1.var1 = 

How do I get something like {{ (.Site.Param "temp1.var1") }} working?

The message is case-insensitivity, which gets obvious with Param.thisLongCamelCasedKey which you earlier had to get exactly right for it to work.

Now, .Site.Param "dateform", .Site.Param "dateForm", .Site.Param "DATEFORM", .Site.Param "DateForm" will all work.

1 Like

Note that this is work in progress – if you want the stable version, please use the release version.