C5-8.4.0 How to use page attributes in package without installing a block?
Permalink
I want to add a page attribute within a package and then use that attribute in various pages to load some JS if the attribute is selected.
I know I can make a block to work with that attribute. But this block will have to be added to each page AND I'll have to set the attribute on that each page anyway.
Is there any functionality in concrete5 where I can programmatically work with the attribute on a global basis from the package without the need to install blocks?
Is a Dashboard single page the right choice? How can I load JS based on that page's value on a global basis from the package throughout the whole site?
I know I can make a block to work with that attribute. But this block will have to be added to each page AND I'll have to set the attribute on that each page anyway.
Is there any functionality in concrete5 where I can programmatically work with the attribute on a global basis from the package without the need to install blocks?
Is a Dashboard single page the right choice? How can I load JS based on that page's value on a global basis from the package throughout the whole site?
There's probably an event you can hook.
As I clarified above and below, the JS has to load on pages or whole site.
Would the 'on_page_view' event be suitable for the page logic? I wouldn't know what page and what type of page is viewed, but as long as the attribute is present on any page I need to load the JS.
For the whole site I guess I can use the 'on_start' event.
How can I load the JS? As a *js file in the footer with addFooterItem?
Would the 'on_page_view' event be suitable for the page logic? I wouldn't know what page and what type of page is viewed, but as long as the attribute is present on any page I need to load the JS.
For the whole site I guess I can use the 'on_start' event.
How can I load the JS? As a *js file in the footer with addFooterItem?
You could do it in your theme header, just do
$c = \Page::getCurrentPage(); if($c->getAttribute('attribute_handle')){ //include the script tag }
Sorry, I wasn't clear, I've updated the original post to make it clearer. I need to install a custom page attribute from a package (I know how to) and then to enable/disable a JS (somewhere, where?) from the package on certain pages or the whole site based on the value of the attribute. All from the package without a block. Is it possible?
on_page_view will work. Once the even triggers you get the view like this
And then you can load your stuff either by requiring assets or adding it to the header/footer
To check for your attribute, once the event triggers you just do the usual
$v = \View::getInstance();
And then you can load your stuff either by requiring assets or adding it to the header/footer
if (is_object($v)) { $v->requireAsset('javascript', 'yourscriptname'); // OR $v->addFootererItem('yourscript); }
To check for your attribute, once the event triggers you just do the usual
$page = Page::getCurrentPage(); if ($page && is_object($page) && !$page->isError()) { $yourAttrValue = $page->getAttribute('your_attr_handle'); }
I may be missing something here. The following in the package controller doesn't work:
'on_before_render' doesn't work either.
public function on_start() { $js = '<script> $(document).ready(function(){ ConcreteAlert.error({ title: "Hello" }); }); </script>'; Events::addListener('on_page_view', function () { $v = \View::getInstance(); if (is_object($v)) {$v->addFooterItem($js); $page = Page::getCurrentPage(); if ($page && is_object($page) && !$page->isError()) {
Viewing 15 lines of 23 lines. View entire code block.
'on_before_render' doesn't work either.
Put a few die(__LINE__); in through the code and remove them until you find out at which stage it doesn't work.
Or use a debugger and breakpoints to trace it.
Or use a debugger and breakpoints to trace it.
2 problems:
1. It failed this:
2. And the $js was not visible to the event function.
I removed the check, moved the variable inside the event and now this works:
So that's a global set up, it adds the JS for the whole site, even the Dashboard. How can I
- load the JS only for that page which has been loaded?
- load the JS only for the user side excluding the Dashboard?
1. It failed this:
if (is_object($dc)) {
2. And the $js was not visible to the event function.
I removed the check, moved the variable inside the event and now this works:
public function on_start() { Events::addListener('on_page_view', function () { $js = '<script> $(document).ready(function(){ ConcreteAlert.error({ title: "Copy disabled" }); }); </script>'; $v = \View::getInstance(); if (is_object($v)) { $page = Page::getCurrentPage(); if ($page && is_object($page) && !$page->isError()) {
Viewing 15 lines of 22 lines. View entire code block.
So that's a global set up, it adds the JS for the whole site, even the Dashboard. How can I
- load the JS only for that page which has been loaded?
- load the JS only for the user side excluding the Dashboard?
you can use
to check whether it's an admin page or not.
As for the attribute, since you're using a checkbox most likely you can just do
$page->isAdminArea()
to check whether it's an admin page or not.
As for the attribute, since you're using a checkbox most likely you can just do
$attr = $page->getAttribute('your_handle'); if (!empty($attr)) { // do something }
Thank you very much, you help a lot!
I got that with the admin page check. I didn't know I could do that. I'll try that.
But what about enabling the JS only for the page which has it, not the whole site? Because once you add the footer in the package, it stick throughout. Maybe there's another event more suitable for that?
I got that with the admin page check. I didn't know I could do that. I'll try that.
But what about enabling the JS only for the page which has it, not the whole site? Because once you add the footer in the package, it stick throughout. Maybe there's another event more suitable for that?
I have packages using this technique and the js is only added when the attribute has the value I want. In your code it's not the case, you are adding the js to the footer no matter what.
Now if you're thinking about a caching issue, maybe put your code in a js file and register it as an asset and require it when the attribute has the proper value.
Now if you're thinking about a caching issue, maybe put your code in a js file and register it as an asset and require it when the attribute has the proper value.
You rock! Thanks a lot for your help. Your suggestion worked.
I'm going to release a package with that soon.
I'm going to release a package with that soon.
We guessed as much ;-)