<p>Surprisingly, the Craft docs aren't super clear on this so I'll post a little info.</p>
<p>When you set up a Section in the Control Panel, you set the <strong>URI Format</strong> and <strong>Template</strong> fields to map to an entry template.</p>
<p>When you hit a route that matches that URI Format, Craft queries for the entry that matches the route, then it automagically injects a Twig variable named <code>entry</code> into that template for you. (If it doesn't find one, it throws a 404 Not Found exception.)</p>
<p>The same is true for Categories. You can set up a Category with a <strong>URI Format</strong> and <strong>Template</strong> to map to a category template. In those templates you'll have a Twig variable named <code>category</code>.</p>
<p>Sometimes, however, you might find yourself in an unfortunate situation where an included/embedded template or a macro doesn't have the current <code>entry</code> variable in its context. In that case, you can do something like this:</p>
<pre><code>{% set entry = craft.app.getUrlManager().getMatchedElement() %}
</code></pre>
<p>See this answer for caveats: <a href="https://craftcms.stackexchange.com/questions/1715/how-can-i-get-the-requested-entry-from-a-plugin">How can I get the requested entry from a plugin?</a></p>
<p>These three blocks of code should render the same thing:</p>
<pre><code>{# This is the way #}
&lt;h1&gt;{{ entry.title }}&lt;h1&gt;
</code></pre>
<pre><code>{# This makes an extra database query #}
{% set uri = craft.app.request.fullUri %}
{% set recipe = craft.entries().type('recipes').uri(uri).one() %}
&lt;h1&gt;{{ recipe.title }}&lt;/h1&gt;
</code></pre>
<pre><code>{# Only if you need to. Doesn't make an extra database query #}
{% set recipe = craft.app.getUrlManager().getMatchedElement() %}
&lt;h1&gt;{{ recipe.title }}&lt;/h1&gt;
</code></pre>
<p>I hope that helps!</p>
<p>Edit:</p>
<p>Can routes collide?</p>
<p>Craft will not let you save an element with a duplicate slug, so for Element routes, there can only be one ⚔️</p>
<p>You can, however, define custom routes in places like the <code>/config/routes.php</code> file or in the Control Panel under Settings -&gt; Routes that might match an Element route. In that case, the Element Route wins.</p>
<p>The Craft docs show the order of precedence: <a href="https://craftcms.com/docs/3.x/routing.html" rel="nofollow noreferrer">https://craftcms.com/docs/3.x/routing.html</a></p>

CC BY-SA 4.0
2021-10-26T18:33:05.667Z
Thanks Sam for the helpful info...followup question, and if you know the answer, maybe you can expand your answer - What happens if two entries match a uri route? Which gets injected into the entry variable? I don't know of many good use cases for this, but it seems that it is quite possible thanks to the flexibility of craft, and it's conceivable it could be useful if the behavior is predictable.
Augustine Calvino
CC BY-SA 4.0
2021-10-27T22:29:25.583Z
ah, that's a good observation. Will update.
Sam Hernandez
CC BY-SA 4.0
2021-10-24T04:07:40.090Z
2021-10-27T22:43:56.550Z
2021-10-27T22:43:56.550Z
Sam Hernandez
<p>If I am visiting <code>/recipes/spaghetti</code> which corresponds to an entry in a <code>recipes</code> entry type and the <code>recipes/entry</code> template, is there a way to directly get the current entry's data from within the template? Here's what I have, and it works, but I feel like there might be a better way. Basically, since the entry is already associated to the route, I'm wondering if there is a shortcut to access the entry's data.</p>
<pre><code>{% set uri = craft.app.request.fullUri %}
{% set recipe = craft.entries().type('recipes').uri(uri).one() %}
</code></pre>

CC BY-SA 4.0
2021-10-24T00:10:23.207Z
What does this Entry's Section settings look like? Craft should be automatically generating URIs and mapping them to a template based on that config—no need to look them up manually, unless you're trying to access them outside that scheme. In short, you may already have access to `entry` in this context!
August Miller
CC BY-SA 4.0
2021-10-24T01:44:34.807Z
The uri is mapped to a template - I get that part. I want to be able to access the field data from the entry - that's what the queries I set up do. I am just wondering if there is a less roundabout way of getting that data.
Augustine Calvino
CC BY-SA 4.0
2021-10-24T02:41:53.900Z
Ok, perfect! You don’t need to do the lookup manually—Craft injects the current Entry/Element as `entry` in your template, along with all the field data you’d expect. 
August Miller
CC BY-SA 4.0
2021-10-24T03:44:31.477Z
Oh, wonderful! It works for me, but strangely doesn't seem to be documented on the Entries page: https://craftcms.com/docs/3.x/entries.html.

Could you add an answer with that info, along with a link to documentation if there is one?
Augustine Calvino
CC BY-SA 4.0
2021-10-24T03:49:04.387Z
It's true, I just looked through the docs, and they aren't clear on this.
Sam Hernandez
CC BY-SA 4.0
2021-10-24T04:07:36.213Z
Just made a PR to the docs, so hopefully that will be changed soon.
Augustine Calvino
<templating><routes><entry-type><best-practice>
Get entry associated with current uri
# Get entry associated with current uri

(Asked by: username_0 on 2021-10-23)

If I am visiting /recipes/spaghetti which corresponds to an entry in a recipes entry type and the recipes/entry template, is there a way to directly get the current entry's data from within the template? Here's what I have, and it works, but I feel like there might be a better way. Basically, since the entry is already associated to the route, I'm wondering if there is a shortcut to access the entry's data.
{% set uri = craft.app.request.fullUri %}
{% set recipe = craft.entries().type('recipes').uri(uri).one() %}

**Tags:** templating, routes, entry-type, best-practice

> **Comments:**
> **username_1**: What does this Entry's Section settings look like? Craft should be automatically generating URIs and mapping them to a template based on that config—no need to look them up manually, unless you're trying to access them outside that scheme. In short, you may already have access to `entry` in this context!  
> **username_0**: The uri is mapped to a template - I get that part. I want to be able to access the field data from the entry - that's what the queries I set up do. I am just wondering if there is a less roundabout way of getting that data.  
> **username_1**: Ok, perfect! You don’t need to do the lookup manually—Craft injects the current Entry/Element as `entry` in your template, along with all the field data you’d expect.   
> **username_0**: Oh, wonderful! It works for me, but strangely doesn't seem to be documented on the Entries page: https://craftcms.com/docs/3.x/entries.html.  Could you add an answer with that info, along with a link to documentation if there is one?  
> **username_2**: It's true, I just looked through the docs, and they aren't clear on this.  
> **username_0**: Just made a PR to the docs, so hopefully that will be changed soon.  

---

## 1 answers

### Answer by username_2 on 2021-10-24. Score: 7 | Accepted answer

Surprisingly, the Craft docs aren't super clear on this so I'll post a little info.
When you set up a Section in the Control Panel, you set the URI Format and Template fields to map to an entry template.
When you hit a route that matches that URI Format, Craft queries for the entry that matches the route, then it automagically injects a Twig variable named entry into that template for you. (If it doesn't find one, it throws a 404 Not Found exception.)
The same is true for Categories. You can set up a Category with a URI Format and Template to map to a category template. In those templates you'll have a Twig variable named category.
Sometimes, however, you might find yourself in an unfortunate situation where an included/embedded template or a macro doesn't have the current entry variable in its context. In that case, you can do something like this:
{% set entry = craft.app.getUrlManager().getMatchedElement() %}

See this answer for caveats: How can I get the requested entry from a plugin?
These three blocks of code should render the same thing:
{# This is the way #}
{{ entry.title }}

{# This makes an extra database query #}
{% set uri = craft.app.request.fullUri %}
{% set recipe = craft.entries().type('recipes').uri(uri).one() %}
{{ recipe.title }}

{# Only if you need to. Doesn't make an extra database query #}
{% set recipe = craft.app.getUrlManager().getMatchedElement() %}
{{ recipe.title }}

I hope that helps!
Edit:
Can routes collide?
Craft will not let you save an element with a duplicate slug, so for Element routes, there can only be one ⚔️
You can, however, define custom routes in places like the /config/routes.php file or in the Control Panel under Settings -> Routes that might match an Element route. In that case, the Element Route wins.
The Craft docs show the order of precedence: https://craftcms.com/docs/3.x/routing.html

> **Comments:**
> **username_0**: Thanks Sam for the helpful info...followup question, and if you know the answer, maybe you can expand your answer - What happens if two entries match a uri route? Which gets injected into the entry variable? I don't know of many good use cases for this, but it seems that it is quite possible thanks to the flexibility of craft, and it's conceivable it could be useful if the behavior is predictable.  
> **username_2**: ah, that's a good observation. Will update.  

---

