I have a project which I'm working on which is going to need something similar to the following URL Structure :

site.com/dfe45c4f/news_title, site.com/gyb66dx/news_title or site.com/76vvg3s/news_title

The First URI Segment is the 'Partner Reference' - a hash value for every partner we work with, the second is a simple entry url title. Every page will show the same data, but each page will be 'branded' differently based on the Partner Reference.

What I need to do is to query a Craft channel a set a variety of variables (styling/logo/branding etc) for the page based on the partner reference.

How would I set routing to look up the first Segment URI to look at the partner section and return all the field information as variables?


  • Ugghhh, can't you do anything about that URL structure? Even something like site.com/p/dfe45c4f/news_title would allow you to easily route it to a template called "p.html" and then perform your logic in there.
    – Ben Croker
    Commented May 6, 2016 at 20:00
  • Yes, I could... would that be a preferred way of doing it then? Or just easier? Commented May 6, 2016 at 20:06
  • see my answer which should hopefully help explain
    – Ben Croker
    Commented May 6, 2016 at 20:22
  • 2
    Rather than considering routing, try an Entry URL Format of something like {{ object.partnerReference }}/{{ slug }} that just points to a template that contains the logic to apply the correct branding changes. Similar example: craftcms.stackexchange.com/questions/13622/… Commented May 6, 2016 at 21:11

3 Answers 3


Go to Settings → Routes, and create a route like this:

enter image description here

Then create that partners/_partner_news_entry.html template. (You can change the location/name of the template if you want; just make sure it matches the “Load this template” setting within your route.)

In that template, you can get the Partner Reference and the entry slug like this:

{% set partnerRef = matches[1] %}
{% set entrySlug = matches[2] %}

I’m not sure how you have it set up, but assuming you have a “Partners” channel with a “Partner Reference” custom field, which stores all of the styling/logo/branding info you need, you can get those relevant entries like this:

{% set partnerEntry = craft.entries({
    section: 'partners',
    partnerReference: partnerRef
}).first() %}

Make sure it’s a valid Partner Reference like this:

{% if not partnerEntry %}
    {% exit 404 %}
{% endif %}

Do the same stuff for the News entry:

{% set newsEntry = craft.entries({
    section: 'news',
    slug: entrySlug
}).first() %}

{% if not newsEntry %}
    {% exit 404 %}
{% endif %}

If there’s an Entries field that actually ties the News entries to a specific partner and you want to ensure that you’re not viewing a News entry that should have only been associated with someone else, you can tweak that like this:

{% set newsEntry = craft.entries({
    section: 'news',
    slug: entrySlug,
    relatedTo: {targetElement: partnerEntry},
}).first() %}

I can't see a solid way of setting up routing to handle all of the possible use cases for your URL structure as it is now.

You could set up a dynamic route to look for URI's that are of the form slug/slug and then route them to a custom template where you can then deal with the logic. But this route is very ambiguous and could easily catch false positives.

In my opinion a better way would be to use an extra URI segment in your dynamic route, for example partner/slug/slug or p/slug/slug for brevity. Then you can be sure that this will load the custom template only in the correct use cases.

Note that the slug in the dynamic route above does not necessarily represent a slug, but any string of characters, except for a forward slash. So you can then do whatever you need to in your custom template.



I had a similar issue, and the way I solved it in Craft CMS 3 was through routes, similar to the answer from Brandon Kelly.

I have the entries location, category and subcategory. These last two without URI (they are just entries without URL).

But I want to display a template when visiting the routes:

// Route for menu, categories and subcategories e.g. paris/menu/after-5pm/salads:


// Route for menu and categories e.g. paris/menu/after-5pm:


So what I did in my config/routes.php was:


return [

    // Route for menu, categories and subcategories e.g. paris/menu/after-5pm/salads
    '<location>/menu/<category>/<subcategory>' => ['template' => 'locations/_menu-entry'],

    // Route for menu and categories e.g. paris/menu/after-5pm
    '<location>/menu/<category>' => ['template' => 'locations/_menu-entry'],


and in my locations/_menu-entry.twig file was:

{% set locationEntry = craft.entries.section('store').slug(location).one()  %}
{% set categoryEntry = craft.entries.section('menuCategory').slug(category).one()  %}
{% set subcategoryEntry = subcategory is defined ? craft.entries.section('menuSubcategories').slug(subcategory).one() : null %}

{% if not locationEntry or not categoryEntry %}
    {% exit 404 %}
{% endif %}

... manipulate entries as needed...

Hope this helps!

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.