How do I set­up a route to point to a con­troller action instead of a template?

The registerCpRoutes() method in our primary plugin class PrimaryClassName.php allows to route a particular URL to a template.

// PluginClassName.php
// Redirect a CP request from `pluginname/edit` 
// to the `pluginname/templates/_edit.html` template
public function registerCpRoutes()
{
  return array(
    'pluginname/edit' => 'pluginname/_edit',
  );
}

Notice that we omit the templates folder from the route and Craft knows that pluginname/_edit should actually be routed to the pluginname/templates/_edit template.

However, in some cases, we may not want to route directly to a template. Craft also allows us to route a request to a controller instead.

// PluginClassName.php
// Redirect a CP request from `pluginname/edit` 
// to the method `editItem()` in the controller 
// `pluginname/controllers/PluginNameController.php`
public function registerCpRoutes()
{
  return array(
    'pluginname/edit' => array('action' => 'pluginName/editItem'),
  );
}

Again, notice that we omit the controllers folder from our route. When we make our route an array with the action key, Craft knows to use redirect the request to your controller, in this case pluginname/controllers/editItem.

You may want to reconsider redirecting to the Controller instead of the template when you find yourself adding too much logic into your templates that could be handled more easily in PHP.

In our controller we can do several things which include creating variables that will be available to our tempaltes and telling Craft which template we want to route the request to after we are done.

// PluginNameController.php
public function actionEditItem()
{
    // Create any variables you want available in your template
    $variables['items'] = craft()->pluginName->getAllItems();

    // Load a particular template and with all of the variables you've created
    $this->renderTemplate('pluginname/_edit', $variables);
}

In the above example, we could then access the items variable in our pluginname/templates/_edit template.

{% for item in items %}
    {{ item }}
{% endfor %}

In more advanced plugins, you may need multiple controllers. When we add multiple controllers the syntax for our route changes slightly and we need to be sure to reference our controller in the second segment of the routes action value. Note the difference below in how we route to PluginNameController.php and PluginName_AnotherController.php.

// PluginClassName.php
public function registerCpRoutes()
{
  return array(
    // Route to our primary controller
    // `pluginname/controllers/PluginNameController.php`
    'pluginname/edit' => array('action' => 'pluginName/editItem'),

    // Route to a secondary controller
    // `pluginname/controllers/PluginName_AnotherController.php`
    'pluginname/edit' => array('action' => 'pluginName/another/editItem'),
  );
}

Level up in Craft CMS with practical examples, snippets, and patterns.
Craft The Planet emails are sent out several times a week.