Créer une barre de boutons sociaux pour Facebook, Twitter et Google+ avec Symfony2

Share Button

Read the English version

Nous allons créer une barre de boutons sociaux pour partager une page sur Facebook, Twitter et Google+ avec Symfony2 et Twig.

Le résultat escompté est quelque chose qui ressemble à :

Créez les helpers

La première étape est de créer les helpers. Comme vous le voyez, nous créons un helper pour chaque bouton, plus un autre pour “les gouverner tous”.

<?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';
    }
}

Créez les fonctions Twig

Nous pouvons maintenant créer les fonctions Twig. Comme pour les helpers, nous allons créer trois fonction pour afficher chacun des boutons et une dernière fonction qui affichera tous les boutons sociaux. Cette dernière fonction nous permettra également de n’afficher que deux boutons, ou même un seul.

<?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())
    {
      // Aucun paramètre défini, on garde les valeurs par défaut
      if (!array_key_exists('facebook', $parameters)){
        $render_parameters['facebook'] = array();
      // des paramètres sont définis, on surcharge les valeurs
      }else if(is_array($parameters['facebook'])){
        $render_parameters['facebook'] = $parameters['facebook'];
      // le bouton n'est pas affiché
      }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;
      }

      // récupère le service du helper et affiche le template
      return $this->container->get('acme.socialBarHelper')->socialButtons($render_parameters);
    }
 
    // https://developers.facebook.com/docs/reference/plugins/like/ 
    public function getFacebookLikeButton($parameters = array())
    {
       // valeurs par défaut. Vous pouvez les surcharger en les définissant
       $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);
    }
}

Définissez les services

Maintenant, nous devons enregistrer les services dans le conteneur de services pour que les helpers et les fonctions Twig puissent fonctionner ensembles.

# 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 ]

Ajoutez les templates

Enfin, nous pouvons créer les quatre templates (un pour chaque bouton et celui qui affiche la barre complète).

Le template du bouton Facebook :

// 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 %}

Le template du bouton Twitter :

// 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 %}

Le template du bouton Google+ :

// 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 %}

Et pour finir, le template Unique :

// 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 %}

Intégrer les boutons sociaux

Vous pouvez insérer cette barre très facilement en appelant les fonctions dans vos templates :

// insère la barre complète avec les valeurs par défaut
{{ socialButtons() }}

// insère seulement le bouton Twitter
{{ twitterButton() }}
// ou 
{{ socialButtons( {'googleplus':false, 'facebook':false} ) }}

// insère le bouton google+ avec des paramètres personnalisés
{{ googlePlusButton( {'locale':'fr', 'url':'http://google.fr' }) }}

// insère la barre complète avec des valeurs spécifiques pour Facebook
{{ socialButtons( { 'facebook': {'locale':'fr_FR', 'send':true}} ) }}

Share Button

3 thoughts on “Créer une barre de boutons sociaux pour Facebook, Twitter et Google+ avec Symfony2

  1. Hello,
    I’m from France so , sorry for my basic langage ;)
    thx for this tuto, very nice :)

    I contact you because I have a problem with the FacebookLike button.

    My website is not actually in prod on the web but only in dev on my PC with Wampserver.

    the FacebookLike button doesn’t appear !!

    I’m searching but if you have the solution, it would be very nice

    thank’s very much

    marc

  2. Why inject container ? Why not inject directly “acme.socialBarHelper” in AcmeTwigSocialBar ?
    I dislike share button with js, alternative without js : nojs-socialshare on GitHub

  3. Hi,
    Injecting the service_container avoids circular reference to the “templating” service issue.

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