2
2

More than 5 years have passed since last update.

[Grails]namespaceの使い方

Last updated at Posted at 2014-06-19

参考

http://d.hatena.ne.jp/mottsnite/20140521/1400684993
http://grails.org/doc/latest/guide/single.html#namespacedControllers

概要

以前にも一度namespaceに関して投稿しました。
今回Grails2.4で再度チャレンジしてリンクの生成が上手く行ったので再投稿です。

メリット

namespaceを用いることで、同名のコントローラ名(ファイル名)が利用できるようになります。

テストプロジェクトの作成

プロジェクト名は namespace_sample とする。
grails create-app namespace_sampleを実行した後、その場でgrailsコマンドを実行してインタラクティブモードに入っておく。

コントローラの作成

インタラクティブモードで以下のコマンドを実行する。

#まずフロントエンド用
grails> create-controller frontend.hello
| Created file grails-app/controllers/frontend/HelloController.groovy
| Created file grails-app/views/hello
| Created file test/unit/frontend/HelloControllerSpec.groovy
grails> 

#続いてバックエンド用
grails> create-controller backend.hello
| Created file grails-app/controllers/backend/HelloController.groovy
| Created file grails-app/views/hello
| Created file test/unit/backend/HelloControllerSpec.groovy

# 最後にデフォルトパッケージのコントローラも作っておいてみる。
grails> create-controller hello
| Created file grails-app/controllers/namespace_sample/HelloController.groovy
| Created file grails-app/views/hello
| Created file test/unit/namespace_sample/HelloControllerSpec.groovy

コントローラの編集

上記で作成したコントローラを以下のように編集する。

namespace_sample/grails-app/controllers/backend/HelloController.groovy
package backend

class HelloController {

    // namespaceの指定
    static namespace = 'backend'

    def index() {
        [msg:"BACKEND!"]
    }
}
namespace_sample/grails-app/controllers/frontend/HelloController.groovy
package frontend

class HelloController {

    // namespaceの指定
    static namespace = 'frontend'

    def index() {
        [msg:"FRONTEND!"]
    }
}
namespace_sample/grails-app/controllers/namespace_sample/HelloController.groovy
package namespace_sample

class HelloController {

    /*
     * namespaceの指定はなし
     */

    def index() {
        [msg:"DEFAULT!"]
    }
}

データ表示用のViewの生成

namespaceが指定されているコントローラは、デフォルトで grails-app/views/<NAMESPACE名>/<CONTROLLER名>/ディレクトリを優先的に利用するようになります。
該当するgspファイルやディレクトリがなかった場合、旧来通りgrails-app/views/<NAMESPACE名>/<CONTROLLER名>/ディレクトリが利用されます。

とりあえず共通で利用されるgspファイルを作成してみます。

namespace_sample/grails-app/views/hello/index.gsp
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
  <title></title>
</head>
<body>
This page is<h1>"${msg}"</h1>
</body>
</html>

URLの設定

UrlMappings.groovyを以下のように編集します。

namespace_sample/grails-app/conf/UrlMappings.groovy
class UrlMappings {

    static mappings = {
        /********** ここから追加 **********/
        "/frontend/$controller/$action?/$id?(.${format})?"(namespace: 'frontend')
        "/backend/$controller/$action?/$id?(.${format})?"(namespace: 'backend')
/*
ここのコメントアウトされた書き方だとNG(g:linkタグなどが正しく動作しない)
        '/frontend' {
            namespace = 'frontend'
        }

        '/backend' {
            namespace = 'backend'
        }

        "/$namespace/$controller/$action?"()
*/
        /********** ここまで追加 **********/

        "/$controller/$action?/$id?(.$format)?"{
            constraints {
                // apply constraints here
            }
        }

        "/"(view:"/index")
        "500"(view:'/error')
    }
}

確認してみる

インタラクティブモードでrun-appを実行してGrailsを起動します。
その後、以下のURLにそれぞれアクセスすれば、ちゃんとnamespaceが有効になっていて異なるページが表示されます。

http://localhost:8080/namespace_sample/backend/hello/index
http://localhost:8080/namespace_sample/frontend/hello/index
http://localhost:8080/namespace_sample/hello/index

Viewも分けてみる

とても簡単。
単純に以下のディレクトリとファイルを作るだけ。

  • namespace_sample/grails-app/views/backend/hello/index.gsp
  • namespace_sample/grails-app/views/frontend/hello/index.gsp

こうすることで、namespaceが指定されたコントローラは自動的に自分のnamespaceのディレクトリは以下を優先的に利用するようになります。

GSPタグでのリンクの生成

単純にnamespace属性を追加するだけです。
サンプルとして、namespace_sample/grails-app/views/hello/index.gspを以下のようにしてみます。

namespace_sample/grails-app/views/hello/index.gsp
<g:link namespace="backend" controller="hello" action="index">To Backend</g:link><br />
<g:link namespace="frontend" controller="hello" action="index" >To Frontend</g:link><br />
<g:link controller="hello" action="index">To Default</g:link><br />

これでちゃんと動くはず。

それでもやっぱりg:formは上手く動かない

前回の投稿同様に、g:formでは namespaceの指定が有効になりません。
回避方法としてはやはり引き続きmappingを利用するしかなさそうです。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2