この記事はOpal Advent Calendar 2016の20日目の投稿として書いています。

あいかわらず間に合っていませんが気にしないでいきたいと思います。

今日はhtmlファイルをhamlから変換して生成するようにします。
前回の記事で気がついたのですが、タイトルの「OpalでElectronのアプリをつくる」というのがすでに「OpalでElectronのアプリをつくるためのgemをつくる」に内容が変ってしまっています。
まあ、気にせずにつづけていきたいと思います。

今回の修正のコードはv0.0.2としてタグづけしてあります。

$ git show 8f2c1ab

してみます。
ダイジェストで変更点を紹介しましょう。

lib/electron_opal/default.hamlというファイルが追加されています。既存の処理と同じようにhamlファイルがなければデフォルトのhtmlファイルを生成するようにします。

hamlからhtmlへ変換するためにHaml::Engineを生成します。

def haml(pathname)
  haml = pathname.parent + "#{pathname.basename('.rb')}.haml"
  haml = Pathname.new(File.expand_path('../default.haml', __FILE__)) unless haml.exist?
  Haml::Engine.new(haml.read)
end

javascript_include_tagメソッドはそのまま使いたいので、Haml#renderに渡すコンテキストとして、Indexのインスタンスを渡すようにします。

html = haml(pathname).render(Index.new(asset_name, server.sprockets, true, "http://localhost:8080/"))
write_to("#{asset_name}.html", html)

これでhamlファイルからhtmlファイルを生成するようにできました。

app/main_window.hamlファイルを置くとhtmlファイルに変換されてそちらが使われるようになります。

!!!
%html
  %head
    %title Hello world
  %body
    %h1 Hello world
    = javascript_include_tag

デフォルトのhtmlファイルと違って'Hello world'という文字が表示されます。

スクリーンショット 2016-12-21 3.03.09.png

さて、hamlファイルを書けば自由に表示されるhtmlを変更することが出来るようになりました。
debugタスクはDebugServerを使って.rbファイルを書きかえたときにリロードすればすぐに画面に反映されるようになっています。
せっかくなので、hamlファイルの変更についても追従できるように変更したいと思います。

$ git show d1f2ef7

すれば変更点を確認することができます。

Gemfileを見れば分るとおり、fssmというgemを使っています。fssmはファイルシステムをモニタリングするgemです。

つかいかたはこんな感じです。

def haml(pathname, &block)
  haml = pathname.parent + "#{pathname.basename('.rb')}.haml"

  if haml.exist? && block
    EM.defer do
      FSSM.monitor(haml.parent, haml.basename) do
        update { block.call(Haml::Engine.new(haml.read)) }
      end
    end
  end

  haml = Pathname.new(File.expand_path('../default.haml', __FILE__)) unless haml.exist?
  engine = Haml::Engine.new(haml.read)
  block.call(engine) if block
  engine
end

hamlメソッドを変更して、blockが渡されたときにはファイルをモニタリングするようにしました。
ファイルに更新があった場合はblockを呼び出します。

これで、hamlファイルを変更したときにもリロードするだけで変更が反映されるようになりました。

今回はOpalというより、Hamlに変換する話とかfssmでファイルをモニタリングする話になってしまいました。
次回はElectronの最終回として、ElectronのAPIを使えるようにWrapperを書くことにします。