-
-
Notifications
You must be signed in to change notification settings - Fork 7.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Custom Output Formats to Hugo #3122
Conversation
e5d23dd
to
d975b9c
Compare
It would be great with some feedback on the above:
|
@bep This is a really exciting feature, and thank you so much for putting in all the hard work. As an aside, I'm impressed with how well this spec is written and articulated. I can learn a lot from you. That said, I see some points of confusion for "newbs," but I leave it up to you as to whether Hugo wants to continue to target this audience. Confusion Over
|
Type | Layouts |
---|---|
JSON | json-index.json, index.json, _default/json-list.json, _default/list.json |
AMP | amp-index.html, index.html, _default/amp-list.html, _default/list.html |
I think these will draw confusionb:
_default/json-list.json
vs_default/list.json
_default/amp-list.html
vs_default/list.html
Suggested Alternative
1. Defining formats in config
The question becomes whether users will need to arbitrarily define as many output types as they want or whether Hugo should come with a set of baked-in formats for easier reference: json
,amp
,ics
.
So, for example, this might be a cleaner configuration:
# config.yml
outputs: ['html','json','amp','ics']
With the sane default (when omitted) of just:
#config.yml
outputs: ['html']
2. Naming Conventions for templates/lookup
And then with a similar directory structure like the following:
.
├── content
│ ├── events
│ └── posts
├── layouts
│ ├── _default
│ │ ├── list.html
│ │ ├── list.json
│ │ ├── single.amp.html
│ │ ├── single.html
│ │ ├── single.ics
│ │ └── single.json
│ ├── events
│ │ ├── single.html
│ │ └── single.ics
│ ├── index.amp.html
│ ├── index.html
│ ├── index.json
│ └── section
│ ├── posts.amp.html
│ ├── posts.html
│ └── posts.json
This doesn't require users to learn anything new about the lookup order and doesn't conflate file extension with name (see the language used around the .File
object).
Note: This helps too since the lookup is going to be even more consistent and intuitive with your recent improvements to
section
😄
Drawbacks
The drawbacks, however, are the same as one of the major drawbacks of the current lookup: how to keep certain pages from not rendering at all. For example, if in the above example I do not want to create individual .ics
files for every file in posts
.
Even with the current HTML-only model we have now, users are required to create a blank file in certain cases at layouts/<SECTION>/single.html
if they want to keep multiple instances of a content type in one content directory but only render a single list page (e.g., with documentation and smooth scrolling).
BUT, I think your solution now solves this problem even for people who are only interested in generating HTML (although I'm not sure if that was your intention, but if so, awesome).
At the page level, outputs
in the front matter would/could override the lookup. So continuing with your idea of explicitly declared formats in individual front matter being the only format rendered, you could do this in content/posts/special-post.md
:
---
outputs: ['html','json']
---
So then only the following are rendered:
- example.com/posts/special-post/index.html
- example.com/posts/special-post/index.json
And the following are not because they override the lookup:
- example.com/posts/special-post/index.amp.html
- example.com/posts/special-post/index.ics
And this would be fantastic if it meant that in any single-content file I could add an empty array....
#posts/special-post.md
outputs: []
...and then example.com/posts/special-post/index.html
...would render as nothing; i.e., no file rendered at all.
Questions
Also, I'm curious as to what your planning for pretty VS ugly URLs in config
. Would it follow the same pattern? That is, special-post.json
vs special-post/index.json
?
@rdwatters thanks for the input.
You assume I have planned every detail ... Much of the details will have to be decided when I run into them in tests (believe me, there will be lots of tidbits). I have not thought too hard about
I'm not sure I understand. We may have more built-in "output formats" that can be used (like AMP, JSON, YAML etc.), but the definition for a new one (say a rare calendar format), cannot be one word (we need the file suffix etc.). Hugo will still aim to be extremely easy to use, but with some added power tools if you need it. |
D'oh. My bad. Maybe I was thinking of If this is really just a matter of running the same templating and changing the file extension:
It's certainly pretty intuitive since it's a one-to-one relationship between what's in the front matter and the actual file extension used in the templating lookup I mentioned above, but I get the feeling this is too restrictive. Hmmm...is just
So you're saying the following is not a feasible idea... (Or maybe just a bad idea, which I'm okay with as well.)
And instead...
Just to clarify, I'm talking about an actual one-liner in the configuration file, so... logFile = ""
outputs = ["html","json","amp"]
metaDataFormat = "yaml"
pluralizelisttitles = false With default being |
No, that does not work. That breaks already on AMP, which is kind of one of the main motivations behind all of this. As I said before:
|
Why even "per Kind"? I think the notion of So, for example, what I'm saying is it's on the user to ensure mirroring of what's in ExampleYou would have the following one-liner in your configuration:
And then you create
If there isn't a corresponding file, it just doesn't build it. This actually reflects the current system, right? I mean, in that if you don't have any If I take what you mean by configuring outputs per #config.yml
output:
section: ["html","json"]
taxonomy: ["html","rss"]
taxonomyTerm: ...
....
# With the assumption that unspecified kinds output default "html" Whereas what I'm saying is that a
Or maybe you just don't want that page to be rendered to anything because the content is most definitely a post, but you want to only include it in that directory for your own sort of organizational purposes. In this sense, the directory becomes more like a "collection" (quasi Jekyll reference) and you can keep it from rendering at all with...
Or further customize the layout of the intended JSON output by going up the ladder in the lookup. Are we saying the same thing here? |
How will partials be handled? That is, will there be such thing as I can't think of how blocks/base would provide a ton of benefit for media types other than HTML/XML... |
No, it doesn't. We currently treat missing template file(s) as a WARNING, but there is an issue about making it an ERROR. But this is side-tracking the discussion. The default output set must be defined per Having the "if there are no template, then we do not render that output type" will not work, as with the flexible layout system we have, we will in most cases find a template to use (esp. in the ambiguous cases like HTML vs AMP and the list templates etc.) and in many cases it does not make sense to render to a type just because we can dig up a template for it (RSS for regular pages etc.). So we must have a defined set of rules. Re. partials: That will eventually follow naturally when the big picture is painted -- as I said, I'm not digging into all the details now. |
Me:
You:
I don't find it confusing, but if I did, I can assure you I wouldn't be alone in such sentiment. You're right, I could a. start a new thread I'll go with b. |
That sentence doesn't make sense ... :-) Again, I appreciate your input on this, and I really want to make it as simple as possible ... With an emphasis on possible. If we want to do this, it should ... work. So any suggestions for a simpler model should be evaluated against the actual needs. And the scope of this task is certainly NOT to redo the whole And note that
|
It makes enough sense colloquially, but you're right that I should rephrase: "I am not confused by the concept of That damn subjunctive mood is not a strength of we Chicagoans, haha. Besides, I hope these threads never come to that level of pedantry. P.S. "Front matter" has always been two words. 😉 |
It is a fairly new and constructed word, so I would say both would be equally correct; I prefer frontmatter. Besides, I'm from Norway, so English isn't my first language. |
I know. I was making a bad joke; i.e., by saying that I hope these conversations never care about things like spelling rules and then making that comment at the end. Seriously, I would never give a fellow American a hard time about "proper" spelling of "front matter" and I'm a publisher! Now I just feel bad. Sorry, Bjorn. |
So, as far as I can tell from this thread, to use this feature, one needs to:
Is it necessary to declare them at all in the config (pardon GO/Hugo ignorance here), unless we were registering a completely new type? Would a piece of content declaring that it was using a particular output type be sufficient?
As an aside, it would also be neat to be able to turn off the default "HTML" for a given
This layout scheme
does seem a bit clunky with the output prefix repeated with the extension, but from what you're saying, it seems this is necessary for the case of AMP, as an example, because it has HTML as a prefix, not "amp." Also, I like "output format" Hope that helps. |
@budparr I will make this more clear in the spec:
|
Great to see progress in this topic. I'm really happy with the explanations above and many things have already been discussed. There ist just one part that I'm not sure about is how to link those different pages together, like in AMP for example where you need to / should specify the related AMP page of a regular page and vice-versa. From the Documentation:
Currently for the canonicals in Hugo we mostly used Ideas:
I personally would prefer the Hope this part was not too much off-topic. Keep up your great work. Thanks. |
@wildhaber no, this was very much on-topic. I haven't invested too much time on AMP, so any feedback in that department is welcomed. I suggest we add
Will have to look into the value of Would that make sense? |
@bep I like the idea of having access to the However I would like to have a direct access on an Output-Type like So a developer can use this on different purposes without having to take care about the internal naming vs. standardized outputs. AMP-Example: # config.toml
[[output]]
name = "AMP"
mediaType = "text/html"
path = "amp" So the value of {{ if ne .Page.AlternativeOutputs.amp nil }}
<link rel="amphtml" href="{{ .Permalink }}">
{{ end }} .ics-Example #config.toml
[[output]]
name = "Calendar"
mediaType = "text/calendar+ics"
isPlainText = true Creating a link in the document to download the .ics file directly like: <a href="{{ .Page.AlternativeOutputs.ics.Permalink }}">Add to the Calendar.</a> In cases of .ics we might also need to think about customizing the Protocol in the configuration like For example: #config.toml
[[output]]
name = "Calendar"
mediaType = "text/calendar+ics"
isPlainText = true
protocol = "webcal://" I think the two examples above show the flexibility that are needed for custom outputs. But on the other hand Hugo developers would really gain an amazing feature. |
2c7ba73
to
9a3f3b9
Compare
This isn't meant to be the final useer docs on this feature!
To make it super-easy to create rel-links.
And remove the now superflous setPageURLs method.
And some other unsed fields and methods.
Using it for list pages doesn't work and has potential weird side-effects. The user probably meant to range over .Site.ReqularPages, and that is now marked clearly in the log.
Hi @bep – I'm late to this discussion but it sounds very promising! To clarify, once this feature is finished, will Hugo support building pages in arbitrary formats and with arbitrary file extensions? I'm working on building some tooling on top of Hugo that could output a site as an EPUB, a process that requires building XML files with specific extensions like Thanks for all the great work on this project! |
@egardner -- short answer: Yes, but I have not added the option to add your own MIME-types and output formats, but that will land in a couple of days. |
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
See https://github.com/bep/hugo/blob/custom-output/docs/content/extras/custom-output-types.md
Also see #2828
Also see https://discuss.gohugo.io/t/custom-output-content-types/4584