MailPoet\EmailEditor\Engine\Renderer\ContentRenderer
Content_Renderer{} │ WC 1.0
Class Content_Renderer
Hooks from the class
Usage
$Content_Renderer = new Content_Renderer(); // use class methods
Methods
- public __construct(
- public block_parser()
- private initialize()
- private inline_styles( $html, WP_Post $post, $template = null )
- public preprocess_parsed_blocks( array $parsed_blocks )
- public render( WP_Post $post, WP_Block_Template $template )
- public render_block( string $block_content, array $parsed_block )
- private reset()
- private set_template_globals( WP_Post $post, WP_Block_Template $template )
Content_Renderer{} Content Renderer{} code WC 9.8.1
class Content_Renderer { /** * Blocks registry * * @var Blocks_Registry */ private Blocks_Registry $blocks_registry; /** * Process manager * * @var Process_Manager */ private Process_Manager $process_manager; /** * Settings controller * * @var Settings_Controller */ private Settings_Controller $settings_controller; /** * Theme controller * * @var Theme_Controller */ private Theme_Controller $theme_controller; const CONTENT_STYLES_FILE = 'content.css'; /** * CSS inliner * * @var Css_Inliner */ private Css_Inliner $css_inliner; /** * Content_Renderer constructor. * * @param Process_Manager $preprocess_manager Preprocess manager. * @param Blocks_Registry $blocks_registry Blocks registry. * @param Settings_Controller $settings_controller Settings controller. * @param Css_Inliner $css_inliner Css inliner. * @param Theme_Controller $theme_controller Theme controller. */ public function __construct( Process_Manager $preprocess_manager, Blocks_Registry $blocks_registry, Settings_Controller $settings_controller, Css_Inliner $css_inliner, Theme_Controller $theme_controller ) { $this->process_manager = $preprocess_manager; $this->blocks_registry = $blocks_registry; $this->settings_controller = $settings_controller; $this->theme_controller = $theme_controller; $this->css_inliner = $css_inliner; } /** * Initialize the content renderer * * @return void */ private function initialize() { add_filter( 'render_block', array( $this, 'render_block' ), 10, 2 ); add_filter( 'block_parser_class', array( $this, 'block_parser' ) ); add_filter( 'mailpoet_blocks_renderer_parsed_blocks', array( $this, 'preprocess_parsed_blocks' ) ); do_action( 'mailpoet_blocks_renderer_initialized', $this->blocks_registry ); } /** * Render the content * * @param WP_Post $post Post object. * @param WP_Block_Template $template Block template. * @return string */ public function render( WP_Post $post, WP_Block_Template $template ): string { $this->set_template_globals( $post, $template ); $this->initialize(); $rendered_html = get_the_block_template_html(); $this->reset(); return $this->process_manager->postprocess( $this->inline_styles( $rendered_html, $post, $template ) ); } /** * Get block parser class * * @return string */ public function block_parser() { return 'MailPoet\EmailEditor\Engine\Renderer\ContentRenderer\Blocks_Parser'; } /** * Preprocess parsed blocks * * @param array $parsed_blocks Parsed blocks. * @return array */ public function preprocess_parsed_blocks( array $parsed_blocks ): array { return $this->process_manager->preprocess( $parsed_blocks, $this->theme_controller->get_layout_settings(), $this->theme_controller->get_styles() ); } /** * Renders block * Translates block's HTML to HTML suitable for email clients. The method is intended as a callback for 'render_block' filter. * * @param string $block_content Block content. * @param array $parsed_block Parsed block. * @return string */ public function render_block( string $block_content, array $parsed_block ): string { $renderer = $this->blocks_registry->get_block_renderer( $parsed_block['blockName'] ); if ( ! $renderer ) { $renderer = $this->blocks_registry->get_fallback_renderer(); } return $renderer ? $renderer->render( $block_content, $parsed_block, $this->settings_controller ) : $block_content; } /** * Set template globals * * @param WP_Post $post Post object. * @param WP_Block_Template $template Block template. * @return void */ private function set_template_globals( WP_Post $post, WP_Block_Template $template ) { global $_wp_current_template_content, $_wp_current_template_id; $_wp_current_template_id = $template->id; $_wp_current_template_content = $template->content; $GLOBALS['post'] = $post; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- I have not found a better way to set the post object for the block renderer. } /** * 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. */ private function reset(): void { $this->blocks_registry->remove_all_block_renderers(); remove_filter( 'render_block', array( $this, 'render_block' ) ); remove_filter( 'block_parser_class', array( $this, 'block_parser' ) ); remove_filter( 'mailpoet_blocks_renderer_parsed_blocks', array( $this, 'preprocess_parsed_blocks' ) ); } /** * Method to inline styles into the HTML * * @param string $html HTML content. * @param WP_Post $post Post object. * @param WP_Block_Template|null $template Block template. * @return string */ private function inline_styles( $html, WP_Post $post, $template = null ) { $styles = (string) file_get_contents( __DIR__ . '/' . self::CONTENT_STYLES_FILE ); $styles .= (string) file_get_contents( __DIR__ . '/../../content-shared.css' ); // Apply default contentWidth to constrained blocks. $layout = $this->theme_controller->get_layout_settings(); $styles .= sprintf( ' .is-layout-constrained > *:not(.alignleft):not(.alignright):not(.alignfull) { max-width: %1$s; margin-left: auto !important; margin-right: auto !important; } .is-layout-constrained > .alignwide { max-width: %2$s; margin-left: auto !important; margin-right: auto !important; } ', $layout['contentSize'], $layout['wideSize'] ); // Get styles from theme. $styles .= $this->theme_controller->get_stylesheet_for_rendering( $post, $template ); $block_support_styles = $this->theme_controller->get_stylesheet_from_context( 'block-supports', array() ); // Get styles from block-supports stylesheet. This includes rules such as layout (contentWidth) that some blocks use. // @see https://github.com/WordPress/WordPress/blob/3c5da9c74344aaf5bf8097f2e2c6a1a781600e03/wp-includes/script-loader.php#L3134 // @internal :where is not supported by emogrifier, so we need to replace it with *. $block_support_styles = str_replace( ':where(:not(.alignleft):not(.alignright):not(.alignfull))', '*:not(.alignleft):not(.alignright):not(.alignfull)', $block_support_styles ); /* * Layout CSS assumes the top level block will have a single DIV wrapper with children. Since our blocks use tables, * we need to adjust this to look for children in the TD element. This may requires more advanced replacement but * this works in the current version of Gutenberg. * Example rule we're targetting: .wp-container-core-group-is-layout-1.wp-container-core-group-is-layout-1 > * */ $block_support_styles = preg_replace( '/group-is-layout-(\d+) >/', 'group-is-layout-$1 > tbody tr td >', $block_support_styles ); $styles .= $block_support_styles; /* * Debugging for content styles. Remember these get inlined. * echo '<pre>'; * var_dump($styles); * echo '</pre>'; */ $styles = '<style>' . wp_strip_all_tags( (string) apply_filters( 'mailpoet_email_content_renderer_styles', $styles, $post ) ) . '</style>'; return $this->css_inliner->from_html( $styles . $html )->inline_css()->render(); } }