WooCommerce Docs: Add support for more core block conversion (#39244)
* WIP extend support for frontmatter in manifests. * Change some of the prop names in the frontmatter support, add tests. * WIP support new frontmatter in plugin. * Improve category processing. * restructure the docs to have a nested category with no index. * Add WP test stubs to dev. * Add tests for the ManifestProcessor. * Add param docs to function * Store post meta on posts when they are updated or created. Add supporting tests. * WIP supporting more core block types. * Fix bugs in conversion. * Adjust conversion for issues with tables, blockquotes, code. * Resolve pnpm lock conflicts * Return manifest to state in trunk. * Return pnpm lock to trunk state. * Update fixture for new md content.
This commit is contained in:
parent
0243bfdc42
commit
b128f07af2
|
@ -7,3 +7,14 @@ post_title: Local Development
|
||||||
1. Install
|
1. Install
|
||||||
2. Configure
|
2. Configure
|
||||||
3. Profit!
|
3. Profit!
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cd /path/to/woocommerce-docs
|
||||||
|
```
|
||||||
|
|
||||||
|
> This is a blockquote.
|
||||||
|
|
||||||
|
| First Header | Second Header |
|
||||||
|
| ------------ | ------------- |
|
||||||
|
| Content Cell | Content Cell |
|
||||||
|
| Content Cell | Content Cell |
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace WooCommerceDocs\Blocks;
|
||||||
use League\CommonMark\Environment\Environment;
|
use League\CommonMark\Environment\Environment;
|
||||||
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
|
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
|
||||||
use League\CommonMark\MarkdownConverter;
|
use League\CommonMark\MarkdownConverter;
|
||||||
|
use League\CommonMark\Extension\GithubFlavoredMarkdownExtension;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class MarkdownParser
|
* Class MarkdownParser
|
||||||
|
@ -23,6 +24,7 @@ class BlockConverter {
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
$environment = new Environment();
|
$environment = new Environment();
|
||||||
$environment->addExtension( new CommonMarkCoreExtension() );
|
$environment->addExtension( new CommonMarkCoreExtension() );
|
||||||
|
$environment->addExtension( new GithubFlavoredMarkdownExtension() );
|
||||||
$this->parser = new MarkdownConverter( $environment );
|
$this->parser = new MarkdownConverter( $environment );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,11 +77,18 @@ class BlockConverter {
|
||||||
* @param \DOMNode $node The DOM node.
|
* @param \DOMNode $node The DOM node.
|
||||||
*/
|
*/
|
||||||
private function convert_node_to_block( $node ) {
|
private function convert_node_to_block( $node ) {
|
||||||
$node_name = $node->nodeName; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
$node_name = $node->nodeName; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||||
$node_value = $node->nodeValue; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
$node_value = $node->nodeValue; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||||
$node_content = $this->convert_child_nodes_to_blocks( $node );
|
|
||||||
|
$node_content = $this->convert_child_nodes_to_blocks_or_html( $node );
|
||||||
|
|
||||||
switch ( $node_name ) {
|
switch ( $node_name ) {
|
||||||
|
case 'blockquote':
|
||||||
|
return $this->create_block( 'quote', $node_name, $node_content );
|
||||||
|
case 'table':
|
||||||
|
return $this->create_block( 'table', $node_name, $node_content );
|
||||||
|
case 'pre':
|
||||||
|
return $this->create_block( 'code', $node_name, $node_content );
|
||||||
case 'p':
|
case 'p':
|
||||||
return $this->create_block( 'paragraph', $node_name, $node_content );
|
return $this->create_block( 'paragraph', $node_name, $node_content );
|
||||||
case 'h1':
|
case 'h1':
|
||||||
|
@ -103,7 +112,7 @@ class BlockConverter {
|
||||||
case 'hr':
|
case 'hr':
|
||||||
return $this->create_block( 'separator', $node_name, null );
|
return $this->create_block( 'separator', $node_name, null );
|
||||||
default:
|
default:
|
||||||
return $this->create_block( 'paragraph', $node_value );
|
return $node_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,20 +133,27 @@ class BlockConverter {
|
||||||
if ( 'hr' === $node_name ) {
|
if ( 'hr' === $node_name ) {
|
||||||
$block_html .= "<{$node_name} class=\"wp-block-separator has-alpha-channel-opacity\" />\n";
|
$block_html .= "<{$node_name} class=\"wp-block-separator has-alpha-channel-opacity\" />\n";
|
||||||
} elseif ( null !== $content ) {
|
} elseif ( null !== $content ) {
|
||||||
$block_html .= "<{$node_name}>{$content}</{$node_name}>\n";
|
// Gutenberg seems to require class name to avoid block recovery error on some blocks.
|
||||||
|
if ( 'pre' === $node_name ) {
|
||||||
|
$block_html .= "<pre class=\"wp-block-code\">{$content}</pre>\n";
|
||||||
|
} elseif ( 'blockquote' === $node_name ) {
|
||||||
|
$block_html .= "<blockquote class=\"wp-block-quote\">{$content}</blockquote>\n";
|
||||||
|
} elseif ( 'table' === $node_name ) {
|
||||||
|
$block_html .= "<figure class=\"wp-block-table\"><table>{$content}</table></figure>\n";
|
||||||
|
} else {
|
||||||
|
$block_html .= "<{$node_name}>{$content}</{$node_name}>\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$block_html .= "<!-- /wp:{$block_name} -->\n";
|
$block_html .= "<!-- /wp:{$block_name} -->\n";
|
||||||
|
|
||||||
return $block_html;
|
return $block_html;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert child nodes to blocks.
|
* Convert child nodes to blocks or HTML.
|
||||||
*
|
*
|
||||||
* @param \DOMNode $node The DOM node.
|
* @param \DOMNode $node The DOM node.
|
||||||
*/
|
*/
|
||||||
private function convert_child_nodes_to_blocks( $node ) {
|
private function convert_child_nodes_to_blocks_or_html( $node ) {
|
||||||
$content = '';
|
$content = '';
|
||||||
|
|
||||||
foreach ( $node->childNodes as $child_node ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
foreach ( $node->childNodes as $child_node ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||||
|
@ -145,18 +161,24 @@ class BlockConverter {
|
||||||
$node_name = $child_node->nodeName; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
$node_name = $child_node->nodeName; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||||
|
|
||||||
if ( XML_ELEMENT_NODE === $node_type ) {
|
if ( XML_ELEMENT_NODE === $node_type ) {
|
||||||
if ( 'a' === $node_name ) {
|
if ( 'td' === $node_name || 'thead' === $node_name || 'tbody' === $node_name || 'tr' === $node_name || 'th' === $node_name ) {
|
||||||
|
$inline_content = $this->convert_child_nodes_to_blocks_or_html( $child_node );
|
||||||
|
$content .= "<{$node_name}>{$inline_content}</{$node_name}>";
|
||||||
|
} elseif ( 'a' === $node_name ) {
|
||||||
$href = esc_url( $child_node->getAttribute( 'href' ) );
|
$href = esc_url( $child_node->getAttribute( 'href' ) );
|
||||||
$link_content = $this->convert_child_nodes_to_blocks( $child_node );
|
$link_content = $this->convert_child_nodes_to_blocks_or_html( $child_node );
|
||||||
$content .= "<a href=\"{$href}\">{$link_content}</a>";
|
$content .= "<a href=\"{$href}\">{$link_content}</a>";
|
||||||
} elseif ( 'em' === $node_name || 'strong' === $node_name ) {
|
} elseif ( 'em' === $node_name || 'strong' === $node_name ) {
|
||||||
$inline_content = $this->convert_child_nodes_to_blocks( $child_node );
|
$inline_content = $this->convert_child_nodes_to_blocks_or_html( $child_node );
|
||||||
$content .= "<{$node_name}>{$inline_content}</{$node_name}>";
|
$content .= "<{$node_name}>{$inline_content}</{$node_name}>";
|
||||||
} elseif ( 'img' === $node_name ) {
|
} elseif ( 'img' === $node_name ) {
|
||||||
// Only handle images as inline content for now due to how Markdown is processed by CommonMark.
|
// Only handle images as inline content for now due to how Markdown is processed by CommonMark.
|
||||||
$src = esc_url( $child_node->getAttribute( 'src' ) );
|
$src = esc_url( $child_node->getAttribute( 'src' ) );
|
||||||
$alt = esc_attr( $child_node->getAttribute( 'alt' ) );
|
$alt = esc_attr( $child_node->getAttribute( 'alt' ) );
|
||||||
$content .= "<img src=\"{$src}\" alt=\"{$alt}\" />";
|
$content .= "<img src=\"{$src}\" alt=\"{$alt}\" />";
|
||||||
|
} elseif ( 'code' === $node_name ) {
|
||||||
|
$inline_content = $this->convert_child_nodes_to_blocks_or_html( $child_node );
|
||||||
|
$content .= "<code>{$inline_content}</code>";
|
||||||
} else {
|
} else {
|
||||||
$content .= $this->convert_node_to_block( $child_node );
|
$content .= $this->convert_node_to_block( $child_node );
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,3 +60,35 @@
|
||||||
<!-- wp:paragraph -->
|
<!-- wp:paragraph -->
|
||||||
<p><img src="https://picsum.photos/200/300" alt="An image" /></p>
|
<p><img src="https://picsum.photos/200/300" alt="An image" /></p>
|
||||||
<!-- /wp:paragraph -->
|
<!-- /wp:paragraph -->
|
||||||
|
<!-- wp:code -->
|
||||||
|
<pre class="wp-block-code"><code>$ cd /path/to/woocommerce-docs
|
||||||
|
</code></pre>
|
||||||
|
<!-- /wp:code -->
|
||||||
|
<!-- wp:quote -->
|
||||||
|
<blockquote class="wp-block-quote">
|
||||||
|
<!-- wp:paragraph -->
|
||||||
|
<p>This is a blockquote.</p>
|
||||||
|
<!-- /wp:paragraph -->
|
||||||
|
|
||||||
|
</blockquote>
|
||||||
|
<!-- /wp:quote -->
|
||||||
|
<!-- wp:table -->
|
||||||
|
<figure class="wp-block-table"><table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>First Header</th>
|
||||||
|
<th>Second Header</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Content Cell</td>
|
||||||
|
<td>Content Cell</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Content Cell</td>
|
||||||
|
<td>Content Cell</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table></figure>
|
||||||
|
<!-- /wp:table -->
|
||||||
|
|
|
@ -27,3 +27,14 @@ Here is a link: [Woocommerce.com](https://woocommerce.com).
|
||||||
---
|
---
|
||||||
|
|
||||||
![An image](https://picsum.photos/200/300 'This is an image.')
|
![An image](https://picsum.photos/200/300 'This is an image.')
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cd /path/to/woocommerce-docs
|
||||||
|
```
|
||||||
|
|
||||||
|
> This is a blockquote.
|
||||||
|
|
||||||
|
| First Header | Second Header |
|
||||||
|
| ------------ | ------------- |
|
||||||
|
| Content Cell | Content Cell |
|
||||||
|
| Content Cell | Content Cell |
|
||||||
|
|
|
@ -29,3 +29,14 @@ Here is a link: [Woocommerce.com](https://woocommerce.com).
|
||||||
---
|
---
|
||||||
|
|
||||||
![An image](https://picsum.photos/200/300 'This is an image.')
|
![An image](https://picsum.photos/200/300 'This is an image.')
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cd /path/to/woocommerce-docs
|
||||||
|
```
|
||||||
|
|
||||||
|
> This is a blockquote.
|
||||||
|
|
||||||
|
| First Header | Second Header |
|
||||||
|
| ------------ | ------------- |
|
||||||
|
| Content Cell | Content Cell |
|
||||||
|
| Content Cell | Content Cell |
|
||||||
|
|
Loading…
Reference in New Issue