Social button un po’ più accessibili e con sintassi XHTML valida

Cerchiamo di migliorare i widget che forniscono Facebook, Twitter e Google.

Da diverso tempo collaboro con APT Servizi allo sviluppo del portale turistico dell’Emilia-Romagna e a volte mi capita di dover far andar d’accordo i requisiti di accessibilità con aspetti che hanno esigenze del tutto diverse.

Un caso che mi è successo di recente è la richiesta dell’inserimento dei pulsanti con i contatori per la condivisione delle informazioni sui principali social network.

I widget che vengono forniti già pronti spesso sono poco accessibili e realizzati con tag o attributi proprietari che rendono il codice sintatticamente non valido.

Come possiamo cercare di migliorare la situazione?

Facebook

Il codice che viene fornito per il pulsante con “like” non è un granché.

Innanzi tutto seguiamo le indicazioni che suggeriscono di mettere nel tag HTML il riferimento al namespace proprietario per far apparire il pulsante anche nelle vecchie versioni di Internet Explorer:

<html xmlns:fb="http://ogp.me/ns/fb">

Poi lavoriamo un po’ sul codice per cercare di risolvere i problemi principali di questo widget: il tag e/o gli attributi proprietari che quindi non sono riconosciuti dal validatore sintattico e il fatto che senza JavaScript il pulsante non compare.

Ecco, dunque, il frammento di codice da inserire dove di vuole fare apparire il pulsante:

<div id="bfacebook" class="fb-like"><a class="external-link" href="http://www.facebook.com/share.php?u=http://www.dominio.it/pagina"><img id="facebook-link" width="16" height="16" alt="Condividi su Facebook" title="Condividi su Facebook" src="facebook-ico.gif" /></a></div>
<script type="text/javascript">
<!--
(function(d, s, id) {

    var t = d.getElementById('bfacebook');
    t.innerHTML = '';
    // t.setAttribute('data-send', 'true');
    t.setAttribute('data-layout', 'button_count');

    var js, fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s); js.id = id;
    js.src = "//connect.facebook.net/it_IT/all.js#xfbml=1";
    fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
-->
</script>

In questo modo il codice della pagina diventa sintatticamente corretto e senza di JavaScript il pulsante con il contatore viene sostituito da una immagine e un link che consentono comunque di assegnare il “mi piace” e di segnalare la pagina.

{ho evidenziato “http://www.dominio.it/pagina” e “facebook-ico.gif” perché dovrete sostituirli con quelli adatti al vostro caso: il primo è l’URL della pagina e il secondo è l’URL dell’immagine sostitutiva nel caso il JavaScript non sia operativo}

Il risultato ottenuto, però, non è ancora molto accessibile perché non permette la navigazione tramite tastiera. Purtroppo non è neanche possibile cercare di correggerlo seguendo i preziosi consigli di Jacopo Deyla perché bisognerebbe intervenire con codice JavaScript su di un iframe caricato da un altro dominio, cosa non permessa dai browser per motivi di sicurezza.

Perché, allora, non provare ad usare il vecchio pulsante, quello con “share”?

Quest’ultimo, effettivamente, si presta molto meglio ai nostri scopi perché non usa iframe e l’unico aspetto negativo è che essendo deprecato forse un giorno non funzionerà più.

Ecco il frammento:

<div id="bfacebook">
<a type='button_count' id="fb_share" href="http://www.facebook.com/share.php?u=http://www.dominio.it/pagina"  class="external-link"><img id="facebook-link" src="facebook-ico.gif" width="16" height="16" alt="Condividi su Facebook" title="Condividi su Facebook" /></a>
<script type="text/javascript">
<!--
(function(d, s, id){
    var div = jq('#bfacebook');
    var a = jq('#fb_share');
    div.css('width', '107px');
    a.attr('name', 'fb_share');
    a.html('');

    var js, fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s); js.id = id;
    js.src = "//static.ak.fbcdn.net/connect.php/js/FB.Share";
    fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jsshare'));

function setupFB() {
    no_count = $('.fb_share_no_count');
    if (no_count.length) {
        no_count.removeClass('fb_share_no_count');
        var button = $('.FBConnectButton');
        var inner = $('.fb_share_count_inner');
        var count = $('.fb_share_count');
        button.css('webkit-border-radius', '3px');
        button.css('moz-border-radius', '3px');
        button.css('border-radius', '3px');
        count.css('webkit-border-radius', '3px');
        count.css('moz-border-radius', '3px');
        count.css('border-radius', '3px');
        inner.css('background-color', '#ffffff')
        inner.css('webkit-border-radius', '3px');
        inner.css('moz-border-radius', '3px');
        inner.css('border-radius', '3px');
        inner.css('font-weight', 'normal');
        inner.text('0');
    } else
        setTimeout('setupFB()', 250);
}
$(setupFB());
-->
</script>
</div>

{analogo discorso a quello fatto precedentemente per “http://www.dominio.it/pagina” e “facebook-ico.gif“}

In questa versione ho anche fatto un po’ di restyling grafico per uniformare l’aspetto del pulsante a quello degli altri due, per semplicità ho usato istruzioni jQuery (sono quelle che iniziano con “$”).

Twitter

Il codice che ci viene suggerito, per accessibilità e validità sintattica, è già molto buono, ho solo sostituito il testo “Tweet” con un’icona per uniformare il risultato in caso di JavaScript disabilitato:

<div><a class="twitter-share-button external-link" href="https://twitter.com/share?url=http://www.dominio.it/pagina&amp;lang=it&amp;via=artifex_it"><img width="16" height="16" alt="Condividi su Twitter" title="Condividi su Twitter" src="twitter-ico.gif" /></a></div>
<script type="text/javascript">
<!--
!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>

{anche qui ho evidenziato “http://www.dominio.it/pagina“, “artifex_it” e “twitter-ico.gif” perché dovrete sostituirli con quelli adatti al vostro caso, “artifex_it” è un account twitter. Se non volete indicare un account twitter basta eliminare “&amp;via=artifex_it“}

Google +

Infine ecco il widget per Google +, che non funziona con browser un po’ datati (esempio IE7):

<div id="bplusone"><a href="https://plusone.google.com/_/+1/confirm?hl=it&amp;url='http://www.dominio.it/pagina" class="external-link"><img src="plusone-ico.gif" width="16" height="16" alt="Condividi su Google Plus" title="Condividi su Google Plus" /></a></div>
<script type="text/javascript">
<!--
  window.___gcfg = {lang: 'it'};

  (function() {

    var t = document.getElementById('bplusone');
    var bt = document.createElement('g:plusone');
    bt.setAttribute('size', 'medium');
    // t.parentNode.insertBefore(bt, t);
    t.parentNode.replaceChild(bt, t);

    // alert(document.getElementsByTagName('g:plusone'));

    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>

{come nei casi precedenti “http://www.dominio.it/pagina” e “plusone-ico.gif” andranno personalizzati secondo il caso.}

Una viewlet per Plone

Se usate Plone potete creare una viewlet con il seguente template ed inserirla nel punto della pagina che preferite

<div id="share-links" tal:define="actual_url context/REQUEST/ACTUAL_URL;
                                  query_string python:context.REQUEST['QUERY_STRING'] != '' and '?' + context.REQUEST['QUERY_STRING'] or '';
                                  full_url string:${actual_url}${query_string}">
    <ul>
        <li tal:condition="nothing">
            <!-- FACEBOOK LIKE -->
            <div id="bfacebook" class="fb-like"><a tal:attributes="href python:'http://www.facebook.com/share.php?u=' + full_url" class="external-link"><img id="facebook-link" tal:attributes="src string:${context/portal_url}/portal_skins/custom/facebook-ico.gif" width="16" height="16" alt="Condividi su Facebook" title="Condividi su Facebook" i18n:attributes="alt facebook-share-alt; title facebook-share-title" /></a></div>
            <script type="text/javascript">
            <!--
            (function(d, s, id) {

                var t = d.getElementById('bfacebook');
                t.innerHTML = '';
                // t.setAttribute('data-send', 'true');
                t.setAttribute('data-layout', 'button_count');

                var js, fjs = d.getElementsByTagName(s)[0];
                if (d.getElementById(id)) return;
                js = d.createElement(s); js.id = id;
                js.src = "//connect.facebook.net/it_IT/all.js#xfbml=1";
                fjs.parentNode.insertBefore(js, fjs);
            }(document, 'script', 'facebook-jssdk'));
            -->
            </script>
        </li>
        <li>
            <!-- FACEBOOK SHARE-->
            <div id="bfacebook">
            <a type='button_count' id="fb_share" tal:attributes="href python:'http://www.facebook.com/share.php?u=' + full_url"  class="external-link"><img id="facebook-link" tal:attributes="src string:${context/portal_url}/portal_skins/custom/facebook-ico.gif" width="16" height="16" alt="Condividi su Facebook" title="Condividi su Facebook" i18n:attributes="alt facebook-share-alt; title facebook-share-title" /></a>
            <script type="text/javascript">
            <!--
            (function(d, s, id){
                var div = jq('#bfacebook');
                var a = jq('#fb_share');
                div.css('width', '107px');
                a.attr('name', 'fb_share');
                a.html('');

                var js, fjs = d.getElementsByTagName(s)[0];
                if (d.getElementById(id)) return;
                js = d.createElement(s); js.id = id;
                js.src = "//static.ak.fbcdn.net/connect.php/js/FB.Share";
                fjs.parentNode.insertBefore(js, fjs);
            }(document, 'script', 'facebook-jsshare'));

            function setupFB() {
                no_count = jq('.fb_share_no_count');
                if (no_count.length) {
                    no_count.removeClass('fb_share_no_count');
                    var button = jq('.FBConnectButton');
                    var inner = jq('.fb_share_count_inner');
                    var count = jq('.fb_share_count');
                    button.css('webkit-border-radius', '3px');
                    button.css('moz-border-radius', '3px');
                    button.css('border-radius', '3px');
                    count.css('webkit-border-radius', '3px');
                    count.css('moz-border-radius', '3px');
                    count.css('border-radius', '3px');
                    inner.css('background-color', '#ffffff')
                    inner.css('webkit-border-radius', '3px');
                    inner.css('moz-border-radius', '3px');
                    inner.css('border-radius', '3px');
                    inner.css('font-weight', 'normal');
                    inner.text('0');
                } else
                    setTimeout('setupFB()', 250);
            }
            jq(setupFB());
            -->
            </script>
            </div>
        </li>
        <li>
            <!-- TWITTER -->
            <div><a tal:attributes="href python: 'https://twitter.com/share?url=' + full_url + '&amp;lang=' + context.REQUEST['LANGUAGE'] + '&amp;via=artifexit'" class="twitter-share-button external-link"><img tal:attributes="src string:${context/portal_url}/portal_skins/custom/twitter-ico.gif" width="16" height="16" alt="Condividi su Twitter" title="Condividi su Twitter" i18n:attributes="alt twitter-share-alt; title twitter-share-title" /></a></div>
            <script type="text/javascript">
            <!--
            !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>
        </li>
        <li>
            <!-- GOOGLE + -->
            <div id="bplusone"><a tal:attributes="href python: 'https://plusone.google.com/_/+1/confirm?hl=' + context.REQUEST['LANGUAGE'] + '&amp;url=' + full_url" class="external-link"><img tal:attributes="src string:${context/portal_url}/portal_skins/custom/plusone-ico.gif" width="16" height="16" alt="Condividi su Google Plus" title="Condividi su Google Plus" i18n:attributes="alt plusone-share-alt; title plusone-share-title" /></a></div>
            <script type="text/javascript">
            <!--
              window.___gcfg = {lang: 'it'};

              (function() {

                var t = document.getElementById('bplusone');
                var bt = document.createElement('g:plusone');
                bt.setAttribute('size', 'medium');
                // t.parentNode.insertBefore(bt, t);
                t.parentNode.replaceChild(bt, t);

                // alert(document.getElementsByTagName('g:plusone'));

                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>
        </li>
    </ul>
</div>
Oppure, se siete pigri come me, potete personalizzare direttamente via web (con la ZMI) i template di visualizzazione dei tipi di contenuti che usate nel sito.
{anche in questo caso, come nei precedenti, per le immagini bisogna indicare i riferimenti che sono adatti alla propria installazione, ad esempio “${context/portal_url}/portal_skins/custom/plusone-ico.gif” per Google +, e occorre sostituire “artifex_it” con il proprio account twitter oppure eliminare “&amp;via=artifex_it” se non lo si vuole indicare}

Conclusioni

Siamo riusciti a rendere sintatticamente valido il codice XHTML 1.1 che fa apparire i pulsanti per la condivisione sui social network nella versione con i contatori delle attività.

Abbiamo cercato di rendere il tutto un po’ più accessibile e fare in modo che tutto funzionasse anche senza JavaScript.

Le pagine di questo sito sono fatte utilizzando il codice descritto in questo articolo e potete provare a verificarne la correttezza sintattica o il funzionamento senza JavaScript.

Il rispetto dei requisiti di accessibilità può anche essere divertente se non visto come sterile imposizione ma come sfida intellettuale! 🙂

2 commenti su “Social button un po’ più accessibili e con sintassi XHTML valida”

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *