Craft makes it straightforward to declare dynamic routes as regular expressions and redirect them to be handled by a template. However, the templates themselves remain dumb handlers. They may optionally be passed on some context in the form of named parameters but they have to do the heavy lifting of building the data set required for rendering the page.

This may not be a problem for pages with one or two variables, like a blog's year and month archives (e.g. blog/2015/01). The template would fetch the list of posts from craft.entries and narrow the range depending on if the year and month variables are set.

But what if the blog also added a category page (e.g. blog/camping)? And what if the category pages supported their own yearly and monthly archive pages (e.g. blog/camping/2014)? We would either end up duplicating the code to fetch posts by creating multiple copies of the archive template, or end up adding the logic to handle category, year, and month filters all in a single template and increasing its overall complexity.

The Router plugin attempts to solve this problem by taking on the job of filtering entries based on URL parameters. It adds a new template variable entries which can be configured to, for the URL blog/2015/01 contain blog posts published in January 2015, or for the URL blog/camping/2014 to show blog posts published in 2014 under the category "Camping".

Usage

In order to create URL rules that automatically build an Entry Query based on the URL, you will need to create a router.php file in your config folder, adjacent to your existing routes.php file.

Example

<?php
/* config/router.php */

return [
  'rules' => [
  
    // URI pattern with named subpatterns
    '<section:blog>' => [
      'segments' => [
        '<year:\d{4}>',
        '<category:{slug}>',
        'in:<location:{slug}>',
      ],
      
      // array of filters that are activated when
      // the key matches a subpattern variable declared in
      // the route's regular expression
      'criteria' => [
        
        // Restrict entries to the selected section
        'section' => [
          'type' => 'section',
        ],
        
        // Filter entries by year
        'year' => [
          'type' => 'year',
          'field' => 'postDate',
        ],
        
        // Filter entries by related category
        // from the category group with the handle 'travel-styles'
        'category' => [
          'type' => 'category',
          'group' => 'travel-styles',
        ],
        
        // Filter entries by related entry
        // from the section with the handle 'locations'
        'category' => [
          'type' => 'entry',
          'section' => 'locations',
        ],
      ],
      
      // template file
      'template' => 'blog/_archive',
    ],
    
  ],
];

Parameters

Each rule expects the following parameters:

  • segments — An array of optional URL segment rules. Example:

      [
        '<year:\d{4}>',
        '<category:{slug}>',  // eg. budget, luxury, cruise, urban
        'in:<location:{slug}>',  // eg. asia, europe, australia
      ]
      /*
        This will match the following URL suffixes
        …/2019
        …/2019/budget
        …/2019/budget/in:asia
        …/2019/in:asia
        …/budget
        …/budget/in:asia
        …/asia
          
        Order is relevant, so it will *not* match the following URLs
        …/budget/2019
        …/in:asia/budget
        …/2019/in:asia/budget
      */
    
  • criteria — An array of filters for the Entry Query. Example:

      [
        'year' => [ 'type' => 'year', 'field' => 'postDate' ],
        'category' => [ 'type' => 'category', 'group' => 'tripCategories' ],
        'location' => [ 'type' => 'entry', 'section' => 'locations' ],
      ]
    
  • template — The template path used to render the request.

A filter is activated when the corresponding trigger key (named parameter) is present in the route. Based on the type of filter, a set of conditions (criteria) are added to an Entry Query object. This is repeated for every activated filter, and the resulting Entry Query is passed on to the template as the entries variable.

Filter Types

The plugin currently supports the following different types of filters:

TypeDescription
categoryAdds a relatedTo criteria to the Category with the given slug, and any of its descendants. The Category’s search can be scoped by specifying a Category Group handle in the optional param group. The relation’s field can be specified using the optional param field. Set the filter’s includeDescendants to false if you do not wish descendant Categories to be included in the relatedTo criteria.
entryAdds a relatedTo criteria to the Entry with the given slug, and any of its descendants. The Entry’s search can be scoped by specifying a Section handle in the optional param section. The relation’s field can be specified using the optional param field. Set the filter’s includeDescendants to false if you do not wish descendant Entries to be included in the relatedTo criteria.
fieldAdds a field criteria to the field specified by handle (required param).
searchAdds a search criteria. Criteria value can be overidden using the optional param value.
sectionAdds a section criteria if the specified Section handle is valid. Section handle value can be overidden using the optional param value.
typeAdds a type criteria if the specified EntryType handle is valid. EntryType handle value can be overidden using the optional param value.
uriAdds a relatedTo criteria to the entry with the given URI, and any of its descendants. The Entry’s search can be scoped by specifying a Section handle in the optional param section. The relation's field can be specified using the optional param field. Set the filter's includeDescendants to false if you do not wish descendant Entries to be included in the relatedTo criteria.
yearAdds a date range criteria for the given year on optional param field (which defaults to postDate).
Installation Instructions

To install this plugin, copy the command above to your terminal.

Active Installs
21
Version
1.4.3
License
MIT
Compatibility
Craft 3, Craft 4
Last release
February 1, 2024
Activity (30 days)
0
Closed Issues
0
Open Issues
0
Merged PRs
0
Open PRs