LoginSignup
8
5

More than 5 years have passed since last update.

PlayFramework(Scala)にElmをぶっ込む。

Last updated at Posted at 2019-04-18

はじめに

Elm + PlayFramewark(Scala)をやりたくて、無理矢理ぶっ込んだ話です。
諸々やり方に不備があるかと思いますが、ご了承を。

開発環境

OS: macOS Mojave
Editer: Vim

・言語
Elm 0.19.0
Scala 2.12.8
sbt 1.2.8

PlayFrameworkのアプリを作成

今回は、sbt経由で作成する。
言語は、Scalaで作成する。

$ cd ~
$ sbt new playframework/play-scala-seed.g8
[info] Set current project to play (in build file:/Users/yanagawamasakazu/play/)
[info] Set current project to play (in build file:/Users/yanagawamasakazu/play/)

This template generates a Play Scala project 

name [play-scala-seed]: elm
organization [com.example]: com.play.masa

Template applied in /Users/yanagawamasakazu/play/./elm

PlayFrameworkアプリに、Elmをぶっ込む。

最初は、sbt-elmでの導入を検討したが、結局、appフォルダ内にassetsフォルダを作成し、その中にelmフォルダを作成して、elm内でelm initを実行した。

$ cd elm
$ mkdir app/assets
$ mkdir app/assets/elm
$ cd app/assets/elm
$ elm init

その後、elm initで生成されたsrcフォルダ内で、Main.elmを作成し、以下を記入。

Main.elm
module Main exposing (..)

import Html exposing (..)
import Html.Attributes exposing (..)

main : Html msg 
main = h1 [][text "Hello Elm!"]

その後、ターミナルで以下のコマンドを実行する。

$ elm make src/Main.elm --output=elm.js

気をつけたいのは、elm.jsを生成し、出力している所だ。

Viewに反映させる。

まず、app/views/main.scala.htmlを以下のように編集する。

main.scala.html
@*
 * This template is called from the `index` template. This template
 * handles the rendering of the page header and body tags. It takes
 * two arguments, a `String` for the title of the page and an `Html`
 * object to insert into the body of the page.
 *@
@(title: String)(content: Html)

<!DOCTYPE html>
<html lang="en">
    <head>
        @* Here's where we render the page title `String`. *@
        <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")">
        <!-- 追加した所 -->
        <script src="@routes.Assets.versioned("elm/elm.js")" type="text/javascript"></script>
    </head>
    <body>
        @* And here's where we render the `Html` object containing
         * the page content. *@
        @content
      <script src="@routes.Assets.versioned("javascripts/main.js")" type="text/javascript"></script>
    </body>
</html>

次に、app/views/index.scala.htmlを以下のように編集する。

index.scala.html
@()

@main("Welcome to Elm") {
  <div id="app"></div>
  <script type="text/javascript">
    Elm.Main.init({
      node: document.getElementById("app")
    });
  </script>
}

最後に、~/elmに戻って、PlayFrameworkアプリのサーバを起動する。

$ sbt run

localhost:9000にアクセスすると、「Hello Elm!」が表示される。

スクリーンショット 2019-04-19 13.04.57.png

Controllerから、変数をElmに渡して表示する。

今度は、HomeController.scalaから変数をElmに渡して、Viewに表示させる。
まずは、HomeController.scaladef indexを編集する。

HomeController.scala
def index() = Action { implicit request: Request[AnyContent] =>
   val msg = "Hello, Scala!";
   Ok(views.html.index(msg))
}

Scalaから渡された変数をElmに反映するには、Elmのflagsという機能を使う。
まず、index.scala.htmlを以下のように編集する。

index.scala.html
@(msg: String)

@main("Welcome to Elm") {
  <div id="app"></div>
  <script type="text/javascript">
    Elm.Main.init({
      node: document.getElementById("app"),
      flags: `@msg`
    });

  </script>
}

続いて、Main.elmを以下のように編集する。

Main.elm
module Main exposing (..)

import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Html.Attributes exposing (..)
import Http
import Html.Events exposing(..)

main =
  Browser.element
    { init = init
    , view = view
    , update = update
    , subscriptions = subscriptions
    }

init : String -> ( Model, Cmd msg )
init flags =
  ( { msg = flags }, Cmd.none )

type alias Model =
  { msg : String }

type Msg
  = NoMessage

update : Msg -> Model -> ( Model, Cmd msg)
update msg model =
  ( model, Cmd.none)

view : Model -> Html Msg
view model = 
  div [][
    h1 [][ text "Hello Elm!"]
   ,h1 [][ text model.msg ]
  ]


subscriptions : Model -> Sub Msg
subscriptions model =
    Sub.none

再度、app/assets/elmフォルダ内でelm make src/Main.elm --output=elm.jsを実行した後、サーバを起動する。

すると、以下のように表示される。

スクリーンショット 2019-04-19 13.06.42.png

感想

なんとか、Elm + Playframework(Scala)導入できました。
ただ、flagsの仕様が、まだ把握しきれてないので、
色々試してみたいですね。

8
5
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
8
5