Hi,
I need to migrate a Ghost 3.16.1 to old school long nested URLs with category posts and their related posts in each category. This is an attempt to document a solution for those who have also read everything touching on the subject.
The blog content is already vast and the categories (4 levels) won’t move much so I’ll go with generating routes.yaml
Collections and the redirects JSON. I don’t see another solution if we want:
- to define our static URLs (Channels and Routes do not change the post URL)
- to avoid duplicate content
- to have
sitemap.xml
automatically update to the new URL structure
Every post has an ordered list of tags and their slugs are used to build the URLs.
- post.slug: cat4post
- tag.slugs: category1, category2, category3, category4
- expected URL: /category1/category2/category3/category4/cat4post/
A category post is tagged in addition with an internal #level1
, #level2
, #level3
or #level4
so they can be filtered in or out. For example in post.hbs
related posts, to navigate down the tree i.e. show links to sibling posts on the same level and also to the subcategory post entry points.
- post.slug: category4
- tag.slugs: category1, category2, category3, category4, hash-level4
- expected URL: /category1/category2/category3/category4/
The routes are matched in the order they are declared so we start with the longest. Collection names can be anything as long as they’re unique. We’ll stick to URL naming for clarity.
collections:
### LEVEL4 cluster articles in one go
### excluding the category post to avoid doubling the URL like .../category4/category4/
/category1/category2/category3/category4/:slug/:
permalink: /cours-code/guides/route/autoroute/{slug}/
filter: primary_tag:category1+tag:category2+tag:category3+tag:category4+tag:-hash-level4
template: post
data: post.slug
### LEVEL4 the category post
/category1/category2/category3/category4/:
permalink: /category1/category2/category3/category4/
filter: primary_tag:category1+tag:category2+tag:category3+tag:category4+tag:hash-level4
template: post
data: post.slug
Checking the DEBUG ghost:services:routing:bootstrap Routes
and ghost:services:url:urls
they show what we expect.
Issue #1: The category post URL /category1/category2/category3/category4/
throws a 404 Page not found.
I can see a workaround by removing the last category post tag category4 which will push it up a level however I am curious as to why this doesn’t work.
Something I haven’t understood? A limitation? A bug in this version of Ghost?
PS: I hope my markdown is readable and yes, for the good of all I will update with my full solution after discussion here.