<p>If this is a module and not a plugin, you might need to declare your base template directory in the Module's <code>__construct</code> using:</p>

<pre class="lang-php prettyprint-override"><code>Event::on(View::class, View::EVENT_REGISTER_CP_TEMPLATE_ROOTS, function (craft\events\RegisterTemplateRootsEvent $e) {
    if (is_dir($baseDir = $this-&gt;getBasePath() . DIRECTORY_SEPARATOR . 'templates')) {
        $e-&gt;roots[$this-&gt;id] = $baseDir;
    }
});
</code></pre>

<p>See <a href="https://nystudio107.com/blog/enhancing-a-craft-cms-3-website-with-a-custom-module#2-the-module-class" rel="nofollow noreferrer">Andrews's article</a> on the subject.</p>

CC BY-SA 4.0
2020-04-08T03:20:21.260Z
Thanks, this did the trick.
Adamatronix
CC BY-SA 4.0
2020-04-07T14:13:43.070Z
2020-04-07T14:13:43.070Z
Oli
<p>I've created a custom module trying to implement new field types. I'm using <a href="https://craftcms.stackexchange.com/questions/30092/how-to-create-custom-field-type-in-craft-3?newreg=87ea4975437740918e6f5b4cf160a7cc">How to create custom field type in Craft 3</a> and <a href="https://github.com/mmikkel/IncognitoField-Craft3" rel="nofollow noreferrer">https://github.com/mmikkel/IncognitoField-Craft3</a>
as reference on how to structure the module. </p>

<p>However, with a barebones version, I cannot seem to get the correct path to my templates. My module structure has the templates at:</p>

<pre><code>SalesteamModule/src/templates/_components/fields/_input.twig
</code></pre>

<p>And the main function is:</p>

<pre><code>
public function getInputHtml($value, ElementInterface $element = null): string
    {
        // Get our id and namespace
        $id = Craft::$app-&gt;getView()-&gt;formatInputId($this-&gt;handle);
        $namespacedId = Craft::$app-&gt;getView()-&gt;namespaceInputId($id);

        // Render the input template
        return Craft::$app-&gt;getView()-&gt;renderTemplate(
            'salesteam-module/_components/fields/_input',
            [
                'name' =&gt; $this-&gt;handle,
                'value' =&gt; $value,
                'field' =&gt; $this,
                'id' =&gt; $id,
                'namespacedId' =&gt; $namespacedId,
            ]
        );
    }
</code></pre>

<p>App.php</p>

<pre><code>return [

    // All environments
    '*'       =&gt; [
        'modules'   =&gt; [
            'site-module' =&gt; [
                'class' =&gt; \modules\sitemodule\SiteModule::class,
            ],
            'salesteam-module' =&gt; [
                'class' =&gt; \modules\salesteammodule\SalesteamModule::class,
            ],
        ],
        'bootstrap' =&gt; ['site-module', 'salesteam-module'],
    ],

    // Live (production) environment
    'live'    =&gt; [
    ],

    // Staging (pre-production) environment
    'staging' =&gt; [
    ],

    // Local (development) environment
    'local'   =&gt; [
    ],
];
</code></pre>

<p>The module is registered as "salesteam-module" in the app config, so I don't think it's a module id thing. And the path I copied the structure of the Incognito plugin I posted above. Although that repo is a plugin, not a module if that makes any difference.</p>

<p>Not sure where to go from here since I've tried a whole slew of different path combinations.</p>

<p>Thanks</p>

<templating><custom-fieldtype><modules>
Trouble finding the correct path to template in custom module and getting the "Unable to find the template" error
# Trouble finding the correct path to template in custom module and getting the "Unable to find the template" error

(Asked by: username_0 on 2020-04-07)

I've created a custom module trying to implement new field types. I'm using How to create custom field type in Craft 3 and https://github.com/mmikkel/IncognitoField-Craft3
as reference on how to structure the module. 
However, with a barebones version, I cannot seem to get the correct path to my templates. My module structure has the templates at:
SalesteamModule/src/templates/_components/fields/_input.twig

And the main function is:

public function getInputHtml($value, ElementInterface $element = null): string
    {
        // Get our id and namespace
        $id = Craft::$app->getView()->formatInputId($this->handle);
        $namespacedId = Craft::$app->getView()->namespaceInputId($id);

        // Render the input template
        return Craft::$app->getView()->renderTemplate(
            'salesteam-module/_components/fields/_input',
            [
                'name' => $this->handle,
                'value' => $value,
                'field' => $this,
                'id' => $id,
                'namespacedId' => $namespacedId,
            ]
        );
    }

App.php
return [

    // All environments
    '*'       => [
        'modules'   => [
            'site-module' => [
                'class' => \modules\sitemodule\SiteModule::class,
            ],
            'salesteam-module' => [
                'class' => \modules\salesteammodule\SalesteamModule::class,
            ],
        ],
        'bootstrap' => ['site-module', 'salesteam-module'],
    ],

    // Live (production) environment
    'live'    => [
    ],

    // Staging (pre-production) environment
    'staging' => [
    ],

    // Local (development) environment
    'local'   => [
    ],
];

The module is registered as "salesteam-module" in the app config, so I don't think it's a module id thing. And the path I copied the structure of the Incognito plugin I posted above. Although that repo is a plugin, not a module if that makes any difference.
Not sure where to go from here since I've tried a whole slew of different path combinations.
Thanks

**Tags:** templating, custom-fieldtype, modules

---

## 1 answers

### Answer by username_1 on 2020-04-07. Score: 4 | Accepted answer

If this is a module and not a plugin, you might need to declare your base template directory in the Module's __construct using:
Event::on(View::class, View::EVENT_REGISTER_CP_TEMPLATE_ROOTS, function (craft\events\RegisterTemplateRootsEvent $e) {
    if (is_dir($baseDir = $this->getBasePath() . DIRECTORY_SEPARATOR . 'templates')) {
        $e->roots[$this->id] = $baseDir;
    }
});

See Andrews's article on the subject.

> **Comments:**
> **username_0**: Thanks, this did the trick.  

---

