Answers.Body: <p>An alternative approach is to <a href="https://craftcms.com/docs/5.x/extend/extending-twig.html#extend-the-global-craft-variable" rel="nofollow noreferrer">extend the global <code>craft</code> variable</a>, by adding your <code>amphibian</code> module as a property on it.</p>
  <p>In your main module class' <code>init()</code> method (this example assumes your <code>amphibian</code> module's main class is <code>MyModule</code>):</p>
  <pre class="lang-php prettyprint-override"><code>Event::on(
      CraftVariable::class,
      CraftVariable::EVENT_INIT,
      static function(Event $e) {
          /** @var CraftVariable $variable */
          $variable = $e-&gt;sender;
          $variable-&gt;set('amphibian', MyModule::getInstance());
      }
  );
  </code></pre>
  <p>In a Twig template:</p>
  <pre class="lang-none prettyprint-override"><code>{{ craft.amphibian.utility.test() }}
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-10-22T13:10:28.757Z
Answers.Text: Thanks Mats, I'll try this approach.
Answers.UserDisplayName: Derek Hogue
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-10-24T13:58:04.887Z
Answers.Text: This also did not work for me, BUT, I ended up attaching my custom fuction as a behavior and that _did_ work. Not sure why the other approaches did not.
Answers.UserDisplayName: Derek Hogue
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-10-24T16:28:20.633Z
Answers.Text: @DerekHogue Weird! I've successfully used both approaches exemplified here in the past... Great that you figured out something else though, if it works it works!
Answers.UserDisplayName: Mats Mikkel Rummelhoff
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-10-19T21:41:26.633Z
Answers.LastActivityDate: 2024-10-19T21:41:26.633Z
Answers.UserDisplayName: Mats Mikkel Rummelhoff
Body: <p>I have a custom module setup, which I created via the Craft generator. It includes a service and a Twig extension. I'd like to make all of my module's services and methods available via a Twig variable, which it looks like I can do by extending the Twig <code>GlobalsInterface</code>, <a href="https://craftcms.com/docs/5.x/extend/extending-twig.html#create-a-twig-extension" rel="nofollow noreferrer">as per the docs here</a>:</p>
  <pre><code>namespace mynamespace\myplugin\twig;
  
  use Craft;
  use Twig\Extension\AbstractExtension;
  use Twig\Extension\GlobalsInterface;
  use mynamespace\myplugin\MyPlugin;
  
  class Extension extends AbstractExtension implements GlobalsInterface
  {
  
      public function getGlobals(): array
      {
          // Keys are variable names!
           return [
              'myPlugin' =&gt; MyPlugin::getInstance(),
          ];
      }
  }
  </code></pre>
  <p>However, this is not working for me, and I believe it's because the example is for a plugin, not a module, and IIRC calling <code>MyModule::get_instance()</code> does not work like <code>MyPlugin::get_instance()</code>.</p>
  <p>How do I adapt this code to work for my custom module?</p>
  <p>My current (non-working) code for the Twig extension:</p>
  <pre><code>namespace modules\amphibian\web\twig;
  
  use Craft;
  use Twig\Extension\AbstractExtension;
  use Twig\Extension\GlobalsInterface;
  use modules\amphibian;
  
  class Extension extends AbstractExtension implements GlobalsInterface
  {
  
      public function getGlobals(): array
      {
          // Keys are variable names!
           return [
              'amphibian' =&gt; Amphibian::getInstance(),
          ];
      }
  }
  </code></pre>
  <p>My service, also added via the generator, is called <code>Utility</code>, and I have a function inside named <code>test()</code>.</p>
  <p>Calling <code>{{ amphibian.utility.test() }}</code> yields a <code>Variable &quot;amphibian&quot; does not exist.</code> runtime error.</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-10-18T17:26:48.997Z
Comments.Text: Is your Twig extension registered in the main Module class for all requests? It sounds like it's not being initialized!
Comments.UserDisplayName: August Miller
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-10-18T17:46:47.467Z
Comments.Text: Yup, this is tyake care of by the generator. Inside of `init()` I have `Craft::$app->view->registerTwigExtension(new AmphibianTwig())`.
Comments.UserDisplayName: Derek Hogue
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-10-18T18:20:08.497Z
Comments.Text: Huh! And your module is present in the `bootstrap` array in `config/app.php`?
Comments.UserDisplayName: August Miller
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-10-18T20:49:15.937Z
Comments.Text: Yup, it is, along with my service loaded as a component.
Comments.UserDisplayName: Derek Hogue
Tags: <modules><twigextension>
Title: How to expose a custom module's service as a Twig global?
ThreadText: # How to expose a custom module's service as a Twig global?
  
  (Asked by: username_0 on 2024-10-18)
  
  I have a custom module setup, which I created via the Craft generator. It includes a service and a Twig extension. I'd like to make all of my module's services and methods available via a Twig variable, which it looks like I can do by extending the Twig `GlobalsInterface`, [as per the docs here](https://craftcms.com/docs/5.x/extend/extending-twig.html#create-a-twig-extension):
  
  ```
  namespace mynamespace\myplugin\twig;
  
  use Craft;
  use Twig\Extension\AbstractExtension;
  use Twig\Extension\GlobalsInterface;
  use mynamespace\myplugin\MyPlugin;
  
  class Extension extends AbstractExtension implements GlobalsInterface
  {
  
      public function getGlobals(): array
      {
          // Keys are variable names!
           return [
              'myPlugin' => MyPlugin::getInstance(),
          ];
      }
  }
  
  ```
  
  However, this is not working for me, and I believe it's because the example is for a plugin, not a module, and IIRC calling `MyModule::get_instance()` does not work like `MyPlugin::get_instance()`.
  
  How do I adapt this code to work for my custom module?
  
  My current (non-working) code for the Twig extension:
  
  ```
  namespace modules\amphibian\web\twig;
  
  use Craft;
  use Twig\Extension\AbstractExtension;
  use Twig\Extension\GlobalsInterface;
  use modules\amphibian;
  
  class Extension extends AbstractExtension implements GlobalsInterface
  {
  
      public function getGlobals(): array
      {
          // Keys are variable names!
           return [
              'amphibian' => Amphibian::getInstance(),
          ];
      }
  }
  
  ```
  
  My service, also added via the generator, is called `Utility`, and I have a function inside named `test()`.
  
  Calling `{{ amphibian.utility.test() }}` yields a `Variable "amphibian" does not exist.` runtime error.
  
  **Tags:** modules, twigextension
  
  > **Comments:**
  > **username_1**: Is your Twig extension registered in the main Module class for all requests? It sounds like it's not being initialized!  
  > **username_0**: Yup, this is tyake care of by the generator. Inside of `init()` I have `Craft::$app->view->registerTwigExtension(new AmphibianTwig())`.  
  > **username_1**: Huh! And your module is present in the `bootstrap` array in `config/app.php`?  
  > **username_0**: Yup, it is, along with my service loaded as a component.  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_2 on 2024-10-19. Score: 1
  
  An alternative approach is to [extend the global `craft` variable](https://craftcms.com/docs/5.x/extend/extending-twig.html#extend-the-global-craft-variable), by adding your `amphibian` module as a property on it.
  
  In your main module class' `init()` method (this example assumes your `amphibian` module's main class is `MyModule`):
  
  ```php
  Event::on(
      CraftVariable::class,
      CraftVariable::EVENT_INIT,
      static function(Event $e) {
          /** @var CraftVariable $variable */
          $variable = $e->sender;
          $variable->set('amphibian', MyModule::getInstance());
      }
  );
  
  ```
  
  In a Twig template:
  
  ```none
  {{ craft.amphibian.utility.test() }}
  
  ```
  
  > **Comments:**
  > **username_0**: Thanks username_2, I'll try this approach.  
  > **username_0**: This also did not work for me, BUT, I ended up attaching my custom fuction as a behavior and that _did_ work. Not sure why the other approaches did not.  
  > **username_2**: @username_0 Weird! I've successfully used both approaches exemplified here in the past... Great that you figured out something else though, if it works it works!  
  
  ---
  
  