フォーマット

ブロックエディタの投稿は、投稿の適切なブロック対応表現です:各ブロックが何であるか、そしてその本質的なデータが何であるかの意味的に一貫した説明のコレクションです。この表現は、メモリ内にのみ存在します。それは、印刷工房の中での chase のように、常に変化しながら sorts が取り付けられ、再配置されます。

ブロックエディタの投稿は、生成されるアーティファクトではありません。すなわち、post_content です。後者は、読者のために最適化された印刷ページですが、後で編集するための目に見えないマークを保持しています。

ブロックエディタの入力と出力は、現在のフォーマットのブロックオブジェクトのツリーです:

  1. const value = [ block1, block2, block3 ];

ブロックオブジェクト

各ブロックオブジェクトには、id、属性のセット、および潜在的に子ブロックのリストがあります。

  1. const block = {
  2. clientId, // unique string identifier.
  3. type, // The block type (paragraph, image...)
  4. attributes, // (key, value) set of attributes representing the direct properties/content of the current block.
  5. innerBlocks, // An array of child blocks or inner blocks.
  6. };

属性のキーとタイプに注意してください。許可される内部ブロックはブロックタイプによって定義されます。たとえば、コア引用ブロックには、引用内容を表す cite 文字列属性があり、見出しブロックには、見出しのレベル(1から6)を表す数値 level 属性があります。

エディタ内でのブロックのライフサイクル中に、ブロックオブジェクトは追加のメタデータを受け取ることができます:

  • isValid:ブロックが有効かどうかを示すブール値;
  • originalContent:ブロックの元のHTMLシリアル化。

  1. // A simple paragraph block.
  2. const paragraphBlock1 = {
  3. clientId: '51828be1-5f0d-4a6b-8099-f4c6f897e0a3',
  4. type: 'core/paragraph',
  5. attributes: {
  6. content: 'This is the <strong>content</strong> of the paragraph block',
  7. dropCap: true,
  8. },
  9. };
  10. // A separator block.
  11. const separatorBlock = {
  12. clientId: '51828be1-5f0d-4a6b-8099-f4c6f897e0a4',
  13. type: 'core/separator',
  14. attributes: {},
  15. };
  16. // A columns block with a paragraph block on each column.
  17. const columnsBlock = {
  18. clientId: '51828be1-5f0d-4a6b-8099-f4c6f897e0a7',
  19. type: 'core/columns',
  20. attributes: {},
  21. innerBlocks: [
  22. {
  23. clientId: '51828be1-5f0d-4a6b-8099-f4c6f897e0a5',
  24. type: 'core/column',
  25. attributes: {},
  26. innerBlocks: [ paragraphBlock1 ],
  27. },
  28. {
  29. clientId: '51828be1-5f0d-4a6b-8099-f4c6f897e0a6',
  30. type: 'core/column',
  31. attributes: {},
  32. innerBlocks: [ paragraphBlock2 ],
  33. },
  34. ],
  35. };

シリアル化と解析

図

このデータモデルは、投稿を編集している間にメモリ内に存在するものです。レンダリングされたときにページビューアには表示されず、印刷ページがそれを生成した文字の構造の痕跡を持たないのと同様です。

WordPressエコシステム全体が、投稿をレンダリングまたは編集する際にHTMLを受け取ることを期待しているため、ブロックエディタはそのデータをシリアル化を通じて post_content に保存できるものに変換します。これにより、コンテンツの単一の真実のソースが保証され、このソースは現在WordPressコンテンツと相互作用するすべてのツールと互換性があり、読みやすいままです。オブジェクトツリーを別々に保存すると、post_content とツリーが同期しなくなり、両方の場所でデータの重複の問題に直面するリスクがあります。

したがって、シリアル化プロセスは、HTMLコメントを明示的なブロック区切りとして使用してブロックツリーをHTMLに変換します。これには、非HTML形式の属性を含むことができます。これは、印刷ページに目に見えないマークを印刷し、元の構造的意図の痕跡を残す行為です。

これはプロセスの一端です。もう一方は、投稿が再度編集されるときにブロックのコレクションを再作成する方法です。正式な文法は、ブロックエディタの投稿のシリアル化された表現がどのように読み込まれるべきかを定義します。基本的なルールは、ツリーをHTMLのような文字列に変換する方法を定義します。ブロックエディタの投稿は手動で編集されることを想定していません。HTML文書として編集されることを想定していないのは、ブロックエディタの投稿が本質的にHTMLではないからです。

それらは偶然にも、post_content 内に保存されており、どのレガシーシステムでも表示可能であるために変換を必要としません。保存されたHTMLをブラウザに読み込むと、対応する機械がない場合、体験が劣化する可能性があることは事実です。動的コンテンツのブロックが含まれている場合、動的要素が読み込まれない可能性があり、サーバー生成のコンテンツが表示されない可能性があり、インタラクティブなコンテンツが静的なまま残る可能性があります。しかし、少なくとも、ブロックエディタの投稿をブロックを認識しないテーマやインストールで表示できないリスクから保護し、コンテンツへの最もアクセスしやすい方法を提供します。言い換えれば、保存されたHTMLがそのままレンダリングされても、投稿はほぼ完全に保持されます。

区切り文字と解析表現文法

私たちは、既存のHTML構文における形式性、明示性、および曖昧さのない方法を維持する方法を見つけることを選びました。HTML内にはいくつかのオプションがありました。

これらのオプションの中で、新しいアプローチが提案されました:データをHTMLコメントに保存することで、文書内の他のHTMLを壊さないことがわかり、ブラウザはそれを無視し、文書の解析アプローチを簡素化できることです。

HTMLコメントに特有なのは、<img alt='data-id="14"'> のようなHTML属性内の曖昧な場所に合法的に存在できないという事実です。コメントは非常に許容的です。HTML属性は正しく解析するのが複雑であるのに対し、コメントは先頭に <!-- があり、最初の --> まで -- 以外のもので構成されることが簡単に説明できます。この単純さと許容性により、パーサーはHTMLを正しく理解する必要なく、いくつかの方法で実装できます。また、コメント内でより便利な構文を使用する自由があります。二重ハイフンのシーケンスをエスケープするだけで済みます。私たちは、ブロック属性を保存する方法においてこれを利用しています:コメント内のJSONリテラルとして。

これをパーサーで実行した後、私たちは慣用的に操作できるシンプルなオブジェクトを得ることができ、データのエスケープや非エスケープを心配する必要がありません。それはシリアル化プロセスを通じて処理されます。コメントは他のHTMLタグとは非常に異なり、最初のパスを実行してトップレベルのブロックを抽出できるため、完全に有効なHTMLを持つ必要はありません!

これは、私たちのパーサーをどれだけシンプルでパフォーマンスの高いものにできるかに劇的な影響を与えます。これらの明示的な境界は、単一のブロックの損傷が他のブロックに浸透したり、文書全体を汚染したりするのを防ぎます。また、システムがレンダリングする前に認識されていないブロックを特定できるようにします。

N.B.: ブロックの定義的な側面は、その意味論と提供する隔離メカニズムです。言い換えれば、それらのアイデンティティです。一方、データが保存される場所はより自由な側面です。ブロックは、HTMLコメント内やブロックのHTML内のJSONリテラルを介して静的なローカルデータ以上のものをサポートし、より多くのメカニズム(、グローバルブロックや補完的な WP_Post オブジェクトに保存すること)を期待しています。詳細については、属性を参照してください。

シリアル化されたブロックの解剖

ブロックが編集セッションの後にコンテンツに保存されると、その属性はブロックの性質に応じて、これらの明示的なコメント区切りにシリアル化されます。

  1. <!-- wp:image -->
  2. <figure class="wp-block-image"><img src="source.jpg" alt="" /></figure>
  3. <!-- /wp:image -->

サーバーでレンダリングされる前に表示される純粋に動的なブロックは、次のようになります:

  1. <!-- wp:latest-posts {"postsToShow":4,"displayPostDate":true} /-->

データライフサイクル

要約すると、ブロックエディタのワークフローは、保存された文書をメモリ内のブロックのツリーに解析し、トークン区切り文字を使用して助けます。編集中、すべての操作はブロックツリー内で行われます。プロセスは、ブロックを再び post_content にシリアル化することで終了します。

ワークフロープロセスは、投稿を永続化するためにシリアル化/パーサーペアに依存しています。仮に、投稿データ構造はプラグインを使用して保存されるか、リモートJSONファイルから取得されてブロックツリーに変換される可能性があります。