ムニエルブログ

江戸川区在住のアプリケーションエンジニア。千葉工業大学卒。Apple信者。趣味は読書とプログラミング。Java/HTML/CSS/Sass/JavaScript/jQuery/Vue/GAS BTC:18i4i1Y1Kw2xdB6aHvB62WCWXiULqcqnAd

データバインディング可能なマークアップ言語を作ろうとしてやめた話

最近、Google Apps Script(GAS)でSlackのBOTを作るのにハマっています。*1
基本的には何らかのAPIやウェブページから取得したデータを整形してメッセージを投稿するBOTなのですが、ソースコードをいじらなくてもメッセージの文面を変えられるようにするために、テンプレートをもとにメッセージを生成する仕組みにしています。
当初は特定の文字列を実際のデータの値に置換するだけの単純な仕組みで実装していましたが、「特定の値があるときにのみこの文字列を出力したい」といったケースに対応できないため、条件分岐や繰り返しなどのロジック処理を行なえるような構文を定め、言語として規格化しようと考えました。

どのような言語を作ろうとしたのか

以下のような形式でテンプレートに対してデータをバインドすることで、データが埋め込まれたテキストを生成できるものを作ろうと考えました。

const template = '{{id}}<twitter> @{{id}}</twitter>'
const data = {
  id: 'munieru',
  twitter: {
    id: 'munieru_jp'
  }
}

const output = DataBinder.bind(template, data)  //munieru @munieru_jp

言語名は、分かりやすくDBMLData Bindable Markup Language)などにしようと考えていました。

なぜ作るのをやめたのか

車輪の再発明を避けるためにも既に同じような言語がないか調べていると、Vue.jsのテンプレートで似たようなものを見た覚えがあることに気づきました。
そして、Mustacheの存在に行き着きました。

Mustacheでは、以下のような形式でテンプレートに対してデータをバインドすることで、データが埋め込まれたテキストを生成できます。

const template = '{{id}}{{#twitter}} @{{twitter.id}}{{/twitter}}'
const data = {
  id: 'munieru',
  twitter: {
    id: 'munieru_jp'
  }
}

const output = Mustache.render(template, data)  //munieru @munieru_jp

僕が考えていたものとは構文が異なりますが、HTMLタグとの混同を避けるためにもこちらのほうが良さそうです。
なにより、僕が独自の言語を作ってBOTのドキュメントに仕様を記載するよりも「Mustacheで書けます」と言ったほうが早いです。

MustacheのGoogle Apps Scriptライブラリを作成

Google Apps Scriptでは、通常のJavaScriptライブラリをURL指定で読み込むようなことはできず、Google Apps Script用のライブラリとして作成されたものしか使用できません。
どうやらMustacheのライブラリはなさそうだったので、mustache.jsをもとにMustache.gsというライブラリを作成して公開しました。

  • プロジェクトキー:MoB1GsrPeNTPPX8SRqpw8QDVZgzu5bsVr

これで、Google Apps Scriptでできることの幅が広がりました。


ダブル・バインド (キャラ文庫)

ダブル・バインド (キャラ文庫)

*1:Google Apps Script(GAS)でSlackのBOTを作る方法は、そのうち記事にします。