Интеграция Twitter @Anywhere в Drupal

Как всем уже известно, еще весной разработчики сервиса микроблогов Twitter выпустили очередной API под названием @Anywhere. Нужен он, естественно, для интеграции твиттера повсеместно (то есть anywhere). Сам API представляет собой подключаемый с сервера Twitter внешний JavaScript и набор нехитрых JS-функций, позволяющих разработчикам встраивать в свои сайты следующие вещи:

  • Auto-linkification — автоматическая расстановка ссылок на twitter-аккаунты для всех найденных на странице имен типа @username;
  • Hovercards — добавление ко всем ссылкам на twitter-аккаунты небольших всплывающих при наведении мыши блоков с общей информацией о пользователе. Примерно вот так:
  • @Anywhere Hovercard

  • Follow buttons — кнопки для быстрого фолловинга заданного пользователя. Кнопки умные — они проверяют, не следуем ли мы уже за этим пользователем, и если следуем — на кнопке вместо текста «Follow @username» будет текст «You're following @username»;
  • Tweet Box — очень удобный блок для быстрой отправки сообщения в Twitter не выходя с данного сайта. Вот так:
  • @Anywhere Tweet Box

  • User login & sign-up — позволяет добавлять кнопки для логина/разлогина в Твиттере.

Использовать @Anywhere из коробки достаточно нетрудно, процесс интеграции описан в руководстве по API. Для любителей читать по-русски имеется и русская статья (но в ней рассмотрено не все). Здесь же я попробую рассказать об интеграции Twitter Anywhere в Друпал на примере своей домовой страницы.

Перво-наперво, будем использовать модуль anywhere — раз уж он есть. Обратим, однако, внимание, что на данный момент модуль еще в версии 0.0-beta-2, то есть многое придется доделывать руками. Из коробки же модуль умеет самостоятельно:

  • добавлять внешний скрипт Anywhere на все страницы сайта с помощью hook_init(), чтобы API был доступен в дальнейшем с любой страницы;
  • добавлять тем же способом авторасстановку ссылок на аккаунты (вызовы linkifyUsers) и показ блоков hovercards (нужно включить в админке);
  • добавлять два новых блока: с умной кнопкой Follow и с формой Tweet Box.

Чтобы anywhere заработал, необходимо добавить новое приложение Twitter и ввести в админке модуля полученный при регистрации приложения ключ (API key).

Для начала я взялся за hovercards, но тут оказалось, что модуль пока умеет добавлять всплывающие блоки только к ссылкам, оформленным вот так:
<a class="twitter-anywhere-user" href="http://twitter.com/graker_ru">@graker_ru</a>
Если же хочется показывать блоки при наведении мыши на изображения (например, на изображение синего круглого воробья), необходимо немного потрудиться руками. В реализации hook_init() модуля найдем запись

twttr.anywhere(function(twitter) {
  twitter$link_selector$link_type
});
и заменим ее на
twttr.anywhere(function(twitter) {
  twitter.hovercards({username: function(node) {return node.alt;}});
});
Теперь скрипт hovercards сможет извлечь имя пользователя twitter прямо из атрибута alt у изображения.

Но здесь нас поджидает неприятный подводный камень. Дело в том, что API Anywhere слишком умный: при инициализации скрипта он посмотрит в атрибут lang тега html и попытается автоматически скачать скрипт перевода на указанный там язык. А перевода Твиттера на русский, как известно, еще нет, то есть файл (ru.js) не скачается.

Браузеры типа Firefox это особо не волнует — Anywhere нормально продолжает работать и без этого файла. Но элитный браузер Opera отсутствие ru.js вводит в немедленный ступор, инициализация twttr.anywhere() прекращается и ничего не работает (хорошо еще JS целиком не отрубается). Чтобы решить эту проблему, нам придется лгать воровать и убивать. Обманем Anywhere, изменив содержимое lang прямо перед инициализацией, а потом вернем на место (на всякий случай):

$("html").attr("lang","en");
twttr.anywhere(function(twitter) {
  twitter.hovercards({username: function(node) {return node.alt;}});
  $("html").attr("lang","ru");
});
В результате такой выходки ru.js качаться больше не будет и Anywhere нормально заработает в Опере. По данной проблеме я на всякий случай создал багрепорт на D.org.

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

theme('anywhere_block_tweet_box', $api_version, $counter, $height, $width, $label, $default_content);
, где аргументы соответствуют параметрам настройки Tweet Box. Причем, выводится форма через шаблон anywhere_block_tweet_box.tpl.php, что удобно.

Но мне захотелось не просто вставить Tweet Box на сайт, а чтобы она появлялась и исчезала при нажатии иконки Твиттера в столбике социальных закладок справа. Поэтому я добавил к модулю свой скрипт и подключил его вызовом drupal_add_js(drupal_get_path('module', 'anywhere') . '/anywhere.js');. Содержимое anywhere.js:

Drupal.behaviors.anywhereBehaviour = function (context) {
  $("li.service_links_twitter").click( function() {
    var twbBlock = $("#social-bookmarks-twitbox");
    if(twbBlock.is(":visible")) {
      twbBlock.hide();
      twbBlock.empty();
      return false;
    } else {
      twttr.anywhere(function(twitter) {
        twitter(twbBlock).tweetBox( {
          counter: true,
          height: 80,
          width: 300,
          label: "Написать в Твиттер",
          defaultContent: "RT @graker_ru " + $("h1.title").text() + ": " + document.URL,
        } );
        $(twbBlock).show();
      });
      if (twbBlock.is(":visible")) {
        return false;
      }
    }
  });
}
Отмечу, что в конце скрипта происходит дополнительная проверка на .is(":visible"). И return false; исполняется только если блок стал видимым, то есть инициализация формы Tweet Box действительно прошла успешно. Это нужно, чтобы кнопка Твиттера по-прежнему функционировала как ссылка в тех браузерах, где Anywhere не работает.

В заключение можно сказать, что хотя модуль для Друпала и находится еще в зачаточном состоянии, интегрировать Twitter @Anywhere в свой сайт можно уже сегодня, причем без особого труда. На этом все.

Ingumsky (гость)
Аватар пользователя Ingumsky

Хм... Спасибо. А связывания логина на сайте с аккаунтом Twitter там нет? Просто мне кажется логичным, если аккаунт Twitter использовать а-ля OpenID.

graker
Аватар пользователя graker

В anywhere такого нету. Но в принципе это будет возможно со временем, я думаю. Твиттер же сейчас все свои приложения заставляет на OAuth переходить.

Ingumsky (гость)
Аватар пользователя Ingumsky

graker пишет:
В anywhere такого нету. Но в принципе это будет возможно со временем, я думаю. Твиттер же сейчас все свои приложения заставляет на OAuth переходить.

В принципе, как я понимаю, связка аккаунта Twitter с учётной записью drupal с помощью стороннего модуля есть уже сейчас. Просто, как и во многих других случаях, она реализуется _отдельным_ модулем, а я все лелею надежду, что будет сделан в Друпале какой-нибудь Open API, который позволит разработчикам спокойно подключать ко форме регистрации/входа не только OpenID, но и разные другие системы авторизации и аутентификации (те же Facebook, Twitter, вКонтакте и так далее), которые для конечного пользователя будут выглядеть как равнозначные с OpenID варианты входа.

graker
Аватар пользователя graker

Это конечно хорошо и нужно, но в любом случае ведь это будет отдельный модуль - идеология-то Друпала в том, чтобы ничего лишнего по возможности в ядро не пихать. Вдруг мне для сайта-визитки или интернет-магазина не нужны ни OpenID, ни OAuth, ни все остальное? :)

ingumsky (гость)
Аватар пользователя ingumsky

Конечно, я не про ядро. Я имел в виду дополнительный слой, который позволял бы подключать это всё к сайту :)

graker
Аватар пользователя graker

Будет со временем, я думаю :)

Игорь (гость)
Аватар пользователя Игорь

Извините за вопрос не совсем в тему, но подскажите пожалуйста с помощью чего вы реализовали плавающую панель с кнопками социальных закладок? Очень красиво у вас выглядит

graker
Аватар пользователя graker

Я взял модуль service_links с уже вставленными русскими закладками отсюда, добавил недостающие закладки (twitter, вконтакте) вручную в код модуля, отключил лишние закладки через настройки, заменил иконки по умолчанию, затем добавил в node.tpl.php блок с закладками через вывод переменной шаблона $service_links (она создается модулем) примерно вот так:

<?php if ($page): ?>
  <div class="social-bookmarks-links">
    <?php print $service_links; ?>
  </div>
<?php endif; ?>

Ну а чтобы плавало справа - это просто через CSS делается.

Игорь (гость)
Аватар пользователя Игорь

graker пишет:
добавил недостающие закладки (twitter, вконтакте) вручную в код модуля,

А не подскажете, как можно в формат модуля service_links
  $links['_ru_bobrdobr'] = array(
    'link' => 'http://bobrdobr.ru/addext.html?url=<encoded-url>&amp;title=<encoded-title>',
    'name' => 'Bobrdobr',
    'description' => t('Bookmark this post on Bobrdobr'),
  );

можно добавить скрипт от того-же Вконтакта
<!-- Put this script tag to the <head> of your page -->
<script type="text/javascript" src="http://vkontakte.ru/js/api/share.js?9" charset="windows-1251"></script>

<!-- Put this script tag to the place, where the Share button will be -->
<script type="text/javascript"><!--
document.write(VK.Share.button(false,{type: "link_noicon", text: "Сохранить"}));
--></script>

Прошу прошения за возможно глупый вопрос

graker
Аватар пользователя graker

Да я скрипт собственно не добавлял, я просто добавил иконку с линком на vkontakte.ru/share.php:

$links['service_links_vkontakte'] =
    theme('service_links_build_link',
           t('VKontakte'),
           "http://vkontakte.ru/share.php?url=$url&title=$title",
           t('Bookmark this post on vkontakte.ru.'),
           'images/vkontakte.png',
           $nodelink);

А если хочется именно скрипт добавить, то проще будет в hook_init() какого-нибудь модуля добавить через drupal_set_html_head() первый скрипт (который в head) и в нужный шаблон (e.g. node.tpl.php) вставить второй (который генерит кнопку).

Гость (гость)
Аватар пользователя Гость

graker пишет:
Да я скрипт собственно не добавлял, я просто добавил иконку с линком на vkontakte.ru/share.php:
$links['service_links_vkontakte'] =
    theme('service_links_build_link',
           t('VKontakte'),
           "http://vkontakte.ru/share.php?url=$url&title=$title",
           t('Bookmark this post on vkontakte.ru.'),
           'images/vkontakte.png',
           $nodelink);

А если хочется именно скрипт добавить, то проще будет в hook_init() какого-нибудь модуля добавить через drupal_set_html_head() первый скрипт (который в head) и в нужный шаблон (e.g. node.tpl.php) вставить второй (который генерит кнопку).

graker
Аватар пользователя graker

Пришел, заquotил и ушел :)

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

CAPTCHA
Пройдите, пожалуйста, проверку. Она нужна, чтобы отличать людей от спам-роботов. А если не хотите проходить эту проверку регулярно — зарегистрируйтесь.
Image CAPTCHA
Введите цифры, изображенные на картинке (без пробелов).