Tower.jsは、Ruby on railsやCakePHPの人には、すぐに理解できるパッケージでありましょう。ドキュメントも途中のようですが、敷居は低そうです。
前回のエントリー「さらばExpressよ!Tower.jsを試すの巻」に続き、今回は Tower.jsの全体像を見て行きたいと思います。
Tower.jsでは膨大なパッケージが使われていますが、実際、重要そうなモジュールはこんな感じかな、と。
Tower.Applicationクラス
アプリケーションの定義クラス。各アプリはTower.Applicationを継承して設定してきます。
tower new hogehogeコマンドで自動的に生成されます。Expressと比較してコードが劇的に減っているのがわかります。そして美しい。
# config/application.coffee class App extends Tower.Application @configure -> @use "favicon", Tower.publicPath + "/favicon.ico" @use "static", Tower.publicPath, maxAge: Tower.publicCacheDuration @use "profiler" if Tower.env != "production" @use "logger" @use "query" @use "cookieParser", Tower.session.secret @use "session", Tower.session.key @use "bodyParser" @use "csrf" @use "methodOverride", "_method" @use Tower.Middleware.Agent @use Tower.Middleware.Location @use Tower.Middleware.Router module.exports = global.App = App
Tower.Modelクラス
モデルを定義するクラス。各モデルはTower.Modelを継承して設定してきます。モデル同士の関連(belongsTo, hasMany)もココで定義します。ちょっとした変換もここで。
tower generate scaffold <モデル名>で生成できます。
# app/models/post.coffee class App.Post extends Tower.Model @field "title" @field "body" @field "tags", type: ["String"], default: [] @field "slug" @belongsTo "author", type: "User" @hasMany "comments", as: "commentable" @before "validate", "slugify" slugify: ->; @set "slug", @get("title").replace(/^[a-z0-9]+/g, "-").toLowerCase()
Tower.Routeクラス
ルーティング定義。セッションの生成、破棄もココ。
# config/routes.coffee Tower.Route.draw -> @match "/login", "sessions#new", via: "get", as: "login" @match "/logout", "sessions#destroy", via: "get", as: "logout" @resources "posts", -> @resources "comments" @namespace "admin", -> @resources "users" @resources "posts", -> @resources "comments" @constraints subdomain: /^api$/, -> @resources "posts", -> @resources "comments" @match "(/*path)", to: "application#index", via: "get"
ビュー
描画部分を定義。CoffeeKupで記述。Bootstrap2に対応!
tower generate view <ビュー名> コマンドで生成できます。
# app/views/posts/new.coffee formFor "post", (f) -> f.fieldset (fields) -> fields.field "title", as: "string" fields.field "body", as: "text" f.fieldset (fields) -> fields.submit "Submit"
Layout。指定しなければ、このレイアウトでラップされる。partialだけ書けば良い。
# app/views/layouts/application.coffee doctype 5 html -> head -> meta charset: "utf-8" title t("title") meta name: "description", content: t("description") meta name: "keywords", content: t("keywords") meta name: "robots", content: t("robots") meta name: "author", content: t("author") csrfMetaTag() appleViewportMetaTag width: "device-width", max: 1, scalable: false stylesheets "lib", "vendor", "application" javascriptTag "https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" javascripts "vendor", "lib", "application" body role: "application", -> if hasContentFor "templates" yield "templates" nav id: "navigation", role: "navigation", -> div class: "frame", -> partial "shared/navigation" header id: "header", role: "banner", -> div class: "frame", -> partial "shared/header" section id: "body", role: "main", -> div class: "frame", -> yields "body" aside id: "sidebar", role: "complementary", -> if hasContentFor "sidebar" yields "sidebar" footer id: "footer", role: "contentinfo", -> div class: "frame", -> partial "shared/footer" if hasContentFor "popups" aside id: "popups", -> yields "popups" if hasContentFor "bottom" yields "bottom"
Tower.Controllerクラス
モデルとビューを操作するコントローラクラス。あるアクションに対してモデルとビューをどうするか定義。モデリングにもよるけど、1つのモデルに対して大体1個定義。
tower generate controller コマンドで生成できます。
# app/controllers/postsController.coffee class App.PostsController extends Tower.Controller index: -> App.Post.all (error, posts) => @render "index", locals: posts: posts new: -> @post = new App.Post @render "new" create: -> @post = new App.Post(@params.post) super (success, failure) -> @success.html -> @render "posts/edit" @success.json -> @render text: "success!" @failure.html -> @render text: "Error", status: 404 @failure.json -> @render text: "Error", status: 404 show: -> App.Post.find @params.id, (error, post) => @render "show" edit: -> App.Post.find @params.id, (error, post) => @render "edit" update: -> App.Post.find @params.id, (error, post) => post.updateAttributes @params.post, (error) => @redirectTo action: "show" destroy: -> App.Post.find @params.id, (error, post) => post.destroy (error) => @redirectTo action: "index"
データベースの定義
どのデータベースを使うか。開発用、テスト用、デモ用、本番用など用途に応じて定義可能。
# config/databases.coffee module.exports = mongodb: development: name: "app-development" port: 27017 host: "127.0.0.1" test: name: "app-test" port: 27017 host: "127.0.0.1" staging: name: "app-staging" port: 27017 host: "127.0.0.1" production: name: "app-production" port: 27017 host: "127.0.0.1"
多言語の定義
日本語の場合、たぶんjp.coffeeで定義。多言語化は始めからやっておくと吉。
# config/locales/en.coffee module.exports = hello: "world" forms: titles: signup: "Signup" pages: titles: home: "Welcome to %{site}" posts: comments: none: "No comments" one: "1 comment" other: "%{count} comments" messages: past: none: "You never had any messages" one: "You had 1 message" other: "You had %{count} messages" present: one: "You have 1 message" future: one: "You might have 1 message"
こんなもんかな。
全体的にコードが美しいです。ドキュメントはまだまだ足りませんが、Rails-erやCakePHP-erには読まなくとも大体は理解できるようになっているので、学習時間が少なくて済むのがいいところでしょうか。
0 件のコメント:
コメントを投稿