Render image block on front end
[MAILPOET-2750]
This commit is contained in:
committed by
Veljko V
parent
868a1aaaa6
commit
7a604fa10e
@@ -206,3 +206,30 @@ div.mailpoet_form_popup {
|
|||||||
div.mailpoet_form_popup.active {
|
div.mailpoet_form_popup.active {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MailPoet Form - Image block
|
||||||
|
// Inspired by wp-image-block behaviour
|
||||||
|
.mailpoet_form_image {
|
||||||
|
&.is-style-rounded {
|
||||||
|
border-radius: 9999px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aligncenter {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.alignleft {
|
||||||
|
float: left;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
.alignright {
|
||||||
|
float: right;
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
figcaption {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -185,6 +185,7 @@ class ContainerConfigurator implements IContainerConfigurator {
|
|||||||
$container->autowire(\MailPoet\Form\Block\Divider::class);
|
$container->autowire(\MailPoet\Form\Block\Divider::class);
|
||||||
$container->autowire(\MailPoet\Form\Block\Html::class);
|
$container->autowire(\MailPoet\Form\Block\Html::class);
|
||||||
$container->autowire(\MailPoet\Form\Block\Heading::class);
|
$container->autowire(\MailPoet\Form\Block\Heading::class);
|
||||||
|
$container->autowire(\MailPoet\Form\Block\Image::class);
|
||||||
$container->autowire(\MailPoet\Form\Block\Paragraph::class);
|
$container->autowire(\MailPoet\Form\Block\Paragraph::class);
|
||||||
$container->autowire(\MailPoet\Form\Block\Radio::class);
|
$container->autowire(\MailPoet\Form\Block\Radio::class);
|
||||||
$container->autowire(\MailPoet\Form\Block\Segment::class);
|
$container->autowire(\MailPoet\Form\Block\Segment::class);
|
||||||
|
48
lib/Form/Block/Image.php
Normal file
48
lib/Form/Block/Image.php
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace MailPoet\Form\Block;
|
||||||
|
|
||||||
|
class Image {
|
||||||
|
public function render(array $block): string {
|
||||||
|
if (empty($block['params']['url'])) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return $this->wrapImage($block['params'], $this->renderImage($block['params']));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function renderImage(array $params) {
|
||||||
|
$attributes = [];
|
||||||
|
$attributes[] = 'src="' . $params['url'] . '"';
|
||||||
|
$attributes[] = $params['alt'] ? 'alt="' . $params['alt'] . '"' : 'alt';
|
||||||
|
if ($params['title']) {
|
||||||
|
$attributes[] = 'title="' . $params['title'] . '"';
|
||||||
|
}
|
||||||
|
if ($params['id']) {
|
||||||
|
// WordPress automatically renders srcset based on this class
|
||||||
|
$attributes[] = 'class="wp-image-' . $params['id'] . '"';
|
||||||
|
}
|
||||||
|
if ($params['width']) {
|
||||||
|
$attributes[] = 'width="' . intval($params['width']) . '"';
|
||||||
|
}
|
||||||
|
if ($params['height']) {
|
||||||
|
$attributes[] = 'height="' . intval($params['height']) . '"';
|
||||||
|
}
|
||||||
|
return '<img ' . implode(' ', $attributes) . '" />';
|
||||||
|
}
|
||||||
|
|
||||||
|
private function wrapImage(array $params, string $img) {
|
||||||
|
// Figure
|
||||||
|
$figureClasses = ['size-' . $params['size_slug']];
|
||||||
|
if ($params['align']) {
|
||||||
|
$figureClasses[] = 'align' . $params['align'];
|
||||||
|
}
|
||||||
|
$caption = $params['caption'] ? "<figcaption>{$params['caption']}</figcaption>" : '';
|
||||||
|
$figure = '<figure class="' . implode(' ', $figureClasses) . '">' . $img . $caption . '</figure>';
|
||||||
|
// Main wrapper
|
||||||
|
$divClasses = ['mailpoet_form_image'];
|
||||||
|
if (trim($params['class_name'])) {
|
||||||
|
$divClasses[] = trim($params['class_name']);
|
||||||
|
}
|
||||||
|
return '<div class="' . implode(' ', $divClasses) . '">' . $figure . '</div>';
|
||||||
|
}
|
||||||
|
}
|
@@ -9,6 +9,7 @@ use MailPoet\Form\Block\Date;
|
|||||||
use MailPoet\Form\Block\Divider;
|
use MailPoet\Form\Block\Divider;
|
||||||
use MailPoet\Form\Block\Heading;
|
use MailPoet\Form\Block\Heading;
|
||||||
use MailPoet\Form\Block\Html;
|
use MailPoet\Form\Block\Html;
|
||||||
|
use MailPoet\Form\Block\Image;
|
||||||
use MailPoet\Form\Block\Paragraph;
|
use MailPoet\Form\Block\Paragraph;
|
||||||
use MailPoet\Form\Block\Radio;
|
use MailPoet\Form\Block\Radio;
|
||||||
use MailPoet\Form\Block\Segment;
|
use MailPoet\Form\Block\Segment;
|
||||||
@@ -30,6 +31,9 @@ class BlocksRenderer {
|
|||||||
/** @var Html */
|
/** @var Html */
|
||||||
private $html;
|
private $html;
|
||||||
|
|
||||||
|
/** @var Image */
|
||||||
|
private $image;
|
||||||
|
|
||||||
/** @var Radio */
|
/** @var Radio */
|
||||||
private $radio;
|
private $radio;
|
||||||
|
|
||||||
@@ -67,6 +71,7 @@ class BlocksRenderer {
|
|||||||
Date $date,
|
Date $date,
|
||||||
Divider $divider,
|
Divider $divider,
|
||||||
Html $html,
|
Html $html,
|
||||||
|
Image $image,
|
||||||
Heading $heading,
|
Heading $heading,
|
||||||
Paragraph $paragraph,
|
Paragraph $paragraph,
|
||||||
Radio $radio,
|
Radio $radio,
|
||||||
@@ -82,6 +87,7 @@ class BlocksRenderer {
|
|||||||
$this->date = $date;
|
$this->date = $date;
|
||||||
$this->divider = $divider;
|
$this->divider = $divider;
|
||||||
$this->html = $html;
|
$this->html = $html;
|
||||||
|
$this->image = $image;
|
||||||
$this->radio = $radio;
|
$this->radio = $radio;
|
||||||
$this->segment = $segment;
|
$this->segment = $segment;
|
||||||
$this->select = $select;
|
$this->select = $select;
|
||||||
@@ -103,6 +109,10 @@ class BlocksRenderer {
|
|||||||
$html .= $this->heading->render($block);
|
$html .= $this->heading->render($block);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'image':
|
||||||
|
$html .= $this->image->render($block);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'paragraph':
|
case 'paragraph':
|
||||||
$html .= $this->paragraph->render($block);
|
$html .= $this->paragraph->render($block);
|
||||||
break;
|
break;
|
||||||
|
78
tests/unit/Form/Block/ImageTest.php
Normal file
78
tests/unit/Form/Block/ImageTest.php
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace MailPoet\Test\Form\Block;
|
||||||
|
|
||||||
|
use MailPoet\Form\Block\Image;
|
||||||
|
use MailPoet\Test\Form\HtmlParser;
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../HtmlParser.php';
|
||||||
|
|
||||||
|
class ImageTest extends \MailPoetUnitTest {
|
||||||
|
/** @var Image */
|
||||||
|
private $image;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $block = [
|
||||||
|
'type' => 'image',
|
||||||
|
'id' => 'image',
|
||||||
|
'params' => [
|
||||||
|
'class_name' => 'my-class',
|
||||||
|
'align' => 'left',
|
||||||
|
'url' => 'http://example.com/image.jpg',
|
||||||
|
'alt' => 'Alt text',
|
||||||
|
'title' => 'Title',
|
||||||
|
'caption' => 'Caption',
|
||||||
|
'link_destination' => 'none',
|
||||||
|
'link' => null,
|
||||||
|
'id' => 123,
|
||||||
|
'size_slug' => 'medium',
|
||||||
|
'width' => 100,
|
||||||
|
'height' => 200,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
/** @var HtmlParser */
|
||||||
|
private $htmlParser;
|
||||||
|
|
||||||
|
public function _before() {
|
||||||
|
parent::_before();
|
||||||
|
$this->image = new Image();
|
||||||
|
$this->htmlParser = new HtmlParser();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testItShouldRenderImageBlock() {
|
||||||
|
$html = $this->image->render($this->block);
|
||||||
|
$block = $this->htmlParser->getElementByXpath($html, '//div');
|
||||||
|
$blockClass = $this->htmlParser->getAttribute($block, 'class');
|
||||||
|
expect($blockClass->value)->equals('mailpoet_form_image my-class');
|
||||||
|
|
||||||
|
$figure = $this->htmlParser->getChildElement($block, 'figure');
|
||||||
|
$figureClass = $this->htmlParser->getAttribute($figure, 'class');
|
||||||
|
expect($figureClass->value)->equals('size-medium alignleft');
|
||||||
|
|
||||||
|
$img = $this->htmlParser->getChildElement($figure, 'img');
|
||||||
|
$imgSrc = $this->htmlParser->getAttribute($img, 'src');
|
||||||
|
expect($imgSrc->value)->equals('http://example.com/image.jpg');
|
||||||
|
$imgWidth = $this->htmlParser->getAttribute($img, 'width');
|
||||||
|
expect($imgWidth->value)->equals(100);
|
||||||
|
$imgHeight = $this->htmlParser->getAttribute($img, 'height');
|
||||||
|
expect($imgHeight->value)->equals(200);
|
||||||
|
$imgTitle = $this->htmlParser->getAttribute($img, 'title');
|
||||||
|
expect($imgTitle->value)->equals('Title');
|
||||||
|
$imgAlt = $this->htmlParser->getAttribute($img, 'alt');
|
||||||
|
expect($imgAlt->value)->equals('Alt text');
|
||||||
|
|
||||||
|
$caption = $this->htmlParser->getChildElement($figure, 'figcaption');
|
||||||
|
expect($caption->textContent)->equals('Caption');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testItRendersNothingWhenUrlIsEmpty() {
|
||||||
|
$block = $this->block;
|
||||||
|
$block['params']['url'] = null;
|
||||||
|
$html = $this->image->render($block);
|
||||||
|
expect($html)->equals('');
|
||||||
|
$block['params']['url'] = '';
|
||||||
|
$html = $this->image->render($block);
|
||||||
|
expect($html)->equals('');
|
||||||
|
}
|
||||||
|
}
|
@@ -3,9 +3,20 @@
|
|||||||
namespace MailPoet\Test\Form;
|
namespace MailPoet\Test\Form;
|
||||||
|
|
||||||
class HtmlParser {
|
class HtmlParser {
|
||||||
|
|
||||||
|
private $allowedHtml5Tags = ['<figure', '<figcaption'];
|
||||||
|
|
||||||
public function findByXpath(string $html, string $xpath): \DOMNodeList {
|
public function findByXpath(string $html, string $xpath): \DOMNodeList {
|
||||||
|
$isHtml5 = str_replace($this->allowedHtml5Tags, '', $html) !== $html;
|
||||||
$dom = new \DOMDocument();
|
$dom = new \DOMDocument();
|
||||||
$dom->loadHTML($html);
|
if ($isHtml5) {
|
||||||
|
// HTML 5 tags like figure, nav are not supported so we need to turn off errors
|
||||||
|
libxml_use_internal_errors(true);
|
||||||
|
$dom->loadHTML($html);
|
||||||
|
libxml_clear_errors();
|
||||||
|
} else {
|
||||||
|
$dom->loadHTML($html);
|
||||||
|
}
|
||||||
$value = (new \DOMXPath($dom))->query($xpath);
|
$value = (new \DOMXPath($dom))->query($xpath);
|
||||||
return $value ?: new \DOMNodeList();
|
return $value ?: new \DOMNodeList();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user