Umi Uyuraのブログ

Titaniumを使ったスマートフォンアプリ開発を中心に、プログラミング関連の作業ログ。

Alloy with Jadeでincludeを使う

私は普段Titanium開発をする際、ViewをJade、StyleをStylusで書いています。

umi-uyura.hatenablog.com

今回、Viewの中でJadeの include を使ってみようとしたところ、上記のalloy.jmkだけではエラーになってしまうようだったので、少し修正してみました。

alloy.jmkの修正箇所

上記のalloy.jmkの中で、Jadeに関する処理をしている部分に、以下のように手を加えました。

  // jade
  event.alloyConfig.xml = [];
  wrench.readdirSyncRecursive(view_root).forEach(function(view) {
    if (view.match(/\.jade$/)) {
      event.alloyConfig.xml.push(view.replace(/\.jade$/, ".xml"));
      var jadeOption = {
        filename: path.join(view_root, view),                           // ←1.includeを使えるようにする
        pretty: (event.alloyConfig.deploytype === "development"),
        compileDebug: (event.alloyConfig.deploytype !== "production")
      };
      fs.writeFileSync(
        path.join(view_root, view.replace(/\.jade$/, ".xml")),
        jade.compile(fs.readFileSync(path.join(view_root, view)).toString(), jadeOption)(event));
    }
  });

  // Files that start with '_' ,
  // because is to use in `include` of Jade, it should be deleted here
  event.alloyConfig.xml.forEach(function(view) {                        // ←2.include済みXMLは削除しておく
    if (view.match(/^_\S*.xml$/g)) {
      fs.unlinkSync(path.join(view_root, view));
    }
  });
  // ~jade

ポイントは2箇所あります。

1.includeを使えるようにする

はじめ、include を使ってみたところ、 the "filename" option is required to use "include" with "relative" paths というエラーが出力されました。

index.jade

Alloy
  Window
    include ./_index_body.jade

_index_body.jade

Label Hello, World

どうやら、 include で取り込む対象ファイルを相対パスで指定するためには、Jadeコンパイル時に filename を指定する必要があるようでした。

そこで、上記の 1. の部分のようにパスを取得し、 jade.compile のオプションとして渡すようにしたところ、コンパイルが通るようになりました。

2.include済みXMLは削除しておく

上記の問題は解決されたのですが、次にAlloyコンパイル時に、include済み.jadeを.xmlに変換したファイル(上記の例では _index_body.jade )がエラーになってしまうようになりました。

includeされるファイルは、includeした方の.xmlに取り込まれる形になるため、Alloyコンパイル時には不要なものなのですが、プロジェクトのviewフォルダ内にある.xmlは全てコンパイル対象となるからです。

そこで、Alloyコンパイルする対象を分別するために、以下のようなルールを設けることしました。

  • includeするファイルは、ファイル名を _ で始める

そして、alloy.jmkに 2. のコードを追加しました。

これは、ひととおり.jadeをコンパイルした後で、ファイル名に _ が付いている.jadeについては、対応する.xmlを事前に削除するというものです。

これにより、Alloyコンパイル時にはinclude済みの.xmlは存在しないため、エラーは発生しなくなります。

alloy.jmk全体

上記の修正をしたalloy.jmkです。

Alloy with Jade & Stylus, and Stylus Extend Notati ...

ついでに、JadeとStylusを設定して、 include を使っている状態のサンプルプロジェクトです。

umi-uyura/AlloyJadeStylusExam

まとめ

Alloy XMLには Require という仕組みがありますが、この場合、あるViewに別のViewを連携するような感じなので、コントローラが分離されるなど、データのやり取りなどが複雑になってしまう場合があります。

Jade側でincludeする仕組みでは、include対象を取り込んだXMLを生成することになるため、同一のViewやコントローラ内で扱える点が便利かな、と思います。

何か使いドコロがあれば、使ってみようと思います。

パーフェクトJavaScript

パーフェクトJavaScript