Using a custom route and preserving title, meta data etc

Note: I think that I've actually solved this issue so rather than asking for help on how to do the above I'm really asking whether or not the way I've done is is likely to cause any unforeseen issues or not as I'm not completely sure I understand how it's working the way that I've done it.

My use case is that I need to support the following URL structure from an existing site I'm thinking about migrating to Statamic:

/blogs                       <-- display all blogs in collection
/blogs/category              <-- display all blogs belonging to a category
/blogs/category/article      <-- display a blog post
  • I have the blogs collection mounted onto a page in the pages collection with a slug of blogs.

  • Each blogs entry can have a maximum of one categories taxonomy term.

  • blogs is a collection with a route of {mounted}/{categories}/{slug} and categories is a taxonomy where each term is the name of a category.

The /blogs and /blogs/category/article URLs obviously work properly with the default Statamic magic doing it's thing.

However, if I want to show the entries in a particular category, I would have to use the /category/term URL which breaks the URL pattern that I need to support from the old CMS. And I obviously can't change the name of the taxonomy to blogs to take advantage of /blogs/term URLs because that would clash with the fact that blogs is the slug of the blogs page which the blogs collection is mounted to.

The first thing I did to try and solve this issue was set up a custom route as so:

Route::statamic('blogs/{category}', 'blogs.category');

This works ok to a certain extent, with the following in the template:

{{ taxonomy:categories slug:is=category }}
    <h1>{{ title }}</h1>
    <p>{{ content }}</p>
{{ /taxonomy:categories }}

{{ collection:blogs categories:is=category paginate="5" }}
    <p><a href="{{ url }}">{{ title }}</a></p>
{{ /collection }}

That displays the title and content fields from the taxonomy term (the category) which is what I need, and it also displays a list of blogs collection entries that have the relevant category.

However, the big problem with this is that things like title (ie: the title of the taxomomy term, the category name) do not get sent up to the layout. And as I also plan to use the SEO Pro add-on with this site, it would also mean that none of the SEO meta data for the taxomony terms (the category names) is getting sent to the layout either. I can hardcode stuff in the YAML Front Matter but that's once per template, not once per taxonomy term / category.

So, I ended up creating a Laravel-style custom route and then using Statamic Facades to get what I wanted.

This is the custom route:

Route::get('blogs/{category}', function($category) {

    if ($term = \Statamic\Facades\Term::findBySlug($category,'categories')) {
        return $term;

    throw new \Statamic\Exceptions\NotFoundHttpException;


And this is the template:

<h1>{{ title }}</h1>
<p>{{ content }}</p>

{{ entries paginate="5" }}
    {{ results }}
        <p><a href="{{ url }}">{{ title }}</a></p>
    {{ /results }}
{{ /entries }}

As I said at the beginning of this post, this seems to work and I can now support my custom URL structure and get title and meta data from the entry, taxonomy and SEO Pro add-on sent back to the layout. I'm just not 100% sure whether or not the way I've done it is considered "correct" or not? I kinda figured it out by looking over code in the Statamic vendor directory but I don't really understand how or why returning a \Statamic\Facades\Term::findBySlug() in a regular Laravel route is actually resulting in the page being rendered by Statamic and whether this is likely to carry on working between 3.x updates or not?

Any insight into this, as well of suggestions on better ways to achieve the same thing are very much appreciated!

>>>>>>> Unanswered <<<<<<<
0 Replies
1 Follower