getindiekit/indiekit

mp-slug removed from post template properties

aciccarello opened this issue · 5 comments

Description of the bug

I have an 11ty site that either uses the title or a slug frontmatter property to define the slug. Recently I started noticing some of my pages were being posted at /YYYY/MM/DD/undefined/ paths with the slug missing. I checked the properties passed and mp-slug was indeed no longer passed.

It seems like recently (beta.8??) the mp-* properties were removed. I couldn't fine the exact commit but I saw it was intentional. While the other micropub directives don't seem important, the slug is used in rendering. I guess jekyll pulls from the file name, but that's not true for all SSGs.

Steps to reproduce

Console.log all the properties sent to a post template function and create a new post.

Expected behaviour

mp-slug or slug is returned in the post template properties or document the change better in the release notes (assuming I didn't miss something obvious).

Environment

https://github.com/aciccarello/ciccarello-indiekit/blob/main/lib/formatFile.js

Additional context

I should be able to work around this with the url property.

aciccarello/ciccarello-indiekit@8f96c9f

Maybe I could have made this clearer in the release notes, but under breaking changes in the release notes there’s this:

If you are using the Hugo or Jekyll presets, there may be some slight changes in output, as post templates now output all provided properties (except those prefixed with mp-*). However, in most cases there should be no difference.

The specific commit that changed this behaviour is here: 128299c

However, this (again) exposes my preset-centric mindset! While the Hugo and Jekyll presets didn’t output mp-* properties, mp-* properties were provided to the postTemplate function, which you are using directly here.

The reason for this – and correct me if this is wrong – is that the mp-* values serve as commands to the server:

  • mp-destination – which publication to post to (not used yet, but will be)
  • mp-syndicate-to – which syndication targets to publish to (the result being saved to the syndication properties)
  • mp-slug – which slug to use (which, if not provided, will be generated)

In terms of a post, a slug value should no longer be needed, as the work of the slug has been done, in that the file has been written with that value (if configured to do this).

How static site generators use slugs

If the resulting slug value is needed, static site generators often provide a means of inferring this from the file name:

The Hugo documentation does however mention using an explicit Slug value to override the file name:

---
slug: sushi
title: How to make spicy tuna hand rolls
---
# file: content/recipes/spicy-tuna-hand-rolls.md
# url: https://example.org/recipes/sushi

At the heart of this issue I suspect is that slug can mean 2 things: file base name, and URL slug. 🤪

In your specific case, it appears you are trying to generate a value that is already provided by Eleventy (with page.fileSlug), a value which will always be correct, which can’t be said of data supplied via Indiekit and included in a posts front matter. Although, maybe that’s desirable, as it means the URL slug won’t change if the file’s base name does.

There’s possibly a story around specifying separate file base names versus URL slugs, how and where they should be defined, but that gets complicated and confusing very quickly, and I think I’d want more evidence of need before adding.

Sorry I didn’t make this change clearer; I should have included as a change to the behaviour of postTemplate, not under presets. Let me know if using page.fileSlug works.

Hmmm, looking at Stable Extensions, I see that Slug is listed as a property alongside post-status and visibility, which do get sent to postTemplate. And that a slug is intended primarily for the URL, not the file name.

Perhaps I should include slug in properties, after all.

Right now, mp-slug is doing more than it’s intended for. It is primarily being used for the purpose of generating a slug path token (which falls back to slugified name if there’s a name, else generating 5 random letters).

Instead, mp-slug should only be used to indicate a desired URL slug (which may then be used in front matter and/or paths). If no mp-slug value is provided, there should not be a slug property.

However, Indiekit needs a fallback value if there’s not a value for slug. As such, I think the following change should be implemented:

  • If request includes mp-slug, a slug property is supplied to postTemplate and therefore to a post’s front matter
  • Indiekit provides the following path tokens:
    • {random}: outputs 5 random digits
    • {name}: outputs slugified name property (using configured slug separator), falling back {random} if there’s no name property
    • {slug}: outputs slug property, falling back to {name} if no slug property (falling back to {random})

Wow, this is really interesting. I was under the impression that page.fileSlug wouldn't work for me because I use a date prefix for file sorting (i.e. YYYY-MM-DD-SLUG.md). I think I inherited this pattern from Jekyll. However, when I tested it, Eleventy already takes that into account and only shows the part after the date. I could use that property but it'll require some migration to avoid breaking existing URLs. At this point I'm not sure what approach I'd like to take.

I think your proposed changes sound good. I can see how mp-* properties shouldn't be passed. A slug property passed to the post template would be great.