Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-07T15:56:52.427Z
Answers.Text: 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')"
Answers.UserDisplayName: Russ Back
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-07T16:03:02.577Z
Answers.Text: 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.
Answers.UserDisplayName: Douglas McDonald
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-07T16:12:21.587Z
Answers.Text: Trouble is, if I remove that, neither route works!
Answers.UserDisplayName: Russ Back
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-07T16:38:21.930Z
Answers.Text: 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',`)
Answers.UserDisplayName: Douglas McDonald
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-07T16:55:22.027Z
Answers.Text: 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.
Answers.UserDisplayName: Douglas McDonald
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-07T17:00:26.890Z
Answers.Text: Do you have anything like this in your plugin? `if (craft()->request->isSiteRequest()) {throw new HttpException(404); }`
Answers.UserDisplayName: Douglas McDonald
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-07T17:05:25.060Z
Answers.Text: 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
Answers.UserDisplayName: Russ Back
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-07T17:10:15.570Z
Answers.Text: And no, I don't have isSiteRequest() in there at all.
Answers.UserDisplayName: Russ Back
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-07T15:32:54.050Z
Answers.LastActivityDate: 2014-11-07T15:47:39.640Z
Answers.LastEditDate: 2014-11-07T15:47:39.640Z
Answers.UserDisplayName: Douglas McDonald
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-07T10:47:04.723Z
Answers.Text: Tried that, no change.
Answers.UserDisplayName: Russ Back
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-07T10:04:26.503Z
Answers.LastActivityDate: 2014-11-07T10:04:26.503Z
Answers.UserDisplayName: darylknight
Body: <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>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-11-07T08:48:47.633Z
Comments.Text: Have you tried removing the action attribute from your form tag?
Comments.UserDisplayName: Josh Angell
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-11-07T09:15:52.623Z
Comments.Text: Yep - no change.
Comments.UserDisplayName: Russ Back
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-11-07T09:18:47.603Z
Comments.Text: 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`.
Comments.UserDisplayName: Josh Angell
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-11-07T09:47:01.120Z
Comments.Text: Could be that you need a route set up?
Comments.UserDisplayName: darylknight
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-11-07T10:00:01.523Z
Comments.Text: @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'.
Comments.UserDisplayName: Russ Back
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-11-07T10:01:01.193Z
Comments.Text: @DarylKnight same comment as above - it works as is but perhaps that's needed. Where/how would I do that?
Comments.UserDisplayName: Russ Back
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-11-07T10:03:48.783Z
Comments.Text: @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)
Comments.UserDisplayName: Josh Angell
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-11-07T10:05:08.450Z
Comments.Text: Posted link to Hooks Reference as an answer
Comments.UserDisplayName: darylknight
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-11-07T10:05:15.790Z
Comments.Text: 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.
Comments.UserDisplayName: Douglas McDonald
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-11-07T10:32:56.933Z
Comments.Text: @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.
Comments.UserDisplayName: Russ Back
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-11-07T10:34:26.087Z
Comments.Text: @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.
Comments.UserDisplayName: Josh Angell
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-11-07T10:35:08.087Z
Comments.Text: @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
Comments.UserDisplayName: Russ Back
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-11-07T10:39:46.773Z
Comments.Text: @JoshAngell, controller code added to the original post
Comments.UserDisplayName: Russ Back
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-11-07T15:05:43.077Z
Comments.Text: 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?
Comments.UserDisplayName: Douglas McDonald
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-11-07T15:19:50.543Z
Comments.Text: @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
Comments.UserDisplayName: Russ Back
Tags: <plugin-development><form><admin>
Title: Post to an action URL fails, Get works
ThreadText: # 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:
  
  ```
  <form method="post" action="" accept-charset="UTF-8">
      <input type="hidden" name="action" value="{{ actionUrl('broadbean/jobs/new') }}">
  
  ```
  
  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**: @username_1 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**: @username_0 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**: @username_1 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**: @username_0 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**: @username_3 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**: @username_1, 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**: @username_3 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 username_0 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:
  
  ```
  <input type="hidden" name="action" value="broadbean/jobs/new">
  
  ```
  
  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:
  
  ```
  <a href="{{ actionUrl('broadbean/jobs/new', { id: 10 }) }}">
  
  ```
  
  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<widgetId>\d+)' => array('action' => 'cocktails/editCocktail'),
      );
  }
  
  ```
  
  > **Comments:**
  > **username_0**: Tried that, no change.  
  
  ---
  
  