gohugoio / hugo

The world’s fastest framework for building websites.
https://gohugo.io
Apache License 2.0
76.22k stars 7.55k forks source link

Add permalinks tokens contentbasename and contentbasenameorslug #11722

Open hacdias opened 1 year ago

hacdias commented 1 year ago

What version of Hugo are you using (hugo version)?

$ hugo version
hugo v0.120.4-f11bca5fec2ebb3a02727fb2a5cfb08da96fd9df+extended darwin/arm64 BuildDate=2023-11-08T11:18:07Z VendorInfo=brew

Does this issue reproduce with the latest release?

  1. Create a categories taxonomy.
  2. Create file /categories/a/_index.md and /categories/b/_index.md
  3. Create posts for those categories.
  4. Add the following to your config:
[permalinks]
  categories = '/:filename/'

All categories will be concurrently built to /index.html, which leads me to believe that :filename is empty for them.

jmooring commented 1 year ago

/categories/a/_index.md and /categories/b/_index.md

Both filenames are _index.md. Not sure why you would want to do this. Seems like you want this instead:

[permalinks.term]
categories = '/:slug/'
hacdias commented 1 year ago

@jmooring for other files, :filename is filled up with their directory name. I have the following rule:

posts = '/:year/:month/:day/:filename/'

And the post at posts/2023/distributed-tracing-with-opentelemetry/index.md will be published at:

/2023/04/18/distributed-tracing-with-opentelemetry/ (using the date in the frontmatter).

If it works for posts, why doesn't it work for categories?

I want the name attributed to that entry. Whether it is a directory entry of just a markdown file, it should not matter. You can see the source here: https://github.com/hacdias/hacdias.com

I wanted the categories to also use the disk name without me having to define a manual slug and not be dependent on the title, just like the posts.

bep commented 1 year ago

Assuming you have files backing these categories, I don't see how they should behave differently.

But I see this in your config, which does not match your expectations:

[permalinks]
  tags = '/tags/:title/'
  categories = '/:title/'
  posts = '/:year/:month/:day/:filename/'

Also, I suspect that :slugorfilename may be a better option.

hacdias commented 1 year ago

@bep

But I see this in your config, which does not match your expectations:

I want to change to categories = '/:filename/'. But if I do that, it will all concurrently build to /index.html instead of to /:filename/index.html. Feel free to clone my repo, replacing that and building to see. All categories have a matching file.

jmooring commented 1 year ago

https://github.com/gohugoio/hugo/blob/68e95327f7be941c44c256d2dac74ea96e731674/resources/page/permalinks.go#L265-L277

Examining the above, the :filename token is limited to kind page. Before leaf bundles were introduced, "filename" was an accurate description. Then we introduced leaf bundles, and "filename" became either the file name or the directory name, but was still limited to kind page.

To avoid a breaking change, I suggest that we add a :contentbasename token.

ContentBaseName: If the page is a branch or leaf bundle, the name of the containing directory, else the TranslationBaseName.

hacdias commented 1 year ago

That's interesting and looks like the source of the problem. I'm not sure that introducing :contentbasename is necessary though: is it a breaking change, or a bug? It doesn't seem likely to me that someone is using :filename for taxonomies if the current behaviour is that it won't work.

Whatever is done, I think the documentation should be clarified: https://gohugo.io/content-management/urls/#tokens

jmooring commented 1 year ago

I'm not sure that introducing :contentbasename is necessary

  1. Changing the meaning of :filename may change some sites. I've been bitten by the "doesn't seem likely to me" assumption a few times, and there are some ugly and unexpected configs in the wild.
  2. The word "filename" was once an accurate description, but is has not been accurate for a long time. This is an opportunity to clean that up, using the same language we use elsewhere. And maybe we can deprecate :filename at some point.

Other considerations...

In most cases taxonomy terms are not backed by a file, so should :contentbasename fall back to the urlized title? If it doesn't, this will result in missing term pages when terms are not backed by a file:

[permalinks]
categories = '/:contentbasename'

We have a :slugorfilename token, so it seems like we'd want :slugorcontentbasename too... yuck

jmooring commented 7 months ago

While updating https://gohugo.io/content-management/urls/#tokens to match current behavior, adding exceptions to the documentation is clumsy and a bit convoluted (e.g., "This applies to xxx but not to yyy.").

I think we should:

  1. Add a :contentbasename token that returns the File.ContentBaseName for all page kinds, not just limited to page.
  2. Add a :contentbasenameorslug token that applies to all page kinds, not just limited to page.
  3. Deprecate :filename because File.Filename is something different (the absolute file path), and to me the tokens should be symmetrical with the File.xxx names.

@bep I would appreciate it if you would (a) close this as "won't fix", (b) reclassify it as enhancement, or (c) comment with recommended changes. Thanks.

I'm pretty sure the current token implementation predates the File.ContentBaseName implementation.