Add blocks preprocessor
Currently, we need to wrap top-level non-column blocks into a single column. This is done in the preprocessor. [MAILPOET-5540]
This commit is contained in:
committed by
Jan Lysý
parent
69a87e8146
commit
968ff6754e
@@ -319,6 +319,7 @@ class ContainerConfigurator implements IContainerConfigurator {
|
||||
$container->autowire(\MailPoet\EmailEditor\Engine\Renderer\BodyRenderer::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\EmailEditor\Engine\Renderer\BlocksRenderer::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\EmailEditor\Engine\Renderer\BlocksRegistry::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\EmailEditor\Engine\Renderer\Preprocessor::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\EmailEditor\Integrations\Core\Initializer::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\EmailEditor\Integrations\MailPoet\EmailEditor::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\EmailEditor\Integrations\MailPoet\EmailApiController::class)->setPublic(true);
|
||||
|
@@ -13,10 +13,7 @@ class BodyRenderer {
|
||||
$this->blocksRenderer = $blocksRenderer;
|
||||
}
|
||||
|
||||
public function renderBody(string $postContent): string {
|
||||
$parser = new \WP_Block_Parser();
|
||||
$parsedBlocks = $parser->parse($postContent);
|
||||
// @todo We need to wrap top level blocks which are not in columns into a column
|
||||
public function renderBody(array $parsedBlocks): string {
|
||||
return $this->blocksRenderer->render($parsedBlocks);
|
||||
}
|
||||
}
|
||||
|
52
mailpoet/lib/EmailEditor/Engine/Renderer/Preprocessor.php
Normal file
52
mailpoet/lib/EmailEditor/Engine/Renderer/Preprocessor.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\EmailEditor\Engine\Renderer;
|
||||
|
||||
class Preprocessor {
|
||||
|
||||
const SINGLE_COLUMN_TEMPLATE = [
|
||||
'blockName' => 'core/columns',
|
||||
'attrs' => [],
|
||||
'innerBlocks' => [[
|
||||
'blockName' => 'core/column',
|
||||
'attrs' => [],
|
||||
'innerBlocks' => [],
|
||||
]],
|
||||
];
|
||||
|
||||
public function preprocess(array $parsedBlocks): array {
|
||||
return $this->addTopLevelColumns($parsedBlocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* In the editor we allow putting content blocks directly into the root level of the email.
|
||||
* But for rendering purposes it is more convenient to have them wrapped in a single column.
|
||||
* This method walks through the first level of blocks and wraps non column blocks into a single column.
|
||||
*/
|
||||
private function addTopLevelColumns(array $parsedBlocks): array {
|
||||
$wrappedParsedBlocks = [];
|
||||
$nonColumnsBlocksBuffer = [];
|
||||
foreach ($parsedBlocks as $block) {
|
||||
// The next block is columns so we can flush the buffer and add the columns block
|
||||
if ($block['blockName'] === 'core/columns') {
|
||||
if ($nonColumnsBlocksBuffer) {
|
||||
$columnsBlock = self::SINGLE_COLUMN_TEMPLATE;
|
||||
$columnsBlock['innerBlocks'][0]['innerBlocks'] = $nonColumnsBlocksBuffer;
|
||||
$nonColumnsBlocksBuffer = [];
|
||||
$wrappedParsedBlocks[] = $columnsBlock;
|
||||
}
|
||||
$wrappedParsedBlocks[] = $block;
|
||||
continue;
|
||||
}
|
||||
// Non columns block so we add it to the buffer
|
||||
$nonColumnsBlocksBuffer[] = $block;
|
||||
}
|
||||
// Flush the buffer if there are any blocks left
|
||||
if ($nonColumnsBlocksBuffer) {
|
||||
$columnsBlock = self::SINGLE_COLUMN_TEMPLATE;
|
||||
$columnsBlock['innerBlocks'][0]['innerBlocks'] = $nonColumnsBlocksBuffer;
|
||||
$wrappedParsedBlocks[] = $columnsBlock;
|
||||
}
|
||||
return $wrappedParsedBlocks;
|
||||
}
|
||||
}
|
@@ -13,6 +13,9 @@ class Renderer {
|
||||
/** @var BodyRenderer */
|
||||
private $bodyRenderer;
|
||||
|
||||
/** @var Preprocessor */
|
||||
private $preprocessor;
|
||||
|
||||
const TEMPLATE_FILE = 'template.html';
|
||||
const STYLES_FILE = 'styles.css';
|
||||
|
||||
@@ -21,14 +24,21 @@ class Renderer {
|
||||
*/
|
||||
public function __construct(
|
||||
\MailPoetVendor\CSS $cssInliner,
|
||||
Preprocessor $preprocessor,
|
||||
BodyRenderer $bodyRenderer
|
||||
) {
|
||||
$this->cssInliner = $cssInliner;
|
||||
$this->preprocessor = $preprocessor;
|
||||
$this->bodyRenderer = $bodyRenderer;
|
||||
}
|
||||
|
||||
public function render(\WP_Post $post, string $subject, string $preHeader, string $language, $metaRobots = ''): array {
|
||||
$renderedBody = $this->bodyRenderer->renderBody($post->post_content); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
|
||||
$parser = new \WP_Block_Parser();
|
||||
$parsedBlocks = $parser->parse($post->post_content); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
|
||||
|
||||
$parsedBlocks = $this->preprocessor->preprocess($parsedBlocks);
|
||||
$renderedBody = $this->bodyRenderer->renderBody($parsedBlocks);
|
||||
|
||||
$styles = (string)file_get_contents(dirname(__FILE__) . '/' . self::STYLES_FILE);
|
||||
$styles = apply_filters('mailpoet_email_renderer_styles', $styles, $post);
|
||||
|
||||
|
@@ -0,0 +1,63 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\EmailEditor\Engine\Renderer;
|
||||
|
||||
class PreprocessorTest extends \MailPoetUnitTest {
|
||||
|
||||
private $paragraphBlock = [
|
||||
'blockName' => 'core/paragraph',
|
||||
'attrs' => [],
|
||||
'innerHTML' => 'Paragraph content',
|
||||
];
|
||||
|
||||
private $columnsBlock = [
|
||||
'blockName' => 'core/columns',
|
||||
'attrs' => [],
|
||||
'innerBlocks' => [[
|
||||
'blockName' => 'core/column',
|
||||
'attrs' => [],
|
||||
'innerBlocks' => [],
|
||||
]],
|
||||
];
|
||||
|
||||
/** @var Preprocessor */
|
||||
private $preprocessor;
|
||||
|
||||
public function _before() {
|
||||
parent::_before();
|
||||
$this->preprocessor = new Preprocessor();
|
||||
}
|
||||
|
||||
public function testItWrapsSingleTopLevelBlockIntoColumns() {
|
||||
$parsedDocument = [$this->paragraphBlock];
|
||||
$result = $this->preprocessor->preprocess($parsedDocument);
|
||||
expect($result[0]['blockName'])->equals('core/columns');
|
||||
expect($result[0]['innerBlocks'][0]['blockName'])->equals('core/column');
|
||||
expect($result[0]['innerBlocks'][0]['innerBlocks'][0]['blockName'])->equals('core/paragraph');
|
||||
expect($result[0]['innerBlocks'][0]['innerBlocks'][0]['innerHTML'])->equals('Paragraph content');
|
||||
}
|
||||
|
||||
public function testItDoesntWrapColumns() {
|
||||
$parsedDocumentWithMultipleColumns = [$this->columnsBlock, $this->columnsBlock];
|
||||
$result = $this->preprocessor->preprocess($parsedDocumentWithMultipleColumns);
|
||||
expect($result)->equals($parsedDocumentWithMultipleColumns);
|
||||
}
|
||||
|
||||
public function testItWrapsTopLevelBlocksSpreadBetweenColumns() {
|
||||
$parsedDocument = [$this->paragraphBlock, $this->columnsBlock, $this->paragraphBlock, $this->paragraphBlock];
|
||||
// We expect to wrap top level paragraph blocks into columns so the result should three columns blocks
|
||||
$result = $this->preprocessor->preprocess($parsedDocument);
|
||||
expect($result)->count(3);
|
||||
// First columns contain columns with one paragraph block
|
||||
expect($result[0]['innerBlocks'][0]['blockName'])->equals('core/column');
|
||||
expect($result[0]['innerBlocks'][0]['innerBlocks'][0]['blockName'])->equals('core/paragraph');
|
||||
// Second columns remains empty
|
||||
expect($result[1]['innerBlocks'][0]['blockName'])->equals('core/column');
|
||||
expect($result[1]['innerBlocks'][0]['innerBlocks'])->isEmpty();
|
||||
// Third columns contain columns with two paragraph blocks
|
||||
expect($result[2]['innerBlocks'][0]['blockName'])->equals('core/column');
|
||||
expect($result[2]['innerBlocks'][0]['innerBlocks'])->count(2);
|
||||
expect($result[2]['innerBlocks'][0]['innerBlocks'][0]['blockName'])->equals('core/paragraph');
|
||||
expect($result[2]['innerBlocks'][0]['innerBlocks'][1]['blockName'])->equals('core/paragraph');
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user