Dynamic Filtering by Slug for Custom Channel in routes.yaml

Hello Ghost Community,

I’m trying to create custom routes to filter posts by tags and further categorise and have a channel called “popular” for each tag. Basically show the most popular posts within a tag in a specific format.

The goal is to set up a dynamic structure where the tag slug is used to filter posts, without hardcoding any specific values.

Here’s what I’ve tried in my routes.yaml file to setup this channel:

routes:
  /:slug/popular/:
    controller: channel
    template: popular
    filter: tag:[{:slug}]

collections:
  /:
    permalink: /{primary_tag}/{slug}/
    template: index

taxonomies:
  tag: /{slug}/

The intention is for this configuration to allow URLs like:

URL (Channel) Associated Tag URL
https://www.wisdominanutshell.academy/andrew-huberman/popular https://www.wisdominanutshell.academy/andrew-huberman/
https://www.wisdominanutshell.academy/elon-musk/popular https://www.wisdominanutshell.academy/elon-musk/
https://www.wisdominanutshell.academy/steve-jobs/popular https://www.wisdominanutshell.academy/steve-jobs/

This should work across all tags, fetching all posts with a specific tag (e.g., “andrew-huberman”) and then filtering them under a “popular” channel using the given slug. I will later render them there in there with the “popular” template.

Unfortunately, this configuration doesn’t seem to be working, and it returns empty pages. I think filter does not allow this. When I hard code explicitly

  /andrew-huberman/popular/:
    controller: channel
    template: popular
    filter: tag:[andrew-huberman]

then it works. I’d like to avoid hardcoding specific values for each tag. I have 100 or more tags.

Questions:

  • Is it possible to directly use the value “:slug” in the filter property?
  • If not, what would be the best way to achieve this dynamic filtering based on the URL slug?

I appreciate any guidance on this issue. Thank you in advance for your assistance!

Best regards,
Adi

Complete route file for reference.

routes:
  /vault/:
    template: vault
  /signup/: 
    template: signup
    # data: page.signup # When active data will be taken from the  "/signup/" page
  /signin/: 
    template: signin
    # data: page.signin # When active data will be taken from the  "/signin/" page
  /account/: 
    template: account 
    # data: page.account # When active data will be taken from the  "/account/" page
  /membership/:
    template: membership
    # data: page.membership # When active data will be taken from the  "/membership/" page
  
  # Homepage
  /:
    template: home
  /authors/: 
    template: authors
    # data: page.authors # When active data will be taken from the  "/authors/" page
  /tags/:
    template: tags
    # data: page.tags # When active data will be taken from the  "/tags/" page
  /archive/: 
    controller: channel
    template: archive
    # data: page.archive # When active data will be taken from the  "/archive/" page
  /editors-picks/: 
    controller: channel
    template: editors-picks
    filter: tag:hash-editors-picks
    # data: page.editors-picks # When active data will be taken from the  "/editors-picks/" page

  /:slug/popular/:
    controller: channel
    template: popular
    filter: tag:[{:slug}]


collections:
  /:
    permalink: /{primary_tag}/{slug}/
    template: index

taxonomies:
  tag: /{slug}/