2
votes

I'm looking for a way to add a section of JavaScript code to a page that is required for my plugin. I know you can include a file via $this->addJs() but I need the JavaScript to be dynamically constructed from settings in the plugin's settings model.

I can do this using a {% put scripts %}...{% endput %} block in my default.htm, but this gets injected multiple times if I use the component multiple times in the page.

Is there a way to inject the code into the page only once, no matter how many times the component is used on the page?

3
Why not pyt IT in a document.ready()?Dawid Dave Kosiński

3 Answers

2
votes

Figured this one out. In my component I've added a property $renderCount and increment this in the onRender() method. All I need to do is check __SELF__.renderCount in the component's default template and output the script only if it is 1.

1
votes

I do it this way with the help of a private function (mapSettings) in Plugin.php to rewite settings to my needs.

Event::listen('cms.page.beforeRenderPage', function($controller, $page) {
    if($page->hasComponent('myComponentName')) {
        Event::listen('cms.page.render', function($controller, $pageContents) {

            $this->settings = \Acme\Plugin\Models\Settings::instance();
            $script = "<script>let hounddd = {". json_encode($this->mapSettings()) ."};</script>";

            return $pageContents . $script;
        });

    }
});

My first concern whas to avoid browser's caching for some essentials page's javascript datas.
Maybe a better way exist to inject "backend" compiled data to October's {% scripts %} tag.

0
votes

To remove multiply injects when you use {% put scripts %}...{% endput %} and {% put styles %}...{% endput %} you can remove duplicates by handled output styles and scripts in Plugin.php function:

public function boot()
{
    Event::listen('cms.block.render', function ($name, $result) {
        if ($name == 'styles' || $name == 'scripts') {
            $array = preg_split('/\n/', $result);
            $items = array_filter(array_unique(array_map('trim', $array)));

            return join(PHP_EOL, $items);
        }
    });
}