Reputation: 83
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?
Upvotes: 2
Views: 1455
Reputation: 15
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);
}
});
}
Upvotes: 0
Reputation: 33
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.
Upvotes: 1
Reputation: 83
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.
Upvotes: 2