目次

Version 8, last updated by tomlurge at Nov 28 01:17 UTC

Todo サンプルアプリケーション

このページは以前に作成したバージョン 1 のスタートガイドのページ[訳注:リンク切れ。おそらくこちら]がベースになっています。以下のサンプルでは Mapper コンポーネントを使っています。しかしこれは、代わりに Record を使うよう修正した方がよいでしょう。

(このページはまだ作成中です)

空のアプリケーションの新規作成

ベーシックな archetype を使い、groupId に com.liftworkshop を、artifactId には todo を設定して新しい Lift プロジェクトを作成します。

アプリケーションを実行して、問題なく動作することを確認します。

条件付き表示

todo リストはユーザーに固有のものなので、ユーザーの todo リストを表示する前に、該当ユーザーがログインしていることを確かめる必要があります。実際の todo リストの表示は、ユーザーがログインしている場合にのみ、アプリケーションのレンダンリングを行なうことで実現します。最初は、ログインしたユーザーにようこそというメッセージを表示するアプリケーションを作成します。次に、このアプリケーションに手を加えて、ユーザーがログインしている場合には todo アプリケーションを表示するようにします。

こうした機能を実現するために、コードの断片 (スニペット) を作成し、その中にユーティリティ関数を用意します。
これらの (loggedIn および loggedOut という名前の) 関数は、条件が満たされる場合には、渡された子ノードを返し、それ以外の場合には空のシーケンスを返します。テンプレートでは、これらのスニペットを使って、目的のコンテンツを囲むことができます。

テンプレートなどのコンセプトの詳細については、「テンプレートとバインディング」を参照してください。

ファイル src/main/scala/com/liftworkshop/snippet/Util.scala を新しく作成し、次のコードを記述します。

package com.liftworkshop.snippet

import scala.xml.{NodeSeq}
import com.liftworkshop._
import model._

class Util {
 def loggedIn(html: NodeSeq) =
   if (User.loggedIn_?) html else NodeSeq.Empty

 def loggedOut(html: NodeSeq) =
   if (!User.loggedIn_?) html else NodeSeq.Empty
}

HTML テンプレート内でこのスニペットを使えば、ユーザーにログインを促すメッセージとようこそというメッセージのいずれかを表示できます。

ファイル src/main/webapp/index.html の内容を次のように書き換えます。

<lift:surround with="default" at="content"> 
 <lift:Util.loggedOut>Please 
   <lift:menu.item name="Login">Log In</lift:menu.item> 
   </lift:Util.loggedOut> 
 <lift:Util.loggedIn>
     Welcome. You may
   <lift:menu.item name="Logout">Log Out</lift:menu.item> if you wish
   </lift:Util.loggedIn> 
</lift:surround>

ブラウザでアプリケーションを読み込み直すと、ログインを求められるはずです。

アカウントを作成してログインすると、今度はようこそという意味のメッセージが表示されます。

モデルの作成

次のステップとして、ToDo オブジェクトを格納するモデルを作成する必要があります。モデルと Mapper 永続化レイヤの詳細については、Mapper を参照してください。

ファイル src/main/scala/com/liftworkshop/model/ToDo.scala を作成し、次のコードを記述します。

package com.liftworkshop.model 

import net.liftweb._ 
import mapper._ 
import http._ 
import SHtml._ 
import util._ 

class ToDo extends LongKeyedMapper[ToDo] with IdPK { 
    def getSingleton = ToDo 
    object done extends MappedBoolean(this) 
    object owner extends MappedLongForeignKey(this, User) 
    object priority extends MappedInt(this) { 
        override def defaultValue = 5 
    } 
    object desc extends MappedPoliteString(this, 128) 
} 

object ToDo extends ToDo with LongKeyedMetaMapper[ToDo]

続いて、作成したモデルを Schemifier に追加します。

ファイル src/main/scala/boostrap/liftweb/Boot.scala を編集し、Schemifier.schemify の行に ToDo モデルへの参照が含まれるようにします。

Schemifier.schemify(true, Log.infoF _, User, ToDo)

jetty を再起動すると、jetty のコンソールに次のようなメッセージが表示されるはずです。

INFO - CREATE TABLE todo (desc_c VARCHAR(128) , priority INTEGER , owner BIGINT , done BOOLEAN , id BIGINT NOT NULL AUTO_INCREMENT) 
INFO - ALTER TABLE todo ADD CONSTRAINT todo_PK PRIMARY KEY(id)
INFO - CREATE INDEX todo_owner ON todo ( owner )

ベーシックな永続性

ToDo データを格納するモデルは作成したので、ユーザーが ToDo データを入力するためのフォームと、入力されたデータをデータベースに挿入するコードを作成します。ファイル src/main/scala/com/liftworkshop/snippet/TD.scala を作成し、次のコードを記述します。

package com.liftworkshop.snippet

import com.liftworkshop._
import model._

import net.liftweb._
import http._
import SHtml._
import S._

import js._
import JsCmds._

import mapper._

import util._
import Helpers._

import scala.xml.{NodeSeq, Text}

class TD {
 def add(form: NodeSeq) = {
   val todo = ToDo.create.owner(User.currentUser)

   def checkAndSave(): Unit =
   todo.validate match {
    case Nil => todo.save ; S.notice("Added "+todo.desc)
    case xs => S.error(xs) ; S.mapSnippet("TD.add", doBind)
   }

   def doBind(form: NodeSeq) =
   bind("todo", form,
      "priority" -> todo.priority.toForm,
      "desc" -> todo.desc.toForm,
      "submit" -> submit("New", checkAndSave))

   doBind(form)
 }
}

ファイル src/main/webapp/index.html を編集し、次のように変更します。

<lift:surround with="default" at="content">
   <lift:Util.loggedOut>
       Please <lift:menu.item name="Login">Log In</lift:menu.item>
   </lift:Util.loggedOut>
   <lift:Util.loggedIn>
       <lift:TD.add form="post">
        <table>
          <tr>
           <td>Description:</td>
           <td><todo:desc>To Do</todo:desc></td>
          </tr>

          <tr>
           <td>
             Priority 
           </td>
           <td>
             <todo:priority>
              <select><option>1</option></select>
             </todo:priority>
          </td>
          </tr>
          <tr>
           <td>&nbsp;</td>
           <td>
             <todo:submit>
              <button>New</button>
             </todo:submit>
           </td>
          </tr>
        </table>
       </lift:TD.add>
   </lift:Util.loggedIn>
</lift:surround>

Web ページを読み込み直すと、Description を入力するためのテキストボックスと Priority を入力するためのテキストボックスが表示されるはずです。フォームは実際に動作するので、テキストを入力すると保存されます。ただし、ToDo アイテムのリストを表示するためのコードはまだ作成していません。

ToDo アイテムのリストの表示

要作成

有効性確認とカスタムフォームレンダリングの追加