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

CC BY-SA 4.0
2024-10-22T13:10:28.757Z
Thanks Mats, I'll try this approach.
Derek Hogue
CC BY-SA 4.0
2024-10-24T13:58:04.887Z
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.
Derek Hogue
CC BY-SA 4.0
2024-10-24T16:28:20.633Z
@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!
Mats Mikkel Rummelhoff
CC BY-SA 4.0
2024-10-19T21:41:26.633Z
2024-10-19T21:41:26.633Z
Mats Mikkel Rummelhoff
<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>

CC BY-SA 4.0
2024-10-18T17:26:48.997Z
Is your Twig extension registered in the main Module class for all requests? It sounds like it's not being initialized!
August Miller
CC BY-SA 4.0
2024-10-18T17:46:47.467Z
Yup, this is tyake care of by the generator. Inside of `init()` I have `Craft::$app->view->registerTwigExtension(new AmphibianTwig())`.
Derek Hogue
CC BY-SA 4.0
2024-10-18T18:20:08.497Z
Huh! And your module is present in the `bootstrap` array in `config/app.php`?
August Miller
CC BY-SA 4.0
2024-10-18T20:49:15.937Z
Yup, it is, along with my service loaded as a component.
Derek Hogue
<modules><twigextension>
How to expose a custom module's service as a Twig global?
# 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:
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, 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):
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:
{{ craft.amphibian.utility.test() }}

> **Comments:**
> **username_0**: Thanks Mats, 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**: @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!  

---

