Add dynamic JS and non-JS/CSS content to HTML-head with Block

Permalink
I am just building a Concrete5 Block that will be used to include recommendation/like buttons for sharing the current site in different social networks.
For these to work correctly I need
1. to include open-graph meta tags in the HTML-head.
2. to include a generated java script element in the HTML-head.

I already have code that generates the meta tags/java script. I used it in an C5 elements that were included in the header of the theme in my C5 installation. But now I want this to get an installable Block that can be distributed to other installations and automatically adds the required information.

I have seen that I can add JS and CSS files to the head with magic files/folders or addHeaderItem. But how can I add other elements/generated java script elements to the head?

The code that generates the meta-tags and the required java script element is given in the attached files for reference.

Regards, Tilmann

2 Attachments

tilm4nn
 
mkly replied on at Permalink Reply
mkly
EDIT: To reflect @JohntheFish's comment

You can use the on_page_view() method of BlockController with addHeaderItem() to add any content to the header, not just js and css file links.

EDIT: You can only put strings in there. So you can either modify it to use output buffering (ob_start) or just put it in a big string. But either way those functions will need to return a string.

/* In controller.php */
public function on_page_view() {
  $this->addHeaderItem($this->outputOpenGraph());
  $this->addHeaderItem($this->outputSocialSharePrivacy());
}
protected function outputOpenGraph() {
  // put that opengraph code here
}
protected function outputSocialSharePrivacy() {
  // put that socialshareprivacy code here
}


Like you can just do
$this->addHeaderItem('<script type="text/javascript">alert("Up in da header!")</script>');
in the on_start() and it will just add that string.
JohntheFish replied on at Permalink Best Answer Reply
JohntheFish
If the script string is complex, you can avoid a lot of messing about with escapes and concatenation by using a php heredoc to 'write' the script into a string.
http://www.php.net/manual/en/language.types.string.php#language.typ...

In a block controller you can also use the controller event function on_page_view() instead of on_start().

I seem to remember reading that it was a more efficient place to add header items in block controllers, but can't find where and don't know whether it is significant. So maybe someone else can verify or correct me on that.
mkly replied on at Permalink Reply
mkly
Indeed. on_page_view() is preferred. I was under the impression that on_page_view() would not load if "Track Statistics" was turned off. After testing this only effects Package Controllers.

on_page_view() is described as "the only way to inject items into the page's header from within a block" in the official documentation.

http://www.concrete5.org/documentation/developers/blocks/mvc-approa...

Thanks @JohntheFish for correcting me. I will update my answer.

ps. I think it would only be fair that you mark his answer as the correct one as opposed to mine as my answer was not correct until he corrected it.
tilm4nn replied on at Permalink Reply
tilm4nn
Thanks to both of you I'll look into your suggestions as soon as I am back at C5 development on the weekend :)

Regarding how to add content to the header I think the documentation of
$controller->addHeaderItem($file)
inhttp://www.concrete5.org/documentation/developers/blocks/mvc-approa... is a bit missleading and could be improved. From what is given there I had learned that that method can be used to add CSS/JS file references only.
tilm4nn replied on at Permalink Reply
tilm4nn
I tried your suggestions and they worked perfectly :)
gaijin4life replied on at Permalink Reply
Trying to edit this to add Amazon cart functionality.

This is what I added to controller.php (in the path /concrete/controllers/dashboard):

public function on_page_view() {
     $this->addHeaderItem('<script src="https://images-na.ssl-images-amazon.com/images/G/01/cba/js/jquery.js" type="text/javascript"></script> <script src="https://images-na.ssl-images-amazon.com/images/G/01/cba/js/common/cba_shared.js" type="text/javascript"></script> <script src="https://images-na.ssl-images-amazon.com/images/G/01/cba/js/shoppingcart/merchant_cart.js" type="text/javascript"></script>');
  }


But it didn't seem to add anything to the header when I view the page source.