OpenSocial 用DSLをJavascriptで。

gadget.xmlCouchDBの show 機能で出力するものを実装中。


couchapp が使用するアプリケーション定義ファイルを拡張し、couchapp.json を次のように定義する。

{
    "name"        : "Sticky",
    "description" : "This gadget provides sticky HTML/Markdown/etc formatted contents",
    "category"    : "Utility",
    "tags"        : ["sample"],
    "author"      : "yssk22",
    "author_email": "yssk22@example.com",
    "gadgets"  : [
        {
            "title" : "Markdown",
            "xml"   : "_show/markdown",
            "title_url": "http://project.webjourney.org/projects/apps-sticky",
            "description" : "This gadget provides sticky Markdown formatted contents"
        }
    ]
}

このcouchapp.jsonOpenSocialコンテナに登録され、CouchDBMapReduceによってアプリケーションディレクトリとして利用可能になります。
で、登録されたガジェットのデータベース上ではCouchDBアプリケーションサーバーとして使えるので xmlのパスを "_show/markdown" にしています。

markdown.js の方

function(doc, req){
  // !json couchapp
  // !json templates.markdown

  // !code vendor/couchapp/path.js
  // !code vendor/ejs/ejs_production.js
  // !code vendor/webjourney/util.js
  // !code vendor/webjourney/gadget.js
  if(gadget){
    return render(templates.markdown);
  }else{
    return {
      code: 404,
      body: "Not Found"
    };
  }
}

これは普通のCouchAppアプリケーション。webjourney/*.js はOpenSocial用の拡張ライブラリです。これを読み込んでおくと、render(...)とか gadget とかが使えるようになります。

一方 templates/markdown のほう。これはEJSを組み込みつつ、webjourney/*.js で定義されたOpenSocial用の関数が使えます。

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <%= modulePrefs(["opensocial-0.9"]) %>
  <Content type="html">
    <![CDATA[
    <%= require("markdown.js") %>
    ]]>
  </Content>
</Module>

ModulePrefs は couchapp.json に定義済なのでそこからひっぱてくるための modulePrefs(features); 関数を使うことが出来ます。また、JavaScript や Stylesheet はOpenSocialだとパスの解決が面倒になるので、require(path); で、自身が登録されているCouchDBのアプリケーションディレクトリからの相対パスを絶対URIで出力するようにしました。

これで次のような出力が出るようになりました。

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs
title='Markdown'
title_url='http://project.webjourney.org/projects/apps-sticky'
description='This gadget provides sticky Markdown formatted contents'
author='yssk22'
author_email='yssk22@example.com'
category='Utility'>
<Require feature='opensocial-0.9' />
</ModulePrefs>
  <Content type="html">
    <![CDATA[
    <script src="//localhost:5984/webjourney-sticky-default/_design/sticky/markdown.js"></script>
    ]]>
  </Content>
</Module>

初期化時に、AppData とかJavaScriptで呼び出すのも面倒だな、ということで app_data(key, when_not_found) のような感じで使えるようにしたいけど、こちらはまだデザイン中。。。

といった話をデモを交えてOSCでする予定。どこまでいけるかわからないけれど。Markdown Sticky ぐらいは動作させたいなぁ。