モジュールの動作理解にはVewsが有効(WorkspacesとContent Moderationの共存を理解する)

最近Coreで正式版となったWorkspacesモジュールも、以前から正式版として存在するContent Moderationモジュールもコンテンツのリビジョンを利用して実現している。本稿ではViewsの機能を用いて、どのような形で、両モジュールが機能を実現しているかを探っていく。

随分さかのぼるが、Drupal coreでリビジョンが当たり前になったのは2016年、Drupal 8.2の頃のことである(Node revisions are enabled by default)。その前は、一度コンテンツを編集すると元には戻せなかったということもあるが、説明ページのRelated ContentにContent Moderation is a new experimental moduleが含まれているので、当初からCoreで編集ワークフローを統一的に管理しようという意図があったのは明白である。編集ワークフローでは、差し戻しや仮版の作成は必須だから、最終的にコンテンツとして公開されるものに対して複数の版(リビジョン)を関連付けられるようにしなければいけない。

Viewsではコンテンツもコンテンツリビジョンもエンティティとして扱えるようになっているので、実際に何が起きているのかをコードに当たらなくても確認することができる。

WorkspacesモジュールやContent Moderationモジュールの挙動を理解するために、まず、コンテンツとコンテンツリビジョンのviews(基本ページ)を以下のように作成しておく(フィルターから公開限定をはずして、公開状態を見られるようにしておくことが重要)。

  • views content-fields

    画像
    画像
    画像
  • views content-revision-fields

    画像
    画像

最初にページを作成して、次に編集して格納する(まだWorkspacesもContent Moderationも有効化していない)。

  • content creation and edit

    画像
    画像
  • views content-revision-fields

    画像
  • vews content-fields

    画像

こうすると、コンテンツリビジョンのViewでは自然とIDが1、リビジョンIDが1と2のリビジョンが存在し、どちらもPublishedになっている。そして、コンテンツのViewではリビジョンIDは2を指している。これは、コンテンツを表示する時にはリビジョン2の内容が表示されるということを意味している。

次にWorkspaceモジュールを有効化して、管理画面(/admin/config/workflow/workspaces)に行きStage環境に遷移する。

  • workspace enabled

    画像
  • switch Stage

    画像
    画像

ここでID=1のコンテンツを編集して格納する。

  • edit node/1

    画像
    画像

    この状態で、node/1を見ると修正内容が反映されているが、Liveにスイッチして見ると、修正内容は反映されていない。

Viewsの編集はLive環境でないと保管できないので、再びLive環境に遷移した上で、コンテンツリビジョンのViewで追加可能フィールドを再検索するとワークスペースが出てくる。そのフィールドを追加すると、当該リビジョンがどのワークスペースに属しているかを見えるようになる。同様にコンテンツのViewでもコンテンツリビジョンのワークスペースフィールドを追加しておく。Live環境では当然これは常に空になる。

  • modify views content-revision-fields setup

    画像
    画像
  • views content-fields

    画像

そして、コンテンツのViewを見ると、依然として、リビジョンIDは2を指している。ここがWorkspaceモジュールのマジックな部分となる。ちょっと考えれば分かるが、Workspaceを導入して、コンテンツを見る時には、表示する際にリビジョンのワークスペースフィールドを見て、自分のワークスペースのコンテンツがあれば、それを見るという形になっている。さらに言えば、リビジョンは枝分かれさせることができない設計になっているので、既にどこかのワークスペースに所属してしまった(そこで改変してしまった)コンテンツはLiveでも編集できないし、Stage以外のワークスペースでも編集できない。

  • edit node/1 in Live

    画像
    画像
    画像

ついで、今度はContent Moderationを有効にして、Workspacesモジュールとの連携を確認する(Live環境)。

画像
画像

ID=1のコンテンツを下書きにして保存する(Stage環境)。

画像

当然、リビジョンIDが1つあがって4になり、公開状態は未掲載になる(コンテンツリビジョンのViewはLiveでもStageでも同じ結果になる)。LiveでコンテンツのViewを見ると、リビジョンIDは2のままで、Stageで見ると、リビジョンIDは3のままになる(ここにもWorkspaceモジュールが効いていて異なる結果が出る)。

画像
画像
画像

Liveではもちろん、Moderation状態を変更することはできず、Stageでは可能になる。実際にやってみると、リビジョンIDは5になり、Stageで見たコンテンツのViewでのリビジョンIDも5に変わる。そして、Liveで見たコンテンツのViewではIDは2のままで変わらない。

  • edit node/1 in stage to publish

    画像
  • views content-revision-fields

    画像

    モデレーション状態も見られるようにViewsも変更しておくと内容がよく分かる。

ここで、StageからLiveにPublishする。

画像

Stageの現在のリビジョンであるID=5のワークスペースフィールドが空になる。同時にコンテンツが指すリビジョンIDが5になり、Liveが最新状態となる。ただし、Stageで作成したリビジョンID4と3のワークスペースフィールドはStageのまま変化がない(全部消すわけではない)。

  • views content-revision-fields

    画像
  • vews content-fields in Live

    画像

    Stage環境でも同じ結果となる

さらに、Stageで変更を加えて下書きで保存するとリビジョンID=6で保存される。もちろん、Stage環境で(非公開コンテンツの最終リビジョンが見られる)管理者がコンテンツを見れば、非公開コンテンツを見ることができるし、ライブ環境では引き続きリビジョンID=5が表示されることになる(画面は省略)。

これでWorkspaceモジュールとContent Moderationが相反するものでないことが分かった。

ちなみに、GroupモジュールとContent Moderationは基本的に相反しない。Content ModerationはPublish状態をコンテンツのリビジョンIDの指し先で決めているから、Groupモジュールがコンテンツリビジョンを意識しなくてもそのまま機能する。一方、WorkspaceはコンテンツのリビジョンIDの指し先を変えるから、もしGroupがそれに対応しようと思ったら、Workspaceが機能している場合の挙動を扱えるようにならなければ併存できない。これは中々難しい話で、RDB的な解釈をした時に、コンテンツというエンティティがレコードなのか、Viewなのかという違いとなる。RDBの世界のViewはダイナミックに生成される(コンテキストで値が変わる)ので、Group Relationでそれに対応することは恐らくできない。

実際、Issue(Integrate with the Workspaces module)も出ている。個人的には、Workspaceのアクセス権をロールベースからGroupのmembershipに依存したWorkspaceの拡張モジュールを作成するほうが近道ではないかと考えている。Access Policy APIがCoreに組み込まれたことで、アクセス権に関する考慮は各モジュール側で設定しやすくなったので、実装方法の選択肢は広がる。

ユースケースから考えると、Workspaceのアクセス権をグループ管理したいというニーズ(Workspaceの不利)は当然あり、一方で、コンテンツの一括リリースはGroupとContent Moderationの組み合わせでも実現はできるが複雑になる(Groupの不利)。中々悩ましいが、当面はユーザー要件に併せて何を優先し、何を劣後させるのかをサイトビルダーや開発者が考えるしか無いだろう。

Drupalのコントリビューションモジュールはほとんど相反しないところが素晴らしいのだが、Workspaceモジュールの正式リリースに非常に長い時間がかかったように、Coreのレベルできちんと解決するのは決して易しいことではない。Drupal 12以降でもCoreのリファクタリングは不可避だと思う。Drupal 8へのバージョンアップで少なくないユーザーや開発者が離反したことがある種トラウマになって、特にDrupal10以上では移行容易性に猛烈な熱意が注がれている。それでも、やがてどこかで再びジャンプアップは必要になるだろう。再び注目を浴びそうなのは、リビジョンメカニズムとAccess Policyのあたりだろう。

※この記事は、Drupal Advent Calendar 2024用に作成されたものです。

タグ
feedback
こちらに記入いただいた内容は執筆者のみに送られます。内容によっては、執筆者からメールにて連絡させていただきます。