Как создать плагин встраимого контента для WordPress?

WordPress является одной из самых используемых систем управления контентом. Одной из основных причин этого является большое количество доступных плагинов и легкость, с которой мы можем пользоваться системой. Нет ничего необычного в том, чтоб найти сайты, использующие десятки плагинов для выполнения различных задач и функций. Разве не было бы здорово, если бы вы могли делиться содержанием своего сайта с другими сайтами!

Быть может, вам нужно поделиться анонсами, информацией о продукте или, если вы дизайнер, вашей фото галереей. Какой бы ни была причина, эта статья покажет вам путь к созданию плагина. при помощи которого вы сможете делиться содержанием вашего WordPress сайта с другими веб-сайтами.

Share WordPress content via widgets.

Способы обмена контентом

Существуют множество способов, с помощью которых можно обмениваться контентом между веб-сайтами — RSS и Atom каналы, API и встраиваемые виджеты. Содержание RSS-фидов в WordPress, как правило, ограничено сообщениями, в то время как API, не так-то легко использовать на других сайтах без добавления дополнительного кода. Остаются встраиваемые виджеты, как те, которые используются Google AdSense для отображения рекламы на веб-сайтах или Facebook для вставки кнопок “ Share” и “ Like”. Все они основаны на встраиваемом JavaScript коде, предназначенном для отображения конкретного содержания на сайте. Идея упомянутая в этой статье, определенно, не нова, но в контексте использования WordPress она открывает множество возможностей. Преимущества техники, упомянутой здесь, в сравнении с остальными заключается в том, что она позволяет вам делиться с другими сайтами практически любым контентом, даже содержимым плагинов, установленных на вашем блоге.

Наша цель в этой статье, написать код виджета, который пользователь может вставить в свой сайт, чтобы отобразить список последних сообщений родительского сайта. Конечно, это также может быть легко выполнено при помощи RSS, но это всего лишь пример, призванный продемонстрировать технику. На самом деле, вы можете использовать его для более интересных целей, например, для показа изображений популярных продуктов, если у вас коммерческий сайт.

КОД ВИДЖЕТА

Встраиваемый код будет выглядеть следующим образом. Этот код пользователь вставит в код своих веб-страниц, что позволит им отображать содержимое родительского сайта. Ключевой элемент этого виджета файл wp-widget.js, который вызывает удаленный WordPress сайт, получает контент и встраивает его как iframe в исходную страницу.

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

Добавление этого блока кода на любую страницу сайта, приведет к отображению списка последних постов сайта example.com. Не обязательно, чтоб контентом были посты, он может быть любым, это могут быть изображения, комментарии, теги, данные из других плагинов — все, чем вы, как владелец WordPress сайта, хотели бы поделиться с другими людьми. Для этого примера я ограничил загружаемый контент списком последних постов, так как чаще всего делятся именно этим контентом и с него довольно легко начать. Конечно, чтобы поделиться другим содержанием, вам потребуется отредактировать код плагина, но базовый скелет плагина будет тем же .

Создание Плагина

Первый шаг на пути к созданию встраиваемого виджета это разработка небольшого WordPress плагина, который будет перехватывать вызовы виджета, размещенного на другом сайте, и возвращать необходимые данные. Вам может показаться, что это сложная задача, на самом же деле нет ничего проще. Всего несколько строк кода, и наш плагин готов. Полный код для плагина показан ниже. Я буду объяснять, как он работает, по мере нашего продвижения вперед.

Чтоб получить контент от плагина, нам понадобится передать с удаленного сервера в переменной em_embed параметры запроса с указанием того, какой именно контент нам нужен. Этот параметр будет перехвачен плагином,  и будет возвращено соответствующее содержание. Кроме того, мы будем передавать в качестве параметра URL-адрес вызывающей страницы, таким образом в последствии мы сможем использовать эту информацию для анализа или ограничения числа сайтов, имеющих возможность разместить наш виджет.

Например, чтобы получить список последних сообщений, нам нужно отправить GET запрос на основной WordPress сайт, как показано ниже. Конечно, этот запрос будет создан нашим JavaScript виджетом, wp-widget.js.

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

Полный код для плагина представлен ниже.

<?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();

?>

Для успешного перехвата вызова с другого сайта, сначала нужно добавить параметры em_embed и em_domain в WordPress переменную query_var. Эта информация будет использоваться позже, чтоб определить какого рода данные должны быть отправлены на удаленный сайт. Делается это следующий функцией.

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

Далее, мы должны поймать при помощи template_redirect переменную запроса и обработать данные, если переменная em_embed сохранена ​​в глобальной переменной.

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();
}

В нашем примере, мы будем экспортировать список заголовков последних постов, поэтому наша функция export_posts  будет выглядеть следующим образом.

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

Вот и  весь плагин. Если вам нужно экспортировать другие данные, необходимо заменить код получения сообщений, кодом получения тех данных которые вам нужны.

Пишем код встраиваемого виджета

На данный момент мы завершили только часть, связанную с WordPress плагином. Но нам все еще нужно написать встраиваемый JavaScript код, который будет удаленно получать доступ к нашему сайту и вставлять подходящий контент в вызывающую страницу. Самый простой способ отображения на странице контента, полученного с другого сайта, это использование iframe. Код, необходимый для вставки контента на сайте, представлен ниже.

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

Если вы собираетесь использовать виджет для возврата данных только одного типа, вы можете распрощаться с переменной widget_embed. Таким образом, у вас будет что-то вроде следующего.

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

wp-widget.js это скрипт, написанный на языке JavaScript,  который делает всю работу, связанную с вызовом удаленного WordPress сайта и добавлением контента в iframe. Вам нужно разместить файл wp-widget.js в подкаталог вашего WordPress сайта, причем точное название и расположение не имеет значения.

Полный код файла wp-widget.js показан ниже, и не требует пояснений.

/**
  * 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);
    });
}

})();

Задача вставки iframe и содержания с WordPress сайта в DOM осуществляется функцией main(). Размер iframe должен быть изменен в зависимости от ваших требований или задан динамически, путем разрешения пользователю передавать дополнительные параметры при помощи переменной widget_embed в основной код виджета.

Применяем к контенту настраиваемые CSS

Вы можете добавить настраиваемые CSS, для отображаемого плагином контента. Пример CSS который идет с вышеупомянутым плагином, приведен ниже. Вы также можете указать URL таблицы стилей, если это необходимо.

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>';
    .
    .

Тип CSS, который вы применяете к контенту, будет зависеть от того, какой именно контент вы показываете. Творчески подойдя к написанию плагина, вы можете также позволить пользователям добавлять определенные параметры отображения для виджета, при помощи которых они могут контролировать стиль отображения встроенного виджета.

Ограничение отображения для определенных доменов

Возможно, вы хотите только определенным сайтам разрешить показ вашего контента при помощи виджета. Это вполне возможно, так как у нас уже есть URL-адрес вызывающего сайта в переменной em_domain. Все, что нам нужно сделать, это проверить домен и выборочно разрешить отображение контента.

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();
}

Проблемы с производительностью

Предоставление другим сайтам доступа к контенту через виджеты означает дополнительную нагрузку на ваши серверы. Несколько сотен веб-сайтов использующих ваш виджет могут легко Если вы хотите прочитать полностью статью, посетите сайт наших спонсоров

Comments are closed.