Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-06-03T13:34:29.557Z
Answers.Text: Best solution for me too. Thanks a lot.
Answers.UserDisplayName: Jannie Theunissen
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-12-19T13:41:33.427Z
Answers.LastActivityDate: 2018-12-19T13:41:33.427Z
Answers.UserDisplayName: Mike
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-12-16T22:01:28.107Z
Answers.Text: 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!
Answers.UserDisplayName: Mike
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-12-16T16:31:53.087Z
Answers.LastActivityDate: 2018-12-16T16:31:53.087Z
Answers.UserDisplayName: andrew.welch
Body: <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>
  
Tags: <plugin-development><templating><controller>
Title: How to render plugin templates in Craft CMS 3?
ThreadText: # 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.
  
  ```
  <?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
  
  **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:
  
  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](https://docs.craftcms.com/v3/extend/template-roots.html) 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.  
  
  ---
  
  