Status code 404 on custom route

I have custom tags route in route.yaml:

routes:
  /tags/:
    template: tags
    data: tag.all

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

taxonomies:
  tag: /tag/{slug}/
  author: /author/{slug}/

I created a tags.hbs at the root level of the template:

{{!< default}}
{{!-- The tag above means - insert everything in this file into the {body} of the default.hbs template --}}
<main id="site-main" class="site-main outer">
<div class="inner posts">
    <div class="post-feed">
Test filler to confirm page working
    </div>
</div>
</main>

Still didnā€™t work. So I broke the syntax in route.yaml to test, and ghost fails to start due to syntax error with route.yaml. Then I undid the syntax error.

Still status code 404 (expected)

I temporarily edited default.hbs to confirm whether I was editing in the right place and the edits to that file are reflected into the html the browser receives.

Why isnā€™t my custom tags page working and itā€™s showing status code 404? I will want it to be dynamic later on. But, for now, I donā€™t handle data.

You might start ghost with ghost run -D, which will cause more verbose logging.

OK. I did as suggested. The only meaningful output is:

INFO "GET /tags/" 404 718ms

Thereā€™s no errors. Thereā€™s no other reference to tags.

Huh. And the tag with slug ā€œallā€ exists? And is applied to at least one published post?

Slug all? That question makes me think Iā€™m doing this all wrong.

I want to get all the tags. I tried tags and didnā€™t work. Thatā€™s why I tried with the .all too

Ah. I see. OK, new plan. Remove the data line entirely. I donā€™t think thereā€™s a way in routes.yaml to pull in data for all tags, but if there is, that isnā€™t it.

Instead, youā€™re going to do something like this in your tags.hbs:

{{#get "tags" limit="all"}}
{{#foreach tags}}
  whatever you want here for each tag, i.e. {{name}}, {{slug}}
{{/foreach}}
{{/get}}

The ā€˜getā€™ pulls the tag data right into your template, and then you can use it. While there are times that the routes.yaml approach can be superior (i.e. if you need pagination), this probably isnā€™t one of them.

OK. That was the solution.

with this testing HTML:

{{!< default}}
{{!-- The tag above means - insert everything in this file into the {body} of the default.hbs template --}}

<main id="site-main" class="site-main outer">
<div class="inner posts">
    <div class="post-feed">
{{#get "tags" limit="all"}}
{{#foreach tags}}
  <p>whatever you want here for each tag, i.e. {{name}}, {{slug}}</p>
{{/foreach}}
{{/get}}

    </div>


</div>
</main>

Itā€™s now listing all tagsā€™ name and slug.

Accoring to the documentation, I can set more metadata that the API returns.

  1. Are all the fields available as regular placeholders? Including ones Iā€™ll most likely not use, such as codeinjection_head
  2. (Itā€™s a bit of a stretch to repurpose this question for this butā€¦) Can use #if if I want to make 3 groups for the tags? based on either a substring of the slug or a substring in the description? This is something Iā€™d like for the near future.

Yes, everything listed is available.

(Pro-tip: If youā€™re ever curious about whatā€™s available, run ghost with ghost run -D and use the {{log}} helper, i.e. {{log posts}} ā€“ that gets you a whole bunch of spammy logging in the Ghost console that can be used for figuring out whatā€™s available, debugging, etc.)

#if is probably not the right choice, because it just checks boolean (true/false or exists/not exists) values. Try #match, or #has.

Substring matching is tough. Itā€™s possible to do something like #match slug.[0] "B" to match all slugs starting with B (and you could /technically/ match multiple characters, but UGH, itā€™d be a snarly mess), but I think an easier approach if you have three groups of tags identified is to do something like:

{{#get "tags" filter="slug:[{{@custom.first_group_tag_slugs}}]" limit="all"}} 

for each of your three groups, and set up a custom variable in the theme to let you maintain your three lists of tags. Or if you anticipate changes being rare, you could hard code them in the theme (filter="slug:[tag-a,tagb,tag-c]").

Actually, another idea that might get you closer to substring matching. Try something like

{{#get "tags" filter="slug:~^recipe"}} 

^^ That should match all tag slugs that start with recipe, like recipe-italian, recipe-dessert, etc. Tag slugs and names donā€™t have to match, so you can have something nicer for the tag names, and ā€˜/tag/recipe-italianā€™ would be a fine url for a grouping of italian recipes anyway.
NQL syntax docs here: Ghost Content API Documentation - thereā€™s a lot more available in NQL (which is used for retrieving content) than in handlebars.

Right the log! I read it and then I forgot it :man_facepalming:

#matchor #has. Got it. For my own notes, I can find these here

Oh! That should handle what Iā€™m planning here. Thank you so much. Thatā€™s all for this subject.

1 Like