I have a template route like the following:

/{static_country:regex[(zh|cn|usa)]}/{alpha_dash} which matches a URI like website.com/usa/about-us fine and points to my template I've called static - this works fine.

However, when I navigate to something like website.com/usa/sdfsdfsdfsd which is a fake route and isn't a route matching an entry in my channel, it still points to the first entry in the static channel instead of throwing a 404.

I know I can limit this using regex like /{static_country:regex[(zh|cn|usa)]}/{static_page:regex[(about-us)]} but that isn't very dynamic if the client adds their own pages as we'd have to update the regex each time.

Is there a way around this at all?

  • First of all, isn't there an extra |? Shouldn't be zh|cb|usa?
    – Sobral
    Sep 7, 2016 at 12:58
  • @RobsonSobral Removed that now Sep 7, 2016 at 13:33

1 Answer 1



First things first: the documentation does not say it, but isn't advisable to use a route on the first segment. Why? I've no idea. This is something a former EllisLab developer told me.

loading the entry

The Template Routes mess up with the automatic discovery of entries. From the docs:

Template Routes overrides the default behavior of URLs, if you wish to use a Channel Entries Tag in your template you must manually provide segments for any parameters that are normally set in the URL. You must provide a segment for pagination, categories, and entry titles if you wish to use those in your Channel Entries Tag. Additionally, be careful when using dynamic="yes" with Template Routes, this can cause issues if your route does not have an appropriate segment set.

So, you need to deal with everything by yourself. Use the dynamic, the require_entry and the url_title parameters together with the no_results conditional.

Also, let's give your entry segment a name: /{static_country:regex[(zh|cn|usa)]}/{entry:alpha_dash}

{exp:channel:entries channel="static" limit="1" dynamic="no" require_entry="yes" url_title="{segment:entry}"}
    {if no_results}{redirect="404"}{/if}

Require all segments

If you need to set Require All Variables to no, its default, you also need to prevent something like to match the second segment without the first one.

{if segment:static_country == ""}{redirect="404"}{/if}

And you need to prevent the exp:channel:entries from trying to look for an unparsed {segment:entry}. Putting everything together:

{if segment:static_country == ""}
{if:elseif segment:entry == ""}
    {exp:channel:entries channel="static" limit="1" dynamic="no" require_entry="yes" url_title="{segment:entry}"}
        {if no_results}{redirect="404"}{/if}

Or, you can just enable the "Require all segments" setting.

Without routes

Or you can create one index.php file for every language:

    |- /index.php
    |- /zh
        |- /index.php

    |- /cn
        |- /index.php

    |- /usa
        |- /index.php

On every index.php, you can set variables related to the language they load

$assign_to_config['global_vars'] = array(); // This array must be associative

$assign_to_config['global_vars']['cv-language_code'] = "zh";
$assign_to_config['site_url'] = '/'.$assign_to_config['global_vars']['cv-language_code'];
  • Oooo nice, I'll try this now. Luckily this route doesn't require pagination however I have done it on the other routes I'm working with. I'll get back to you in a second. Sep 7, 2016 at 13:51
  • Hey Robson, this looks like it works for the most part. However, website.com/usa/about-us returns the correct page but website.com/about-us throws an error (but doesn't redirect to the 404) Sep 7, 2016 at 14:35
  • Let's try to fix it!
    – Sobral
    Sep 7, 2016 at 14:48
  • I'm not sure what to do website.com/about-us needs to point the to static template like website.com/usa/about-us does. At the moment it just completely fails. I can't require all segments because without the static_country its meant to load the default UK site Sep 7, 2016 at 14:52
  • 1
    One last option? I hope it helps!
    – Sobral
    Sep 7, 2016 at 17:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.