<p>Using template variables in URL formats is brilliant, but if you don't want to write your own plugin, you could use the fantastic <a href="https://github.com/aelvan/Preparse-Field-Craft" rel="nofollow">Preparse</a> plugin as well.</p>

<p>First, create a Preparse field that contains the following Twig code, and add the field to your entry type's field layout:</p>

<pre><code>{% spaceless %}
    {{ craft.entries({
        relatedTo: {
            targetElement: entry,
            field: 'productConfigs'
        }
    }).first().uri|default('') }}
{% endspaceless %}
</code></pre>

<p>Then, add the following to your URL format setting (<code>preparseFieldHandle</code> should be the handle for your Preparse field, obviously):</p>

<pre><code>{{object.preparseFieldHandle ? object.preparseFieldHandle ~ '/'}}{slug}    
</code></pre>

<p>Note that any existing entries in the relevant section would have to be re-saved in order to have the Preparse field actually parse.</p>

CC BY-SA 3.0
2016-08-05T19:30:23.380Z
2016-08-05T19:30:23.380Z
Mats Mikkel Rummelhoff
<p>I'm not sure this is the best answer, but since others can post answers too:</p>

<p>One solution to this may be to disable the Section setting <em>Entries in this section have their own URLs</em> and manage your URLs manually using a custom route and the appropriate template logic. </p>

CC BY-SA 3.0
2016-08-05T06:54:55.033Z
By disabling that setting you also disable live preview.
carlcs
CC BY-SA 3.0
2016-08-05T14:53:34.973Z
Good point. It would be possible to have URLs enabled for Live Preview and route things differently on the front-end. Not saying this is ideal. It always feels wrong when you have URLs enabled just for Live Preview or in a situation where the CP and front-end URLs need to be different.
Ben Parizek
CC BY-SA 3.0
2016-08-05T00:35:09.180Z
2016-08-05T00:35:09.180Z
Ben Parizek
<p>It's not documented so I guess not officially supported, but you can use template variables in the URL formats. For example if you had a <code>UrlFormats</code> plugin, you could use something like this:</p>

<pre><code>&lt;?php
namespace Craft;

class UrlFormatsVariable
{
    // Use in the URL Format box:
    // 
    //  {{ craft.urlFormats.yourSectionHandle(object) }}
    public function yourSectionHandle($entry)
    {
        // Craft checks the URL format with an array "object" first, to see if there's a {slug},
        // and so whether it should be checked for uniqueness and incremented if necessary.
        if (!$entry || !($entry instanceof EntryModel))
        {
            return '{slug}';
        }

        $relation = craft()-&gt;elements-&gt;getCriteria(ElementType::Entry)
            -&gt;relatedTo(array(
                'targetElement' =&gt; $entry,
                'field'         =&gt; 'productConfigs',
            ))-&gt;first();

        if (!$relation)
        {
            // throw an exception or default to something
        }

        return $relation-&gt;uri.'/'.$entry-&gt;slug;
    }
}
</code></pre>

<p>Then you can keep your URL Format and Nested URL Format inputs cleaner:</p>

<pre><code>{{ craft.urlFormats.yourSectionHandle(object) }}
</code></pre>

CC BY-SA 3.0
2016-08-09T19:52:03.730Z
returning '{slug}' didn't work for me. I would end up with an error message like "URI "{slug}" has already been taken."

Instead, this seems to do the trick: `{{ craft.urlFormats.yourSectionHandle(object)|default(object.slug) }}`
Tim Kelty
CC BY-SA 4.0
2023-02-27T03:44:41.603Z
This is great - very handy if you want to get a little more complex with titles.  The twig mini templates are tricky/limited, but with this you can do basically anything.  Thanks!
Jeremy Daalder
CC BY-SA 3.0
2016-08-05T11:16:55.290Z
2016-08-05T11:16:55.290Z
Mike Pepper
<p>This works:</p>

<pre><code>{{ craft.entries.section('products').relatedTo(object).first.uri }}/{slug}
</code></pre>

<p>However, in this case, I need to use the extended <code>relatedTo</code> property, which includes curly braces:</p>

<pre><code>{{ craft.entries({relatedTo: {targetElement: object, field: 'productConfigs'}}).first.uri }}/{{ object.slug }}
</code></pre>

<p>Because of the way <code>renderObjectTemplate</code> replacement <a href="https://craftcms.com/docs/sections-and-entries#dynamic-entry-titles" rel="nofollow">seems to happen</a>, the braces get screwed up.</p>

<p>Any way to work around this?</p>

<p>I'd actually rather do this in PHP/plugin if possible, but I'm not sure if a relevant hook/event exists.</p>

<plugin-development><entries>
Trouble with curly braces in Entry URL Format / renderObjectTemplate
# Trouble with curly braces in Entry URL Format / renderObjectTemplate

(Asked by: username_0 on 2016-08-05)

This works:
{{ craft.entries.section('products').relatedTo(object).first.uri }}/{slug}

However, in this case, I need to use the extended relatedTo property, which includes curly braces:
{{ craft.entries({relatedTo: {targetElement: object, field: 'productConfigs'}}).first.uri }}/{{ object.slug }}

Because of the way renderObjectTemplate replacement seems to happen, the braces get screwed up.
Any way to work around this?
I'd actually rather do this in PHP/plugin if possible, but I'm not sure if a relevant hook/event exists.

**Tags:** plugin-development, entries


---

## 3 answers

### Answer by username_4 on 2016-08-05. Score: 7 | Accepted answer

It's not documented so I guess not officially supported, but you can use template variables in the URL formats. For example if you had a UrlFormats plugin, you could use something like this:
elements->getCriteria(ElementType::Entry)
            ->relatedTo(array(
                'targetElement' => $entry,
                'field'         => 'productConfigs',
            ))->first();

        if (!$relation)
        {
            // throw an exception or default to something
        }

        return $relation->uri.'/'.$entry->slug;
    }
}

Then you can keep your URL Format and Nested URL Format inputs cleaner:
{{ craft.urlFormats.yourSectionHandle(object) }}

> **Comments:**
> **username_0**: returning '{slug}' didn't work for me. I would end up with an error message like "URI "{slug}" has already been taken."  Instead, this seems to do the trick: `{{ craft.urlFormats.yourSectionHandle(object)|default(object.slug) }}`  
> **username_5**: This is great - very handy if you want to get a little more complex with titles.  The twig mini templates are tricky/limited, but with this you can do basically anything.  Thanks!  

---

### Answer by username_1 on 2016-08-05. Score: 3

Using template variables in URL formats is brilliant, but if you don't want to write your own plugin, you could use the fantastic Preparse plugin as well.
First, create a Preparse field that contains the following Twig code, and add the field to your entry type's field layout:
{% spaceless %}
    {{ craft.entries({
        relatedTo: {
            targetElement: entry,
            field: 'productConfigs'
        }
    }).first().uri|default('') }}
{% endspaceless %}

Then, add the following to your URL format setting (preparseFieldHandle should be the handle for your Preparse field, obviously):
{{object.preparseFieldHandle ? object.preparseFieldHandle ~ '/'}}{slug}    

Note that any existing entries in the relevant section would have to be re-saved in order to have the Preparse field actually parse.


---

### Answer by username_2 on 2016-08-05. Score: 2

I'm not sure this is the best answer, but since others can post answers too:

One solution to this may be to disable the Section setting *Entries in this section have their own URLs* and manage your URLs manually using a custom route and the appropriate template logic.

> **Comments:**
> **username_3**: By disabling that setting you also disable live preview.  
> **username_2**: Good point. It would be possible to have URLs enabled for Live Preview and route things differently on the front-end. Not saying this is ideal. It always feels wrong when you have URLs enabled just for Live Preview or in a situation where the CP and front-end URLs need to be different.  

---

