Need to redefine the whole Outputs map when needing to set just one Kind?

Hello,

After adding this to my config.toml:

[Outputs]
  home = ["HTML", "RSS", "JSON"] # default: home = ["HTML", "RSS"]

The RSS feed for sections, tags, etc. stopped generating…

So mydomain.com/tags/foo/index.xml would return 404.

But if I comment out that whole Outputs customization, that same feed will generate fine.

Then looking at the documentation:

… there’s an innocuous looking line:

Any Kind without a definition will default to HTML.

!!

This is the workaround I use right now… just to get JSON output format added to home Kind… which looks like an overkill.

[Outputs]
  home = ["HTML", "RSS", "JSON"] # default: home = ["HTML", "RSS"]
  section = ["HTML", "RSS"]
  taxonomy = ["HTML", "RSS"]
  taxonomyTerm = ["HTML", "RSS"]

Tomorrow if more kinds are added to outputformats, I would need to add even that to all my sites.

Can this feature request be considered:

If customizing the output formats for one Kind, leave the output formats for other Kinds at their default values.

That would be a breaking change, which is always problematic. But it is also a change I don’t agree with. Which is obviously why it is implemented the way it is.

The default outputs config had HTML + RSS so that existing sites would continue to work as is. If you provide your own config, you tell Hugo that you want your own custom config. There is nothing particularly special about the RSS output type, and HTML is added as the one single default just because Hugo kind of does not work without at least one.

So, if you want an RSS for taxonomies, go ahead and configure it. But I don’t want that, so I don’t see why I should have to do anything special about it.

More kinds? I don’t see how we have any more kinds that RSS is relevant for, and it would probably be surprising to people if we added some new “kind” and a new RSS feed just popped up.

Thanks for the reply.

Yes, I see that as a good solution moving forward.

The behavior is surprising, because if you do not set the Outputs in config.toml, RSS feeds get generated by default for sections, taxonomies, etc. (this is also mentioned in docs as By default, all pages will render as HTML with some of them also as RSS (homepage, sections, etc.).). But then if I specify the Outputs for home, section, taxonomy, etc. Outputs get stripped down to just HTML.

So we kind of see a hysteresis over here… initial untouched default (Edit: I mean if user has not customized the Outputs variable at all in their site config) includes RSS for sections, but once Outputs is touched, the default changes to include only HTML.

If this is a backward incompatible change, I can understand… but let me open an issue to at least document this behavior more prominently.

Related question:

Also for documentation, what are the default outputs for all kinds if user hasn’t configured outputs at all in their config.toml?

Output is set. Which is a semantic difference.

I should have been clearer… I meant if user has not configured the Outputs var in their site config.

OK, I figured out the default if user has not set outputs:

So the question is that why is the default set to to HTML for all Kinds if user has set the outputs for only one of the Kinds.

It would be less surprising if the default for all Kinds before setting outputs and after setting outputs stayed the same.

One reason: Hugo would crash without at least one output format for a given kind.

Yes, I understand that part… the question is… why not set the defaults as createDefaultOutputFormats is doing?

Probably I am reading the code wrong, but looks like the setting of defaults after user sets outputs is done here. Inside createDefaultOutputFormats we have a if kind != KindPage { clause which is missing in the alternative default setting code I linked in the “here” above.

Are you saying that the code looks different compared to how it behaves?

No… it obviously behaves as coded… but I wouldn’t have known that without reading the code… and also the coded behavior is surprising.

Let me give an example:

User has not set outputs in site config initially

So this is what the outputs will get set automatically by default, using createSiteOutputFormats (which would be equivalent to below in site config):

INIT BLOCK

[outputs]
  page = ["HTML"]
  home = ["HTML", "RSS"]
  section = ["HTML", "RSS"]
  taxonomy = ["HTML", "RSS"]
  taxonomyTerm = ["HTML", "RSS"]
  ...

Now user sets only the home in outputs in site config

… to set the JSON output too for search index.

[outputs]
  home = ["HTML", "RSS", "JSON"]

That in turns wipes out the RSS format from everything not set by the user!

[outputs]
  page = ["HTML"]
  home = ["HTML", "RSS", "JSON"]
  section = ["HTML"] # why is this touched?
  taxonomy = ["HTML"] # why is this touched?
  taxonomyTerm = ["HTML"] # why is this touched?
  ...

Ideally the resultant outputs should have been:

[outputs]
  page = ["HTML"] # same value as in INIT BLOCK
  home = ["HTML", "RSS", "JSON"] # user modified value
  section = ["HTML", "RSS"] # same value as in INIT BLOCK
  taxonomy = ["HTML", "RSS"] # same value as in INIT BLOCK
  taxonomyTerm = ["HTML", "RSS"] # same value as in INIT BLOCK
  ...

The kind of behaviour I would expect is as if:

  • createSiteOutputFormats first gets set to the value returned by createDefaultOutputFormats unconditionally.
  • Then, if user has set outputs in their site config, update the value of outputs map internally only for the keys that the user set, and only if the key value if non-nil (non-empty or whatever the correct semantic term is).

The logic is basically first set the sane non-empty defaults, then update only the keys the user set for which the value is non-empty.

The issue we have at the moment is that we are setting different values of defaults for these 2 scenarios:

  • One where the user does not set outputs at all.
    • Using the createDefaultOutputFormats function.
  • Another where the user updates the outputs only for selected few Kinds.
    • Using the 3 line range loop that does not have the special clause for kinds != page.

I hope the case I make is clearer now.

I understand where you are coming from, but the current implementation (which Is deliberate) is coming from the idea that

  • You set the output formats map. This is analogous to setting the related config and the sitemap config and the permalinks config. You have to provide the complete definition.
  • There is nothing particularly special about the RSS output format. I think that getting it by default for each list node in the tree would be surprising to many who take their time to “configure their own”.
  • We need at least one, so we have HTML as a fall back (not default, a fall back). I assume we can agree that it makes more sense to use HTML than RSS as that one fallback option.
  • And: Changing this behaviour would be a breaking change. I would do it if I thought it was a really good idea, but I’m not convinced.

Maybe others will chime in with their thoughts.

OK, I will buy it as long as there is consistency. It’s just that the implementation is different from my way of thinking. I think of setting a key in a map as modifying just that key. But the current hugo implementation considers that as setting that key and resetting all the other keys not set.

So I will update the documentation on Ouput Formats listing the default value set by createSiteOutputFormats.


Update: Submitted PR

@bep I believe I should leave out the “other” Kinds ( []string{kindRSS, kindSitemap, kindRobotsTXT, kind404} ref) from the Output Formats documentation?

Yes, I made a mental note about the current implementation (which includes all kinds) – which includes those, but it has no practical implications.

Note that the current implementation is according to my head. If you somehow can gather support for your view on this that shows that I’m in clear minority on this, I will take a second look on it.

Thanks. As I mentioned earlier, I am buying this logic as it is consistent. And so I have also opened that PR that clarifies the Page Kind concept that go hand in hand with understanding the default value of outputs, and what happens when a user modifies just one outputs Kind.

Also note that I’m about to break the above “pattern” with the new “frontmatter” config section.

That’s not good… would be nice to have consistency.

Also, I never understood why my suggestion would be a breaking change. It’s not as if the Hugo builds will start failing… only that RSS pages will be generated when they were getting generated before. And anyways those RSS pages get generated for people who don’t set outputs.

So the people who did not want RSS would have already set the outputs to do so, and my proposed change will have no effect on them.

You will start building RSS for people that did not have it before. It is not a glass breaking change, and I would not think too hard about doing it, if I felt if was right.

The frontmatter is a little bit different beast. We need some defaults for the dates. It is probably comparable to the mediaTypes. You can add/override.