Публикация постов в WordPress с помощью XML-RPC и CodeIgniter

25 августа, 2008
codeigniter wordpress xml-rpc

Движок WordPress буквально «нашпигован» различными функциями и возможностями. В этой статье я расскажу, как написать небольшое web приложение, из которого вы сможете публиковать посты в ваш блог.

Как вы понимаете, писать такое приложение имеет смысл только в том случае, если оно расширяет стандартные возможности движка.

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

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

Вторая – различные программы для сеошников. Здесь смысл в том, чтобы публиковать посты автоматически в нескольких блогах.

Эта статья больше ориентирована на второй вариант.

Немного теории.

WordPress имеет два механизма публикации постов. Первый – web интерфейс (в данном случае он нас не интересует). И второй – с помощью XML-RPC. RPC расшифровывается как Remote Procedure Call (удаленный вызов процедур/функций). В принципе эта технология очень похожа на обычные запросы. От клиента к серверу передается строка с данными. Но XML-RPC требует, чтобы эта строка имела специальный формат.

Примечание. По большому счету существует еще и третий вариант – использование встроенных функций WordPress. Но он доступен только для плагинов.

Используя XML-RPC можно опубликовать пост с помощью всего одного запроса, а специальные библиотеки позволяют не углубляться в тонкости стандарта. Таким образом, не сложно написать программу, которая будет отправлять пост сразу в сотню-другую блогов.

Примечание. Естественно, сначала вам придется сделать эти посты «уникальными», но это отдельная тема.

Переходим к практике.

Инструменты.

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

Т.е. лучше с самого начала использовать фреймворк. Для этого примера я выбрал CodeIgniter, который очень прост в изучении и имеет встроенную библиотеку для работы с XML-RPC.

Также нам понадобится документация по функциям, которые поддерживает WordPress. XML-RPC определяет только формат запросов, а уже разработчик приложения решает какие функции будут поддерживаться.

WordPress поддерживает сразу четыре API:
1) WordPress API.
2) Blogger API.
3) metaWeblog API ().
4) Movable Type API.

Но, насколько я знаю, они не взаимозаменяемые. Например, Wordpress API не имеет функции для публикации поста (wp.newPage публикует страницу, а не пост, и при этом используется функция mw_newPost из MetaWeblog API).

В общем, для публикации постов мы будем использовать MetaWeblog API.

Настраиваем CodeIgniter.

Для данной задачи настроек минимум.
Открываем system\application\config\autoload.php и подключаем url helper.

  1. $autoload['helper'] = array('url');

В файле system\application\config\config.php указываем адрес приложения

  1. $config['base_url'] = ….;

И указываем имя контроллера, который будет использоваться по-умолчанию (файл system\application\config\routes.php).

  1. $route['default_controller'] = "poster";

Интерфейс. Т.к. пример демонстрационный, ограничимся одной формой.

Форма для постинга с помощью XML-RPC

Т.е. пользователь указывает URL блога (с http:// и без слеша в конце адреса), заголовок поста, теги и текст. И после нажатия на кнопку «Отправить» мы публикуем пост.

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

Напишем представление, которое создаст эту форму (postform.php).

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="ru-RU">
  4. <head>
  5. <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
  6. <title><?php echo $title; ?></title>
  7. </head>
  8.  
  9. <body>
  10.  
  11. <?php
  12. if (isset($mes)) {
  13.     echo '<p>'.$mes.'</p>';
  14. }
  15. ?>
  16. <form method="post" action="<?php echo site_url("poster/sendpost"); ?>">
  17. <p>
  18. <label for="blogurl">URL блога</label>
  19. <input name="blogurl" id="blogurl" type="text" size="20" />
  20. (c http:// и без слеша в конце)
  21. </p>
  22. <p>
  23. <label for="posttitle">Заголовок поста</label>
  24. <input name="posttitle" id="posttitle" type="text" size="20" />
  25. </p>
  26. <p>
  27. <label for="posttags">Теги</label>
  28. <input name="posttags" id="posttags" type="text" size="20" />
  29. </p>
  30. <p>
  31. <label for="posttext">Тескт поста</label>
  32. <textarea name="posttext" id="posttext" cols="20" rows="5"></textarea>
  33. </p>
  34. <p>
  35. <input type="submit" name="sbmbtn" id="sbmbtn" value="Отправить" />
  36. </p>
  37. </form>
  38. </body>
  39. </html>

Как видите – это обычная страница с формой. Сразу после тега <body> мы добавили код, который будет показывать сообщение с результатами отправки (строки 11-15).

Переходим к контроллеру (poster.php).

  1. <?php
  2.  
  3. class Poster extends Controller {
  4.  
  5.     function Poster()
  6.     {
  7.         parent::Controller();
  8.     }
  9.  
  10.     function index()
  11.     {
  12.         $pageData['title'] = "Отправка постов в WordPress";
  13.         $this->load->view('postform', $pageData);
  14.     }
  15.  
  16.     function sendpost() {
  17.         $this->load->library('xmlrpc')
  18.  
  19.         $pageData['title'] = "Отправка постов в WordPress";
  20.        
  21.         $blogUrl = $this->input->post('blogurl');
  22.         $postTitle = $this->input->post('posttitle');
  23.         $postTags = $this->input->post('posttags');
  24.         $postText = $this->input->post('posttext');
  25.  
  26.         if (!$blogUrl || !$postTitle || !$postTags || !$postText) {
  27.             $pageData['mes'] = 'Нужно заполнить форму';
  28.         }
  29.         else {
  30.             $this->xmlrpc->server($blogUrl.'/xmlrpc.php', 80);
  31.             $this->xmlrpc->method('metaWeblog.newPost');
  32.             $request = array(
  33.                            array(0, 'int'), //blog id
  34.                            array('admin', 'string'), //username
  35.                            array('your_pass', 'string'), //password
  36.                            array(
  37.                                array(
  38.                                    'title'=>array($postTitle, 'string'),
  39.                                    'description'=>array($postText, 'string'),
  40.                                    'mt_keywords'=>array(split(',\s*', $postTags), 'array'),
  41.                                    'mt_allow_comments'=>array(1, 'int'),
  42.                                    'mt_allow_pings'=>array(0, 'int'),
  43.                               ),
  44.                               'struct'
  45.                             ), //content
  46.                            array(TRUE, 'boolean') //publish
  47.                         );
  48.             $this->xmlrpc->request($request);
  49.           //  $this->xmlrpc->set_debug(TRUE);
  50.            
  51.             if ( ($res = $this->xmlrpc->send_request()) === FALSE) {
  52.                 $pageData['mes'] = $this->xmlrpc->display_error();
  53.             }
  54.             else {
  55.                 $pageData['mes'] = 'Пост опубликован';
  56.             }
  57.         }
  58.         $this->load->view('postform', $pageData);
  59.     }
  60. }
  61. ?>

Его разберем подробнее.

Метод index (строки 10-14) просто показывает пустую форму. При нажатии на кнопку «Отправить» будет вызван метод sendpost.

Метод sendpost работает следующим образом.

1) Подключаем библиотеку для работы с XML-RPC (строка 17).

2) Получаем введенные в форму данные и проверяем их (строки 21-28) (в реальном приложении эта проверка будет сложнее).

3) Формируем запрос.

С помощью методов server и method указываем адрес сервера и название функции (metaWeblog.newPost) соответственно.

Примечание. К адресу блога мы добавляем название скрипта (xmlrpc.php), который обрабатывает XML-RPC запросы. Во втором параметре указываем порт сервера, на котором работает WordPress.

Теперь нужно сформировать массив с данными (строки 32-47). Это, наверное, самая сложная часть.

В массиве нужно указать не только значения, но и тип данных. Например, в строке 34 мы указали логин пользователя (admin) и тип данных (string). Точно также в строке 46 значение – TRUE, а тип – boolean (этот параметр означает, что пост должен быть опубликован, а не сохранен как черновик).

Кстати, параметры в этом массиве должны идти в том порядке, в котором они описаны в документации (нормальной справки я, к сожалению, не нашел, поэтому лучший источник информации – файл xmlrpc.php).

Исключение из этого правила составляет структура с данными (четвертый параметр). Она задается как массив и имеет тип struct (строки 36-44). Вообще эта структура может содержать больше полей, чем использовано в этом примере. Например, нет особого смысла указывать wp_author_id, т.к. WordPress автоматически подставит id автора, под логином которого вы подключились.

Теперь обратите внимание на строку 40. Здесь мы добавили параметр, который имеет тип array и содержит массив с тегами поста. Исходную строку с тегами мы преобразовали в массив с помощью функции split (разделитель – запятая и любое количество пробелов после нее).

Несколько замечаний по поводу тегов.

Для группировки постов WordPress позволяет использовать теги, рубрики или и то, и другое одновременно. Но работать с тегами, на мой взгляд, немного удобнее. Вы просто передаете массив с ними, а дальше все делает WordPress. Если тег с таким же именем существует, то используется он, если нет – то создается новый.

Единственное, что от вас потребуется – это добавить облако тегов в сайдбар. Для стандартного шаблона открываем файл wp-content\themes\default\sidebar.php, находим строку
<?php wp_list_categories('show_count=1&title_li=<h2>Categories</h2>'); ?>
и после нее добавляем код

  1. <?php if ( function_exists('wp_tag_cloud') ) : ?>
  2. <li>
  3. <h2>Popular Tags</h2>
  4. <ul>
  5. <?php wp_tag_cloud('smallest=8&amp;largest=22'); ?>
  6. </ul>
  7. </li>
  8. <?php endif; ?>

Естественно, место размещения и настройки вы выбираете сами.

4) Возвращаемся к контроллеру.

Массив с данными сформирован. С помощью метода request добавляем его в запрос (строка 48) и отправляем (строка 51, метод send_request).

Обратите внимание на строку 49 – очень полезно для отладки :-)

5) После отправки запроса мы загружаем страницу с формой.

Как видите, использовать XML-RPC не сложно, главное - правильно сформировать массив с данными.

Скачать пример.

Если хотите поэкспериментировать – качайте архив с примером. Он содержит папку application с контроллером и представлением. Эту папку нужно скопировать в папку system фреймворка.

И, естественно, для работы вам нужно будет установить WordPress.

Пост получился довольно длинным ;) и если у вас возникли вопросы – пишите в комментариях.

До встречи!

Интересно почитать:

Как легально продавать аффилиэйт-продукты на eBay.

Понравилась статья? Подпишитесь на продолжение rss link !

]]>

Добавьте эту страницу в google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru

]]>

Опубликовано в CodeIgniter, PHP, Web разработка, WordPress

]]>

Комментарии (7)

Вы можете отслеживать обсуждение записи с помощью RSS 2.0 rss link

Вы также можете оставить комментарий, или трекбек с Вашего сайта.

  1. [...] Движок WordPress буквально «нашпигован» различными функциями и возможностями. В этой статье я расскажу, как написать небольшое web приложение, из которого вы сможете публиковать посты в ваш блог. Как вы понимаете, писать такое приложение имеет смысл только в том случае, если оно расширяет стандартные возможности движка. Далее… [...]

  2. Зачем всё так сложно?
    На сервисе от WP, где я сижу это делается так: http://blogion.ru/faq
    Word-2007 рулит. Даже таблицы можно в блог постить. TinyMCE (или как его там), по-моему, таблицы создавать не умеет.

    1. Владимир 28.08.2008 в 21:19 (Ответить)

      Так Word использует этот же метод. У вас в инструкции написан пример подключения:

      Пример: blogion.ru/ivanov/xmlrpc.php

      Т.е. Word используется как обычный блог-клиент. А когда вы пишите собственное приложение, то можете делать что угодно. Например, автоматический постинг в несколько блогов.

  3. exolon 05.09.2008 в 15:09 (Ответить)

    Интересное использование клиентской RPC библиотеки CodeIgniter. К сожалению, к WordPress нет подробной спецификации на все интерфейсы, приходится читать исходный код библиотеки.

    Для решения подобной задачи я поступил чуть проще - отследил передаваемые BlogJet'ом запросы и формировал скриптом аналогичные. Просто функциями для работы со строками :) Что, конечно, не так красиво и правильно, как использование специальных функций для создания XML-пакета.

    Есть нюанс, который может быть важным. При обновлении WordPress с помощью metaWeblog.newPost в отдельной структуре нужно передавать список пингуемых серверов. Дефолтный список пинг-сервисов при обновлении по данному методу не пингуется (пробовал на WP 2.5).

    Было бы интересно использовать CodeIgniter для создания сервера RPC-запросов, т.е. альтернативу использования Wordpress'а. Может быть подскажете простой, быстрый и надежный фреймворк/набор библиотек для создания приложения, обновляющегося по XML-RPC? ;) Я пока что думаю, что CodeIgniter подойдет…

    1. Владимир 05.09.2008 в 16:04 (Ответить)

      >> список пингуемых серверов

      здесь есть еще один нюанс - бан за частые пинги. В обычном режиме работы я использую MaxBlogPress Ping Optimizer. Но я не знаю работает ли он при постинге через XML-RPC. По-идее, должен, т.к. для публикации поста используется одна и таже функция, но я не проверял.

      Да, стандартная библиотека CI позволяет создать XML-RPC сервер. Насколько я знаю, вполне нормально работает. Правда, читал, что были проблемы в версии 1.6.2.

  4. souznik 31.10.2008 в 10:42 (Ответить)

    Очень полезная статья!
    Только есть вопрос: А как передать рубрику, в которой должен опубликоваться пост?

    1. Владимир 31.10.2008 в 21:04 (Ответить)

      Принцип такой же как и с тегами.
      Список рубрик передается в структуре с данными, параметр называется categories. В этом примере я его просто пропустил, т.к. использовал теги.
      Посмотрите метод mw_newPost в файле xmlrpc.php. Он довольно длинный, но имена переменных говорят сами за себя ;) .

Оставить комментарий

Введите ваш комментарий

* - обязательные для заполнения поля

Quicktags:

]]>