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).


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.


Controller code:

class Broadbean_JobsController extends BaseController
    protected $allowAnonymous = true;

    public function actionNew()

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

  • Have you tried removing the action attribute from your form tag? Commented Nov 7, 2014 at 8:48
  • Yep - no change.
    – Russ Back
    Commented Nov 7, 2014 at 9:15
  • 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. Commented Nov 7, 2014 at 9:18
  • Could be that you need a route set up? Commented Nov 7, 2014 at 9:47
  • @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
    Commented Nov 7, 2014 at 10:00

2 Answers 2


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:


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:


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

  • 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
    Commented Nov 7, 2014 at 15:56
  • 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. Commented Nov 7, 2014 at 16:03
  • Trouble is, if I remove that, neither route works!
    – Russ Back
    Commented Nov 7, 2014 at 16:12
  • 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',) Commented Nov 7, 2014 at 16:38
  • 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. Commented Nov 7, 2014 at 16:55

You may need to set up a route using this Hook Reference from the plugin docs:


function registerCpRoutes()
        return array(
        'cocktails/new'               => 'cocktails/_edit',
        'cocktails/(?P<widgetId>\d+)' => array('action' => 'cocktails/editCocktail'),
  • Tried that, no change.
    – Russ Back
    Commented Nov 7, 2014 at 10:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.