Ghost: Feature: redirects.yaml

Created on 6 Sep 2019  路  12Comments  路  Source: TryGhost/Ghost

Our redirect feature is cool and powerful, but having to correctly format a JSON file by hand is HORRIBLE.

We are now using YAML for user-edited settings files, we should do that for redirects as well.

Ref material

Our current JSON redirects format looks like:

{
  "from": "/url/" ,
  "to":  "/url/",
  "permanent": true | false
}
  • We support full JavaScript regexes in the from field
  • Regex patterns e.g. $1, $2 so on can be substituted into the to field.
  • Redirects can be either permanent (301) redirects, or temporary (302) redirects, based on the permanent flag.
  • Also (currently undocumented) we support adding an i flag to the end of the from path, e.g. "from": "/my-url/i" which makes it do a case insensitive match.

Statamic have a similar feature, provided in YAML: https://docs.statamic.com/routing#redirects

Netlify use a tab separated values style: https://www.netlify.com/docs/redirects/

Spec

We will add support for uploading a redirects file called redirects.yaml. The file must contain valid YAML.

Redirects will apply to the web application of Ghost only (same as now).

This new file will support all the same features as the old redirects.json format but in an easier to write and maintain style. The main change is that instead of a property, the type of redirect is specified via one of two top-level keys.

Full example:

302:
  /from-url/: /to-url/

301:
  /category/([a-z0-9\-]+)/i: /tag/$1/
  /v([0-9\.]+)/docs/([a-z0-9\-]+)/i: /docs/$2/

Migration

For now we should just support both formats. In the next major version we can drop support for uploading the JSON format.

We may be able to write a migration for a major upgrade using something like https://www.npmjs.com/package/json2yaml

However JSON is valid YAML 馃

feature help wanted pinned

Most helpful comment

I've been using Ghost for over a year, it's probably time to give something back; I'll take this on!

All 12 comments

I've been using Ghost for over a year, it's probably time to give something back; I'll take this on!

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

This feature has almost been finished with https://github.com/TryGhost/Ghost/pull/11218, easy candidate for somebody from the community to pick up :wink:

Yeah, that's my bad; winter got weird IRL. If nobody else picks it up I'll see where I can get this weekend.

I'm getting a bit caught up on the unit testing framework, although the configuration work went OK.

@Assisting let me know if I could help with any guidance and feel free to ask _any_ related questions :wink:

@naz @sainthkh I'm looking at the original spec for this, and I have a suggestion for a small change:

The example given in the original spec would imo be better as:

temporary:
  /from-url/: /to-url/

permanent:
  /category/([a-z0-9\-]+)/i: /tag/$1/
  /v([0-9\.]+)/docs/([a-z0-9\-]+)/i: /docs/$2/

My reasoning for this is that it removes the requirement for non-technical users to understand the meaning of 301/302 in the context of HTTP status codes while still making sense to technical users.

wdyt?

@matthanley this seems like a good idea. I think we could introduce these as "aliases" to start with. This approach should allow us to keep back compatibility with the current format and leave space for technical users to keep using 302/301 notation.

That said one bit I see becoming problematic with this approach is potential conflict in naming if we ever have a need to support 307 redirect which is named exactly that - 307 Temporary Redirect. Not sure what the best solution out of this is, but would definitely keep the original (status codes) key names as a main line of support and add the aliases as "beta" feature.

@matthanley I also like your idea. And as for @naz's concern about 307 redirect. Maybe we should name it, temporary-preserve-method. I wasn't sure about the difference, so I checked it here.

@sainthkh to be clear, think it would be best if we wrap up current PR with the scope it already touched. We can add the aliasing proposed here and more improvements in future iterations. Wanted to avoid bloating with features as the branch has been running for long enough already :)

Right. I agree with you. It seems that we can organize leftover todos in this way.

Current PRs

  • [x] Add endpoints and change them in admin client.
  • [x] copy review and apply them.
  • [x] check/change setFromFilePath signature

Future PRs

  • [x] aliased routes => I think it's a good candidate for good first issue.

Maybe

  • [ ] 307 redirect.

@naz all things clear. Waiting for review and merge.

Was this page helpful?
0 / 5 - 0 ratings