<p>I believe that when you post data using <code>name='action'</code> from a form that craft automatically uses the <code>actionUrl</code> to route the request properly, so that if your controller is here:</p>

<pre><code>/craft/plugins/broadbean/controllers/Broadbean_JobsController.php
</code></pre>

<p>with a method <code>actionNew</code>, then craft will create the action route <code>broadbean/jobs/new</code> automatically:</p>

<pre><code>&lt;input type="hidden" name="action" value="broadbean/jobs/new"&gt;
</code></pre>

<p>On the other hand if you are linking directly then craft doesn't know to use the action route, so you need to explicitly tell it that this is an action request:</p>

<pre><code>&lt;a href="{{ actionUrl('broadbean/jobs/new', { id: 10 }) }}"&gt;
</code></pre>

<p>or from javascript:</p>

<pre><code>var url = Craft.getActionUrl('broadbean/jobs/new', { id: 10 });
</code></pre>

<p>If you were to call the action externally then you would have to write the full action url without the benefit of using the automatic config routing:</p>

<pre><code>http://mysite.com/actions/broadbean/jobs/new?id=10
</code></pre>

<p>or, if the admin had, for example, set up a custom actionUrl in the config file:</p>

<pre><code>http://mysite.com/methods/broadbean/jobs/new?id=10
</code></pre>

CC BY-SA 3.0
2014-11-07T15:56:52.427Z
Thanks, that makes sense. How can I remove /admin from the route? For example the action "broadbean/jobs/new" works when you post a form from within the admin panel, but it only works from a frontend template with the action "admin/broadbean/jobs/new". I have this in registerCpRoutes(): "'broadbean/jobs/new' => array('action' => 'broadbean/jobs/new')"
Russ Back
CC BY-SA 3.0
2014-11-07T16:03:02.577Z
That's why I was confused. I have never seen 'admin' as being part of any url unless it is related to the admin interface, or unless you were trying to bypass the built in routing. I don't know to be honest. I would start by removing that cpRoute as it's not really doing anything.
Douglas McDonald
CC BY-SA 3.0
2014-11-07T16:12:21.587Z
Trouble is, if I remove that, neither route works!
Russ Back
CC BY-SA 3.0
2014-11-07T16:38:21.930Z
Strange... if you print out the url using `{{ actionUrl('broadbean/jobs/new' }}` and test that that works, then `<input type="hidden" name="action" value="broadbean/jobs/new">` should be posting to the same place, because its using the same method to derive the url. Is it possible that you have some condition in your plugin that is rejecting the request? Or perhaps a custom actionUrl defined in your config file? (i.e. `'actionTrigger' => 'actions',`)
Douglas McDonald
CC BY-SA 3.0
2014-11-07T16:55:22.027Z
Ah wait... I reread your post. It sounds like you are posting from with the CP. If that's the case then craft may add `admin` to the front of the uri, to indicate its a CP request (I'm guessing here). But you shouldn't have to explicitly set that anywhere.
Douglas McDonald
CC BY-SA 3.0
2014-11-07T17:00:26.890Z
Do you have anything like this in your plugin? `if (craft()->request->isSiteRequest()) {throw new HttpException(404); }`
Douglas McDonald
CC BY-SA 3.0
2014-11-07T17:05:25.060Z
Well initially I was testing just from a form within a CP page, but now I'm putting the form on a template OUTSIDE of the admin panel and that's where I see the difference - OUTSIDE of the admin panel I need to add /admin to the URL
Russ Back
CC BY-SA 3.0
2014-11-07T17:10:15.570Z
And no, I don't have isSiteRequest() in there at all.
Russ Back
CC BY-SA 3.0
2014-11-07T15:32:54.050Z
2014-11-07T15:47:39.640Z
2014-11-07T15:47:39.640Z
Douglas McDonald
<p>You may need to set up a route using this Hook Reference from the plugin docs:</p>

<p><a href="http://buildwithcraft.com/docs/plugins/hooks-reference#registerCpRoutes" rel="nofollow">http://buildwithcraft.com/docs/plugins/hooks-reference#registerCpRoutes</a></p>

<pre><code>function registerCpRoutes()
    {
        return array(
        'cocktails/new'               =&gt; 'cocktails/_edit',
        'cocktails/(?P&lt;widgetId&gt;\d+)' =&gt; array('action' =&gt; 'cocktails/editCocktail'),
    );
}
</code></pre>

CC BY-SA 3.0
2014-11-07T10:47:04.723Z
Tried that, no change.
Russ Back
CC BY-SA 3.0
2014-11-07T10:04:26.503Z
2014-11-07T10:04:26.503Z
darylknight
<p>I have a simple plugin that's expected POST data from a form:</p>
<pre><code>&lt;form method=&quot;post&quot; action=&quot;&quot; accept-charset=&quot;UTF-8&quot;&gt;
    &lt;input type=&quot;hidden&quot; name=&quot;action&quot; value=&quot;{{ actionUrl('broadbean/jobs/new') }}&quot;&gt;
</code></pre>
<p>When I submit the form, that fails:</p>
<blockquote>
<p>Page Not Found</p>
<p>Unable to resolve the request &quot;http:/craft.dev/index.php/admin/actions/broadbean/jobs/new&quot;.</p>
</blockquote>
<p>If I cut and paste that URL into a new window, I get the plugin response, so what gives here? The plugin is set up to allow anonymous access (but I'm submitting the form from within an admin view anyway).</p>
<p><strong>EDIT:</strong></p>
<p>According to <a href="http://buildwithcraft.com/docs/plugins/controllers#posting-to-controller-actions" rel="nofollow noreferrer">http://buildwithcraft.com/docs/plugins/controllers#posting-to-controller-actions</a> I should be able to put the action URL in a hidden field, which I've done. If I dispense with that and instead put the actionUrl() directly in the form's action parameter, everything works.</p>
<p>Is this a bug? This is on Craft 2.2.2601.</p>
<p><strong>EDIT:</strong></p>
<p>Controller code:</p>
<pre><code>class Broadbean_JobsController extends BaseController
{
    protected $allowAnonymous = true;

    public function actionNew()
    {    
        $this-&gt;requirePostRequest();

        $result = craft()-&gt;broadbean_jobs-&gt;createJob();
        
        var_dump(array(
            'message' =&gt; ($result['success']) ? Craft::t('Job created.') : Craft::t('Unable to create job.'),
            'values' =&gt; craft()-&gt;request-&gt;getPost(),
            'errors' =&gt; $result['errors']
        ));

    }
}
</code></pre>

CC BY-SA 3.0
2014-11-07T08:48:47.633Z
Have you tried removing the action attribute from your form tag?
Josh Angell
CC BY-SA 3.0
2014-11-07T09:15:52.623Z
Yep - no change.
Russ Back
CC BY-SA 3.0
2014-11-07T09:18:47.603Z
Ok - another stab in the dark here - but is your plugin class camel cased? I.e. is it BroadBeanPlugin or BroadbeanPlugin? If its the former then your action url might need to be `broadBean/jobs/new`.
Josh Angell
CC BY-SA 3.0
2014-11-07T09:47:01.120Z
Could be that you need a route set up?
darylknight
CC BY-SA 3.0
2014-11-07T10:00:01.523Z
@JoshAngell The class is BroadbeanPlugin. The action URL is correct: as I said it works if you put it in the form action and hit it directly in a browser. It doesn't work if it's in an input with the name of 'action'.
Russ Back
CC BY-SA 3.0
2014-11-07T10:01:01.193Z
@DarylKnight same comment as above - it works as is but perhaps that's needed. Where/how would I do that?
Russ Back
CC BY-SA 3.0
2014-11-07T10:03:48.783Z
@RussBack hang on I've just noticed in your error message that there is a slash missing in the `http://` part - it is showing `http:/`. Maybe check your `siteUrl` setting - either in the cp or [config](http://buildwithcraft.com/docs/config-settings#siteUrl)
Josh Angell
CC BY-SA 3.0
2014-11-07T10:05:08.450Z
Posted link to Hooks Reference as an answer
darylknight
CC BY-SA 3.0
2014-11-07T10:05:15.790Z
I've always just used the uri directly without the wrapper, like so: `<input type="hidden" name="action" value="broadbean/jobs/new">` I'm not sure what `actionUrl` does.
Douglas McDonald
CC BY-SA 3.0
2014-11-07T10:32:56.933Z
@JoshAngell yes I noticed that too. However that only shows itself in the error message Craft displays - the URL is correct in config and outputs correctly via Twig's actionUrl() method.
Russ Back
CC BY-SA 3.0
2014-11-07T10:34:26.087Z
@RussBack Nnnngg. This is very weird! Maybe post your controller code? I'm out of other ideas - particularly as I've got plenty of controller actions working fine right now in various Craft versions.
Josh Angell
CC BY-SA 3.0
2014-11-07T10:35:08.087Z
@DouglasMcDonald actionUrl() is recommended so that you don't get tripped up by expecting /admin/actions/broadbean/jobs/new if a user has changed their config to say /admin/methods/broadbean/jobs/new
Russ Back
CC BY-SA 3.0
2014-11-07T10:39:46.773Z
@JoshAngell, controller code added to the original post
Russ Back
CC BY-SA 3.0
2014-11-07T15:05:43.077Z
I'm totally confused. Isn't this a plugin? I would expect the controller to be here: `/craft/plugins/broadbean/controllers/Broadbean_JobsController.php`, and craft would automatically create the action route `broadbean/jobs/new'. Are you using a different pattern?
Douglas McDonald
CC BY-SA 3.0
2014-11-07T15:19:50.543Z
@DouglasMcDonald Yes it's a plugin and the path you mention is correct. I was using actionUrl('broadbean/jobs/new') as that's what the docs recommend when linking direct: http://buildwithcraft.com/docs/plugins/controllers#linking-directly-to-controller-actions. But looking back now I see that POSTING is different: http://buildwithcraft.com/docs/plugins/controllers#posting-to-controller-actions. As you say, you don't use action in the URL, do you know why two different URL patterns are used? Problem resolved so if you add an answer I'll mark it as accepted. Thanks
Russ Back
<plugin-development><form><admin>
Post to an action URL fails, Get works
# Post to an action URL fails, Get works

(Asked by: username_0 on 2014-11-07)

I have a simple plugin that's expected POST data from a form:

    

When I submit the form, that fails:

Page Not Found
Unable to resolve the request "http:/craft.dev/index.php/admin/actions/broadbean/jobs/new".

If I cut and paste that URL into a new window, I get the plugin response, so what gives here? The plugin is set up to allow anonymous access (but I'm submitting the form from within an admin view anyway).
EDIT:
According to http://buildwithcraft.com/docs/plugins/controllers#posting-to-controller-actions I should be able to put the action URL in a hidden field, which I've done. If I dispense with that and instead put the actionUrl() directly in the form's action parameter, everything works.
Is this a bug? This is on Craft 2.2.2601.
EDIT:
Controller code:
class Broadbean_JobsController extends BaseController
{
    protected $allowAnonymous = true;

    public function actionNew()
    {    
        $this->requirePostRequest();

        $result = craft()->broadbean_jobs->createJob();
        
        var_dump(array(
            'message' => ($result['success']) ? Craft::t('Job created.') : Craft::t('Unable to create job.'),
            'values' => craft()->request->getPost(),
            'errors' => $result['errors']
        ));

    }
}

**Tags:** plugin-development, form, admin

> **Comments:**
> **username_1**: Have you tried removing the action attribute from your form tag?  
> **username_0**: Yep - no change.  
> **username_1**: Ok - another stab in the dark here - but is your plugin class camel cased? I.e. is it BroadBeanPlugin or BroadbeanPlugin? If its the former then your action url might need to be `broadBean/jobs/new`.  
> **username_2**: Could be that you need a route set up?  
> **username_0**: @JoshAngell The class is BroadbeanPlugin. The action URL is correct: as I said it works if you put it in the form action and hit it directly in a browser. It doesn't work if it's in an input with the name of 'action'.  
> **username_0**: @DarylKnight same comment as above - it works as is but perhaps that's needed. Where/how would I do that?  
> **username_1**: @RussBack hang on I've just noticed in your error message that there is a slash missing in the `http://` part - it is showing `http:/`. Maybe check your `siteUrl` setting - either in the cp or [config](http://buildwithcraft.com/docs/config-settings#siteUrl)  
> **username_2**: Posted link to Hooks Reference as an answer  
> **username_3**: I've always just used the uri directly without the wrapper, like so: `<input type="hidden" name="action" value="broadbean/jobs/new">` I'm not sure what `actionUrl` does.  
> **username_0**: @JoshAngell yes I noticed that too. However that only shows itself in the error message Craft displays - the URL is correct in config and outputs correctly via Twig's actionUrl() method.  
> **username_1**: @RussBack Nnnngg. This is very weird! Maybe post your controller code? I'm out of other ideas - particularly as I've got plenty of controller actions working fine right now in various Craft versions.  
> **username_0**: @DouglasMcDonald actionUrl() is recommended so that you don't get tripped up by expecting /admin/actions/broadbean/jobs/new if a user has changed their config to say /admin/methods/broadbean/jobs/new  
> **username_0**: @JoshAngell, controller code added to the original post  
> **username_3**: I'm totally confused. Isn't this a plugin? I would expect the controller to be here: `/craft/plugins/broadbean/controllers/Broadbean_JobsController.php`, and craft would automatically create the action route `broadbean/jobs/new'. Are you using a different pattern?  
> **username_0**: @DouglasMcDonald Yes it's a plugin and the path you mention is correct. I was using actionUrl('broadbean/jobs/new') as that's what the docs recommend when linking direct: http://buildwithcraft.com/docs/plugins/controllers#linking-directly-to-controller-actions. But looking back now I see that POSTING is different: http://buildwithcraft.com/docs/plugins/controllers#posting-to-controller-actions. As you say, you don't use action in the URL, do you know why two different URL patterns are used? Problem resolved so if you add an answer I'll mark it as accepted. Thanks  

---

## 2 answers

### Answer by username_3 on 2014-11-07. Score: 4

I believe that when you post data using name='action' from a form that craft automatically uses the actionUrl to route the request properly, so that if your controller is here:
/craft/plugins/broadbean/controllers/Broadbean_JobsController.php

with a method actionNew, then craft will create the action route broadbean/jobs/new automatically:


On the other hand if you are linking directly then craft doesn't know to use the action route, so you need to explicitly tell it that this is an action request:


or from javascript:
var url = Craft.getActionUrl('broadbean/jobs/new', { id: 10 });

If you were to call the action externally then you would have to write the full action url without the benefit of using the automatic config routing:
http://mysite.com/actions/broadbean/jobs/new?id=10

or, if the admin had, for example, set up a custom actionUrl in the config file:
http://mysite.com/methods/broadbean/jobs/new?id=10

> **Comments:**
> **username_0**: Thanks, that makes sense. How can I remove /admin from the route? For example the action "broadbean/jobs/new" works when you post a form from within the admin panel, but it only works from a frontend template with the action "admin/broadbean/jobs/new". I have this in registerCpRoutes(): "'broadbean/jobs/new' => array('action' => 'broadbean/jobs/new')"  
> **username_3**: That's why I was confused. I have never seen 'admin' as being part of any url unless it is related to the admin interface, or unless you were trying to bypass the built in routing. I don't know to be honest. I would start by removing that cpRoute as it's not really doing anything.  
> **username_0**: Trouble is, if I remove that, neither route works!  
> **username_3**: Strange... if you print out the url using `{{ actionUrl('broadbean/jobs/new' }}` and test that that works, then `<input type="hidden" name="action" value="broadbean/jobs/new">` should be posting to the same place, because its using the same method to derive the url. Is it possible that you have some condition in your plugin that is rejecting the request? Or perhaps a custom actionUrl defined in your config file? (i.e. `'actionTrigger' => 'actions',`)  
> **username_3**: Ah wait... I reread your post. It sounds like you are posting from with the CP. If that's the case then craft may add `admin` to the front of the uri, to indicate its a CP request (I'm guessing here). But you shouldn't have to explicitly set that anywhere.  
> **username_3**: Do you have anything like this in your plugin? `if (craft()->request->isSiteRequest()) {throw new HttpException(404); }`  
> **username_0**: Well initially I was testing just from a form within a CP page, but now I'm putting the form on a template OUTSIDE of the admin panel and that's where I see the difference - OUTSIDE of the admin panel I need to add /admin to the URL  
> **username_0**: And no, I don't have isSiteRequest() in there at all.  

---

### Answer by username_2 on 2014-11-07. Score: 1

You may need to set up a route using this Hook Reference from the plugin docs:
http://buildwithcraft.com/docs/plugins/hooks-reference#registerCpRoutes
function registerCpRoutes()
    {
        return array(
        'cocktails/new'               => 'cocktails/_edit',
        'cocktails/(?P\d+)' => array('action' => 'cocktails/editCocktail'),
    );
}

> **Comments:**
> **username_0**: Tried that, no change.  

---

