8 августа 2009 г.

Капля волны: встраивание GW на примере CMS Drupal


Как вы уже знаете, наверное, одно из достоинств проекта Google Wave состоит в его открытости. И не только в смысле доступности исходных кодов и документированности протокола. Но еще и в том, что пользоваться «волнами» можно не только на wave-сервере Гугла (т.е. не только через гугловский «клиент»). Вы можете работать с волной прямо у себя на сайте!

Да, да, знаю — сейчас вы меня забросаете гнилыми ананасами с криками «нас не пускают в песочницу, а этот рассуждает об открытости!» Потерпите, ребята, все будет — сейчас, насколько знаю, рассылаются остатки из 20 тыс. инвайтов в «песочницу» для девелоперов.
А с 30 сентября будут раздавать еще и 100 тыс. аккаунтов уже в рабочую Волну wave.google.com. Как говорится, «все там будем». :)
Так, о чем это я? Ах да. О том, что все будем в Волне и Волна будет повсюду.


Попробую рассказать о возможностях встраивания «волн» Google Wave на примере CMS Drupal. Хотя на самом деле неважно, будет ли это именно эта CMS или любая другая. Неважно даже, будет ли это сайт с использованием какой-то Content Managenment System. Google предоставляет открытый API для встраивания «волн» в любые html-страницы. Пока API очень простенький, будем надеяться, что все это дело будет развиваться дальше.

И, пока не началось, честно предупреждаю, что посмотреть внедренную волну вы сможете, только если у вас есть доступ в «песочницу». Жестоко, знаю.
Но это временно, парни из Гугла уже в курсе и усиленно работают над анонимным доступом к embed wave.

Итак, что мы имеем на август 2009 года?
Для начала вот две официальные ссылки:
Руководство — code.google.com/intl/ru-RU/apis/wave/embed/guide.html
Справка — code.google.com/intl/ru-RU/apis/wave/embed/reference.html

1. Чтобы не пересказывать официальное руководство, давайте разберем встраивание на примере.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Wave Embed API Example: Simple Wave</title>
// Добавим javascript с Embed Wave API.
<script src="http://wave-api.appspot.com/public/embed.js" type="text/javascript"></script>

<script type="text/javascript">
// Функция инициализации волны, которая будет вызываться после загрузки страницы.
function initialize() {
// Создаем новый экземпляр класса WavePanel, указывая ему адрес wave-сервера.
// Пока используется адрес девелоперской "песочницы".
// Когда появятся другие wave-сервера, можно будет их указывать здесь.
// Не забудьте указать слеш в конце адреса.
var wavePanel = new WavePanel('http://wave.google.com/a/wavesandbox.com/');
// Загружаем определенную волну.
// Определяется она по ее waveID (выглядит примерно как "2Bi7arMxYM%25A").
wavePanel.loadWave('wavesandbox.com!w+waveID');
// Наконец, вставляем волну в div с идентификатором "waveframe"
wavePanel.init(document.getElementById('waveframe'));
}
</script>
</head>

<body onload="initialize()">
// В этом div'е будет размещаться iframe с вашей волной.
// Желательно задать достаточную ширину div,
// чтобы поместились аватары всех участников волны,
// поэтому обычно лучше сразу поставить width: 100%;
<div id="waveframe" style="width: 500px; height: 100%"></div>
</body>
</html>


Вот такой пример кода приведен в руководстве (я только добавил свои пояснения). Берете, просто копируете его и вставляете в ваш материал (node) на Drupal. Только поставьте вместо waveID идентификатор какой-то реальной волны. И не забудьте включить фильтр ввода «Full HTML» (это убирает в Drupal фильтрацию нежелательных html-тегов, если кто не в курсе).

Все будет работать. Волна будет показываться в iframe на вашей странице, вы сможете спокойно добавлять, удалять и редактировать «блипы» (т.е. отдельные сообщения в рамках волны). Можете еще создавать дочерние волны (wavelets, «подволны», «вейвлеты» — русская терминология еще устоялась).

2. Но на самом деле для встраивания достаточно даже вот такого кода (мы можем убрать определение DOCTYPE и тег html):

<script src="http://wave-api.appspot.com/public/embed.js" type="text/javascript"></script>
<script type="text/javascript">
function initialize() {
var wavePanel = new WavePanel('http://wave.google.com/a/wavesandbox.com/');
wavePanel.loadWave('wavesandbox.com!w+2Bi7arMxYM%25A');
wavePanel.init(document.getElementById('waveframe'));
}
</script>
<body onload="initialize()">
<div id="waveframe" style="width: 100%; height: 100%"></div>
</body>


3. Идем дальше. Как-то не хочется иметь в исходном коде страницы сразу два тега body. Поэтому переделаем наш код, добавив заодно некоторые фичи Wave Embed API: вставим кнопки и раскрасим волну.

<script src="http://wave-api.appspot.com/public/embed.js" type="text/javascript"></script>
<div id="waveframe" style="width: 100%; height: 100%"></div>
// Добавим кнопки "Подключиться к этой волне" и "Ответить"
// ("Follow this wave" и "Reply")
<form id="comment_form">
<button type="button" onclick="wavePanel.addReply()">Говорить сюда</button>
<button type="button" onclick="wavePanel.addParticipant()">Следуй за кроликом</button>
</form>

<script>
var wavePanel = new WavePanel('https://wave.google.com/a/wavesandbox.com/');
// Настроим дизайн под оформление сайта (фон, текст, шрифт, кегль/размер шрифта).
// Размер шрифта можно указывать только в pt или px.
wavePanel.setUIConfig('#446666', '#cceedd', 'verdana', '9pt');

wavePanel.loadWave('wavesandbox.com!w+i7arMxYM%A');
wavePanel.init(document.getElementById('waveframe'));
</script>


При нажатии кнопок выполняются функции wavePanel.addReply() и wavePanel.addParticipant(). Первая кнопка добавляет новый «блип» в волну, а вторая — добавляет текущего пользователя в участники данной волны. Но ведь новый «блип» можно было добавить и раньше, скажете вы. Да, но эта кнопка добавляет его как ответ на начальное сообщение волны.
И важное замечание по второй кнопке — она добавляет в участники волны не пользователя Drupal (волна о Drupal ничего не знает), а текущего пользователя Волны. Поэтому, чтобы эта функция сработала, вы должны быть залогинены в Google Wave.

Примечание: как вы заметили, в первом варианте wavePanel.init() вызывалась по событию onload. Это было нужно, чтобы до вставки волны вся страница отрендерилась, DOM построился, были вставлены все внешние скрипты и картинки. Наверное, второй вариант, где мы убрали эту проверку — не лучшее решение и в некоторых случаях может привести к каким-то последствиям.
«Но ведь пока все работает», говорил оператор Чернобыльской АЭС, щелкая выключателями.

4. Изучение Wave Embed API показывает нам, что для wavePanel.loadWave() и wavePanel.init() есть возможность вызывать callback-функции. Для чего это нужно в народном хозяйстве — пока не очень ясно. Но можно предложить, например, такой вариант — выдать при загрузке волны приветственное сообщение с использованием имени пользователя сайта.

<script src="http://wave-api.appspot.com/public/embed.js" type="text/javascript"></script>
<div id="waveframe" style="width: 100%; height: 100%"></div>
// Добавим элемент, в котором выведем какое-либо значение, например, имя пользователя Drupal-сайта.
// Или его волновой адрес, если он его указал в своем профиле при регистрации на вашем сайте. Или еще что-то.
// Все это не обязательно выводить именно здесь, можно использовать любой элемент на странице.
<span id="waveuser"><?php global $user; print $user->name;?></span>

<form id="comment_form">
<button type="button" onclick="wavePanel.addReply()">Ответить за все</button>
<button type="button" onclick="wavePanel.addParticipant()">Пройдемте, гражданин</button>
</form>
<script>
var wavePanel = new WavePanel('https://wave.google.com/a/wavesandbox.com/');
wavePanel.setUIConfig('#446666', '#cceedd', 'verdana', '9pt');
// Для примера добавим вызов функции с приветствием пользователю, в котором используем его имя. Аналогично можно добавить callback к wavePanel.init()
wavePanel.loadWave('wavesandbox.com!w+i7arMxYM%A', welcomeMsg("Welcome to World Wide Wave, "));
wavePanel.init(document.getElementById('waveframe'));

// Собственно callback функция, которая в этом примере формирует приветственное сообщение
function welcomeMsg(text) {
var item=document.getElementById("waveuser");
if(item) {
item.innerHTML=text + item.innerHTML + "!";
}
}
</script>


В итоге, при загрузке волны наш пользователь получит сообщение типа «Welcome to World Wide Wave, Neo!». Что, в общем и целом, соответствует новой реальности.

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

5. Другое, более полезное на мой взгляд, применение callback состоит в следующем. Как я уже сказал, если сейчас встраивать волну на страницу сайта, то ее увидят только обладатели аккаунта в «песочницу». Обычные посетители будут натыкаться на «заглушку» с сообщением о необходимости залогиниться на wavesandbox.com. Чтобы не смущать простых смертных этим огорчительным неравноправием, можно воспользоваться таким трюком:

a. Делаем изначально невидимым тот div, в котором будет показываться волна.
<div id="waveframe" style="width:100%; height: 100%; visibility:hidden;"></div>

b. А при инициализации волны вызываем callback-функцию, которая делает этот див «visible».
window.wavePanel.init(document.getElementById('waveframe'), initCallback);
function initCallback() {
document.getElementById("waveframe").style.visibility="visible";
}


Таким образом, если вы не залогинены в «песочнице», вы не увидите на странице никаких следов волны.

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

p.s. Мы не использовали еще функцию getFrameId() из Embed API, которая позволяет получить идентификатор созданного iframe. Но я пока не понимаю, как ею можно было бы с умом распорядиться.

Еще несколько полезных ссылок в тему «Drupal и Google Wave»:
обсуждение в группе «Google Wave Россия»
обсуждение на сайте Drupal.ru
дискуссионная группа на офсайте Drupal.org

В начале статьи использована картинка с сайта dreamstime.com

Upd.: Просили скриншотов. Пока держите вот такой:
image

Комментариев нет:

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