ReactでJSONを読み込んで表示しているのですが、PowerCMS Xにおいて編集内容を保存していない状態でプレビューした時にプレビューに反映されないと質問を受けました。HTMLファイルを単純に表示しているわけではないので「そりゃそうだ」と思うのですが、自分が考えている内容が正しいか確認してみました。
ポイント
- 入力内容がPOSTで送信するとPOSTしたデータでオブジェクトが生成され、指定したビューがビルドされて表示される
- 保存済み下書きデータの表示(管理画面ログイン時)やLivePreviewとは動作の仕組みが違う
- 指定したビュー以外のファイル(例えばFetchで取得するJSONファイル)には反映されない
- そもそも処理対象になっていない
編集途中のプレビューは、お問い合わせフォームの確認画面を表示しているのと同じようなイメージです。
処理の要旨
オブジェクト編集画面でプレビューボタンを押すと、saveメソッド(保存に関する処理)が始まります。まず、編集していたモデルの新しいオブジェクトが生成されます。
$obj = $db->model($model)->new();
編集画面は<input type="text" name="カラム名">
のようにinput要素のname属性値がカラム名になっています。よってモデルに設定されているカラムを順に処理していくと、POSTで送信された値がオブジェクトにセットされていきます。
$value = $app->param($col);
$obj->$col($value);
オブジェクトに値がセットし終わるとstashにセットしてビルドします。その結果をレスポンスで返します。$obj->save();
を実行しないので、データベースに入力途中のデータが保存されることはありません。
$ctx->stash($obj->_model, $obj);
$preview = $ctx->build($tmpl, false, null, true);
このように、指定したビューにPOSTしたデータを当てはめてビルドしているので、Fetchで取得するJSONファイルには入力途中のデータは反映されないというわけです。保存済の下書きデータ・LivePreviewの場合はデータベースのデータを利用するので、編集途中のプレビューとは動作が異なります。
ReactでJSONを読み込んでいる場合のプレビューはどうする?
<mt:if name="request._preview"></mt:if>
でプレビューページでのみ出力したいデータが記述できます。そこで、HTMLにwindow.previewData
のような変数にカラムの値をセットします。(つまりtitle: '<mt:EntryTitle />'
のようにする)Reactではwindow.previewData
に値がある場合、JSONをFetchせずwindowオブジェクトにセットされている編集中の値を利用するようにすれば良さそうです。ただ、そう単純に実現できないケースもありますので、編集途中のプレビューは実現できず、保存済みの値が表示されるという仕様にしておいた方が良いかもしれません。