Answers.Body: <p>Since this is a module rather than a plugin, you need to register control panel template roots, like so:</p>
  <pre><code>  Event::on(
      View::class,
      View::EVENT_REGISTER_CP_TEMPLATE_ROOTS,
      function (RegisterTemplateRootsEvent $e) {
          $e-&gt;roots['app-module'] = __DIR__ . '/templates/cp';
      }
    );
  </code></pre>
  <p>(I've swapped 'custom' for 'app-module' as I think it's a little more clear, but feel free to keep it as 'custom') If your module's <code>src</code> folder does not have a <code>templates/cp</code> directory, create one and add an <code>index.twig</code> to it. Now going to <code>admin/app-module</code> should load the index file you've created. (You'll need to update the <code>EVENT_REGISTER_CP_NAV_ITEMS</code> from 'custom' to 'app-module' to have the CP url match the change I've made here.) However, since you're working with an element, it's probably better to create another directory named after your element. Let's use &quot;Item&quot; as a generic element class name, you might have <code>templates/cp/items/index.twig</code> who's contents might look like this:</p>
  <pre><code>{% extends elementType is defined ? '_layouts/elementindex' : '_layouts/cp' %}
  
  {% set elementType = 'modules\\appmodule\\elements\\ItemElement' %}
  {% set title = 'My Custom Items'|t('app-module') %}
  
  {% block actionButton %}
   &lt;div id=&quot;extra-headers&quot;&gt;
      &lt;div class=&quot;buttons right&quot;&gt;
        &lt;a href=&quot;{{ url('app-module/items/new') }}&quot; class=&quot;btn submit add icon&quot;&gt;
         {{ &quot;New custom item&quot;|t('app-module')}}
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  {% endblock %}
  </code></pre>
  <p>You don't need to register this URL via the <code>EVENT_REGISTER_CP_URL_RULES</code>, but you will want to for the element edit and creation page. e.g.</p>
  <pre><code>Event::on(
      UrlManager::class,
      UrlManager::EVENT_REGISTER_CP_URL_RULES,
      function (RegisterUrlRulesEvent $event) {
          $event-&gt;rules['app-module/items/new'] = 'app-module/items/edit-item';
          $event-&gt;rules['app-module/items/&lt;itemId:\d+&gt;' =&gt; 'app-module/items/edit-item']
      }
  );
  </code></pre>
  <p>Here, the key is the URL you will hit in the control panel and the value is the action URL you'll need to create in your module. <code>src/controllers/ItemsController.php</code>, which will have an <code>actionEditItem</code> function.</p>
  <p>Hope this helps!</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-12-28T16:00:47.517Z
Answers.LastActivityDate: 2020-12-28T16:00:47.517Z
Answers.UserDisplayName: andrewmenich
Body: <p>Hello I've created a new element type in a module (a web app within Craft) that I'm developing.
  I have initially created my models to be <code>craft\db\ActiveRecord</code> and save directly to their tables, but that is not the &quot;craft&quot; way.</p>
  <p>I decided to extend from <code>craft\base\Element</code> and do the needful in order to leverage elementindex.html (search, sort, filter), but going to <code>/admin/custom/index</code> gives a &quot;404 Not Found&quot;. Do I need to create my own CustomController.php ?</p>
  <p>I did the configuration needed in my Module class, as well as creating the Custom.php and CustomQuery.php according to the <a href="https://craftcms.com/docs/3.x/extend/element-types.html" rel="nofollow noreferrer">documentation here</a></p>
  <pre><code>   // CP Routes
      Event::on(
          UrlManager::class,
          UrlManager::EVENT_REGISTER_CP_URL_RULES,
          function (RegisterUrlRulesEvent $event) {
              $event-&gt;rules['custom'] = '/app-module/custom/index';
          }
      );
  
      // CP Nav Items
      Event::on(
          Cp::class,
          Cp::EVENT_REGISTER_CP_NAV_ITEMS,
          function (RegisterCpNavItemsEvent $event) {
              $event-&gt;navItems[] = [
                  'url' =&gt; 'custom',
                  'label' =&gt; 'Custom',
                  'icon' =&gt; 'share',
              ];
          }
      );
  
      // Custom Element Types
      Event::on(Elements::class,
          Elements::EVENT_REGISTER_ELEMENT_TYPES,
          function(RegisterComponentTypesEvent $event) {
              $event-&gt;types[] = Custom::class;
          }
      );
  </code></pre>
  
Tags: <control-panel><modules><elementtype><elementquery><index>
Title: Custom Module: new element type index page access
ThreadText: # Custom Module: new element type index page access
  
  (Asked by: username_0 on 2020-12-28)
  
  Hello I've created a new element type in a module (a web app within Craft) that I'm developing.
  I have initially created my models to be `craft\db\ActiveRecord` and save directly to their tables, but that is not the "craft" way.
  
  I decided to extend from `craft\base\Element` and do the needful in order to leverage elementindex.html (search, sort, filter), but going to `/admin/custom/index` gives a "404 Not Found". Do I need to create my own CustomController.php ?
  
  I did the configuration needed in my Module class, as well as creating the Custom.php and CustomQuery.php according to the [documentation here](https://craftcms.com/docs/3.x/extend/element-types.html)
  
  ```
     // CP Routes
      Event::on(
          UrlManager::class,
          UrlManager::EVENT_REGISTER_CP_URL_RULES,
          function (RegisterUrlRulesEvent $event) {
              $event->rules['custom'] = '/app-module/custom/index';
          }
      );
  
      // CP Nav Items
      Event::on(
          Cp::class,
          Cp::EVENT_REGISTER_CP_NAV_ITEMS,
          function (RegisterCpNavItemsEvent $event) {
              $event->navItems[] = [
                  'url' => 'custom',
                  'label' => 'Custom',
                  'icon' => 'share',
              ];
          }
      );
  
      // Custom Element Types
      Event::on(Elements::class,
          Elements::EVENT_REGISTER_ELEMENT_TYPES,
          function(RegisterComponentTypesEvent $event) {
              $event->types[] = Custom::class;
          }
      );
  
  ```
  
  **Tags:** control-panel, modules, elementtype, elementquery, index
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2020-12-28. Score: 2 | Accepted answer
  
  Since this is a module rather than a plugin, you need to register control panel template roots, like so:
  
  ```
    Event::on(
      View::class,
      View::EVENT_REGISTER_CP_TEMPLATE_ROOTS,
      function (RegisterTemplateRootsEvent $e) {
          $e->roots['app-module'] = __DIR__ . '/templates/cp';
      }
    );
  
  ```
  
  (I've swapped 'custom' for 'app-module' as I think it's a little more clear, but feel free to keep it as 'custom') If your module's `src` folder does not have a `templates/cp` directory, create one and add an `index.twig` to it. Now going to `admin/app-module` should load the index file you've created. (You'll need to update the `EVENT_REGISTER_CP_NAV_ITEMS` from 'custom' to 'app-module' to have the CP url match the change I've made here.) However, since you're working with an element, it's probably better to create another directory named after your element. Let's use "Item" as a generic element class name, you might have `templates/cp/items/index.twig` who's contents might look like this:
  
  ```
  {% extends elementType is defined ? '_layouts/elementindex' : '_layouts/cp' %}
  
  {% set elementType = 'modules\\appmodule\\elements\\ItemElement' %}
  {% set title = 'My Custom Items'|t('app-module') %}
  
  {% block actionButton %}
   <div id="extra-headers">
      <div class="buttons right">
        <a href="{{ url('app-module/items/new') }}" class="btn submit add icon">
         {{ "New custom item"|t('app-module')}}
        </a>
      </div>
    </div>
  {% endblock %}
  
  ```
  
  You don't need to register this URL via the `EVENT_REGISTER_CP_URL_RULES`, but you will want to for the element edit and creation page. e.g.
  
  ```
  Event::on(
      UrlManager::class,
      UrlManager::EVENT_REGISTER_CP_URL_RULES,
      function (RegisterUrlRulesEvent $event) {
          $event->rules['app-module/items/new'] = 'app-module/items/edit-item';
          $event->rules['app-module/items/<itemId:\d+>' => 'app-module/items/edit-item']
      }
  );
  
  ```
  
  Here, the key is the URL you will hit in the control panel and the value is the action URL you'll need to create in your module. `src/controllers/ItemsController.php`, which will have an `actionEditItem` function.
  
  Hope this helps!
  
  
  ---
  
  