Social buttons bar for Facebook, Twitter and G+ with Symfony

Share Button

Lire la version française

We are going to create a custom social bar to share a page on Facebook, Twitter and Google+ with Symfony2 and Twig.

The expected result is something like that :

Create the helpers

The first step is to create the helpers. As you see, we create a helper for each button, and another one to “rule them all”.

<?php

namespace Acme\DemoBundle\Templating\Helper;

use Symfony\Component\Templating\Helper\Helper;
use Symfony\Component\Templating\EngineInterface;

class SocialBarHelper extends Helper
{
    protected $templating;

    public function __construct(EngineInterface $templating)
    {
        $this->templating  = $templating;
    }


    public function socialButtons($parameters)
    {
      return $this->templating->render('AcmeDemoBundle:helper:socialButtons.html.twig', $parameters);
    }

    public function facebookButton($parameters)
    {
      return $this->templating->render('AcmeDemoBundle:helper:facebookButton.html.twig', $parameters);
    }

    public function twitterButton($parameters)
    {
      return $this->templating->render('AcmeDemoBundle:helper:twitterButton.html.twig', $parameters);
    }

    public function googlePlusButton($parameters)
    {
      return $this->templating->render('AcmeDemoBundle:helper:googlePlusButton.html.twig', $parameters);
    }

    public function getName()
    {
        return 'socialButtons';
    }
}

Create the Twig functions

Now we can create the Twig functions. As for the helpers, we’ll create three functions to display each button, and another function to display all buttons. This last function will also allow us to display only two buttons or even just one.

<?php

namespace Acme\DemoBundle\Twig\Extensions;

class AcmeTwigSocialBar extends \Twig_Extension{

    protected $container;

    /**
     * Constructor.
     *
     * @param ContainerInterface $container
     */
    public function __construct($container)
    {
        $this->container = $container;
    }
    
    public function getName()
    {
        return 'acme_social_bar';
    }
    
    public function getFunctions()
    {
      return array(
        'socialButtons' => new \Twig_Function_Method($this, 'getSocialButtons' ,array('is_safe' => array('html'))),
        'facebookButton' => new \Twig_Function_Method($this, 'getFacebookLikeButton' ,array('is_safe' => array('html'))),
        'twitterButton' => new \Twig_Function_Method($this, 'getTwitterButton' ,array('is_safe' => array('html'))),
        'googlePlusButton' => new \Twig_Function_Method($this, 'getGooglePlusButton' ,array('is_safe' => array('html'))),
      );
    }

    public function getSocialButtons($parameters = array())
    {
      // no parameters were defined, keeps default values
      if (!array_key_exists('facebook', $parameters)){
        $render_parameters['facebook'] = array();
      // parameters are defined, overrides default values
      }else if(is_array($parameters['facebook'])){
        $render_parameters['facebook'] = $parameters['facebook'];
      // the button is not displayed 
      }else{
        $render_parameters['facebook'] = false;
      }

      if (!array_key_exists('twitter', $parameters)){
        $render_parameters['twitter'] = array();
      }else if(is_array($parameters['twitter'])){
        $render_parameters['twitter'] = $parameters['twitter'];
      }else{
        $render_parameters['twitter'] = false;
      }

      if (!array_key_exists('googleplus', $parameters)){
        $render_parameters['googleplus'] = array();
      }else if(is_array($parameters['googleplus'])){
        $render_parameters['googleplus'] = $parameters['googleplus'];
      }else{
        $render_parameters['googleplus'] = false;
      }

      // get the helper service and display the template
      return $this->container->get('acme.socialBarHelper')->socialButtons($render_parameters);
    }
 
    // https://developers.facebook.com/docs/reference/plugins/like/ 
    public function getFacebookLikeButton($parameters = array())
    {
       // default values, you can override the values by setting them
       $parameters = $parameters + array(
            'url' => null,
            'locale' => 'en_US',
            'send' => false,
            'width' => 300,
            'showFaces' => false,
            'layout' => 'button_count',
        );

       return $this->container->get('acme.socialBarHelper')->facebookButton($parameters);
    }

    public function getTwitterButton($parameters = array())
    {
       $parameters = $parameters + array(
            'url' => null,
            'locale' => 'en',
            'message' => 'I want to share that page with you',
            'text' => 'Tweet',
            'via' => 'The Acme team',
            'tag' => 'ttot',           
        );


       return $this->container->get('acme.socialBarHelper')->twitterButton($parameters);
    }

    public function getGooglePlusButton($parameters = array())
    {
       $parameters = $parameters + array(
            'url' => null,
            'locale' => 'en',
            'size' => 'medium',
            'annotation' => 'bubble',
            'width' => '300',
        );

       return $this->container->get('acme.socialBarHelper')->googlePlusButton($parameters);
    }
}

Register the services

Now, we must register the services so the helper and the Twig functions can work together.

# src/Acme/DemoBundle/Resources/config/services.yml
services:
  acme.socialBarHelper:
    class : Acme\DemoBundle\Templating\Helper\SocialBarHelper
    tags : 
      - {name : 'templating.helper', alias : 'social-buttons'} 
    arguments : [ @templating ]

  twig.extension.acme_social_bar:
    class: Acme\DemoBundle\Twig\Extensions\AcmeTwigSocialBar
    tags:
        - { name: 'twig.extension' }
    arguments : [ @service_container ]

Add the templates

Finally, we can create the four templates (one for each button and the one to display the whole bar).

The template for the Facebook button :

// src/Acme/DemoBundle/Resources/views/helper/facebookButton.html.twig

{% if url is not defined or url == null %}
    {% set url = app.request.uri %}
{% endif %}

{% spaceless %}
 {# initialize facebook SDK #}
 <div id="fb-root"></div>
 <script>(function(d, s, id) {
   var js, fjs = d.getElementsByTagName(s)[0];
   if (d.getElementById(id)) return;
   js = d.createElement(s); js.id = id;
   js.src = "//connect.facebook.net/{{locale}}/all.js#xfbml=1";
   fjs.parentNode.insertBefore(js, fjs);
 }(document, 'script', 'facebook-jssdk'));</script>

 <div class="fb-like" data-href="{{url}}" data-send="{{send}}" data-layout="{{layout}}" data-width="{{width}}" data-show-faces="{{showFaces}}"></div>

{% endspaceless %}

The template for the Twitter button :

// src/Acme/DemoBundle/Resources/views/helper/twitterButton.html.twig

{% if url is not defined or url == null %}
    {% set url = app.request.uri %}
{% endif %}

{% spaceless %}
 <a href="https://twitter.com/share" class="twitter-share-button"

   data-text="{{message}}" 
   data-url="{{url}}"
   data-lang="{{locale}}"

   {% if via is not sameas(false) %}
     data-via="{{via}}"
   {% endif %}

   {% if tag is not sameas(false) %}
     data-hashtags="{{tag}}"
   {% endif %}
 >{{text}}</a>

 <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
{% endspaceless %}

The template for the Google+ button :

// src/Acme/DemoBundle/Resources/views/helper/googlePlusButton.html.twig

{% if url is not defined or url == null %}
    {% set url = app.request.uri %}
{% endif %}

{% spaceless %}
 <div class="g-plusone" data-size="{{size}}" data-annotation="{{annotation}}" data-width="{{width}}" data-href="{{url}}"></div>

 <script type="text/javascript">
   window.___gcfg = {lang: '{{locale}}'};

   (function() {
     var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
     po.src = 'https://apis.google.com/js/plusone.js';
     var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
   })();
 </script>

{% endspaceless %}

And the One template :

// src/Acme/DemoBundle/Resources/views/helper/socialButtons.html.twig

{% if facebook is not sameas(false) %} <div class="button facebookButton"> {{ facebookButton(facebook) }} </div> {% endif %} {% if googleplus is not sameas(false) %} <div class="button googleplus"> {{ googlePlusButton(googleplus) }} </div> {% endif %} {% if twitter is not sameas(false) %} <div class="button twitterButton"> {{ twitterButton(twitter) }} </div> {% endif %}

Display the social buttons

You can insert this bar very easily by calling the functions in your templates :

// insert the whole bar with default values
{{ socialButtons() }}

// insert the Twitter button only
{{ twitterButton() }}
// or 
{{ socialButtons( {'googleplus':false, 'facebook':false} ) }}

// insert the google+ button with custom parameters
{{ googlePlusButton( {'locale':'fr', 'url':'http://google.fr' }) }}

// insert the bar with specific values for Facebook
{{ socialButtons( { 'facebook': {'locale':'fr_FR', 'send':true}} ) }}

Share Button

17 thoughts on “Social buttons bar for Facebook, Twitter and G+ with Symfony

  1. Thanks for excellent tutorial, keep it going! :) A+

    p.s. just one thing, in my case it worked when I moved templates to views folder
    //src/Acme/DemoBundle/Resources/VIEWS/helper/socialButtons.html.twig

  2. Hi,

    I’m trying to add this functionality to an implementation of SonataNewsBundle.

    After I created the classes and the functions and the configuration, when using the
    {{ facebookButton() }} in the template, I just get the text /div>

    The {{ twitterButton() }} adds the text Tweet.

    Below there’s an example of the page source, with the js for the FB button… Could you point me in the right direction? What did I do wrong?

    (function(d, s, id) {
    var js, fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s); js.id = id;
    js.src = “//connect.facebook.net/en_US/all.js#xfbml=1″;
    fjs.parentNode.insertBefore(js, fjs);
    }(document, ‘script’, ‘facebook-jssdk’));<div class="fb-like" data-href="http://localhost/pp/web/app_dev.php/news/archive&quot; data-send="" data-layout="button_count" data-width="300" data-show-faces=""/div>

    Regards

    • Hi,

      1) Do you still have your problem?
      2) Which version of Symfony do you use?
      3) Does the {{ twitterButton() }} only display “Tweet”?
      4) Does the Google + button work properly?

      For the moment I have no idea, but let’s find a solution.

      Regards

      • Hi,

        Thank you for replying.
        I use Symfony 2.2.

        The FB button seems to appear after I changed a few issues for the FB button template:

        1. there is no app id
        I looked at the FB SDK and their code has an app id after

        js.src = “//connect.facebook.net/{{locale}}/all.js#xfbml=1″;

        so I modified it to something like

        js.src = “//connect.facebook.net/{{locale}}/all.js#xfbml=1&appId=99999….(number here)”;

        2. the FB code also shows an extra just before the js.
        I’m not sure what it does, but I placed it in the template as well.

        3. You missed a div closing:

        <div class="fb-like" data-href="{{url}}" data-send="{{send}}" data-layout="{{layout}}" data-width="{{width}}" data-show-faces="{{showFaces}}"/div>

        … I guess it should be …
        data-show-faces=”{{showFaces}}”>

        So in the end I have the FB button, though I’m not sure how to test it (since I’m using everything on localhost).

        On to the others, they don’t work at all.
        The google button does not display anything.
        The twitter just the text ‘Tweet’

        Regards,
        Ciprian

  3. In the answer above at point 2, it was about an extra DIV (I guess it got cleaned).
    the code was DIV id=”fb-root” /DIV

    • Since another user told it worked well, I think some code is missing since I wrote again the post (changed the way the code is displayed).
      I think some piece of code are interpreted and not displayed well on this page.
      I’m going to check it now

      • Indeed, there were the following errors :
        - a div was not displayed :
        - a div was not closed properly (the one you found)
        - a link was not displayed properly (in the felper for the twitter button)
        - a div was missing in the helper for the Google+ button
        - 3 div elements were not displayed in the final template (socialButtons.html.twig)

        I hope it work well now. I apologize for the time you wasted because of that, and thank you so much to have seen these errors.

  4. Hi Gregquat,

    thanx for the great tutorial!

    I used you code as base to create a bundle for this => see AzineSocialBarBundle on packagist

    I hope that is ok for you.

    Best regards, Don

    • Hi,

      I’m happy to see the post was helpfull for you. Don’t worry, it’s ok and that is the goal of our posts.
      Thank you for having mentionned us in your bundle documentation.

      Greg

  5. Hey Hi,

    Thanks for such a excellent post but there is an issue regarding facebook. I am getting an error in facebook share it is says that: “Message Failed: This message contains content that has been blocked by our security systems…”

    Krishna

  6. Hello,
    Thanks for such a excellent post, But if i what facebook share instead of like, What i need to do to achive it

    Thanks,
    Laxman Parmar

  7. Hello,

    I am still new in symfony but I didn’t understand few things:

    I follow they entire tutorial but when I try one of the to call twitterButton($parameters) in controller.
    it first doesn’t recognize the parameters from the twig extenstion (I checked with php app/console container:debug and the service is vaild) and if I add custom twig file in the same place it didn’t recognize it.

    how the $this->templating->render working?

    • Hey, the goal of the tutorial is to create Twig helpers to display share buttons.
      So, they are meant to be used in a Twig view and not in a Controller. I hope I helped.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Protected by WP Anti Spam