Provide computed meta tags in page header

Permalink 1 user found helpful
Hi C5 community,

I am writing an Add-On for the C5 marketplace that allows users to include social sharing buttons on their pages. It is made up of two functionalities:
1. Add social sharing buttons to pages (now implemented as Block thanks to the helpers:http://www.concrete5.org/community/forums/customizing_c5/add-dynami...
2. Add open graph meta tags in the page header for facebook/others

Since the two can be used independent from each other. I abandoned my first attempt to build them both in one block. And now the question arises what to do with number 2.

Number two should add the open graph meta tags to the page and automatically fills in the values from page attributes, collection urls, other meta information etc. allowing the user to manually override the computed values.

I have already built this functionality as an element that can be included in the header of the theme. But now I want this to be installable by Marketplace users without having to edit their themes.

Sure, I could build it as a C5 block that when inserted in a page does not render any content (except in edit mode) and only adds the header items. But is this an encouraged solution? Blocks are meant to render displayable date in a page I think.

Does C5 offer any other hooks that would allow me to do add computed header items? Overriding configuration could be done by setting page attributes for the meta tags for example. But I don't know where to plug in the code actually rendering the computed/given values independent from the theme in use.

Regards, Tilmann Kuhn

tilm4nn
 
Mainio replied on at Permalink Reply
Mainio
Hi,

You can add header items to the view if you grab on e.g. to the on_before_render event in the package:
public function on_before_render() {
   $v = View::getInstance();
   $v->addHeaderItem('<item>Your Header Item</item>');
   // And of course you can use the html helper to automate things:
   $v->addHeaderItem(Loader::helper('html')->javascript('your_script.js'));
}


Br,
Antti / Mainio

EDIT: And you can grab on to that event in the on_start() function of your package.
tilm4nn replied on at Permalink Reply
tilm4nn
Thanks Mainio!

In addition to the block solution I'll look into this approach. Though on the first glance it looks to me as if it could be discouraged:http://www.concrete5.org/documentation/developers/system/packages... says about the package controller "This file only contains the information needed for your system to identify the package and to install it. All other logic relating to what your package actually does should be located elsewhere."

Regards, Tilmann
mkly replied on at Permalink Reply
mkly
"Though on the first glance it looks to me as if it could be discouraged"

That's a bummer since this is how every Package I've seen that hooks into concrete5's Event system works.

in controller.php
public function on_start() {
  Events::extend('on_page_view',
    'ModelClass',
    'modelMethod',
    DIR_BASE . '/packages/' . $this->pkgHandle . '/models/model_class.php'
  );
}


Then create a model in the packages model directory with the method.

Since you seem to have this stuff sorted out so well maybe you should look into writing a couple howto's for the community. I'm sure everyone would really appreciate it.

Best,
Mike
tilm4nn replied on at Permalink Reply
tilm4nn
Hey cool, if every Add-On works like that I gladly work my way into it.

I'm sorry if I made the impression to criticize on the suggestions you made. I really appreciate that you help me and others in this community. Sadly I am new to C5 development and just created an initial version of my first block meaning I am mainly working myself through the documentation taking for granted what I read there. The documentation on this site is good and extensive but in some cases a little bit missleading. I think I'll still need some time to have everything sorted out so well.

Regading taking part in the how-tos: Thanks for that hint. Actually I have just now seen that there are how-tos! Also regarding open graph and such. Why has Google only found entries from the Forums and not the HowTos so far? However now I am richer on information :) (And will probably use one of the search fields directly on the site.)

Now I'd first try to finish my Add-Ons so they can be provided for the community in the marketplace (for free). And afterwards I'm glad to consolidate any findings that might be of community interest in one or more howtos. If there is a address towards I can direct improvements suggestions for the documentation I'm also glad to provide what I can.

Cheers, Tilmann Kuhn
Mainio replied on at Permalink Reply
Mainio
Just one point I'd like to make here is that you're completely right (together with mkly) that the on_before_render() should NOT be in the Package's main class. mkly already pointed out the "correct way" to do that but the main issue of hooking into events in the package's on_start() method is 100% encouraged by the core team. Or why else would they use it themselves in their add-ons? ;)

I just assumed above that you were looking how this is done in the first place and showed you "the first steps" to take. Usually that helps you get started and figure out these things yourself.

But my point in shorter way: mkly pointed out the correct way to hook into the event, you probably should move the actual functionality to a model or a library.

Antti
tilm4nn replied on at Permalink Reply
tilm4nn
Thanks for the addition. Now that makes sense, also from an architectural point of view :) I see I still have quite a way to go as well in PHP and C5 development and apreciate your input very much.

Yours, Tilmann Kuhn
mkly replied on at Permalink Reply
mkly
Google finds them. I just ranks the forums higher. I end up doing this a lot in the google search bar.

site:www.concrete5.org/documentation

But ya, one of the best times to discover things people would want to know is when you are are doing them for the first time. Once you have things down you forget how certain parts of the documentation could be a little clearer. It's really easy to post a new howto.

If you addon is free and open source consider opening up a github account, concrete5 is there as well as a couple addon developers. The more the merrier for sure. My username is mkly and concrete5 is at concrete5
mkly replied on at Permalink Reply
mkly
In your blocks controller you can do
public function on_page_view() {
  // this puts your string to output in
  // the Loader::element('header_required')
  // class
  $this->addHeaderItem($this->openGraph());
}
protected function openGraph() }
  //
  // some code to get values
  //
  $open_graph_data = '';
  $open_graph_data .= "<meta property=\"og:title\" content=\"$title\"/>\n";
  // include the rest of open graph stuff
  return $open_graph_data;
}


The part that gets you in trouble is the html tag
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:og="http://ogp.me/ns#"
      xmlns:fb="http://www.facebook.com/2008/fbml">

I'm not sure if there is a way to solve that issue without modifying that part of the theme.

In your view.php I usually do this to show site editors that it's there.
<?php global $c ?>
<?php if($c->isEditMode()): ?>
  <p>Facebook OpenGraph Block</p>
<?php endif; ?>
tilm4nn replied on at Permalink Reply
tilm4nn
Hey great work, that's the whole outline of the block solution, thanks! But the actual question was if this is the usual and right thing to do to achieve things like that with C5 or if there is another encouraged way.

Regarding the XML namespaces on the html-tag another option would be to include them on each single meta element I suppose.
mkly replied on at Permalink Reply
mkly
<?php global $c ?>
<?php if($c->isEditMode()): ?>
  <p>Facebook OpenGraph Block</p>
<?php endif; ?>


Is the usual way. Sorry I didn't make that clear enough.
mkly replied on at Permalink Reply
mkly
"Blocks are meant to render displayable data in a page I think."

I have been unable to find reference to this in the source or documentation. Maybe you could throw me an anyone else who sees this thread a link for future reference?

Much appreciated,
Mike
tilm4nn replied on at Permalink Reply
tilm4nn
Gladly,

http://www.concrete5.org/documentation/developers/blocks/overview...

mentions that in the first pragraph.
mkly replied on at Permalink Reply
mkly
I can see how there could be confusion about "primarily". I read that as "most common use"(which is it), but I could see how someone could see that as "recommended use".

Although we could get all technical and talk about how the open graph data is to display content... haha.