Krypton Solid

Cómo crear un complemento de contenido incrustable para WordPress – Smashing Magazine

Cómo crear un complemento de contenido incrustable para WordPress – Smashing Magazine

WordPress es uno de los sistemas de gestión de contenido más implementados. Una de las principales razones es la cantidad de complementos disponibles y la facilidad con la que podemos usar el sistema. No es raro encontrar sitios web que utilizan decenas de complementos para realizar diversas tareas y funciones. ¿No sería bueno si pudiera compartir el contenido de su sitio con otros sitios web?

Es posible que tenga la necesidad de compartir anuncios, información de productos o, si es diseñador, su galería de fotos. Cualquiera sea el motivo, este artículo le mostrará una forma de crear un complemento de contenido incrustable para compartir su contenido de WordPress con otros sitios web.

Hay varias formas de compartir contenido en sitios web: feeds RSS y Atom, API y widgets integrables. Las fuentes RSS en WordPress generalmente están restringidas a publicaciones, mientras que las API no son fáciles de integrar en otros sitios web sin agregar código adicional. Esto nos deja con widgets incrustables, como los que utiliza Google AdSense para mostrar anuncios en sitios web o los botones «Compartir» y «Me gusta» de Facebook; todos ellos dependen del código JavaScript incrustable para mostrar contenido específico en un sitio web.

La idea mencionada en este artículo ciertamente no es nueva, pero en el contexto de WordPress abre muchas posibilidades. Las ventajas de la técnica mencionada aquí en comparación con otras es que le permitirá compartir casi cualquier contenido, incluso contenido de otros complementos en su blog, con otros sitios web.

Nuestro objetivo en este artículo es crear un código de widget que un usuario pueda insertar en su sitio web para mostrar una lista de publicaciones recientes del sitio web principal. Por supuesto, esto también se puede lograr fácilmente usando RSS, pero esto es solo un ejemplo para mostrar la técnica. En realidad, lo usaría para fines más interesantes, como compartir imágenes de productos populares si está ejecutando un sitio web de comercio electrónico de WordPress.

El código del widget

El código incrustable tendrá un aspecto similar al siguiente. Este es el código que el usuario insertará en su página web, lo que le permitirá mostrar el contenido del sitio web principal. El elemento crucial de este widget es el wp-widget.js file, que llama al sitio web remoto de WordPress, obtiene el contenido y lo incrusta como un iframe en la página de llamada.

<script type="text/javascript">
  var widget_embed = 'posts';
</script>
<script src="http://www.example.com/widget/wp-widget.js"
type="text/javascript">
</script>
<div id="embed-widget-container"></div>

Agregar este bloque de código a cualquier página del sitio web mostrará la lista de publicaciones recientes de example.com. El contenido puede ser cualquier cosa además de publicaciones: imágenes, comentarios, etiquetas, datos de otros complementos, cualquier cosa que usted, como propietario de un sitio web de WordPress, le gustaría compartir con otras personas. Para este ejemplo, he limitado el contenido a una simple lista de publicaciones, ya que este es un denominador común en todos los sitios web de WordPress y será fácil comenzar con él. Por supuesto, deberá agregar código adicional para compartir otro contenido, pero el esqueleto del complemento base seguirá siendo el mismo.

Creando el complemento

El primer paso para crear un widget integrable es diseñar un pequeño complemento de WordPress que interceptará las llamadas del widget desde otro sitio web y devolverá los datos requeridos. Puede estar pensando que este será un trabajo complicado, pero nada podría ser más fácil. Solo unas pocas líneas de código y nuestro complemento está listo. El código completo del complemento se muestra a continuación. Explicaré cómo funciona esto a medida que avancemos.

Para obtener el contenido del complemento, necesitaremos pasar un parámetro de consulta de qué contenido nos gustaría del servidor remoto en el em_embed variable. Este parámetro de consulta será interceptado por el complemento y se devolverá el contenido correspondiente. También pasaremos implícitamente la URL del dominio de la página de llamada, para que luego podamos usarla con fines analíticos o para restringir los sitios web que pueden incrustar nuestro widget.

Por ejemplo, para obtener la lista de publicaciones recientes, debemos enviar un GET consulta al sitio web principal de WordPress como se muestra a continuación. Por supuesto, esta consulta será creada por nuestro widget de JavaScript, wp-widget.js.

http://www.example.com/?em_embed=posts

El código completo del complemento se proporciona a continuación.

<?php

/**
 * Plugin Name: WordPress Widget Embed
 * Description: Allow people to embed WordPress content in an iframe on other websites
 * Version: 1.0
 * Author: Sameer Borate
 * Author URI: http://www.codediesel.com
 */

class WPWidgetEmbed  
{
    public function __construct()
    {
        add_action('template_redirect', array($this, 'catch_widget_query'));
        add_action('init', array($this, 'widget_add_vars'));
    }

    /**
     * Adds our widget query variable to WordPress $vars
     */
    public function widget_add_vars() 
    { 
        global $wp; 
        $wp->add_query_var('em_embed'); 
        $wp->add_query_var('em_domain'); 
    }

    private function export_posts()
    {
        $outstring  = '<html>';
        $outstring .= '<head><style>';
        $outstring .= 'ul {
                padding:0;
                margin:0;
              }
              li {
                 list-style-type:none;
               }';
        $outstring .= '</style></head><body>';

        /* Here we get recent posts for the blog */
        $args = array(
            'numberposts' => 6,
            'offset' => 0,
            'category' => 0,
            'orderby' => 'post_date',
            'order' => 'DESC',
            'post_type' => 'post',
            'post_status' => 'publish',
            'suppress_filters' => true
        );

        $recent_posts = wp_get_recent_posts($args);

        $outstring .= '<div class="widget-posts"><ul>';
        foreach($recent_posts as $recent)
        {
            $outstring .= '<li><a target="_blank" href="' . get_permalink($recent["ID"]) . '">' . $recent["post_title"]. '</a></li>';
        }

        $outstring .= '</ul></div>';
        $outstring .= '</body></html>';

        return $outstring;
    }

    /**
     * Catches our query variable. If it’s there, we’ll stop the
     * rest of WordPress from loading and do our thing, whatever 
     * that may be.

     */
    public function catch_widget_query()
    {
        /* If no 'embed' parameter found, return */
        if(!get_query_var('em_embed')) return;

        /* 'embed' variable is set, export any content you like */

        if(get_query_var('em_embed') == 'posts')
        { 
            $data_to_embed = $this->export_posts();
            echo $data_to_embed;
        }

        exit();
    }
}

$widget = new WPWidgetEmbed();

?>

Para interceptar correctamente las llamadas de otro sitio web, primero debemos agregar el em_embed y em_domain parámetros a nuestro WordPress query_var variable. Esto se utilizará más adelante para ver qué tipo de datos deben enviarse al sitio web remoto. Esto se realiza mediante la siguiente función.

public function widget_add_vars() 
{ 
    global $wp; 
    $wp->add_query_var('em_embed'); 
    $wp->add_query_var('em_domain');
}

A continuación, necesitaremos capturar la variable de consulta en el template_redirect enganchar y procesar cualquier dato si el em_embed La variable se establece en la variable global.

public function catch_widget_query()
{
    /* If no 'embed' parameter found, return */
    if(!get_query_var('em_embed')) return;

    /* 'embed' variable is set, export any content you like */

    if(get_query_var('em_embed') == 'posts')
    { 
        $data_to_embed = $this->export_posts();
        echo $data_to_embed;
    }

    exit();
}

En nuestro ejemplo, exportaremos una lista de títulos de publicaciones recientes, por lo que nuestro export_posts La función se verá como a continuación.

private function export_posts()
{
    $outstring  = '<html>';
    $outstring .= '<head><style>';
    $outstring .= 'ul {
             padding-left:10px;
             margin:0;
          }

          li > a {
             text-decoration: none;
             font-family: Arial, Helvetica, Sans-serif;
             font-size:12px;

          }

          li {
             border-bottom: 1px solid #c0c0c0;
             padding: 3px 0 3px 0;
          }

          .widget-posts {
             width: 250px;
             border: 1px solid #c0c0c0;
             padding: 12px;
             margin-left: 3px;
          }';
    $outstring .= '</style></head><body>';

    /* Here we get recent posts for the blog */
    $args = array(
        'numberposts' => 6,
        'offset' => 0,
        'category' => 0,
        'orderby' => 'post_date',
        'order' => 'DESC',
        'post_type' => 'post',
        'post_status' => 'publish',
        'suppress_filters' => true
    );

    $recent_posts = wp_get_recent_posts($args);

    $outstring .= '<div id="widget-posts"><ul>';
    foreach($recent_posts as $recent)
    {
        $outstring .= '<li><a target="_blank" href="' . get_permalink($recent["ID"]) . '">' . $recent["post_title"]. '</a></li>';
    }

    $outstring .= '</ul></div>';
    $outstring .= '</body></html>';

    return $outstring;
}

Esto es todo lo que hay en el complemento. Si necesita exportar cualquier otro dato, deberá reemplazar el código para obtener publicaciones con el código para obtener los datos que desee.

Escribir el código del widget integrable

Ahora hemos completado solo la parte del complemento de WordPress. Todavía tenemos que escribir el código de incrustación de JavaScript que accederá de forma remota a nuestro sitio web e insertará el contenido apropiado en la página de llamada. La forma más sencilla de mostrar contenido de otro sitio web en su página web es mediante un iframe. El código necesario para incrustar el contenido en un sitio web se muestra a continuación.

<script type="text/javascript">
  var widget_embed = 'posts';
</script>
<script src="http://www.example.com/widget/wp-widget.js"
type="text/javascript">
</script>
<div id="embed-widget-container"></div>

Si va a utilizar el widget para devolver solo un tipo de datos, puede eliminar el widget_embed variable. Entonces tendrás algo como lo siguiente.

<script src="http://www.example.com/widget/wp-widget.js"
type="text/javascript">
</script>
<div id="embed-widget-container"></div>

wp-widget.js es el JavaScript que hace todo el trabajo de llamar al sitio web remoto de WordPress y agregar el contenido al iframe. Necesitas colocar el wp-widget.js archivo en un subdirectorio de su sitio web de WordPress; el nombre exacto y la ubicación no importa.

El código completo para el wp-widget.js se muestra a continuación y se explica por sí mismo.

/**
  * wp-widget.js
  *
  * Inserts an iframe into the DOM and calls the remote embed plugin
  * via a get parameter:
  * e.g http://www.example.com/?embed=posts
  * This is intercepted by the remote 'WordPress Widget Embed' plugin
  *
  */

(function() {

// Localize jQuery variable
var jQuery;

/* Load jQuery if not present */
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.7.2') 
{
    var script_tag = document.createElement('script');
    script_tag.setAttribute("type","text/javascript");
    script_tag.setAttribute("src",
        "http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js");
    if (script_tag.readyState) 
    {
      script_tag.onreadystatechange = function () 
      { // For old versions of IE
          if (this.readyState == 'complete' || this.readyState == 'loaded') 
          {
              scriptLoadHandler();
          }
      };
    } 
    else 
    {
      script_tag.onload = scriptLoadHandler;
    }

    (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
} 
else 
{
    // The jQuery version on the window is the one we want to use
    jQuery = window.jQuery;
    main();
}

/* Called once jQuery has loaded */
function scriptLoadHandler() 
{
    jQuery = window.jQuery.noConflict(true);
    main(); 
}

/* Our Start function */
function main() 
{ 
    jQuery(document).ready(function($) 
    { 
        /* Get 'embed' parameter from the query */
        var widget = window.widget_embed;
        var domain = encodeURIComponent(window.document.location);

        /* Set 'height' and 'width' according to the content type */
        var iframeContent="<iframe style="overflow-y: hidden;" 
                             height="550" width="400" frameborder="0" 
                             border="0" cellspacing="0" scrolling="no" 
                             src="http://www.example.com/?em_embed=" + widget + '&em_domain=' + domain + '"></iframe>';

        $("#embed-widget-container").html(iframeContent);
    });
}

})();

La tarea de insertar el iframe y el contenido de WordPress en el DOM la realiza el main() función. El tamaño del iframe debe cambiarse según sus requisitos o crearse dinámicamente permitiendo que el usuario pase parámetros adicionales junto con el widget_embed variable en el código del widget principal.

Agregar CSS personalizado al contenido

También puede agregar CSS personalizado al contenido mostrado a través del complemento. A continuación, se proporciona un ejemplo de CSS para combinar con el complemento anterior. También puede especificar una URL de hoja de estilo si es necesario.

private function export_posts()
{
    $outstring  = '<html>';
    $outstring .= '<head><style>';
    $outstring .= 'ul {
             padding-left:10px;
             margin:0;
          }

          li > a {
             text-decoration: none;
             font-family: Arial, Helvetica, Sans-serif;
             font-size:12px;
          }

          li {
             border-bottom: 1px solid #c0c0c0;
             padding: 3px 0 3px 0;
          }

          .widget-posts {
             width: 250px;
             border: 1px solid #c0c0c0;
             padding: 12px;
             margin-left: 3px;
          }';
    $outstring .= '</style></head><body>';
    .
    .

El tipo de CSS que agregue al contenido dependerá del contenido que esté mostrando. Con un poco de codificación creativa, también puede permitir que el usuario agregue ciertas opciones de visualización al widget con las que puede controlar el estilo de visualización del widget incrustado.

Restricción de la visualización a determinados dominios

Es posible que desee permitir que solo ciertos dominios puedan mostrar su contenido mediante el widget. Esto puede ser posible fácilmente, ya que ya tenemos la URL del sitio web que llama en el em_domain variable. Todo lo que tenemos que hacer es verificar el dominio y permitir selectivamente que se muestre el contenido.

public function catch_widget_query()
{
    /* If no 'embed' parameter found, return */
    if(!get_query_var('em_embed')) return;

    /* 'embed' variable is set, export any content you like */

    if(get_query_var('em_embed') == 'posts')
    { 
        $allowed_domains = array('site1.com',
                                 'site2.com',
                                 'site3.com');

        $calling_host = parse_url(get_query_var('em_domain'));

        /* Check if the calling domain is in the allowed domains list */
        if(in_array($calling_host['host'], $allowed_domains))
        {
            $data_to_embed = $this->export_posts();
            echo $data_to_embed;
        }
        else
        {
            echo "Domain not registered!";
        }
    }

    exit();
}

Preocupaciones sobre el rendimiento

Permitir que otros sitios web accedan a su contenido a través de widgets significa una carga adicional en sus servidores. Unos cientos de sitios web que usen su widget podrían ralentizar fácilmente su servidor, así que tenga en cuenta este factor cuando promocione widgets. Sin embargo, los complementos como WP Super Cache se pueden usar para almacenar en caché los datos de los widgets y reducir la carga del servidor. Si no está usando WP Super Cache o cualquier otro complemento de caché, puede intentar usar el API de transitorios de WordPress para guardar los resultados en la base de datos.

La API de WordPress Transients ofrece una forma simple y estandarizada de almacenar datos en caché en la base de datos temporalmente al darle un nombre personalizado y un período de tiempo, después del cual caducará y se eliminará. La catch_widget_query() La función después de agregar el código de la API transitoria de WP se muestra a continuación.

public function catch_widget_query()
{
    /* If no 'embed' parameter found, return */
    if(!get_query_var('em_embed')) return;

    /* 'embed' variable is set, export any content you like */

    if(get_query_var('em_embed') == 'posts')
    { 
        /* Here we are now using the 'WP Transient API'.

           See if we have any saved data for the 'ewidget' key.
         */
        $cached = get_transient('ewidget');

        /* Oops!, the cache is empty */
        if(empty($cached))
        {
            /* Get some fresh data */
            $data_to_embed = $this->export_posts();

            /* Save it using the 'WP Transient API' using the 'ewidget' key,
               set it to expire after 12 hours.
             */
            set_transient('ewidget', $data_to_embed, 60 * 60 * 12);
            echo $data_to_embed;
        }
        /* Yes we found some, so we return that to the user */
        else
        {
            echo $cached;
        }
    }

    exit();
}

En conclusión

Compartir su contenido en diferentes sitios web es una buena manera de comercializar sus servicios y crear conciencia de marca. Con millones de sitios web de WordPress, existe una gran cantidad de contenido que se puede compartir de manera rentable entre los usuarios. No solo texto, sino también imágenes, videos, anuncios, etc. Este artículo es solo una implementación simple de un widget integrable. Puede personalizarlo de varias maneras para incluir seguridad, código de análisis para rastrear el uso de widgets y otras funciones.

Otras lecturas en SmashingMag:

Deja un comentario