Hugo: Allow setting the delimiter used for setting config via OS env, e.g. HUGO_

Created on 14 Oct 2020  路  6Comments  路  Source: gohugoio/hugo

Issue

Hugo lets the user inject single values into the configuration by using HUGO_PARAMS_<paremeterName>=<value> hugo. If more than one parameter, or a parameter with an underscore in the name, needs to be injected, this has to be done by injecting the entire section, e.g. HUGO_PARAMS_<sectionName>=<JSONstring> hugo. When injecting integers, that would be type int64 when defined in the config files, they are recast to type float64.

Example

In /config/default_/params.toml:

[<sectionName>]

param_INT = 1
paramSTR = "placeholder"  

In order to change the parameters we need to inject a JSON string.

HUGO_PARAMS_<sectionName>='{"param_INT"=2,"paramSTR"="someStr"}' hugo

After injection param_INT is type float64 and not int64.

Hugo version

v0.76.4

Bug

All 6 comments

The underlying limitation: .Site.Params.a_b cannot be overridden with an environment variable.

HUGO_PARAMS_a_b="foo" hugo tries to set .Site.Params.a.b not .Site.Params.a_b.

If you want to be able to override configuration values with environment variables, define the configuration variables using camelCase instead of snake_case.

The OP worked around this limitation by setting an environment variable to a JSON string, but that introduced unwanted side effects (unmarshal produces float64 regardless of number format).

Using camelCase sounds like a good idea for future projects. But this doesn't really help people relying on a 3rd party theme!
The JSON workaround would be a great solution if it weren't for the recasting of integers, hence the reason why I opened this issue.

So, the recasting is done by Go's json package; as in: Every number turns into a float64; the idea being that you would be able to turn it back into an int when you turn it into a struct. But that is not this case.

So,

  • I don't know how to fix the number thing in JSON without too much work
  • But looking at the code, we do also support YAML and TOML in these env vars. TOML may be hard, but YAML would probably be more compact than what you have. Both YAML and TOML should have proper number support.
  • But should also, and I will keep this issue open for that, figure out a way to "quote" these environment settings so we could use the reserved underscore.
  • But looking at the code, we do also support YAML and TOML in these env vars. TOML may be hard, but YAML would probably be more compact than what you have. Both YAML and TOML should have proper number support.

How should I structure the YAML input? Standard YAML uses line breaks. Will \n work?
HUGO_PARAMS_MAP='--- \n engine:int \n api_key: str'

Not elegant, but this works to pass YAML in a Bash shell:

HUGO_PARAMS_MAP=$(printf "%s\\n%s\\n%s" "engine: 1" "api_key: '12345'" "zoom: 15") hugo

Resulting values and types:

.Site.Params.map.engine = 1 (int)
.Site.Params.map.api_key = 12345 (string)
.Site.Params.map.zoom = 15 (int)

OK, I stumbled upon this problem myself ...

I will test this, but I suggest that we allow the user setting the delimiter to be used as the first character after HUGO. e.g. assuming it's valid Bash (or whatever), all of the below will work:

HUGO#PARAMS#API_CONFIG#APP_ID
HUGO%PARAMS%API_CONFIG%APP_ID
Was this page helpful?
0 / 5 - 0 ratings

Related issues

MunifTanjim picture MunifTanjim  路  3Comments

moorereason picture moorereason  路  3Comments

antifuchs picture antifuchs  路  3Comments

nikolas picture nikolas  路  3Comments

artelse picture artelse  路  3Comments