Pull to refresh

Создание Rich Internet Appliations с помощью OpenLaszlo. Пример разработки фреймворка для приложений Вконтакте

Reading time10 min
Views903
image
В одном из топиков была затронута тема создания приложений для Вконтакте. Что ж, продолжим её, только на этот раз перейдем на другое средство разработки. В этом топике я не буду рассматривать методы API вконтакта, принцип создания подписи и т.п., что было описано в том топике.

Всем известно, что приложения Вконтакте — флеш приложения. В основном для разработки вконтактовских приложений используют продукты Adobe. Я же использую для разработки богатых интернет приложений бесплатную свободную среду OpenLaszlo. Данный фреймворк (назовём его так) бесплатен, его исходные коды доступны, все компоненты можно изменять (сразу оговорюсь, что я не знаю, как лазла компилирует xml файлы в бинарный флеш, потому что я этим не интересовался). Кроме, собственно, компиляции во флеш, есть возможность создавать приложения на DHTML.

Основные понятия.


Исходные коды в лазло — обычные xml файлы. Любое приложение на лазло должно содержать главный узел . Внутрь канваса можно помещать существующие классы в лазло, создавать свои классы. Любой класс в лазло наследуется от класса <node>. Второй по значимости класс в лазло — <view>, похож на элемент <div> в (x)html.
Напишем простенькое приложение на лазло, программку, выводящую hello world:
<canvas>
  <text>Hello World<text>
</canvas>

Здесь появился новый стандартный элемент — <text>. Основные атрибуты: text, selectable, pattern, multiline. Дальше заостряться на нём не будем.
Для создания логики приложения используется JavaScript. Приведу пример посложнее:
<canvas height="30">
    <class name="clickClock" extends="text">
     <attribute name="dayTable"
          value='["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]'/>
     <handler name="onclick">
      var now = new Date;
      this.format("You clicked me at %02d:%02d:%02d on %s",
            now.getHours(),
            now.getMinutes(),
            now.getSeconds(),
            dayTable[now.getDay()]);
     </handler>
    </class>
    <clickClock>
     Click Me!
    </clickClock>
   </canvas>

Результат
image

Этот пример полезен тем, что здесь видно, как переопределяются классы, используются обработчики. В частности на основе класса text мы создали свой класс clickClock (обращаю внимание, что лазла чувствительна к регистру). Добавили в класс новый атрибут — dayTable (добавлять атрибуты можно и с помощью js, как — объяснять не буду :)). У тега <attribute> три атрибута: name, value & type. Для задания обработчика onclick используется элемент <handler>. Внутри код на js. Так как используется xml, то внутри скриптов нельзя использовать сущности из xml, такие как <, >, & и др. Вместо них используются всем давно известные & lt;, & gt;, & amp;. Если это кого-то не устраивает, то можно весь скрипт поместить внутрь текстового блока
<![CDATA[ var i = 0; if (i > 1) doSomething; ]]>

На этом знакомство можно закончить и перейти непосредственно к созданию фреймворка для вконтактовских приложений.

Создание фрейморка для приложений Вконтакте на OpenLaszlo.


Для начала создадим основной файл проекта, назовём его main.lzx. В нём пропишем наш канвас
<canvas width="607" height="590" bgcolor="white">
  <include href="lib/library.lzx" />
</canvas>

Здесь мы задали максимальный размер для нашего приложения (максимальный, который разрешён вКонтакте), задали белый фон и включили файл с определением наших классов, которые мы сейчас будем создавать. Для этого мы использовали тег <include>. Какое там имя файла — не важно. Просто будем называть файлики говорящими именами. Вот содержимое нашей библиотеки:
<library>
  <include href="ServerData.lzx"/>
  <include href="framework.lzx"/>
  <include href="md5.js"/>
</library>

Библиотека задается элементом <library>. В библиотеке мы подключаем три файла — первый для работы с удалённым сервером и сервером вконтакта, второй, логика приложения, третий — ф-ии для создания md5 хеша. Начнём, пожалуй!

framework.lzx


<library>
  <attribute name="api_id"   type="string" value=""/>
  <attribute name="user_id"   type="string" value=""/>
  <attribute name="group_id"  type="string" value=""/>
  <attribute name="viewer_id"  type="string" value=""/>
  <attribute name="is_app_user" type="string" value=""/>
  <attribute name="viewer_type" type="string" value=""/>
  <attribute name="auth_key"  type="string" value=""/>
  <attribute name="secret"   type="string" value="secret"/>
  <node id="framework">
   <handler name="oninit">
     <![CDATA[
     if ($debug)
     {
    canvas.setAttribute("api_id",   '1566108');
    canvas.setAttribute("user_id",   '6781573');
    canvas.setAttribute("group_id",  '0');
    canvas.setAttribute("viewer_id",  '6781573');
    canvas.setAttribute("is_app_user", '1');
    canvas.setAttribute("viewer_type", '0');
    canvas.setAttribute("auth_key",  '556C75F1EFBC11CFB9F300A0247033C4');
     }
     else
     {
      canvas.setAttribute("api_id",   lz.Browser.getInitArg('api_id'));
      canvas.setAttribute("user_id",   lz.Browser.getInitArg('user_id'));
      canvas.setAttribute("group_id",  lz.Browser.getInitArg('group_id'));
      canvas.setAttribute("viewer_id",  lz.Browser.getInitArg('viewer_id'));
      canvas.setAttribute("is_app_user", lz.Browser.getInitArg('is_app_user'));
      canvas.setAttribute("viewer_type", lz.Browser.getInitArg('viewer_type'));
      canvas.setAttribute("auth_key",  lz.Browser.getInitArg('auth_key'));
     }
    ]]>
   </handler>
</library>

Здесь мы определяем основные атрибуты приложения. Если находимся в режиме дебага, то используем свои параметры, если в режиме работы, то получаем через флешварс наши параметры. Чтобы не перегружать наш фрейворк, не будем создавать какого-то класса для него, будем использовать корневой класс node. Замечу, что всем элементам можно задавать как идентификаторы, которые видны из любой точки приложения, так и имена. В общем, здесь всё аналогично (x)html. Продолжим развивать фреймворк дальше. Определю я в этом топике только один метод из API вконтакта — getProfile:
Добавим внутрь <node id=«framework»> пару методов
<!-- запросы Вконтакте -->
     <method name="_getProfile">
         canvas.setAttribute("cntr", canvas.cntr + 1);
         this._website.getProfile({c: this, f: "_getProfileCallback"}, canvas.viewer_id);
     </method>
     <method name="_getProfileCallback" args="data">
         status.setText("Загрузка профайла...");
         var o = {};
         o.auth_key = canvas.auth_key;
         o.uid = data.xpathQuery("user/uid/text()");
         o.first_name = data.xpathQuery("user/first_name/text()");
         o.last_name = data.xpathQuery("user/last_name/text()");
         o.sex = data.xpathQuery("user/sex/text()");
         status.setText("Регистрация...");
         this._register(o);
         canvas.setAttribute("cntr", canvas.cntr - 1);
     </method>

Обработки ошибок от вконтакта здесь я приводить не буду. Каждый из методов представлен парой — запрос, колбэк. В первом устанавливаем счетчик запросов (canvas.cntr), вызываем метод запроса профайла, передавая туда ссылку на фреймворк, имя метода колбэка, дальше остальные параметры. Во втором методе получаем данные. В данном случае ответ от сервера вконтакте в виде xml (к сожалению в лазле нет поддержки JSON, весь обмен данными только через xml).

Теперь узнаем, что же такое _website. Для этого приведу пример файла serverData.lzx:
<library>
  <class name="ServerWebsite" extends="node">
     <handler name="oninit">
         this.base_url = "http://api.vkontakte.ru/api.php";
     </handler>

     <method name="_getSignature" args="params">
         /*if ($debug)
         {
             paraxms.test_mode = 1;
         }*/
         params.test_mode = 1;
         params.rnd = Math.random();
         var result = "";
         var arr = [];
         var j = 0;
         for (var i in params)
         {
            result = i + "=" + params[i];
            arr[j] = result;
            j++;
         }
         arr.sort();
         result = "";
         for (j = 0; j < arr.length; j++ )
            result += arr[j];
         return canvas.viewer_id + result + canvas.secret;
     </method>

     <method name="getProfile" args="cb_ref, uids">
         var data = {};
         data.api_id = canvas.api_id;
         data.method = "getProfiles";
         data.uids = uids;
         data.v = "2.0";
         data.fields = "sex,photo";
         data.sig = md5(_getSignature(data));
         var ds = new lz.ServerWebsiteDataset(this, {cb_ref: cb_ref});
         ds.setAttribute("src", this.base_url);
         ds.setAttribute("querytype", "POST");
         ds.setQueryParams(data);
        
         ds.doRequest();
     </method>
  </class>

  <class name="ServerWebsiteDataset" extends="dataset" type="http" request="false">
     <attribute name="cb_ref" value="null"/>
     <handler name="ondata">
         var p = this.getPointer();
         p.selectChild();
         this.destroy();
         this.cb_ref.c[this.cb_ref.f](p);
     </handler>

     <handler name="onerror">
         this.destroy();
         this.cb_ref.c[this.cb_ref.f](-1);
     </handler>

  </class>
</library>

_website — это id созданного экземпляра класса ServerWebsite. Здесь два класса. Первый определяет собственно сами запросы к серверу вконтакта, второй — датасет, делающий запросы и получающий данные от сервера.
Метод _getSignature создаёт подпись для запросов.
Пока остановимся на этом, скажу лишь, что у датасета есть три важных события: ondata, onerror, ontimeout. И все их можно определить самостоятельно. В обработчике ondata мы получаем datapointer и вызываем наш колбек, передав туда датапоинтер. Поинтер нам нужен для траверса xml-ки.

Ссылки


openlaszlo.org — Основной сайт OpenLaszlo.
openlaszlo.org/download — Здесь можно скачать последнюю версию лазлы для Windows, Linux, Mac OS…
С последней версией у меня в висте и семёрке были замечены проблемы с компиляцией, поэтому можно попробовать версию 4.5.1. С ней пока проблем не было.
openlaszlo.org/archive — здесь можно скачать более ранние версии
openlaszlo.org/taxonomy/term/14 — документация для разработчика
openlaszlo.org/node/409 — примеры разработанных приложений на лазло. (Замечу, что есть опыт аутсорсинга для H&R Block. Раньше, года два назад, сайт у них был гораздо интереснее)

Если зайти в мой список приложений вконтакте, то можно посмотреть примеры (работающий только один, ещё один пришлось закрыть. Третий пример сейчас в разработке)

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

Жду комментариев :)
_________
Source code was highlighted with Source Code Highlighter.
Текст подготовлен в ХабраРедакторе
Tags:
Hubs:
+4
Comments5

Articles