<p>I think <a href="https://craftcms.stackexchange.com/a/38324/4169">my other answer</a> is also part of this one.</p>
<p>The only specifics I'd add here is that your action is getting &quot;double-declared,&quot; in a way. Using the <code>action</code> param in a request has a lot of weight in Craft's eye—but you're stacking two strategies, and the system can't match it with your intent.</p>
<p>My recommendation is (whenever possible) to use Craft's Twig helpers:</p>
<pre><code>&lt;form method=&quot;POST&quot;&gt;
    {{ csrfInput() }}
    {{ actionInput('mapit-api2entry/default/map-it') }}

    &lt;button&gt;Go!&lt;/button&gt;
&lt;/form&gt;
</code></pre>
<p>This will generate a hidden <code>action</code> input that looks like this:</p>
<pre class="lang-html prettyprint-override"><code>&lt;input name=&quot;action&quot; value=&quot;mapit-api2entry/default/map-it&quot;&gt;
</code></pre>
<p>Notice that we don't declare <code>action</code> as part of the route! Craft already knows you want to route directly to a Controller/Action path because it sees the <code>action</code> param.</p>
<p>The direct-access behavior you see is a vanity/convenience feature—the <a href="https://craftcms.com/docs/3.x/config/config-settings.html#actiontrigger" rel="nofollow noreferrer"><code>actionTrigger</code></a> (the first segment in that path, aside from the <a href="https://craftcms.com/docs/3.x/config/config-settings.html#cptrigger" rel="nofollow noreferrer"><code>cpTrigger</code></a>—<code>admin</code> by default) is actually customizable, and not particularly useful in my mind, when the Twig helpers (and <code>action</code> query/POST param) are so reliable.</p>

CC BY-SA 4.0
2021-09-15T15:15:37.397Z
Thanks for taking the time to reply.(lovely work by the way )
Finally got a result.
So is there no need to tell craft that this is a cptrigger - is this done in the route?   $event->rules['mapit-api2entry/default/map-it'] = 'results';
And or in the controller? Eg $this->renderTemplate('xxx')
joomkit
CC BY-SA 4.0
2021-09-16T16:46:01.450Z
Keep in mind that the "key" you assign to the `rules` array is the alias to your controller action, and the "value" (what is assigned) is the full controller path: `$event->rules['my-shortcut-route'] = 'mapit-api2entry/default/map-it';`, where `DefaultController::actionMapIt()` becomes available at `my-shortcut-route` (or `admin/my-shortcut-route`, if you're in the CP). I'm not entirely sure how the determinations of an "Action Request" and a "CP Request" overlap—but generally, actions are for logic + processing, and they redirect to an `admin/my-route` in success/fail states.
August Miller
CC BY-SA 4.0
2021-09-15T03:47:27.727Z
2021-09-15T03:47:27.727Z
August Miller
<p>I have a plugin that has a menu and in backend which basically has a button that calls the plugins default controller actionXXXX method.</p>
<p>The action does some database / api work then is meant to return a result in a results template.</p>
<p>I have no idea how plugins got so complicated in craft and Im about ready to give up after today. The plugin main file supplies EVENT_REGISTER_CP_URL_RULES</p>
<pre><code> Event::on(
            UrlManager::class,
            UrlManager::EVENT_REGISTER_CP_URL_RULES,
            function (RegisterUrlRulesEvent $event) {
                $event-&gt;rules['mapit-api2entry/default/map-it'] = 'results';
            }
        );
</code></pre>
<p>The plugin form in the cp has a hidden action like so. Do I need admin here? I assume so because we are in the CP.</p>
<pre><code>&lt;input type=&quot;hidden&quot; name=&quot;action&quot; value=&quot;admin/actions/mapit-api2entry/default/map-it&quot;&gt;
</code></pre>
<p>I can put the url &quot;admin/actions/mapit-api2entry/default/map-it&quot; in the browser and pull up my template as expected.</p>
<p>But when I hit the submit button I get:</p>
<pre><code>Unable to resolve the request &quot;admin/actions/mapit-api2entry/default/map-it&quot;.
</code></pre>
<p>How do I tell the plugin / cp the right route to use after the action is triggered? Is this case of camel -vs kebab somewhere?</p>

<plugin-development><control-panel><routes>
Why do i get an Invalid route error in cp when calling plugin action?
# Why do i get an Invalid route error in cp when calling plugin action?

(Asked by: username_0 on 2021-09-14)

I have a plugin that has a menu and in backend which basically has a button that calls the plugins default controller actionXXXX method.
The action does some database / api work then is meant to return a result in a results template.
I have no idea how plugins got so complicated in craft and Im about ready to give up after today. The plugin main file supplies EVENT_REGISTER_CP_URL_RULES
 Event::on(
            UrlManager::class,
            UrlManager::EVENT_REGISTER_CP_URL_RULES,
            function (RegisterUrlRulesEvent $event) {
                $event->rules['mapit-api2entry/default/map-it'] = 'results';
            }
        );

The plugin form in the cp has a hidden action like so. Do I need admin here? I assume so because we are in the CP.


I can put the url "admin/actions/mapit-api2entry/default/map-it" in the browser and pull up my template as expected.
But when I hit the submit button I get:
Unable to resolve the request "admin/actions/mapit-api2entry/default/map-it".

How do I tell the plugin / cp the right route to use after the action is triggered? Is this case of camel -vs kebab somewhere?

**Tags:** plugin-development, control-panel, routes

---

## 1 answers

### Answer by username_1 on 2021-09-15. Score: 3 | Accepted answer

I think my other answer is also part of this one.
The only specifics I'd add here is that your action is getting "double-declared," in a way. Using the action param in a request has a lot of weight in Craft's eye—but you're stacking two strategies, and the system can't match it with your intent.
My recommendation is (whenever possible) to use Craft's Twig helpers:

    {{ csrfInput() }}
    {{ actionInput('mapit-api2entry/default/map-it') }}

    Go!


This will generate a hidden action input that looks like this:


Notice that we don't declare action as part of the route! Craft already knows you want to route directly to a Controller/Action path because it sees the action param.
The direct-access behavior you see is a vanity/convenience feature—the actionTrigger (the first segment in that path, aside from the cpTrigger—admin by default) is actually customizable, and not particularly useful in my mind, when the Twig helpers (and action query/POST param) are so reliable.

> **Comments:**
> **username_0**: Thanks for taking the time to reply.(lovely work by the way ) Finally got a result. So is there no need to tell craft that this is a cptrigger - is this done in the route?   $event->rules['mapit-api2entry/default/map-it'] = 'results'; And or in the controller? Eg $this->renderTemplate('xxx')  
> **username_1**: Keep in mind that the "key" you assign to the `rules` array is the alias to your controller action, and the "value" (what is assigned) is the full controller path: `$event->rules['my-shortcut-route'] = 'mapit-api2entry/default/map-it';`, where `DefaultController::actionMapIt()` becomes available at `my-shortcut-route` (or `admin/my-shortcut-route`, if you're in the CP). I'm not entirely sure how the determinations of an "Action Request" and a "CP Request" overlap—but generally, actions are for logic + processing, and they redirect to an `admin/my-route` in success/fail states.  

---

