5

I cannot find a way to render templates from a plugin controller in Craft 3. I feel as though I've tried every variation advised online but for some reason this still isn't working.

<?php

namespace abc\members\controllers;

class LoginController extends \craft\web\Controller
{
    public function actionForm()
    {
        $this->renderTemplate('abc-members/login.html');
    }
}

The plugin handle is "abc-members".

The plugin has a "templates" directory with "login.html".

I've tried the following, with and without the .html extension, but none can find the template:

$this->renderTemplate('abc-members/login.html');
$this->renderTemplate('abc-members/templates/login.html');
$this->renderTemplate('abc-members/src/templates/login.html');
$this->renderTemplate('abc/members/src/templates/login.html');
$this->renderTemplate('plugins/abc/members/src/templates/login.html');

The following works fine but then I cannot include templates from the installation's main template directory.

<?php

namespace abc\members\controllers;

class LoginController extends \craft\web\Controller
{
    public function actionForm()
    {
        \Craft::$app->view->setTemplatesPath(__DIR__ . '/../templates');
        $this->renderTemplate('login.html');
    }
}

Any suggestions as to where I'm going wrong? I find the Craft 3 docs are a bit lacking in the whole area of plugin controllers, routing and templates other than in the Craft 2 => Craft 3 upgrade guide.

Thanks

2 Answers 2

8

You don't specify, but it sounds like you're trying to have the plugin render its templates as a result of frontend requests? If so, you'd need to do:

use Craft;
use craft\web\View;

$oldMode = \Craft::$app->view->getTemplateMode();
Craft::$app->view->setTemplateMode(View::TEMPLATE_MODE_CP);
$html = \Craft::$app->view->renderTemplate('plugin-handle/path/to/template');
Craft::$app->view->setTemplateMode($oldMode);

If you're trying to mix and match between the normal Craft templates directory and your plugin's templates, you'd need to change the template mode as you bounce back and forth.

c.f.: https://docs.craftcms.com/v3/extend/updating-plugins.html#rendering-templates

1
  • 1
    Ah, I managed to try just about everything but this. I tried setTemplateMode(View::TEMPLATE_MODE_SITE) assuming that View::TEMPLATE_MODE_CP was related to rendering templates for routes in the admin control panel, rather than on the public frontend of the site. Thanks!
    – Mike
    Commented Dec 16, 2018 at 22:01
10

After becoming more familiar with Craft and Yii, I've found a more appropriate solution for my use case. I have a couple of ideal requirements:

  1. Templates are stored in a directory within my module or plugin.
  2. Templates can be mixed with general application templates (e.g. my module or plugin template can extend from a general site layout template).

It turns out that the Template Roots functionality enables this, so it is documented but for some reason I was overlooking this previously.

You can simply register the template root during plugin/module init like so:

Event::on(View::class, View::EVENT_REGISTER_SITE_TEMPLATE_ROOTS, function (RegisterTemplateRootsEvent $event) {
   $event->roots['_my_prefix'] = __DIR__ . '/templates';
});

Then templates in the defined directory can be rendered using the defined prefix (_my_prefix in this case), as though that directory exists in the main templates directory. This means they can be used in any context and extend or include templates in the main directory ‒ desirable for app specific plugins/modules.

1
  • Best solution for me too. Thanks a lot. Commented Jun 3, 2020 at 13:34

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.