# Workaround for a plugin setting before the plugin is initialized

**URL:** <https://forum.getkirby.com/t/workaround-for-a-plugin-setting-before-the-plugin-is-initialized/16846>\
**Category:** Questions\
**Tags:** v3\
**Created:** [January 13, 2020, 1:49pm UTC](https://forum.getkirby.com/t/workaround-for-a-plugin-setting-before-the-plugin-is-initialized/16846 "2020-01-13T13:49:22Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![hdodov](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/hdodov/32/8171_2.png) [@hdodov](https://forum.getkirby.com/u/hdodov)\
**Post date:** [January 13, 2020, 1:49pm UTC](https://forum.getkirby.com/t/workaround-for-a-plugin-setting-before-the-plugin-is-initialized/16846/1 "2020-01-13T13:49:22Z")

</div>

I have [a plugin](https://github.com/OblikStudio/kirby-variables) that loads translations by using YAML files. However, I want to provide an option to specify which folder should contain those files.

The problem is - I need to load the translations before the plugin is set up, yet the folder in which those translations reside is determined by a plugin option that’s available _after_ the plugin is initialized:

```php
$folder = kirby()->option('oblik.variables.folder'); // NULL
$translations = loadTranslationsFrom($folder);

Kirby::plugin('oblik/variables', [
    'translations' => $translations,
    'options' => [
        'folder' => kirby()->root('languages')
    ]
]);

```

Essentially, I want the default folder to be the `site/languages` folder, but also allow it to be set to the content folder for use cases where content is managed in a separate Git submodule and variables should be stored there.

So by default, YAML files are stored in `site/languages` but with this config setting:

```php
return [
    'oblik.variables.folder' => kirby()->root('content')
];

```

…they should be stored in `content` instead.

Is there a way to make this happen?

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 13, 2020, 2:10pm UTC](https://forum.getkirby.com/t/workaround-for-a-plugin-setting-before-the-plugin-is-initialized/16846/2 "2020-01-13T14:10:40Z")

</div>

Your problem here is using `kirby()` in the config, right? But to circumvent that problem we now have the `ready` config option.

> **[ready](https://getkirby.com/docs/reference/system/options/ready)**
>
> Inject last minute configuration options

---

<div class="post-metadata">

**Author:** ![hdodov](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/hdodov/32/8171_2.png) [@hdodov](https://forum.getkirby.com/u/hdodov)\
**Post date:** [January 13, 2020, 2:40pm UTC](https://forum.getkirby.com/t/workaround-for-a-plugin-setting-before-the-plugin-is-initialized/16846/3 "2020-01-13T14:40:08Z")

</div>

Not quite. I need this mechanism, yes, but from a plugin perspective. In other words, I need a `ready` callback in my _plugin_ config, not in the user’s _config.php_. Something like this:

_plugin/index.php_

```php
Kirby::plugin('oblik/variables', [
    'options' => [
        'folder' => kirby()->root('languages')
    ],
    'ready' => function () {
        $folder = kirby()->option('oblik.variables.folder');

        return [
            'translations' => loadTranslationsFrom($folder)
        ];
    }
]);

```

User’s _config.php_

```php
return [
    'oblik.variables.folder' => kirby()->root('content')
];

```

Unfortunately, there seems to be no `ready` functionality for plugins.

**Edit:** Perhaps I can somehow register translations from within the plugin after the plugin is loaded via [`system.loadPlugins:after`](https://getkirby.com/docs/reference/plugins/hooks/system-loadplugins-after)?

---

<div class="post-metadata">

**Author:** ![hdodov](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/hdodov/32/8171_2.png) [@hdodov](https://forum.getkirby.com/u/hdodov)\
**Post date:** [January 13, 2020, 3:16pm UTC](https://forum.getkirby.com/t/workaround-for-a-plugin-setting-before-the-plugin-is-initialized/16846/4 "2020-01-13T15:16:46Z")

</div>

This seems to do the job:

```php
Kirby::plugin('oblik/variables', [
    'options' => [
        'folder' => kirby()->root('languages')
    ],
    'hooks' => [
        'system.loadPlugins:after' => function () {
            kirby()->extendTranslations(Manager::loadTranslations());
        }
    ]
]);

```

And in `loadTranslations()`, I call:

```php
$folder = kirby()->option('oblik.variables.folder');

```

Is this reliable, though? Can I safely use `extendTranslations()`? Is it an internal method @distantnative?

---

<div class="post-metadata">

**Author:** ![distantnative](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/distantnative/32/11319_2.png) [@distantnative](https://forum.getkirby.com/u/distantnative)\
**Post date:** [January 13, 2020, 4:29pm UTC](https://forum.getkirby.com/t/workaround-for-a-plugin-setting-before-the-plugin-is-initialized/16846/5 "2020-01-13T16:29:07Z")

</div>

> [@hdodov](#):
>
> This seems to do the job

Does it really work? The method is marked as `protected`, so I thought you would not be able to call it.

---

<div class="post-metadata">

**Author:** ![hdodov](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/hdodov/32/8171_2.png) [@hdodov](https://forum.getkirby.com/u/hdodov)\
**Post date:** [January 13, 2020, 4:39pm UTC](https://forum.getkirby.com/t/workaround-for-a-plugin-setting-before-the-plugin-is-initialized/16846/6 "2020-01-13T16:39:31Z")

</div>

Seems like it:

 ![image](https://europe1.discourse-cdn.com/flex017/uploads/getkirby/original/2X/6/6ac5b9dc00d8034e533af145cce290152b05355a.png)

I’m using my [kirby-tester](https://github.com/OblikStudio/kirby-tester) utility, but it still shouldn’t work. I don’t extend the base App class, I simply [create a new instance](https://github.com/OblikStudio/kirby-tester/blob/master/src/Loader.php#L99) of it. I should still get an error?

Anyways, it seems I should avoid doing that since it’s protected. Are there any alternatives so I can solve my initial problem?

---

<div class="post-metadata">

**Author:** ![hdodov](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/hdodov/32/8171_2.png) [@hdodov](https://forum.getkirby.com/u/hdodov)\
**Post date:** [January 13, 2020, 4:56pm UTC](https://forum.getkirby.com/t/workaround-for-a-plugin-setting-before-the-plugin-is-initialized/16846/7 "2020-01-13T16:56:02Z")

</div>

@distantnative what’s even stranger is that if I add `private $foo = '42` in the AppPlugins trait, I can access _that_ as well in my closure. How is this possible? Could it be a bug in PHP?

**Edit:** I removed kirby-tester to make sure it doesn’t affect anything and I still get this behavior. Even if I simply open the site in the browser and run no other shenanigans:

 ![image](https://europe1.discourse-cdn.com/flex017/uploads/getkirby/original/2X/a/ad39569672454a222291c9a0944d578623c2a117.png)

**Edit 2:** To be super duper sure, I cloned a fresh version of the plainkit and added this plugin:

```php
Kirby::plugin('me/test', [
    'hooks' => [
        'system.loadPlugins:after' => function () {
            kirby()->extendTranslations([
              'en' => ['foo' => 'bar']
            ]);
        }
    ]
]);

```

It still works. In the default template, I have `<?= t('foo') ?>` and I get `bar`. So this is definitely not related to my setup.

**Edit 3:** Actually, this is not related to the translations logic at all. I **can’t** do this in a template:

```php
var_dump(kirby()->roots);

```

> Cannot access protected property Kirby\Cms\App::$roots

But I **can** do it in a plugin:

![image](https://europe1.discourse-cdn.com/flex017/uploads/getkirby/original/2X/3/3f9b5576c8fd00cb2f9522428929e1acc8133bf1.png)

---

<div class="post-metadata">

**Author:** ![bvdputte](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/bvdputte/32/8179_2.png) [@bvdputte](https://forum.getkirby.com/u/bvdputte)\
**Post date:** [January 13, 2020, 7:58pm UTC](https://forum.getkirby.com/t/workaround-for-a-plugin-setting-before-the-plugin-is-initialized/16846/8 "2020-01-13T19:58:07Z")

</div>

Wow, really creative coding @hdodov 😳

All I can add is some background info about the `system.loadPlugins:hook`: [https://github.com/getkirby/ideas/issues/23](https://github.com/getkirby/ideas/issues/23)

---

<div class="post-metadata">

**Author:** ![distantnative](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/distantnative/32/11319_2.png) [@distantnative](https://forum.getkirby.com/u/distantnative)\
**Post date:** [January 14, 2020, 10:39am UTC](https://forum.getkirby.com/t/workaround-for-a-plugin-setting-before-the-plugin-is-initialized/16846/9 "2020-01-14T10:39:36Z")

</div>

I think it’s happening because hooks are called through

> <https://github.com/getkirby/kirby/blob/c1ff870e4f13b647f57f99b3e963340c3e0a286c/src/Cms/App.php#L1292>

And in that case the instance still calls the method internally, I guess.

---

<div class="post-metadata">

**Author:** ![hdodov](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/hdodov/32/8171_2.png) [@hdodov](https://forum.getkirby.com/u/hdodov)\
**Post date:** [January 14, 2020, 11:01am UTC](https://forum.getkirby.com/t/workaround-for-a-plugin-setting-before-the-plugin-is-initialized/16846/10 "2020-01-14T11:01:31Z")

</div>

So what would you recommend for my initial problem? I think I shouldn’t rely on access to private and protected properties. Is there another solution? How would you implement this functionality?

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 14, 2020, 12:55pm UTC](https://forum.getkirby.com/t/workaround-for-a-plugin-setting-before-the-plugin-is-initialized/16846/11 "2020-01-14T12:55:53Z")

</div>

Maybe I’m completely missing something, why can’t you call the config option and set your default folder as default in the absence of a config setting?

```auto
'options' => [
        'folder' => option('oblik.variables.folder', kirby()->root('languages'))
    ],

```

Then user can set option in config:

```auto
    'ready' => function() {
        return [
            'oblik.variables.folder' => kirby()->root('content')
        ];
    }
```

---

<div class="post-metadata">

**Author:** ![hdodov](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/hdodov/32/8171_2.png) [@hdodov](https://forum.getkirby.com/u/hdodov)\
**Post date:** [January 14, 2020, 3:23pm UTC](https://forum.getkirby.com/t/workaround-for-a-plugin-setting-before-the-plugin-is-initialized/16846/12 "2020-01-14T15:23:22Z")

</div>

The problem comes from the fact that I need the final value of the setting _before_ the plugin is loaded. Or - to add translations _after_ it’s loaded.

```php
$finalFolderValue = kirby()->option('oblik.variables.folder');
$data = readTranslations($finalFolderValue);

Kirby::plugin('oblik/variables', [
    'translations' => $data,
    'options' => [
        'folder' => kirby()->root('languages')
    ]
]);

```

This is a bit paradoxical because I need the value of the `folder` option on line 1, but set the default value later in `Kirby::plugin()`. Also, that value should be configurable from `config.php` by the user, which happens long after `Kirby::plugin()`.

The more logical solution appears to be not reading the option before it’s available, but to delay the functionality that depends on that option _after_ it’s available. That’s what I did with the hook trick above:

```php
Kirby::plugin('oblik/variables', [
    'options' => [
        'folder' => kirby()->root('languages')
    ],
    'hooks' => [
        'system.loadPlugins:after' => function () {
            $finalFolderValue = kirby()->option('oblik.variables.folder');
            $data = readTranslations($finalFolderValue);
            kirby()->extendTranslations($data);
        }
    ]
]);

```

The `loadPlugins` hook triggers _after_ all plugins have loaded an therefore after the final value of `oblik.variables.folder` is available. Then, I use that value to add the corresponding translations.

This works perfectly, but depends on having access to protected properties and using internal Kirby methods. Since I think that’s a bad idea, I’m asking for alternatives.

**Edit:** What I need, basically, is a similar functionality to [`ready`](https://getkirby.com/docs/reference/system/options/ready) but for plugins:

```php
Kirby::plugin('oblik/variables', [
    'options' => [
        'folder' => kirby()->root('languages')
    ],
    'ready' => function () {
        $folder = kirby()->option('oblik.variables.folder');
        $data = readTranslations($folder);

        return [
            'translations' => $data
        ];
    }
]);

```

…or in other words:

```php
Kirby::plugin('oblik/variables', [
    ...
    some plugin config
    ...
    'ready' => function () {
        return [
            ...
            more plugin config
            ...
        ];
    }
]);

```

---

<div class="post-metadata">

**Author:** ![hdodov](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/hdodov/32/8171_2.png) [@hdodov](https://forum.getkirby.com/u/hdodov)\
**Post date:** [January 17, 2020, 11:44am UTC](https://forum.getkirby.com/t/workaround-for-a-plugin-setting-before-the-plugin-is-initialized/16846/13 "2020-01-17T11:44:11Z")

</div>

@distantnative @texnixe can I have some conclusion on this? Is there a decent way to do it, or should I open an issue in the ideas repo for what I posted above?

---

<div class="post-metadata">

**Author:** ![moeli](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/moeli/32/8964_2.png) [@moeli](https://forum.getkirby.com/u/moeli)\
**Post date:** [August 17, 2020, 5:34pm UTC](https://forum.getkirby.com/t/workaround-for-a-plugin-setting-before-the-plugin-is-initialized/16846/14 "2020-08-17T17:34:35Z")

</div>

@hdodov have you found a solution for this?

I am trying to load translations from a plugin blueprint, but they are not yet registered when the translation registration happens.
