2022年11月30日水曜日

Cozy Web/HelloScript

前回はCozy Scriptの組込み関数を使用して、システムが提供するオペレーションをフォーム画面から呼出して使用する方法について説明しました。

今回はフォーム画面から入力したパラメタを引数にしてCozy Scriptを実行する方法について説明します。

HelloScript

フォームから使用できるアプリケーション・ロジックをCozy Scriptのスクリプトとして記述することができます。

Cozy scriptを用いたWebアプリケーションHelloScriptを作成します。

準備

cozyを起動するディレクトリのwebappsディレクトリに、アプリケーションのホームディレクトリとなるHelloScriptを作成します。

Formページ

フォームを使った入力画面として以下のページをindex.jadeとしてホームディレクトリに配置します。

-@val form: ViewForm
html
  head
    title HelloScript
  body
    form(method="POST" action={form.action})
      input(hidden="true" name="$scenario" value={form.scenario})
      input(name="arg1" value={form.arg1})
      input(name="arg2" value={form.arg2})
      input(name="arg3" value={form.arg3})
      button(type="submit" id="submitbutton" name="$submit" value="ok") Submit
      button(type="submit" id="cancelbutton" name="$submit" value="cancel") Cancel

ViewFormオブジェクト

以下の宣言でフォームの設定に必要なViewFormを参照可能にします。

-@val form: ViewForm

Form/action

actionにViewFormオブジェクトのaction属性を設定します。

    form(method="POST" action={form.action})

今回の場合は空文字が設定されます。入力と同じページにフォームのPOSTが行われるということですね。

POST処理に必要な情報は後述する「$scenario」に設定されています。

Input/Hidden

Hidden属性のInputで入力する「$scenario」プロパティにViewFormオブジェクトのscenario属性を設定します。

      input(hidden="true" name="$scenario" value={form.scenario})

今回の場合は「{"name":"invoke-operation","state":"input","data":{}}」が設定されています。URLエンコーディングを解除した値は「{"name":"invoke-operation","state":"input","data":{}}」です。

Cozy Webがフォーム処理を行うために必要な情報が設定されています。

Inputデータ

Hidden属性のないInputでデータ入力を行います。

今回は以下の3行が対象です。

      input(name="arg1" value={form.arg1})
      input(name="arg2" value={form.arg2})
      input(name="arg3" value={form.arg3})

nameにarg1,arg2,arg3を指定しているので、arg1プロパティとarg2プロパティ, arg3プロパティの3つのプロパティの入力ということになります。値のデフォルト値としてViewFormオブジェクトのarg1属性とarg2属性の値を設定しています。今回のケースでは空文字が設定されます。

Input/Ok

OK用のサブミットボタンとして以下のButtonを設定しました。

      button(type="submit" id="submitbutton" name="$submit" value="ok") Submit

name属性に「$submit」、value属性に「ok」を指定しています。

Input/Cancel

キャンセル用のサブミットボタンとして以下のButtonを設定しました。

      button(type="submit" id="cancelbutton" name="$submit" value="cancel") Cancel

name属性に「$submit」、value属性に「cancel」を指定しています。

コントローラ

WEB-INF/controllersにindex.jade用のコントローラである以下のindex.jsonを配置します。

{
  "action": "script-scenario",
  "script0": "(+ 1 2 3)",
  "script": "(+ arg1 (* arg2 arg3))",
  "method": "POST",
  "successView": "index_complete",
  "errorView": "index_error",
  "parameters": [{
    "name": "arg1",
    "datatype": "int"
  },{
    "name": "arg2",
    "datatype": "int"
  },{
    "name": "arg3",
    "datatype": "int"
  }]
}

action

コントローラのアクションとしてscript-scenarioを指定しています。

  "action": "script-scenario",

script-scenarioは、フォームで入力したパラメタ入力を使ってスクリプトを呼び出し、その結果をビューに渡すモデルとして生成する処理を行うシナリオです。

フォーム入力にまつわるWebブラウザとサーバ間のインタラクションをシナリオに従って実現します。

script

実行するスクリプトをCozy Scriptで記述します。

  "script": "(+ arg1 (* arg2 arg3))",

method

メソッドはPOSTを指定しています。

  "method": "POST",

FormのメソッドがPOSTのものを受け付けます。

successView

successViewにはindex_completeを指定しています。

  "successView": "index_complete",

コントローラの処理が成功するとこのページに遷移します。

errorView

errorViewにはindex_errorを指定しています。

  "errorView": "index_error",

コントローラの処理が失敗するとこのページに遷移します。

parameters

フォームから入力されるパラメタとして、パラメタ名とデータ型を指定しています。

  "parameters": [{
    "name": "arg1",
    "datatype": "int"
  },{
    "name": "arg2",
    "datatype": "int"
  },{
    "name": "arg3",
    "datatype": "int"
  }]

パラメタは、パラメタ名arg1でデータ型int, パラメタ名arg2でデータ型int, パラメタ名arg3でデータ型intの3つです。

成功ページ

成功ページとして以下のindex_complete.htmlを用意します。コントローラのsuccessViewで指定したページです。

<html>
    <head>
	<title>Script Success</title>
    </head>
    <body>
	<h1>Script Success</h1>
	<c:model/>
    </body>
</html>

このページ内の以下のタグはコントローラの実行結果のモデルの内容を表形式で表示するものです。

	<c:model/>

今回の場合は、スクリプトの実行結果が出力されます。

エラーページ

成功ページとして以下のindex_error.htmlを用意します。コントローラのerrorViewで指定したページです。

<html>
    <head>
	<title>Script Error</title>
    </head>
    <body>
	<h1>Script Error</h1>
	<c:error/>
    </body>
</html>

このページ内の以下のタグはコントローラの実行時にエラーが発生した場合、そのエラーを表形式で表示するものです。

	<c:error/>

今回の場合は、スクリプトの実行結果がエラーとなる場合に出力されます。

実行

Formページ

curlコマンドによってローカルホストの8080ポート上の/web/HelloScript を取得します。

$ curl http://localhost:8080/web/HelloScript/

以下のHTML文書が返されます。

<!DOCTYPE html>
<html>
  <head>
    <title>HelloScript</title>
  </head>
  <body>
    <form action="" method="POST">
      <input value="{&quot;name&quot;:&quot;execute-script&quot;,&quot;state&quot;:&quot;input&quot;,&quot;data&quot;:{}}" name="$scenario" hidden="true" />
      <input value="" name="arg1" />
      <input value="" name="arg2" />
      <input value="" name="arg3" />
      <button value="ok" name="$submit" id="submitbutton" type="submit">Submit</button>
      <button value="cancel" name="$submit" id="cancelbutton" type="submit">Cancel</button>
    </form>
  </body>
</html>

OK

OKボタンの押下は以下のcurlに相当します。

$ curl http://localhost:8080/web/HelloScript/ -X POST \
--data-urlencode '$submit=ok' \
--data-urlencode 'arg1=3' \
--data-urlencode 'arg2=8' \
--data-urlencode 'arg3=5' \
--data-urlencode '$scenario={"name":"invoke-operation","state":"input","data":{}}'

OKボタン押下と同等の上記curlの結果、以下のHTMLが出力されました。

<!DOCTYPE html>
<html><head>
	<title>Script Success</title>
    </head><body>
	<h1>Script Success</h1>
	43
</body></html>

c:modelタグの場所に、スクリプト「(+ 3 (* 8 5))」の計算結果である43が出力されています。

まとめ

今回はフォーム画面から入力したパラメタを引数にしてCozy Scriptを実行する方法について説明しました。

次回はCozy Scriptに組み込まれたモデル駆動の機能を使用してリソースに対するアクセスを実現する方法について説明する予定です。

諸元

Cozy
0.0.9