2023年4月30日日曜日

Cozy Web/エンティティ作成ビュー

Cozy Webはモデル駆動開発の基盤となるWebフレームワークです。リソースのモデルを定義することで、ノンプログラミングでWeb上のリソースをアクセスできる機能について説明を進めています。

前回はHelloResourceを用いてエンティティの作成操作を実現方法について説明しました。

エンティティのモデル定義をすることでエンティティ作成のオペレーションが可能になりましたが、エンティティ作成画面はCozy Webのデフォルト画面が使用されます。

今回はエンティティ作成用のビューを定義することで、エンティティ作成画面をカスタマイズする方法について説明します。

HelloResource

ここまで作成したHelloResourceは、モデルの定義が行われているのでそのままエンティティの作成を行うことができます。

準備

cozyを起動するディレクトリのwebappsディレクトリに、アプリケーションのホームディレクトリとなるHelloResourceが作成されています。これをベースに開発を進めます。

モデル

WEB-INF/models/model.orgにアプリケーションで使用するモデルが定義されています。

* entity  
** product
*** features  
table=product
*** attributes  
| Name  | Type   | Multiplicity |
|-------+--------+--------------|
| id    | token  |            1 |
| name  | string |            1 |
| price | int    |            1 |

エンティティproductを定義しています。

これがWebのリソースproductとなります。

トップページ

トップページとしてindex.htmlを作成し、プロジェクトのトップページに配置します。

<html>
    <head>
	<title>HelloResource</title>
    </head>
    <body>
	<ul>
	    <li><a href="product">List</a></li>
	    <li><a href="product/create">Create</a></li>
	</ul>
    </body>
</html>

エンティティ操作シナリオ

エンティティのモデル定義を行うとエンティティ作成シナリオが自動的に作成され、このエンティティ作成シナリオによって、エンティティの作成オペレーションが可能になります。

この時、画面はエンティティ作成シナリオのデフォルトのビューが用いられます。

アプリケーションでカスタマイズした画面を使用するためには、エンティティ作成シナリオ用のビューを登録します。

エンティティ作成シナリオ用のビューの格納場所は、エンティティ名+「.entity」ディレクトリです。エンティティproductの場合は「product.entity」です。

エンティティ作成シナリオでは以下のビューを使用します。

  • エンティティ作成
  • 登録データ確認
  • 結果

それぞれカスタマイズした画面を登録していきます。

エンティティ作成

エンティティ作成画面として以下のHTMLを、product.entity配下に「create__input.html」という名前で作成します。

「create__input」の「create」が作成画面を、「input」が入力画面であることを示しています。

Input要素のvalue属性はエンティティ操作シナリオが補完するので空欄にしています。

<?xml version="1.0"?>
<!DOCTYPE html>
<html>
  <head>
    <title>Product作成/入力</title>
  </head>
  <body>
    <h1>Product作成/入力</h1>
    <form action="" method="POST">
      <table class="">
        <tbody>
          <tr class="">
            <th scope="row" class="">Id</th>
            <td class="">
              <input type="text" name="id" value=""/>
            </td>
          </tr>
          <tr class="">
            <th scope="row" class="">Name</th>
            <td class="">
              <input type="text" name="name" value=""/>
            </td>
          </tr>
          <tr class="">
            <th scope="row" class="">Price</th>
            <td class="">
              <input type="text" name="price" value=""/>
            </td>
          </tr>
        </tbody>
      </table>
      <table>
        <tr>
          <td>
            <input type="submit" name="$submit" value="Input"/>
          </td>
          <td>
            <input type="submit" name="$submit" value="Cancel"/>
          </td>
        </tr>
      </table>
      <input type="hidden" name="$scenario" value=""/>
    </form>
  </body>
</html>

登録データ確認

エンティティ作成の登録データ確認画面として以下のHTMLを、product.entity配下に「create__confirm.html」という名前で作成します。

「create__confirm」の「create」が作成画面を、「confirm」がデータ確認画面であることを示しています。

Input要素のvalue属性はエンティティ操作シナリオが補完するので空欄にしています。

<html>
  <head>
    <title>Product作成/データ確認</title>
  </head>
  <body>
    <h1>Product作成/データ確認</h1>
    <form action="" method="POST">
      <table class="">
        <tbody>
          <tr class="">
            <th scope="row" class="">Id</th>
            <td class="">5</td>
          </tr>
          <tr class="">
            <th scope="row" class="">Name</th>
            <td class="">Banana</td>
          </tr>
          <tr class="">
            <th scope="row" class="">Price</th>
            <td class="">250</td>
          </tr>
        </tbody>
      </table>
      <input type="hidden" name="id" value="5"/>
      <input type="hidden" name="name" value="Banana"/>
      <input type="hidden" name="price" value="250"/>
      <table>
        <tr>
          <td>
            <input type="submit" name="$submit" value="Ok"/>
          </td>
          <td>
            <input type="submit" name="$submit" value="Back"/>
          </td>
          <td>
            <input type="submit" name="$submit" value="Cancel"/>
          </td>
        </tr>
      </table>
      <input type="hidden" name="$scenario" value=""/>
    </form>
  </body>
</html>

結果

エンティティ作成の登録データ確認画面として以下のHTMLを、product.entity配下に「create__show.html」という名前で作成します。

「create__show」の「create」が作成画面を、「show」がデータ結果表示画面であることを示しています。

Input要素のvalue属性はエンティティ操作シナリオが補完するので空欄にしています。

<?xml version="1.0"?>
<!DOCTYPE html>
<html>
  <head>
    <title>Product作成/データ確認</title>
  </head>
  <body>
    <h1>Product作成/データ確認</h1>
    <form action="" method="POST">
      <table class="">
        <tbody>
          <tr class="">
            <th scope="row" class="">Id</th>
            <td class="">5</td>
          </tr>
          <tr class="">
            <th scope="row" class="">Name</th>
            <td class="">Banana</td>
          </tr>
          <tr class="">
            <th scope="row" class="">Price</th>
            <td class="">250</td>
          </tr>
        </tbody>
      </table>
      <input type="hidden" name="id" value="5"/>
      <input type="hidden" name="name" value="Banana"/>
      <input type="hidden" name="price" value="250"/>
      <table>
        <tr>
          <td>
            <input type="submit" name="$submit" value="Ok"/>
          </td>
        </tr>
      </table>
      <input type="hidden" name="$scenario" value=""/>
    </form>
  </body>
</html>

実行

それでは実行してみましょう。

エンティティ作成ページ

最初にエンティティ作成を行うためのデータ入力ページを表示します。

以下のようにリソース名の後ろに「_create_」をつけてアクセスします。

$ curl http://localhost:8080/web/HelloResource/product/_create_

次のようにエンティティ作成に必要なデータを登録するためのFORMの画面が表示されました。

product.entityにcreate__input.htmlとして登録したビューが使用されています。

Input要素のvalue属性はエンティティ操作シナリオが補完しています。

<?xml version="1.0"?>
<!DOCTYPE html>
<html>
  <head>
    <title>Product作成/入力</title>
  </head>
  <body>
    <h1>Product作成/入力</h1>
    <form action="" method="POST">
      <table class="">
        <tbody>
          <tr class="">
            <th scope="row" class="">Id</th>
            <td class="">
              <input type="text" name="id" value=""/>
            </td>
          </tr>
          <tr class="">
            <th scope="row" class="">Name</th>
            <td class="">
              <input type="text" name="name" value=""/>
            </td>
          </tr>
          <tr class="">
            <th scope="row" class="">Price</th>
            <td class="">
              <input type="text" name="price" value=""/>
            </td>
          </tr>
        </tbody>
      </table>
      <table>
        <tr>
          <td>
            <input type="submit" name="$submit" value="Input"/>
          </td>
          <td>
            <input type="submit" name="$submit" value="Cancel"/>
          </td>
        </tr>
      </table>
      <input type="hidden" name="$scenario" value="{&quot;name&quot;:&quot;create-entity&quot;,&quot;state&quot;:&quot;input&quot;,&quot;entity&quot;:&quot;product&quot;,&quot;schema&quot;:{&quot;columns&quot;:[{&quot;name&quot;:&quot;id&quot;,&quot;datatype&quot;:&quot;token&quot;,&quot;multiplicity&quot;:&quot;1&quot;}, {&quot;name&quot;:&quot;name&quot;,&quot;datatype&quot;:&quot;string&quot;,&quot;multiplicity&quot;:&quot;1&quot;}, {&quot;name&quot;:&quot;price&quot;,&quot;datatype&quot;:&quot;int&quot;,&quot;multiplicity&quot;:&quot;1&quot;}]},&quot;data&quot;:{}}"/>
    </form>
  </body>
</html>

このページでは以下のボタンが表示されています。

Input
データ登録
Cancel
キャンセル Inputボタンを押下するとエンティティ作成のための次の画面に遷移します。

Cancelボタンを押下するとトップページに戻ります。

登録データ確認ページ

データ登録画面でInputボタンが押されたので、登録データ確認画面が表示されます。

product.entityにcreate__confirm.htmlとして登録したビューが使用されています。

Input要素のvalue属性はエンティティ操作シナリオが補完しています。

<html>
  <head>
    <title>Product作成/データ確認</title>
  </head>
  <body>
    <h1>Product作成/データ確認</h1>
    <form action="" method="POST">
      <table class="">
        <tbody>
          <tr class="">
            <th scope="row" class="">Id</th>
            <td class="">5</td>
          </tr>
          <tr class="">
            <th scope="row" class="">Name</th>
            <td class="">Banana</td>
          </tr>
          <tr class="">
            <th scope="row" class="">Price</th>
            <td class="">250</td>
          </tr>
        </tbody>
      </table>
      <input type="hidden" name="id" value="5"/>
      <input type="hidden" name="name" value="Banana"/>
      <input type="hidden" name="price" value="250"/>
      <table>
        <tr>
          <td>
            <input type="submit" name="$submit" value="Ok"/>
          </td>
          <td>
            <input type="submit" name="$submit" value="Back"/>
          </td>
          <td>
            <input type="submit" name="$submit" value="Cancel"/>
          </td>
        </tr>
      </table>
      <input type="hidden" name="$scenario" value="{&quot;name&quot;:&quot;create-entity&quot;,&quot;state&quot;:&quot;confirm&quot;,&quot;entity&quot;:&quot;product&quot;,&quot;schema&quot;:{&quot;columns&quot;:[{&quot;name&quot;:&quot;id&quot;,&quot;datatype&quot;:&quot;token&quot;,&quot;multiplicity&quot;:&quot;1&quot;}, {&quot;name&quot;:&quot;name&quot;,&quot;datatype&quot;:&quot;string&quot;,&quot;multiplicity&quot;:&quot;1&quot;}, {&quot;name&quot;:&quot;price&quot;,&quot;datatype&quot;:&quot;int&quot;,&quot;multiplicity&quot;:&quot;1&quot;}]},&quot;data&quot;:{&quot;name&quot;:&quot;Banana&quot;,&quot;$scenario&quot;:&quot;{\&quot;name\&quot;:\&quot;create-entity\&quot;,\&quot;state\&quot;:\&quot;input\&quot;,\&quot;entity\&quot;:\&quot;product\&quot;,\&quot;schema\&quot;:{\&quot;columns\&quot;:[{\&quot;name\&quot;:\&quot;id\&quot;,\&quot;datatype\&quot;:\&quot;token\&quot;,\&quot;multiplicity\&quot;:\&quot;1\&quot;},{\&quot;name\&quot;:\&quot;name\&quot;,\&quot;datatype\&quot;:\&quot;string\&quot;,\&quot;multiplicity\&quot;:\&quot;1\&quot;},{\&quot;name\&quot;:\&quot;price\&quot;,\&quot;datatype\&quot;:\&quot;int\&quot;,\&quot;multiplicity\&quot;:\&quot;1\&quot;}]},\&quot;data\&quot;:{}}&quot;,&quot;price&quot;:&quot;250&quot;,&quot;id&quot;:&quot;5&quot;,&quot;$submit&quot;:&quot;Input&quot;}}"/>
    </form>
  </body>
</html>

画面に入力したデータが表示されます。この結果を確認した上で、以下のいずれかのボタンを押下します。

OK
確認OK
Back
入力画面にモデル
Cancel
キャンセル

Okボタンを押下するとエンティティ作成のための次の画面に遷移します。

結果ページ

登録データ確認画面でOKボタンが押されたので、エンティティの作成が行われ、作成されたエンティティの情報表示ページに移ります。

product.entityにcreate__show.htmlとして登録したビューが使用されています。

Input要素のvalue属性はエンティティ操作シナリオが補完しています。

<?xml version="1.0"?>
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <meta name="keywords" content="TBD"/>
    <meta name="description" content="TBD"/>
    <meta name="robots" content="noindex,nofollow"/>
    <meta name="author" content="TBD"/>
  </head>
  <body>
    <form action="" method="POST">
      <table class="">
        <tbody>
          <tr class="">
            <th scope="row" class="">Id</th>
            <td class="">5</td>
          </tr>
          <tr class="">
            <th scope="row" class="">Name</th>
            <td class="">Banana</td>
          </tr>
          <tr class="">
            <th scope="row" class="">Price</th>
            <td class="">250</td>
          </tr>
        </tbody>
      </table>
      <input type="hidden" name="id" value="5"/>
      <input type="hidden" name="name" value="Banana"/>
      <input type="hidden" name="price" value="250"/>
      <table>
        <tr>
          <td>
            <input type="submit" name="$submit" value="Ok"/>
          </td>
        </tr>
      </table>
      <input type="hidden" name="$scenario" value="{&quot;name&quot;:&quot;create-entity&quot;,&quot;state&quot;:&quot;show&quot;,&quot;entity&quot;:&quot;product&quot;,&quot;schema&quot;:{&quot;columns&quot;:[{&quot;name&quot;:&quot;id&quot;,&quot;datatype&quot;:&quot;token&quot;,&quot;multiplicity&quot;:&quot;1&quot;}, {&quot;name&quot;:&quot;name&quot;,&quot;datatype&quot;:&quot;string&quot;,&quot;multiplicity&quot;:&quot;1&quot;}, {&quot;name&quot;:&quot;price&quot;,&quot;datatype&quot;:&quot;int&quot;,&quot;multiplicity&quot;:&quot;1&quot;}]},&quot;data&quot;:{&quot;name&quot;:&quot;Banana&quot;,&quot;$scenario&quot;:&quot;{\&quot;name\&quot;:\&quot;create-entity\&quot;,\&quot;state\&quot;:\&quot;confirm\&quot;,\&quot;entity\&quot;:\&quot;product\&quot;,\&quot;schema\&quot;:{\&quot;columns\&quot;:[{\&quot;name\&quot;:\&quot;id\&quot;,\&quot;datatype\&quot;:\&quot;token\&quot;,\&quot;multiplicity\&quot;:\&quot;1\&quot;},{\&quot;name\&quot;:\&quot;name\&quot;,\&quot;datatype\&quot;:\&quot;string\&quot;,\&quot;multiplicity\&quot;:\&quot;1\&quot;},{\&quot;name\&quot;:\&quot;price\&quot;,\&quot;datatype\&quot;:\&quot;int\&quot;,\&quot;multiplicity\&quot;:\&quot;1\&quot;}]},\&quot;data\&quot;:{\&quot;name\&quot;:\&quot;a\&quot;,\&quot;$scenario\&quot;:\&quot;{\\\&quot;name\\\&quot;:\\\&quot;create-entity\\\&quot;,\\\&quot;state\\\&quot;:\\\&quot;input\\\&quot;,\\\&quot;entity\\\&quot;:\\\&quot;product\\\&quot;,\\\&quot;schema\\\&quot;:{\\\&quot;columns\\\&quot;:[{\\\&quot;name\\\&quot;:\\\&quot;id\\\&quot;,\\\&quot;datatype\\\&quot;:\\\&quot;token\\\&quot;,\\\&quot;multiplicity\\\&quot;:\\\&quot;1\\\&quot;},{\\\&quot;name\\\&quot;:\\\&quot;name\\\&quot;,\\\&quot;datatype\\\&quot;:\\\&quot;string\\\&quot;,\\\&quot;multiplicity\\\&quot;:\\\&quot;1\\\&quot;},{\\\&quot;name\\\&quot;:\\\&quot;price\\\&quot;,\\\&quot;datatype\\\&quot;:\\\&quot;int\\\&quot;,\\\&quot;multiplicity\\\&quot;:\\\&quot;1\\\&quot;}]},\\\&quot;data\\\&quot;:{}}\&quot;,\&quot;price\&quot;:\&quot;10\&quot;,\&quot;id\&quot;:\&quot;5\&quot;,\&quot;$submit\&quot;:\&quot;Input\&quot;}}&quot;,&quot;price&quot;:&quot;250&quot;,&quot;id&quot;:&quot;5&quot;,&quot;$submit&quot;:&quot;Ok&quot;}}"/>
    </form>
  </body>
</html>

作成したエンティティのデータが表示されます。この結果を確認した後に、OKボタンを押下するとトップページに戻ります。

<?xml version="1.0"?>
<!DOCTYPE html>
<html>
  <head>
    <title>HelloResource</title>
  </head>
  <body>
    <ul>
      <li>
        <a href="product">List</a>
      </li>
      <li>
        <a href="product/_create_">Create</a>
      </li>
    </ul>
  </body>
</html>

確認

確認のためにリソースproductの一覧を表示してみましょう。

$ curl http://localhost:8080/web/HelloResource/product

以下のようにカスタムのビューを使った場合も、無事リソースが追加されました。

<?xml version="1.0"?>
<!DOCTYPE html>
<html>
  <head>
    <title>Product List</title>
  </head>
  <body>
    <table class="">
      <caption class="">product</caption>
      <thead class="">
        <tr class="">
          <th scope="col" class="">Id</th>
          <th scope="col" class="">Name</th>
          <th scope="col" class="">Price</th>
        </tr>
      </thead>
      <tbody class="">
        <tr data-href="product/1.html">
          <td class="">1</td>
          <td class="">Apple</td>
          <td class="">300</td>
        </tr>
        <tr data-href="product/2.html">
          <td class="">2</td>
          <td class="">Orange</td>
          <td class="">350</td>
        </tr>
        <tr data-href="product/3.html">
          <td class="">3</td>
          <td class="">Peach</td>
          <td class="">400</td>
        </tr>
        <tr data-href="product/4.html">
          <td class="">4</td>
          <td class="">Banana</td>
          <td class="">250</td>
        </tr>
      </tbody>
    </table>
  </body>
</html>

まとめ

Cozy Web上でエンティティのモデル定義をすることで、Web上でのリソースアクセスをノンプログラミングで行う方法についてみています。

今回はリソースの作成ビューの使用方法について説明しました。

次回はリソースの更新、削除の操作の作成鳳凰について説明します。

諸元

Cozy
0.0.12