LoginSignup
1
4

More than 5 years have passed since last update.

はじめてのPlay Framework個人的メモ

Posted at

Play Framework

よく使うもの

  • ソースファイルの置き場所 app
  • ビルドのためのスクリプトファイル sbt.bat
  • 設定ファイル置き場 conf
  • 全体のレイアウトを記述するファイルや画像などのリソースを置くフォルダ public
  • ビルド生成物が置かれるフォルダ target

appフォルダ

  • controllers ロジック
  • views HTML (Scalaのコードを埋め込んだ.scala.htmlという拡張子のファイル
  • モデルの定義もここに置く
  • ここに作るディレクトリは、フォルダではなくパッケージになる

Welcome to Play! が表示される仕組み

routesというファイルでルーティング設定

(クライアントからサーバに送る要求の種類とURLの組み合わせを、プラグラムのメソッドに結びつける)

GETメソッドでルート(デフォルトではlocalhost:9000)にアクセスすると、
app/controllersフォルダにあるHomeControllerクラスのindexメソッドが呼ばれる

conf/routes
GET     /                           controllers.HomeController.index

app/views/index.scala.html
@()

@main("Welcome to Play") {
  <h1>Welcome to Play!</h1>
  }

indexメソッドによって、テンプレートindexを呼び出す
main関数を実行。
(引数として、

title:Stringである"Welcome to Play
content:Htmlである<h1>Welcome to Play!
を渡している)
app/views/main.scala.html
 *@
@(title: String)(content: Html)

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>@title</title>
        <link rel="stylesheet" media="screen" href="@routes.Assets.versioned("stylesheets/main.css")">
        <link rel="shortcut icon" type="image/png" href="@routes.Assets.versioned("images/favicon.png")">
    </head>
    <body>

        @content

      <script src="@routes.Assets.versioned("javascripts/main.js")" type="text/javascript"></script>
    </body>
</html>

テンプレートindexによって、さらにmainを呼び出す
渡されてきた変数をHtmlに埋め込むには、@変数名とする。

リンクの貼り方

routesに記載された情報を利用する

routes
GET     /                           controllers.HomeController.index

GET     /assets/*file               controllers.Assets.versioned(path="/public", file: Asset)

GET     /viewtest                   controllers.ViewTestController.index   #ここへのリンクを貼りたい

html内にて、

<a href="@routes.ViewTestController.index">view test</a>

のようにする。

注意点

  • ""で囲んでも、Twirlテンプレートとしてちゃんと動いてくれる
  • routes内ではcontrollers.~~となっているが、リンクを貼る際はroutes.~~に変えること

テンプレートへの変数の渡し方

こんな感じでテンプレートがあるとする。

viewtest_index.scala.html
@(title: String="自分で作ったファイル")

@viewtest_main("自分で作ったファイル"){
    <h1>@(title+"です")</h1>
}

titleという変数を受け取れるようしているが、初期値が設定してあるのでcontrollerでは

package controllers

import javax.inject._
import play.api._
import play.api.mvc._

@Singleton // 「シングルトン」の指定。「このクラスからは、たったひとつのオブジェクトしか作ってはいけない」という指示
class ViewTestController @Inject()(cc: ControllerComponents)
  extends AbstractController(cc) { // @Inject 「ccは、フレームワークで作る」というフレームワーク内部への指示

  def index() = Action { implicit request: Request[AnyContent] =>
    Ok(views.html.viewtest_index())
  }
}

この記述でOK。

しかし

@(title: String="自分で作ったファイル")(rnum: Int = 1)

@viewtest_main("自分で作ったファイル"){
    <h1>@(title+"です")</h1>
    <p>末尾が @rnum の方に大チャンス!!</p>

このように、テンプレートに変数を二つ定義しており、かつ初期値を持っている場合は、コントローラにて、
二つの変数どちらにも値を渡さず、初期値のままにする ということを伝えなければいけません。
その際は、
Ok(views.html.viewtest_index())
ではなく、(エラーが起きる)
Ok(views.html.viewtest_index()())
このように、メソッドの呼び出しにおいて()を二つ、(変数の数分)記述してプログラムに意図を伝えなければいけない。

テンプレート最上段の、@(title: String="自分で作ったファイル")(rnum: Int = 1)に、
コントローラのviews.html.viewtest_index()()が対応している形ですね。

そして、初期値を使わずに、コントローラから変数の値を指定する場合にも、変数の数だけ()を二つ並べます。

Ok(views.html.viewtest_index("コントローラから渡したtitle")(5))

また、テンプレート側で、変数の受け取り方を
@(title: String="自分で作ったファイル", rnum: Int = 1)
このように一つの()の中にカンマ区切りで納めると、渡し方のほうも、
Ok(views.html.viewtest_index("コントローラから渡したtitle", 5)
このように「普通の関数みたいな書き方」になります。

状況に応じて使い分けが必要
()を並べる方法は
* 渡す値が関数オブジェクトやHTMLブロックの際に見やすい
* 「変数を渡さない」という記述を、()を書くだけで簡単にできる
その反面、
* 引数が多くなった時にコンパイルに時間がかかる

という特徴があるため。

TwirlでのFor文の書き方

@(title: String= "for loopの練習", topics: Array[String])

<ul>
    @for(topic <- topics) {
        <li>@topic</li>
    }

</ul>

@の場所がちょっとややこしいですね。

1
4
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
1
4