MishkaCmsMigration. Sources. WordPress. Content
(Mishka CMS Migration v0.0.1)
Copy Markdown
View Source
A WordPress post's or page's content.raw as its item's content pieces
(MishkaCmsMigration.Source.Item): %{html: ...} for what is converted here, and
%{name: ..., attrs: ..., raw: ...} for a block or shortcode left to migration:content:convert
(MishkaCmsMigration.Events), in the order they come. call/2 reads the content with LazyHTML,
an HTML5 parser, so its markup is never edited as text; only a shortcode, which is text, is read
with a pattern.
Blocks
A block is what its <!-- wp:name {attrs} --> and <!-- /wp:name --> comments enclose, or a
<!-- wp:name {attrs} /--> alone. A core block (core/…, the name without a namespace) becomes
its own saved markup, which is already semantic HTML: headings, lists, quotes, tables,
<pre><code>, <figure> with its <img> and <figcaption>, a gallery's figures inside one
<figure>, <hr>. The markup loses WordPress's class and style, which no theme here reads,
and the block comments; the blocks inside it are converted the same way. Some take a shape of
their own:
core/columnsandcore/media-text— a<div class="grid gap-6 md:grid-cols-N">, one column per inner block, andcore/groupa<div class="grid gap-6">;core/embed— a<figure>with the player of a YouTube or Vimeo video (below), or with a link to its address for any other;core/html— the author's markup as it is, classes kept, without its comments;core/shortcode— its shortcodes, below;core/block, a reusable block — the content of the reusable block it names, read from WordPress with thefetchcall/2is handed (/wp/v2/blocks) and converted the same way; a reusable block inside it, or one WordPress does not answer, is a piece namedcore/blockwith its"ref".
A block of another namespace (acme/callout) and a block with no saved markup, which WordPress
draws as the page is served (core/latest-posts), are pieces named by the block, with its attrs
and its markup, comments included, as raw.
Classic content and shortcodes
What sits outside any block, all of a post written in the classic editor, has its paragraphs
made as WordPress makes them when it shows the post: a blank line ends one, a line break inside
one is a <br>, and a block element (a heading, a list, a figure) stands on its own. Its
shortcodes, and those of a core/shortcode block, become HTML:
[caption]— a<figure>with the image and its caption;[gallery ids="…"]— a<figure>of a figure per image, each image read from WordPress (/wp/v2/media) and linked to its file (link="file"), to nothing (link="none") or to its attachment page;[embed]— a<figure>with the player of the YouTube or Vimeo video it encloses, or with a link to any other address;[video src="…"]— a<video>with its controls.
Any other shortcode, and a gallery none of whose images WordPress answers, is a piece named by the
shortcode (no namespace, so never mistaken for a block), with its attributes and its text as
raw. A shortcode inside a block other than core/shortcode is left as text.
A YouTube or Vimeo address alone on its line, which WordPress embeds by itself (oEmbed), is the video's player too; any other address on its line stays text.
Images and links keep the addresses WordPress gave them. The links to the site's own posts are
named in the item's links, the links to its pages in its pages, and the files of its media
library they show or link to in its media (MishkaCmsMigration.Sources.WordPress), for the
target to point them at where the posts, the pages and the files move.
An address that runs code or carries a document of its own is dropped, its element kept without
it, wherever the content has it (pieces/1): a javascript: or vbscript: address, and a
data: one but an image's src, in an href, src, action, formaction, poster or
xlink:href, read as a browser reads it, whatever its case and the spaces, tabs and line breaks
in it.
Players
A YouTube video (youtube.com/watch?v=, youtu.be/, /embed/, /shorts/, /live/) is played
by https://www.youtube-nocookie.com/embed/<id>, which sets no cookie until it plays, and a
Vimeo video (vimeo.com/<id>, its unlisted vimeo.com/<id>/<hash>, a channel's, and
player.vimeo.com/video/<id>) by https://player.vimeo.com/video/<id>: an <iframe> with a
title, 560 by 315, lazily loaded and allowed to go full screen. An <iframe> the author wrote,
in a core/html block or in classic content, keeps its own address. The targets that write the
content allow the players' origins on the site (MishkaCmsMigration.Targets.Helpers.Frames).
Summary
Types
A converted node: a LazyHTML.Tree node, or {:piece, piece} where a piece is left to
migration:content:convert.
Functions
The blocks at the top of raw, an HTML string, or of a block's inner nodes, as
{:block, name, attrs, inner, raw} with the name's namespace ("core/navigation-link"), its
attributes as the block comment's JSON says them, the nodes it encloses (nil for a block with
no end comment) and its source nodes. What lies between blocks is dropped. For a reader of a
block tree other than content, such as a block navigation
(MishkaCmsMigration.Sources.WordPress.Navigation).
The pieces raw is made of, reading the reusable blocks and the gallery images it names with
fetch.
A <figure> with the player of the YouTube or Vimeo video at url (see "Players"), or with a
link to any other address.
raw converted as call/2 converts it, as nodes, for a converter that places the converted
content inside markup of its own before it makes the pieces (pieces/1), such as the text of an
Elementor widget (MishkaCmsMigration.Sources.WordPress.Elementor).
The content pieces of nodes, in order: the HTML around each {:piece, piece}, and the piece,
without an address that runs code or carries a document of its own (javascript:, vbscript:,
and data: but an image's).
Types
@type content_node() :: LazyHTML.Tree.html_node() | {:piece, map()}
A converted node: a LazyHTML.Tree node, or {:piece, piece} where a piece is left to
migration:content:convert.
@type fetch() :: (String.t(), [pos_integer()] -> %{optional(pos_integer()) => map()})
How call/2 reads more of WordPress: the rows of a REST route ("/wp/v2/blocks",
"/wp/v2/media") with these ids, by id, or %{} when it cannot.
Functions
@spec blocks_in(String.t() | [LazyHTML.Tree.html_node()]) :: [tuple()]
The blocks at the top of raw, an HTML string, or of a block's inner nodes, as
{:block, name, attrs, inner, raw} with the name's namespace ("core/navigation-link"), its
attributes as the block comment's JSON says them, the nodes it encloses (nil for a block with
no end comment) and its source nodes. What lies between blocks is dropped. For a reader of a
block tree other than content, such as a block navigation
(MishkaCmsMigration.Sources.WordPress.Navigation).
The pieces raw is made of, reading the reusable blocks and the gallery images it names with
fetch.
@spec embed(String.t()) :: LazyHTML.Tree.html_node()
A <figure> with the player of the YouTube or Vimeo video at url (see "Players"), or with a
link to any other address.
@spec nodes(String.t(), fetch()) :: [content_node()]
raw converted as call/2 converts it, as nodes, for a converter that places the converted
content inside markup of its own before it makes the pieces (pieces/1), such as the text of an
Elementor widget (MishkaCmsMigration.Sources.WordPress.Elementor).
@spec pieces([content_node()]) :: [map()]
The content pieces of nodes, in order: the HTML around each {:piece, piece}, and the piece,
without an address that runs code or carries a document of its own (javascript:, vbscript:,
and data: but an image's).