Split renderer into content renderer and renderer
Content renderer - renders the content of the email post Renderer - places the content into the email HTML template and generates text version [MAILPOET-5798]
This commit is contained in:
committed by
Jan Lysý
parent
c7a75a897b
commit
2c5857e89b
@@ -347,6 +347,7 @@ class ContainerConfigurator implements IContainerConfigurator {
|
||||
$container->autowire(\MailPoet\EmailEditor\Engine\Renderer\Preprocessors\TopLevelPreprocessor::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\EmailEditor\Engine\Renderer\Preprocessors\TypographyPreprocessor::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\EmailEditor\Engine\Renderer\Renderer::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\EmailEditor\Engine\Renderer\ContentRenderer::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\EmailEditor\Engine\Renderer\BlocksRegistry::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\EmailEditor\Engine\Renderer\ProcessManager::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\EmailEditor\Integrations\Core\Initializer::class)->setPublic(true);
|
||||
|
88
mailpoet/lib/EmailEditor/Engine/Renderer/ContentRenderer.php
Normal file
88
mailpoet/lib/EmailEditor/Engine/Renderer/ContentRenderer.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\EmailEditor\Engine\Renderer;
|
||||
|
||||
use MailPoet\EmailEditor\Engine\SettingsController;
|
||||
use MailPoet\EmailEditor\Engine\ThemeController;
|
||||
use MailPoet\Util\pQuery\DomNode;
|
||||
|
||||
class ContentRenderer {
|
||||
private \MailPoetVendor\CSS $cssInliner;
|
||||
|
||||
private BlocksRegistry $blocksRegistry;
|
||||
|
||||
private ProcessManager $processManager;
|
||||
|
||||
private SettingsController $settingsController;
|
||||
|
||||
private ThemeController $themeController;
|
||||
|
||||
/**
|
||||
* @param \MailPoetVendor\CSS $cssInliner
|
||||
*/
|
||||
public function __construct(
|
||||
\MailPoetVendor\CSS $cssInliner,
|
||||
ProcessManager $preprocessManager,
|
||||
BlocksRegistry $blocksRegistry,
|
||||
SettingsController $settingsController,
|
||||
ThemeController $themeController
|
||||
) {
|
||||
$this->cssInliner = $cssInliner;
|
||||
$this->processManager = $preprocessManager;
|
||||
$this->blocksRegistry = $blocksRegistry;
|
||||
$this->settingsController = $settingsController;
|
||||
$this->themeController = $themeController;
|
||||
}
|
||||
|
||||
public function render(\WP_Post $post): string {
|
||||
$parser = new \WP_Block_Parser();
|
||||
$parsedBlocks = $parser->parse($post->post_content); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
|
||||
|
||||
$layoutStyles = $this->settingsController->getEmailStyles()['layout'];
|
||||
$parsedBlocks = $this->processManager->preprocess($parsedBlocks, $layoutStyles);
|
||||
$renderedBody = $this->renderBlocks($parsedBlocks);
|
||||
$styles = $this->themeController->getStylesheetForRendering();
|
||||
$styles = apply_filters('mailpoet_email_content_renderer_styles', $styles, $post);
|
||||
|
||||
$renderedBodyDom = $this->inlineCSSStyles("<style>$styles</style>" . $renderedBody);
|
||||
$renderedBody = $this->postProcessTemplate($renderedBodyDom);
|
||||
$renderedBody = $this->processManager->postprocess($renderedBody);
|
||||
return $renderedBody;
|
||||
}
|
||||
|
||||
public function renderBlocks(array $parsedBlocks): string {
|
||||
do_action('mailpoet_blocks_renderer_initialized', $this->blocksRegistry);
|
||||
|
||||
$content = '';
|
||||
foreach ($parsedBlocks as $parsedBlock) {
|
||||
$content .= render_block($parsedBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* As we use default WordPress filters, we need to remove them after email rendering
|
||||
* so that we don't interfere with possible post rendering that might happen later.
|
||||
*/
|
||||
$this->blocksRegistry->removeAllBlockRendererFilters();
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $template
|
||||
* @return DomNode
|
||||
*/
|
||||
private function inlineCSSStyles($template) {
|
||||
return $this->cssInliner->inlineCSS($template);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DomNode $templateDom
|
||||
* @return string
|
||||
*/
|
||||
private function postProcessTemplate(DomNode $templateDom) {
|
||||
// because tburry/pquery contains a bug and replaces the opening non mso condition incorrectly we have to replace the opening tag with correct value
|
||||
$template = $templateDom->__toString();
|
||||
$template = str_replace('<!--[if !mso]><![endif]-->', '<!--[if !mso]><!-- -->', $template);
|
||||
return $template;
|
||||
}
|
||||
}
|
@@ -3,20 +3,15 @@
|
||||
namespace MailPoet\EmailEditor\Engine\Renderer;
|
||||
|
||||
use MailPoet\EmailEditor\Engine\SettingsController;
|
||||
use MailPoet\EmailEditor\Engine\ThemeController;
|
||||
use MailPoet\Util\pQuery\DomNode;
|
||||
use MailPoetVendor\Html2Text\Html2Text;
|
||||
|
||||
class Renderer {
|
||||
private \MailPoetVendor\CSS $cssInliner;
|
||||
|
||||
private BlocksRegistry $blocksRegistry;
|
||||
|
||||
private ProcessManager $processManager;
|
||||
|
||||
private SettingsController $settingsController;
|
||||
|
||||
private ThemeController $themeController;
|
||||
private ContentRenderer $contentRenderer;
|
||||
|
||||
const TEMPLATE_FILE = 'template.html';
|
||||
const TEMPLATE_STYLES_FILE = 'styles.css';
|
||||
@@ -26,31 +21,22 @@ class Renderer {
|
||||
*/
|
||||
public function __construct(
|
||||
\MailPoetVendor\CSS $cssInliner,
|
||||
ProcessManager $preprocessManager,
|
||||
BlocksRegistry $blocksRegistry,
|
||||
SettingsController $settingsController,
|
||||
ThemeController $themeController
|
||||
ContentRenderer $contentRenderer
|
||||
) {
|
||||
$this->cssInliner = $cssInliner;
|
||||
$this->processManager = $preprocessManager;
|
||||
$this->blocksRegistry = $blocksRegistry;
|
||||
$this->settingsController = $settingsController;
|
||||
$this->themeController = $themeController;
|
||||
$this->contentRenderer = $contentRenderer;
|
||||
}
|
||||
|
||||
public function render(\WP_Post $post, string $subject, string $preHeader, string $language, $metaRobots = ''): array {
|
||||
$parser = new \WP_Block_Parser();
|
||||
$parsedBlocks = $parser->parse($post->post_content); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
|
||||
|
||||
$layoutStyles = $this->settingsController->getEmailStyles()['layout'];
|
||||
$themeData = $this->settingsController->getTheme()->get_data();
|
||||
$contentBackground = $themeData['styles']['color']['background'] ?? $layoutStyles['background'];
|
||||
$contentFontFamily = $themeData['styles']['typography']['fontFamily'];
|
||||
$parsedBlocks = $this->processManager->preprocess($parsedBlocks, $layoutStyles);
|
||||
$renderedBody = $this->renderBlocks($parsedBlocks);
|
||||
$renderedBody = $this->contentRenderer->render($post);
|
||||
|
||||
$styles = (string)file_get_contents(dirname(__FILE__) . '/' . self::TEMPLATE_STYLES_FILE);
|
||||
$styles .= $this->themeController->getStylesheetForRendering();
|
||||
$styles = apply_filters('mailpoet_email_renderer_styles', $styles, $post);
|
||||
|
||||
$template = (string)file_get_contents(dirname(__FILE__) . '/' . self::TEMPLATE_FILE);
|
||||
@@ -85,30 +71,12 @@ class Renderer {
|
||||
|
||||
$templateWithContentsDom = $this->inlineCSSStyles($templateWithContents);
|
||||
$templateWithContents = $this->postProcessTemplate($templateWithContentsDom);
|
||||
$templateWithContents = $this->processManager->postprocess($templateWithContents);
|
||||
return [
|
||||
'html' => $templateWithContents,
|
||||
'text' => $this->renderTextVersion($templateWithContents),
|
||||
];
|
||||
}
|
||||
|
||||
public function renderBlocks(array $parsedBlocks): string {
|
||||
do_action('mailpoet_blocks_renderer_initialized', $this->blocksRegistry);
|
||||
|
||||
$content = '';
|
||||
foreach ($parsedBlocks as $parsedBlock) {
|
||||
$content .= render_block($parsedBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* As we use default WordPress filters, we need to remove them after email rendering
|
||||
* so that we don't interfere with possible post rendering that might happen later.
|
||||
*/
|
||||
$this->blocksRegistry->removeAllBlockRendererFilters();
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
private function injectContentIntoTemplate($template, array $content) {
|
||||
return preg_replace_callback('/{{\w+}}/', function ($matches) use (&$content) {
|
||||
return array_shift($content);
|
||||
|
@@ -10,7 +10,7 @@ class Initializer {
|
||||
add_action('mailpoet_blocks_renderer_initialized', [$this, 'registerCoreBlocksRenderers'], 10, 1);
|
||||
add_filter('mailpoet_email_editor_theme_json', [$this, 'adjustThemeJson'], 10, 1);
|
||||
add_filter('mailpoet_email_editor_editor_styles', [$this, 'addEditorStyles'], 10, 1);
|
||||
add_filter('mailpoet_email_renderer_styles', [$this, 'addRendererStyles'], 10, 1);
|
||||
add_filter('mailpoet_email_content_renderer_styles', [$this, 'addRendererStyles'], 10, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -5,8 +5,6 @@ namespace MailPoet\EmailEditor\Engine\Renderer;
|
||||
use MailPoet\EmailEditor\Engine\EmailEditor;
|
||||
use MailPoet\EmailEditor\Engine\SettingsController;
|
||||
|
||||
require_once __DIR__ . '/DummyBlockRenderer.php';
|
||||
|
||||
class RendererTest extends \MailPoetTest {
|
||||
/** @var Renderer */
|
||||
private $renderer;
|
||||
@@ -60,7 +58,7 @@ class RendererTest extends \MailPoetTest {
|
||||
remove_filter('mailpoet_email_renderer_styles', $stylesCallback);
|
||||
}
|
||||
|
||||
public function testItInlinesEmailStyles() {
|
||||
public function testItInlinesBodyStyles() {
|
||||
$rendered = $this->renderer->render($this->emailPost, 'Subject', '', 'en');
|
||||
$doc = new \DOMDocument();
|
||||
$doc->loadHTML($rendered['html']);
|
||||
@@ -75,7 +73,7 @@ class RendererTest extends \MailPoetTest {
|
||||
verify($style)->stringContainsString('margin:0;padding:0;');
|
||||
}
|
||||
|
||||
public function testItInlinesMainStyles() {
|
||||
public function testItInlinesWrappersStyles() {
|
||||
$themeJsonMock = $this->createMock(\WP_Theme_JSON::class);
|
||||
$themeJsonMock->method('get_data')->willReturn([
|
||||
'styles' => [
|
||||
|
Reference in New Issue
Block a user