Play 2.3 がリリースされたので変更点と試し方を説明します
http://www.playframework.com/documentation/2.3.x/Highlights23 https://groups.google.com/forum/#!msg/play-framework/bTvJbeR_zvU/J3reqk6Xo4AJ
変更点は以下の通り
- 新規プロジェクトを作るのに今までは play new コマンドを使っていたけれど Typesafe Activator を使うようになった。
- asset のコンパイルに sbt-web を利用するようになった(sbt-web については http://slides.pab-tech.net/sbt-web/ を見るとよい) 。
- Java8 サポート。Java 6,7 も引き続き使えます。
- Play-Java のパフォーマンス向上
- Scala 2.11 サポート (2.10 も引き続きサポート)
- Anorm の機能追加。SQL Interpolation 使えたりするようになった。
- WS の機能追加。
- ScalaTemplate の実装が twirl になった。
- WebSocket 用の Actor を追加 http://www.playframework.com/documentation/2.3.x/ScalaWebSockets
- HTTPS の SSLEngine がカスタマイズできるようになった。
- Asset のパフォーマンス向上。
- deprecated になっていた古い Result 系の型が削除された。
- いろいろバグ直した
以前からバリバリ使ってるよって人的には Result 型の整理がちょっとめんどいかもしれません。あとは WebSocket が Actor で少し楽に書けるようになったのが嬉しいかもしれませんね。Iteratee わけわからんって人も Actor ならまだなんとかなるんじゃないでしょうか。
ライブラリ・プラグイン作者にとってはまず sbt-web が大きくて、asset 系のプラグインを作りたいなら知っておく必要があります。あとは Scala 2.10, 2.11 のクロスビルドになってしまったので、まあ、ビルド頑張りましょう。
Play 初心者の人はプロジェクトの作成は play new ではなく、activator new を使うということだけ抑えておきましょう。古い情報を見て play new を探さないように。また activator のドキュメントを見ると activator ui というコマンドがありますが、activator ui は別に知らなくても良いただの余興みたいなものですのでとにかく気にせずに activator new しましょう。
activator は typesafe のサイトから手に入りますが、林檎教徒であれば homebrew でインストールできます。
$ brew install typesafe-activator
異教徒の方、こちらです。
$ wget http://downloads.typesafe.com/typesafe-activator/1.2.0/typesafe-activator-1.2.0-minimal.zip $ # いい感じでパスを通す
これで activator コマンドがインストールされるので activator new しましょう。
$ activator new
プロジェクトの名前を打ちます。今回は適当に try-play-23 にしました。
Enter an application name > try-play-23 Fetching the latest list of templates... The new application will be created in /Users/toshi/tmp/try-play-23 Browse the list of templates: http://typesafe.com/activator/templates Enter a template name, or hit tab to see a list
なんかサイト見ろって言ってますが、気にせず tab を押します。
> Display all 125 possibilities? (y or n) PlayStartApp activator-akka-cassandra activator-akka-scala-guice activator-akka-spray activator-akka-tracing activator-gilt-app ...
なんかテンプレートがいっぱい出てくるんですけど使用するのは play-scala です。
> play-scala OK, application "try-play-23" is being created using the "play-scala" template. To run "try-play-23" from the command-line, run: /Users/toshi/tmp/try-play-23/activator run To run the test for "try-play-23" from the command-line, run: /Users/toshi/tmp/try-play-23/activator test To run the Activator UI for "try-play-23" from the command-line, run: /Users/toshi/tmp/try-play-23/activator ui
これで try-play-23 プロジェクトができました。activator 使えってうるさいですね。どれどれ。
$ cd try-play-23 $ ls LICENSE conf README logs activator project activator-launch-1.1.0.jar public app target build.sbt test
プロジェクトの中に activator コマンドと起動用の jar が入っています。2.2 以前は play コマンドを使っていましたが、2.3 からはこの activator コマンドを使うのが流儀のようです。
$ ./activator run
実際 activator は sbt のラッパーなので、あまり必要性を感じない人は rm しちゃって sbt そのまま使えば良いでしょう。
$ rm activator* # 汚物は消毒だ! $ sbt run
これでもりもりとダウンロードやらコンパイルが始まるので待ちましょう。途中で OutOfMemory とか PermGen なんちゃらとか言われて落ちてもくじけない。
ふう、やっと起動した。
感想
- activator の存在意義は未だにわからない
- でも play で採用されることで activator の存在がいよいよ知れ渡ってしまったので一応知っておく必要はある
- sbt にプロジェクトテンプレート作成機能があればいい気がした
- play new したいがために Play のでかい zip を落としてくる必要がなくなったのは嬉しい
Play で Scala.js を使う
Play meetup では Play や Scala のフレームワークの歴史みたいな話をしていましたが、本当はこのネタで LT をするつもりでした。諸事情によりってやつです。
さて Play で Scala.js をサポートしようぜって話は少し前からありますが、今のところまだ進展はないようです。
Add buildin ScalaJs support · Issue #2321 · playframework/playframework
ただ、もちろん sbt をいじれば一緒に使うことが可能です。
単純に optimizeJS して出力された js を Play の public/javascripts フォルダにコピーするとか。
lazy val copyJS = Command.command("copyJS") { (state) => scala.sys.process.Process(List("cp", "js/target/scala-2.10/scala-js-slide-js-opt.js", "server/public/javascripts/")).! state }
ちょっとやっつけ感ありますが問題なく使えます。
でもまあもうちょっとまともな方法はが公式サイトからリンク貼られてました。 これを clone するか設定パクればOKです。
git clone git@github.com:vmunier/play-with-scalajs-example.git
このプロジェクトでは Scala.js のプロジェクトが scalajs というサブプロジェクト、Play アプリが scalajvm というサブプロジェクト、さらにその両方で共有されるコードが shared というサブプロジェクトになっています。
├── README.md ├── project │ ├── Build.scala │ ├── build.properties │ ├── plugins.sbt │ ├── project │ └── target ├── scala │ ├── shared │ └── target ├── scalajs │ ├── src │ └── target └── scalajvm ├── app ├── conf ├── logs ├── public ├── target └── test
このやり方については pab_tech さんも書いてるのでそちらを見てください。
Scala.jsとJVMの両対応コードとScala.jsのテストの書き方 | PABlog
で、Play と使うための build.sbt 設定の中心は以下の部分です。 Scala.js の出力先を Play の public/javascripts にしています。さらに dependsOn を使って Play のアプリをコンパイルしたときに Scala.js のプロジェクトのコンパイルを走らせるようにしています。dist コマンドを使ったときには optimize も行うようになっています。
lazy val scalajvmSettings = play.Project.playScalaSettings ++ Seq( scalajsOutputDir := (crossTarget in Compile).value / "classes" / "public" / "javascripts", compile in Compile <<= (compile in Compile) dependsOn (preoptimizeJS in (scalajs, Compile)), dist <<= dist dependsOn (optimizeJS in (scalajs, Compile)), ) ++ ( // ask scalajs project to put its outputs in scalajsOutputDir Seq(packageExternalDepsJS, packageInternalDepsJS, packageExportedProductsJS, preoptimizeJS, optimizeJS) map { packageJSKey => crossTarget in (scalajs, Compile, packageJSKey) := scalajsOutputDir.value } )
これで、Play でも Scala.js が使えるようになります。やったー!コンパイル時間がさらに伸びますね!
Play 2 meetup を開催しました & スライドまとめ
ドワンゴさんを会場としてお借りして Play meetup を行いました。ありがとうございました!
http://connpass.com/event/6020/
発表資料をTLから拾ってまとめましたのでどうぞ。
Play と Scala のこれまでとこれから/@tototoshi
(開会挨拶的なもので特に面白くはないですが一応貼っておきます)
やさしい Iteratee 入門 / @kawachi
play2のjsonと型クラス @xuwei_k
http://xuwei-k.github.io/slides/play2typeclasses/
DSLからのコードジェネレーションで楽々Play開発 @takezoux2
ActionBuilder の罠(仮) @gakuzzzz
sbt-webを使ったプラグインの作り方(仮) @pab_tech
http://slides.pab-tech.net/sbt-web/
フロントエンドとバックエンドのビルド構成について @kara_d
一番簡単なWebSocketの試し方 @shunjikonishi
Play2 WS 再入門 @magnet88jp
https://docs.google.com/presentation/d/1H8PhVmMqDHf8bRhsuw03KW0jd98SWKRoEnwt1UecRtc/htmlpresent
MyFleetGirls @ponkotuy
なんでこがいに並外れた Typesafe ができたんか言うたら...
「よくシリコンバレーのスタートアップが作ってるようなうさんくさいビデオ」を Typesafe も作っていました。
Typesafe activator ダウンロードするか、めんどくさい...とサイトに行ったらいきなりビデオ見せられました。なかなかのユーザー体験をしました。
何か Typesafe Activator がすごい革新的っぽいことが伝わってきます。
他にもいろいろあります。
去年 Scala Conference に来てくれた Jamie さん
すごそう。
知らない人
すごそう。
Heiko さん
すごそう。
小田好先生
すごい(確信)
まとめ
- Typesafe すごそう
- 広島弁バージョンの登場が待たれる
composer で依存関係から特定のライブラリを除外する
Maven でのこれ
<dependencies> <dependency> <groupId>sample.ProjectA</groupId> <artifactId>Project-A</artifactId> <version>1.0</version> <scope>compile</scope> <exclusions> <exclusion> <!-- declare the exclusion here --> <groupId>sample.ProjectB</groupId> <artifactId>Project-B</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
composer にはこの依存関係から特定のライブラリを除外する機能はない。まだ実装していないのではなく方針として入れるつもりはなさそう。composer 開発者はこの機能を不要と思っているっぽい。
Exclude packages · Issue #1549 · composer/composer
理想をいうと微妙なところだけど、実際こういう問題はよく起きるからカバーするべきじゃないかな。composer 開発者はそういう経験ないのだろうか。PHP はフルスタックでそれのみで完結するようなフレームワークが多く、依存関係のツリーが深くならないから dependency hell が起きづらいと勝手に理解しておく。
一応、問題自体は除外したいモジュールを provide に指定すれば解決する。すでに提供されているのだから composer で持ってくる必要はないよね、ということ。
{ "require": { "foo": "1.0.0" }, "provide": { "bar": "*" } }
ただし、これだと問題は解決するものの意味としては全く違うから気持ち悪い。設定が json だからコメントも書けない。
まとめ
- composer で exclude したいときは provide を使う
- json で設定ファイルはきびしい
Python で Github Flavored Markdown をレンダリングする
前回の補足的な内容
python の Markdown ライブラリ自体は Github Flavored Markdown(GFM) をサポートしていない。
>>> import markdown >>> markdown.markdown("```python\ndef hello():\n print('hello')\n```") u"<p><code>python\ndef hello():\n print('hello')</code></p>"
python の Markdown ライブラリは拡張可能になっている。Markdown ライブラリの拡張ライブラリとして py-gfm を使うと gfm も扱えるようになる。
>>> import markdown >>> markdown.markdown("```python\ndef hello():\n print('hello')\n```", extensions=['gfm']) u'<pre class="highlight"><code class="language-python">def hello():\n print(\'hello\')</code></pre>'
さて、これで python であることを認識してくれたわけではあるけれど、シンタックスハイライトが効いていない。しかし、前回のエントリで MoinMoin に Markdown + py-gfm を組み込んだときはシンタックスハイライトがついていた。なんで?
これが気になっていろいろソース読んだりしたのだけど、答えは MoinMoin が pygments に依存しているから。pygments をインストールする前後で Markdown ライブラリは動きが変わる。
$ pip install pygments
>>> import markdown >>> markdown.markdown("```python\ndef hello():\n print('hello')\n```", extensions=['gfm']) u'<div class="highlight"><pre><span class="k">def</span> <span class="nf">hello</span><span class="p">():</span>\n <span class="k">print</span><span class="p">(</span><span class="s">'hello'</span><span class="p">)</span>\n</pre></div>' >
pygments をインストールしたらシンタックスハイライトがついた。
実は Markdown のほうにこんなコードがあった。
try: from pygments import highlight from pygments.lexers import get_lexer_by_name, guess_lexer, TextLexer from pygments.formatters import HtmlFormatter pygments = True except ImportError: pygments = False
https://github.com/waylan/Python-Markdown/blob/2.4-final/markdown/extensions/codehilite.py#L26-L32
わかりにくい挙動だと思う。markdown 関数の第二引数で extensions=['pygment']
みたいに渡すようにすればいいのに。せっかく拡張を作れるにしたのになぜこういう結合をさせるのか理解に苦しむ。
まあともあれ、Markdown + py-gfm + pygments で良い感じに GFM がレンダリングできるので使うと良いと思います。
MoinMoin で Markdown (Github Flavored Markdown) を使う
Markdown のメモ帳として kobito を使っていたんだけど Qiita に新規投稿ができないし、過去の投稿は編集できるけど取得はできない(つまり書いた記事がいつのまにか巻き戻されている)という状態に頻繁になるので使うのをやめました。なんなんだ、嫌がらせか。
いい加減あきれたので Qiita で書いていたもののうち、非公開にしているものを自分で管理している MoinMoin Wiki に記事を移行することにしました。公開しているものはこのブログに持ってくることにします。
さて、Qiita は Markdown で、MoinMoin は独自記法なので単純に考えると変換を書ける必要がある、と思いきや実はそんな必要はない。MoinMoin の parser はプラガブルになっていて自分で追加ができるので自分で Markdown パーサーを書いてやれば OK。 MoinMoin の公式の Wiki には Python の Markdown ライブラリを用いた方法が紹介されています。
しかし使ってみたら Qiita は Github Flavored Markdown (の亜種?)なのでコードブロックなどが Markdown ライブラリだとうまくレンダリングできませんでした。Github Flavored Markdown を扱えるライブラリを探していたら dart-lang の人たちがなぜか python で実装している py-gfm というのを教えてもらいました。
というわけでまず py-gfm をインストールします。
$ git clone https://github.com/dart-lang/py-gfm.git $ cd py-gfm $ python setup.py install
これで Markdown ライブラリで GFM 拡張が使えるようになるので、これを使って GFM プラグインを書きます。
# coding: utf-8 from markdown import markdown import json Dependencies = ['user'] class Parser: def __init__(self, raw, request, **kw): self.raw = raw self.request = request def format(self, formatter): output_html = markdown(self.raw, extensions=['gfm']) try: self.request.write(formatter.rawHTML(output_html)) except: self.request.write(formatter.escapedText(output_html))
すごくテキトーですが、これで GFM プラグインの完成です。簡単ですね。 text_markdown.py という名前で MoinMoin の plugin/parser ディレクトリに入れてあげましょう。
2015/02/10 追記
原因は追ってないけど最近 py-gfm が動作しなくなったので Markdown の extension を組み合わせてほぼ GFM っぽい感じにしてます。これだけで十分かも。なにか互換性壊れたのかなー。
# coding: utf-8 from markdown import markdown import json Dependencies = ['user'] class Parser: def __init__(self, raw, request, **kw): self.raw = raw self.request = request def format(self, formatter): output_html = markdown( self.raw, extensions=[ 'markdown.extensions.fenced_code', 'markdown.extensions.toc', 'markdown.extensions.codehilite', 'markdown.extensions.wikilinks', 'markdown.extensions.tables', 'markdown.extensions.def_list', 'markdown.extensions.nl2br', 'markdown.extensions.headerid', ]) try: self.request.write(formatter.rawHTML(output_html)) except: self.request.write(formatter.escapedText(output_html))
Markdown で Wiki エントリを追加する
markdown で Wiki にエントリを追加したいときは、書き出しを
#format text_markdown (空行)
にすれば Markdown として解釈してくれるようになります。
これでレンダリングが崩れることはなくなりましたが、CSS が当たっていません。 CSS はどこに追加するのが流儀なんでしょうか。よくわからないので本体の common.css に https://github.com/johnmdonahue/git_marked から拝借したのを突っ込んでしまいました。
.c{color:#998;font-style:italic;} .err{color:#a61717;background-color:#e3d2d2;} .k{font-weight:bold;} .o{font-weight:bold;} .cm{color:#998;font-style:italic;} .cp{color:#999;font-weight:bold;} .c1{color:#998;font-style:italic;} .cs{color:#999;font-weight:bold;font-style:italic;} .gd{color:#000;background-color:#fdd;} .gd .x{color:#000;background-color:#faa;} .ge{font-style:italic;} .gr{color:#a00;} .gh{color:#999;} .gi{color:#000;background-color:#dfd;} .gi .x{color:#000;background-color:#afa;} .go{color:#888;} .gp{color:#555;} .gs{font-weight:bold;} .gu{color:#800080;font-weight:bold;} .gt{color:#a00;} .kc{font-weight:bold;} .kd{font-weight:bold;} .kn{font-weight:bold;} .kp{font-weight:bold;} .kr{font-weight:bold;} .kt{color:#458;font-weight:bold;} .m{color:#099;} .s{color:#d14;} .na{color:#008080;} .nb{color:#0086B3;} .nc{color:#458;font-weight:bold;} .no{color:#008080;} .ni{color:#800080;} .ne{color:#900;font-weight:bold;} .nf{color:#900;font-weight:bold;} .nn{color:#555;} .nt{color:#000080;} .nv{color:#008080;} .ow{font-weight:bold;} .w{color:#bbb;} .mf{color:#099;} .mh{color:#099;} .mi{color:#099;} .mo{color:#099;} .sb{color:#d14;} .sc{color:#d14;} .sd{color:#d14;} .s2{color:#d14;} .se{color:#d14;} .sh{color:#d14;} .si{color:#d14;} .sx{color:#d14;} .sr{color:#009926;} .s1{color:#d14;} .ss{color:#990073;} .bp{color:#999;} .vc{color:#008080;} .vg{color:#008080;} .vi{color:#008080;} .il{color:#099;}
やっつけ感すごいですが、とりあえずこれで MoinMoin で Github Flavored Markdown が使えるようになりました。めでたし。