<p>It's more clear to me now that I've seen the database and extra description from the ticket.</p>

<p>The issue is that you've got an entry that already has has the URI of <code>book</code>.</p>

<p>Normally the code you're trying to use would work, but in <a href="http://buildwithcraft.com/docs/routing" rel="nofollow">resolving a route</a> Craft matches any entry/category requests (Step 4) before it matches any dynamic routes (Step 5). </p>

<p>When you're testing the action URL directly in the browser that works because it hits step 2.</p>

<p>One way to pull off what you're looking for is to give your plugin a <a href="http://buildwithcraft.com/classreference/services/TemplatesService#hook-detail" rel="nofollow">template hook</a>.  Then from the template that loads when <code>book</code> is hit, you can do something like:</p>

<pre><code>{% if craft.request.getSegment(1) == 'book' %}
    {% hook "myAwesomeHook" %}
{% endif %}
</code></pre>

CC BY-SA 3.0
2015-04-14T06:21:53.130Z
So with this approach my plugin's init would call my service method, rather than a controller. Or should I be somehow having my init method calling the controller?
Russ Back
CC BY-SA 3.0
2015-03-24T19:34:40.957Z
2015-03-24T20:04:27.727Z
2015-03-24T20:04:27.727Z
Brad Bell
<p>So I have an entry that has some content displayed in a template.</p>

<p>However ahead of displaying that entry, I want a plugin's action to fire, which pulls some data in from a third party API that will display along with the entry content in the template.</p>

<p>The data from the plugin would need to be available in the template that gets loaded.</p>

<p>What's the best approach to do this?</p>

<p>Here's my routes.php file:</p>

<pre><code>return array(

    'book' =&gt; array(
        'action' =&gt; 'micros/availability/search'
    )

);
</code></pre>

<p>And my plugin:</p>

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

class Micros_AvailabilityController extends BaseController
{

    protected $allowAnonymous = true;

    public function actionSearch()
    {
        Craft::dd('Micros_AvailabilityController-&gt;actionSearch()');
    }
}
</code></pre>

<p>I have an Entry with a slug of 'book' and that loads a template from the templates directory, so what I'm seeing right now is that template, and I don't get the action method running at all.</p>

<p>What I want to do is do something in my action and attach the data to the request and return to whatever template the entry is using.</p>

CC BY-SA 3.0
2015-03-20T18:46:31.917Z
Dupe? https://craftcms.stackexchange.com/questions/953/how-can-i-implement-advanced-action-routes-in-routes-php
Brad Bell
CC BY-SA 3.0
2015-03-20T18:50:23.383Z
I don't think it is? I want it to run on a particular path (for example an entry slug like 'my-page') let the plugin do it's thing and then allow the execution to continue (i.e. load the template for the 'my-page' entry along with the data the plugin provided along the way.
Russ Back
CC BY-SA 3.0
2015-03-20T18:54:46.723Z
Unless I'm missing something, seems exactly the same to me. At the end of your action method, you'd just render the template yourself with any new variables you need:  i.d. `$this->renderTemplate('template/path', $variables);`
Brad Bell
CC BY-SA 3.0
2015-03-20T18:58:46.253Z
OK, perhaps I'm misunderstanding it, or got it wrong. So I want to hook onto 'book' and run an action, however the action isn't getting run (it's fine if I go direct to actions/micros/availability/search: public function registerSiteRoutes()
{
    return array(
        'book' => array('action' => 'micros/availability/search')
    );
}
Russ Back
CC BY-SA 3.0
2015-03-20T18:59:10.433Z
I should add that I have a localised site, so URLs would be en/book, etc
Russ Back
CC BY-SA 3.0
2015-03-20T19:10:24.560Z
Have you allowed anonymous access? http://buildwithcraft.com/docs/plugins/controllers#allowing-anonymous-access-to-actions
Brad Bell
CC BY-SA 3.0
2015-03-20T19:13:22.453Z
Yep - it runs fine when you hit the URL directly in the browser.
Russ Back
CC BY-SA 3.0
2015-03-20T19:15:44.503Z
What are you getting... a 404? Can you share the code you're using in the original question?
Brad Bell
CC BY-SA 3.0
2015-03-20T19:20:16.763Z
I've updated the question with the code. I'm not getting a 404, I'm just getting the entry template when I want to run the action before that loads. I've tried routes.php and also registerSiteRoutes()
Russ Back
CC BY-SA 3.0
2015-03-20T19:52:23.700Z
I just did a test locally identical to yours using both routes.php and registerSiteRoutes() and they both are working as expected.
Brad Bell
CC BY-SA 3.0
2015-03-20T19:54:26.003Z
So your /en/book route dies and dumps on the actionSearch() method of the plugin? Do you have am entry and template setup too so that /en/book routes through to that when the plugin is disabled?
Russ Back
CC BY-SA 3.0
2015-03-20T20:02:45.570Z
Yes, except I'm just using 'book' as in your example. If your actual path is 'en/book', then you'll need to update your code to reflect that.
Brad Bell
CC BY-SA 3.0
2015-03-20T20:05:46.403Z
I've tried both 'book' and 'en/book' but to no avail. How's best to proceed - can I send you a zip of the DB and site root?
Russ Back
CC BY-SA 3.0
2015-03-20T20:48:29.570Z
If it's not on a publicly accessible site, sure. support@buildwithcraft.com
Brad Bell
CC BY-SA 3.0
2015-03-20T22:42:23.720Z
Once you get this sorted, please provide an answer with the resolution. If this thread needs to be closed as a duplicate or a bug report, feel free to do so. Thanks!
Lindsey D
CC BY-SA 3.0
2015-03-24T15:11:31.883Z
I've found that if I have an Entry with the same URI as the route I'm trying to register, Craft shows the Entry rather than firing the plugin action. So I can't achieve what I'm looking to do in my question - that being the need to do something with a plugin action BEFORE the requested Entry is displayed. I've verified this by changing the Entry URI from *book* to *book-test*, at which point my controller action fires. Brad, I'll email you with everything so you can see the setup.
Russ Back
<plugin-development><templating><routes><hook>
How can I fire a controller action for a particular route or entry?
# How can I fire a controller action for a particular route or entry?

(Asked by: username_0 on 2015-03-20)

So I have an entry that has some content displayed in a template.
However ahead of displaying that entry, I want a plugin's action to fire, which pulls some data in from a third party API that will display along with the entry content in the template.
The data from the plugin would need to be available in the template that gets loaded.
What's the best approach to do this?
Here's my routes.php file:
return array(

    'book' => array(
        'action' => 'micros/availability/search'
    )

);

And my plugin:
actionSearch()');
    }
}

I have an Entry with a slug of 'book' and that loads a template from the templates directory, so what I'm seeing right now is that template, and I don't get the action method running at all.
What I want to do is do something in my action and attach the data to the request and return to whatever template the entry is using.

**Tags:** plugin-development, templating, routes, hook

> **Comments:**
> **username_1**: Dupe? https://craftcms.stackexchange.com/questions/953/how-can-i-implement-advanced-action-routes-in-routes-php  
> **username_0**: I don't think it is? I want it to run on a particular path (for example an entry slug like 'my-page') let the plugin do it's thing and then allow the execution to continue (i.e. load the template for the 'my-page' entry along with the data the plugin provided along the way.  
> **username_1**: Unless I'm missing something, seems exactly the same to me. At the end of your action method, you'd just render the template yourself with any new variables you need:  i.d. `$this->renderTemplate('template/path', $variables);`  
> **username_0**: OK, perhaps I'm misunderstanding it, or got it wrong. So I want to hook onto 'book' and run an action, however the action isn't getting run (it's fine if I go direct to actions/micros/availability/search: public function registerSiteRoutes() {     return array(         'book' => array('action' => 'micros/availability/search')     ); }  
> **username_0**: I should add that I have a localised site, so URLs would be en/book, etc  
> **username_1**: Have you allowed anonymous access? http://buildwithcraft.com/docs/plugins/controllers#allowing-anonymous-access-to-actions  
> **username_0**: Yep - it runs fine when you hit the URL directly in the browser.  
> **username_1**: What are you getting... a 404? Can you share the code you're using in the original question?  
> **username_0**: I've updated the question with the code. I'm not getting a 404, I'm just getting the entry template when I want to run the action before that loads. I've tried routes.php and also registerSiteRoutes()  
> **username_1**: I just did a test locally identical to yours using both routes.php and registerSiteRoutes() and they both are working as expected.  
> **username_0**: So your /en/book route dies and dumps on the actionSearch() method of the plugin? Do you have am entry and template setup too so that /en/book routes through to that when the plugin is disabled?  
> **username_1**: Yes, except I'm just using 'book' as in your example. If your actual path is 'en/book', then you'll need to update your code to reflect that.  
> **username_0**: I've tried both 'book' and 'en/book' but to no avail. How's best to proceed - can I send you a zip of the DB and site root?  
> **username_1**: If it's not on a publicly accessible site, sure. support@buildwithcraft.com  
> **username_2**: Once you get this sorted, please provide an answer with the resolution. If this thread needs to be closed as a duplicate or a bug report, feel free to do so. Thanks!  
> **username_0**: I've found that if I have an Entry with the same URI as the route I'm trying to register, Craft shows the Entry rather than firing the plugin action. So I can't achieve what I'm looking to do in my question - that being the need to do something with a plugin action BEFORE the requested Entry is displayed. I've verified this by changing the Entry URI from *book* to *book-test*, at which point my controller action fires. Brad, I'll email you with everything so you can see the setup.  

---

## 1 answers

### Answer by username_1 on 2015-03-24. Score: 1

It's more clear to me now that I've seen the database and extra description from the ticket.
The issue is that you've got an entry that already has has the URI of book.
Normally the code you're trying to use would work, but in resolving a route Craft matches any entry/category requests (Step 4) before it matches any dynamic routes (Step 5). 
When you're testing the action URL directly in the browser that works because it hits step 2.
One way to pull off what you're looking for is to give your plugin a template hook.  Then from the template that loads when book is hit, you can do something like:
{% if craft.request.getSegment(1) == 'book' %}
    {% hook "myAwesomeHook" %}
{% endif %}

> **Comments:**
> **username_0**: So with this approach my plugin's init would call my service method, rather than a controller. Or should I be somehow having my init method calling the controller?  

---

