Hacer un muro de Facebook personalizado con plantillas jQuery

En este tutorial, vamos a crear nuestra propia versión del muro de Facebook. Usaremos la API Graph de Facebook con jQuery y el complemento de plantilla. El complemento jQuery.tmpl nos permitirá definir plantillas dentro de nuestra página y convertir las publicaciones que hemos obtenido de la API en una página HTML real.

Puede usar el ejemplo de hoy para mostrar un feed de las últimas publicaciones en su página o perfil de FB en su sitio web.

Antes de comenzar, digamos algunas palabras sobre la API de Facebook.

La API de gráficos

The Graph es la solución de Facebook para proporcionar una interfaz a cada objeto que existe en el sitio, junto con sus conexiones a otros objetos. Cada página que ve en el sitio tiene una representación gráfica correspondiente, ya sea un usuario, una foto, un grupo, una actualización de estado o cualquier otra cosa. La API también admite solicitudes JSONP, lo que hace que sea muy fácil de usar con jQuery.

Usaremos dos puntos de datos API:uno para seleccionar las últimas publicaciones y el otro para seleccionar el nombre completo y el avatar de la página. Puede ver ejemplos de respuestas a continuación:

http://graph.facebook.com/smashmag/posts/

{
    "data": [{
        "id": "45576747489_10150136051797490",
        "from": {
            "name": "Smashing Magazine",
            "category": "Website",
            "id": "45576747489"
        },
        "message": "Creating a sphere with 3D CSS",
        "picture": "http://platform.ak.fbcdn..",
        "link": "http://bit.ly/epqBBv",
        "name": "Creating a sphere with 3D CSS \u2013 Paul Hayes",
        "caption": "www.paulrhayes.com",
        "description": "A professional slice of newly..",
        "icon": "http://photos-d.ak.fbcdn.net/photos..",
        "actions": [{
            "name": "Share",
            "link": "http://www.facebook.com/share.."
        }],
        "type": "link",
        "application": {
            "name": "Sendible",
            "id": "26065877776"
        },
        "created_time": 1301325483,
        "updated_time": 1301325483,
        "likes": {
            "data": [{
                "name": "Zome Lia",
                "id": "100000643422735"
            }],
            "count": 16
        }
    }]
}

El JSON La respuesta anterior contiene información sobre cada una de las publicaciones publicadas por Smashing Magazine. Algunos de los campos contienen datos sobre la fecha de creación/modificación, número de Me gusta y comentarios, título y descripción, y un tipo. Esta solicitud podría devolver actualizaciones de estado , enlaces compartidos , subió fotos y vídeos y más.

También necesitamos hacer una solicitud adicional para que podamos obtener el avatar, asociado con la página (no está contenido en las respuestas de la publicación):

http://graph.facebook.com/smashmag/

{
    "id": "45576747489",
    "name": "Smashing Magazine",
    "picture": "http://profile.ak.fbcdn.net/hp..",
    "link": "http://www.facebook.com/smashmag",
    "category": "Website",
    "likes": 42696,
    "website": "http://www.smashingmagazine.com/",
    "username": "smashmag",
    "company_overview": "Founded in September 2006..",
    "mission": "The offical Smashing Magazine pa..!",
    "products": "Looking for a web design job? Che.."
}

El campo de imagen de arriba nos da lo que necesitamos. Es un desperdicio solicitar tantos datos, por lo que en el complemento estamos limitando los campos devueltos solo a lo que necesitamos.

Las Plantillas

Ahora digamos algunas palabras sobre las plantillas de jQuery. Como Graph API devuelve datos JSON válidos, es un gran candidato para experimentar con el complemento de plantilla de jQuery. Este complemento oficial nos permite definir bloques de construcción HTML con un marcado fácil de usar. Esto nos evita tener que crear manualmente elementos HTML, concatenar cadenas y secuencias de caracteres de escape.

Las propias plantillas se pueden insertar en línea en una etiqueta de secuencia de comandos especial, o se pueden recibir a través de una llamada AJAX desde un archivo separado. En este tutorial, he elegido el primer enfoque porque es simple y directo.

Cada plantilla tiene la siguiente forma:

<script id="someID" type="text/x-jquery-tmpl">
<!-- HTML markup coupled with template tags -->
</script>

Esta es una etiqueta de script que, debido al atributo de tipo, no es reconocida por el navegador, por lo que no se evalúa ni se muestra. Además, su contenido se trata como datos de caracteres y no se analiza, lo cual es perfecto para la tarea de contener nuestras plantillas. Luego podemos usar el método tmpl() de jQuery y convertirlo en marcado HTML real (más sobre eso en un momento).

Aquí está la primera plantilla, que crea el encabezado de la página:

<script id="headingTpl" type="text/x-jquery-tmpl">
<h1>${name}<span>on Facebook</span></h1>
</script>

La etiqueta de plantilla ${} se reemplaza con el valor de la propiedad de nombre del objeto, que se pasa al método tmpl(), que en nuestro caso es el nombre de la página de Facebook.

La otra plantilla, que muestra las publicaciones individuales, es un poco más compleja y emplea algunas de las funciones de plantilla más avanzadas:

<script id="feedTpl" type="text/x-jquery-tmpl">
<li>
    <img src="${from.picture}" />

    <div>
        <h2><a href="http://www.facebook.com/profile.php?id=${from.id}" target="_blank">${from.name}</a></h2>
        <p>{{html message}}</p>
        {{if type == "link" }}
            <div>
                {{if picture}}
                    <img src="${picture}" />
                {{/if}}
                <div>
                    <p><a href="${link}" target="_blank">${name}</a></p>
                    <p>${caption}</p>
                    <p>${description}</p>
                </div>
            </div>
        {{/if}}
    </div>

    <p>${created_time} ·
    {{if comments}}
        ${comments.count} Comment{{if comments.count>1}}s{{/if}}
    {{else}}
        0 Comments
    {{/if}} ·
    {{if likes}}
        ${likes.count} Like{{if likes.count>1}}s{{/if}}
    {{else}}
        0 Likes
    {{/if}}
    </p>

</li>
</script>

Dentro de las etiquetas de plantilla podemos tener cualquier expresión de JavaScript, incluso llamadas a métodos y funciones. Esto es especialmente útil al construir el {{if}} declaraciones, como puede ver en el código anterior, donde verificamos la cantidad de Me gusta y comentarios.

Una característica del ${} etiqueta es que se escapa del valor textual antes de insertarlo en la plantilla. Sin embargo, en algunos casos esto no es lo que necesita. Por ejemplo, la variable del mensaje contiene el código HTML que queremos mostrar tal cual. Es por eso que usamos el {{html}} en su lugar, que conserva el formato original del código.

Y aquí está el documento HTML con el que terminamos:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Making a Custom Facebook Wall with jQuery | Tutorialzine Demo</title>
<link rel="stylesheet" type="text/css" href="css/styles.css" />

</head>
<body>

<div id="page">

    <div id="wall"></div>

</div>

<!-- jQuery templates. Not rendered by the browser. Notice the type attributes -->

<script id="headingTpl" type="text/x-jquery-tmpl">
<h1>${name}<span>on Facebook</span></h1>
</script>

<script id="feedTpl" type="text/x-jquery-tmpl">
<li>
    <img src="${from.picture}" class="avatar" />

    <div class="status">
        <h2><a href="http://www.facebook.com/profile.php?id=${from.id}" target="_blank">${from.name}</a></h2>
        <p class="message">{{html message}}</p>
        {{if type == "link" }}
            <div class="attachment">
                {{if picture}}
                    <img class="picture" src="${picture}" />
                {{/if}}
                <div class="attachment-data">
                    <p class="name"><a href="${link}" target="_blank">${name}</a></p>
                    <p class="caption">${caption}</p>
                    <p class="description">${description}</p>
                </div>
            </div>
        {{/if}}
    </div>

    <p class="meta">${created_time} ·
    {{if comments}}
        ${comments.count} Comment{{if comments.count>1}}s{{/if}}
    {{else}}
        0 Comments
    {{/if}} ·
    {{if likes}}
        ${likes.count} Like{{if likes.count>1}}s{{/if}}
    {{else}}
        0 Likes
    {{/if}}
    </p>

</li>
</script>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script src="js/jquery.tmpl.min.js"></script>
<script src="js/script.js"></script>

</body>
</html>

El #muro div se completará dinámicamente con los datos de Graph API, después de que se haya representado con nuestras plantillas. Puede ver las plantillas en sí mismas en la parte inferior del archivo. Antes de la etiqueta del cuerpo de cierre, he incluido la biblioteca jQuery , el jQuery.tmpl complemento, y nuestro script.js archivo, que discutiremos a continuación.

Código jQuery

Como tenemos todas las piezas en su lugar, finalmente podemos comenzar a escribir nuestro complemento de muro de Facebook.

secuencia de comandos.js

// Creating our plugin.

(function($){

    $.fn.facebookWall = function(options){

        options = options || {};

        if(!options.id){
            throw new Error('You need to provide an user/page id!');
        }

        // Default options of the plugin:

        options = $.extend({
            limit: 15   // You can also pass a custom limit as a parameter.
        },options);

        // Putting together the Facebook Graph API URLs:

        var graphUSER = 'http://graph.facebook.com/'+options.id+'/?fields=name,picture&callback=?',
            graphPOSTS = 'http://graph.facebook.com/'+options.id+'/posts/?callback=?&date_format=U&limit='+options.limit;

        var wall = this;

        $.when($.getJSON(graphUSER),$.getJSON(graphPOSTS)).done(function(user,posts){

            // user[0] contains information about the user (name and picture);
            // posts[0].data is an array with wall posts;

            var fb = {
                user : user[0],
                posts : []
            };

            $.each(posts[0].data,function(){

                // We only show links and statuses from the posts feed:
                if(this.type != 'link' && this.type!='status'){
                    return true;
                }

                // Copying the user avatar to each post, so it is
                // easier to generate the templates:
                this.from.picture = fb.user.picture.data.url;

                // Converting the created_time (a UNIX timestamp) to
                // a relative time offset (e.g. 5 minutes ago):
                this.created_time = relativeTime(this.created_time*1000);

                // Converting URL strings to actual hyperlinks:
                this.message = urlHyperlinks(this.message);

                fb.posts.push(this);
            });

            // Rendering the templates:
            $('#headingTpl').tmpl(fb.user).appendTo(wall);

            // Creating an unordered list for the posts:
            var ul = $('<ul>').appendTo(wall);

            // Generating the feed template and appending:
            $('#feedTpl').tmpl(fb.posts).appendTo(ul);
        });

        return this;

    };

    // Helper functions:

    function urlHyperlinks(str){
        return str.replace(/\b((http|https):\/\/\S+)/g,'<a href="$1" target="_blank">$1</a>');
    }

    function relativeTime(time){

        // Adapted from James Herdman's http://bit.ly/e5Jnxe

        var period = new Date(time);
        var delta = new Date() - period;

        if (delta <= 10000) {    // Less than 10 seconds ago
            return 'Just now';
        }

        var units = null;

        var conversions = {
            millisecond: 1,     // ms -> ms
            second: 1000,       // ms -> sec
            minute: 60,         // sec -> min
            hour: 60,           // min -> hour
            day: 24,            // hour -> day
            month: 30,          // day -> month (roughly)
            year: 12            // month -> year
        };

        for (var key in conversions) {
            if (delta < conversions[key]) {
                break;
            }
            else {
                units = key;
                delta = delta / conversions[key];
            }
        }

        // Pluralize if necessary:

        delta = Math.floor(delta);
        if (delta !== 1) { units += 's'; }
        return [delta, units, "ago"].join(' ');

    }

})(jQuery);

Estamos usando el $.getJSON funciones para solicitar información de la API Graph. Pero puede notar que no lo estamos usando como lo hicimos en tutoriales anteriores, es decir, proporcionando una función de devolución de llamada como su segundo parámetro. Esto se debe a que queremos que ambas llamadas a Graph API se ejecuten al mismo tiempo (a toda velocidad), lo que no es posible con una simple devolución de llamada.

A partir de jQuery 1.5, todos los métodos AJAX devuelven un objeto diferido, lo que básicamente nos permite agrupar una cantidad de llamadas AJAX en $.when(). Después de que ambas solicitudes AJAX se completen con éxito, el método done se ejecuta una vez.

Después de esto, podemos simplemente renderizar las plantillas:

// Rendering the templates:
$('#headingTpl').tmpl(fb.user).appendTo(wall);

// Creating an unordered list for the posts:
var ul = $('<ul>').appendTo(wall);

// Generating the feed template and appending:
$('#feedTpl').tmpl(fb.posts).appendTo(ul);

El método tmpl() toma un objeto o una matriz de JavaScript y representa la plantilla una vez por cada elemento. Las plantillas se especifican por sus ID (el #headingTpl y #feedTpl elementos de script en nuestro caso).

Finalmente, solo tenemos que llamar al complemento en document.ready con la ID de su página y su token de acceso (más sobre esto en un momento):

$(document).ready(function(){

    // Calling our plugin with a page id:
    $('#wall').facebookWall({
        id:'smashmag',
        access_token:'19304297594165|ZGyz1d0clt2XO3AyrjHmrKORo'
    });

});

Obtención de un token de acceso

El primer paso para obtener un token de acceso es registrarse como desarrollador en http://developers.facebook.com. Después de esto, deberá crear una nueva aplicación de Facebook. Es un proceso simple y no necesita ingresar ningún dato excepto el nombre de la aplicación. Esto le dará una ID de aplicación y un secreto de aplicación , que puede ver en la página "Mis aplicaciones".

A continuación, debe visitar la siguiente URL, reemplazando APP_ID y APP_SECRET con los valores de su aplicación:

https://graph.facebook.com/oauth/access_token?grant_type=client_credentials&client_id=APP_ID&client_secret=APP_SECRET

Esto le dará una cadena, similar a esta:

access_token=19304297594165|ZGyz1d0clt2XO3AyrjHmrKORo

Este es su token de acceso. Deberá incluir la cadena después del signo igual cuando llame al facebookWall complemento en la sección anterior.

¡Con esto nuestro muro personalizado de Facebook está completo!

Conclusión

Con suerte, en el tutorial de hoy, vio que las plantillas son una gran herramienta para tener en su arsenal de jQuery. El complemento de plantilla hace que sea muy fácil definir, renderizar y almacenar plantillas. En combinación con algunas de sus características más avanzadas, puede crear aplicaciones web fáciles de mantener, sin enredarse en largas cadenas de selectores de jQuery.

¿Te gusta este tutorial? ¿Cómo mejorarías el ejemplo? Comparta sus pensamientos en la sección de comentarios a continuación.