<p>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:</p>

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

<p>It turns out that the <a href="https://docs.craftcms.com/v3/extend/template-roots.html" rel="noreferrer">Template Roots</a> functionality enables this, so it is documented but for some reason I was overlooking this previously.</p>

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

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

<p>Then templates in the defined directory can be rendered using the defined prefix (<code>_my_prefix</code> 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.</p>

CC BY-SA 4.0
2020-06-03T13:34:29.557Z
Best solution for me too. Thanks a lot.
Jannie Theunissen
CC BY-SA 4.0
2018-12-19T13:41:33.427Z
2018-12-19T13:41:33.427Z
Mike
<p>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:</p>

<pre><code>use Craft;
use craft\web\View;

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

<p>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.</p>

<p>c.f.: <a href="https://docs.craftcms.com/v3/extend/updating-plugins.html#rendering-templates" rel="noreferrer">https://docs.craftcms.com/v3/extend/updating-plugins.html#rendering-templates</a></p>

CC BY-SA 4.0
2018-12-16T22:01:28.107Z
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
CC BY-SA 4.0
2018-12-16T16:31:53.087Z
2018-12-16T16:31:53.087Z
andrew.welch
<p>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.</p>

<pre><code>&lt;?php

namespace abc\members\controllers;

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

<p>The plugin handle is "abc-members".</p>

<p>The plugin has a "templates" directory with "login.html".</p>

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

<pre><code>$this-&gt;renderTemplate('abc-members/login.html');
$this-&gt;renderTemplate('abc-members/templates/login.html');
$this-&gt;renderTemplate('abc-members/src/templates/login.html');
$this-&gt;renderTemplate('abc/members/src/templates/login.html');
$this-&gt;renderTemplate('plugins/abc/members/src/templates/login.html');
</code></pre>

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

<pre><code>&lt;?php

namespace abc\members\controllers;

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

<p>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.</p>

<p>Thanks</p>

<plugin-development><templating><controller>
How to render plugin templates in Craft CMS 3?
# How to render plugin templates in Craft CMS 3?

(Asked by: username_0 on 2018-12-16)

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

**Tags:** plugin-development, templating, controller

---

## 2 answers

### Answer by username_2 on 2018-12-16. Score: 8 | Accepted answer

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

> **Comments:**
> **username_0**: 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!  

---

### Answer by username_0 on 2018-12-19. Score: 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:

Templates are stored in a directory within my module or plugin.
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.

> **Comments:**
> **username_1**: Best solution for me too. Thanks a lot.  

---

