- Ported newsletter rendering engine
This commit is contained in:
41
lib/Newsletter/Blocks/Button.php
Normal file
41
lib/Newsletter/Blocks/Button.php
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<?php namespace MailPoet\Newsletter\Blocks;
|
||||||
|
|
||||||
|
use MailPoet\Newsletter\Blocks\Renderer as BlocksRenderer;
|
||||||
|
|
||||||
|
class Button {
|
||||||
|
|
||||||
|
static function render($element) {
|
||||||
|
$template = '<tr>
|
||||||
|
<td class="mailpoet_col mailpoet_button mailpoet_padded" valign = "top" >
|
||||||
|
<div>
|
||||||
|
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||||
|
<tr>
|
||||||
|
<td align="' . $element['styles']['block']['textAlign'] . '">
|
||||||
|
<!--[if mso]>
|
||||||
|
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml"
|
||||||
|
xmlns:w="urn:schemas-microsoft-com:office:word"
|
||||||
|
href="' . $element['url'] . '"
|
||||||
|
style="height:' . $element['styles']['block']['lineHeight'] . ';width:' . $element['styles']['block']['width'] . ';v-text-anchor:middle;"
|
||||||
|
arcsize="' . round($element['styles']['block']['borderRadius'] / $element['styles']['block']['lineHeight'] * 100) . '%" strokecolor="' . $element['styles']['block']['borderColor'] . '"
|
||||||
|
fillcolor="' . $element['styles']['block']['backgroundColor'] . '">
|
||||||
|
<w:anchorlock/>
|
||||||
|
<center style="color:' . $element['styles']['block']['fontColor'] . ';font-family:' . $element['styles']['block']['fontFamily'] . ';font-size:' . $element['styles']['block']['fontSize'] . ';font-weight:bold;">
|
||||||
|
' . $element['text'] . '
|
||||||
|
</center>
|
||||||
|
</v:roundrect>
|
||||||
|
<![endif]-->
|
||||||
|
<a class="mailpoet_button" href="' . $element['url'] . '"
|
||||||
|
style="display:inline-block;text-align:center;text-decoration:none;-webkit-text-size-adjust:none;mso-hide:all;' . BlocksRenderer::getBlockStyles($element, array('textAlign')) . '">
|
||||||
|
' . $element['text'] . '
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>';
|
||||||
|
|
||||||
|
return $template;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
22
lib/Newsletter/Blocks/Divider.php
Normal file
22
lib/Newsletter/Blocks/Divider.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php namespace MailPoet\Newsletter\Blocks;
|
||||||
|
|
||||||
|
class Divider {
|
||||||
|
|
||||||
|
static function render($element) {
|
||||||
|
$template = '<tr>
|
||||||
|
<td class="mailpoet_col mailpoet_divider mailpoet_padded" style="background-color: ' . $element['styles']['block']['backgroundColor'] . '; padding: ' . $element['styles']['block']['padding'] . ' 0;" valign="top">
|
||||||
|
<table width="100%">
|
||||||
|
<tr>
|
||||||
|
<td style="border-top-width: ' . $element['styles']['block']['borderWidth'] . ';
|
||||||
|
border-top-style: ' . $element['styles']['block']['borderStyle'] . ';
|
||||||
|
border-top-color: ' . $element['styles']['block']['borderColor'] . ';">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>';
|
||||||
|
|
||||||
|
return $template;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
27
lib/Newsletter/Blocks/Footer.php
Normal file
27
lib/Newsletter/Blocks/Footer.php
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php namespace MailPoet\Newsletter\Blocks;
|
||||||
|
|
||||||
|
use MailPoet\Newsletter\Blocks\Renderer as BlocksRenderer;
|
||||||
|
|
||||||
|
class Footer {
|
||||||
|
|
||||||
|
static function render($element) {
|
||||||
|
// apply link styles
|
||||||
|
if(isset($element['styles']['link'])) {
|
||||||
|
$element['text'] = str_replace('<a', '<a style="' . BlocksRenderer::getStyles($element['styles'], 'link') . '"', $element['text']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply text styles
|
||||||
|
if(isset($element['styles']['link'])) {
|
||||||
|
$element['text'] = str_replace('<p', '<p style="' . BlocksRenderer::getStyles($element['styles'], 'text') . '"', $element['text']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$template = '<tr>
|
||||||
|
<td class="mailpoet_col mailpoet_footer" style="' . BlocksRenderer::getStyles($element['styles'], 'block') . '" valign="top">
|
||||||
|
<div>' . $element['text'] . '</div>
|
||||||
|
</td>
|
||||||
|
</tr>';
|
||||||
|
|
||||||
|
return $template;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
27
lib/Newsletter/Blocks/Header.php
Normal file
27
lib/Newsletter/Blocks/Header.php
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php namespace MailPoet\Newsletter\Blocks;
|
||||||
|
|
||||||
|
use MailPoet\Newsletter\Blocks\Renderer as BlocksRenderer;
|
||||||
|
|
||||||
|
class Header {
|
||||||
|
|
||||||
|
static function render($element) {
|
||||||
|
// apply link styles
|
||||||
|
if(isset($element['styles']['link'])) {
|
||||||
|
$element['text'] = str_replace('<a', '<a style="' . BlocksRenderer::getStyles($element['styles'], 'link') . '"', $element['text']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply text styles
|
||||||
|
if(isset($element['styles']['link'])) {
|
||||||
|
$element['text'] = str_replace('<p', '<p style="' . BlocksRenderer::getStyles($element['styles'], 'text') . '"', $element['text']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$template = '<tr>
|
||||||
|
<td class="mailpoet_col mailpoet_header" style="' . BlocksRenderer::getBlockStyles($element) . '" valign="top">
|
||||||
|
<div>' . $element['text'] . '</div>
|
||||||
|
</td>
|
||||||
|
</tr>';
|
||||||
|
|
||||||
|
return $template;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
19
lib/Newsletter/Blocks/Image.php
Normal file
19
lib/Newsletter/Blocks/Image.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?php namespace MailPoet\Newsletter\Blocks;
|
||||||
|
|
||||||
|
use MailPoet\Newsletter\Blocks\Renderer as BlocksRenderer;
|
||||||
|
|
||||||
|
class Image {
|
||||||
|
|
||||||
|
static function render($element) {
|
||||||
|
$element['width'] = (int) $element['width'];
|
||||||
|
|
||||||
|
$template = '<tr>
|
||||||
|
<td class="mailpoet_col mailpoet_image ' . (($element['padded'] === true) ? "mailpoet_padded" : "") . '" style="' . BlocksRenderer::getBlockStyles($element) . '" valign="top">
|
||||||
|
<img style="top:0; left:0; height: auto; width:100%;" src="' . $element['src'] . '" width="' . (($element['padded'] === true) ? $element['width'] - (20 * 2) : $element['width']) . '">
|
||||||
|
</td>
|
||||||
|
</tr>';
|
||||||
|
|
||||||
|
return $template;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
107
lib/Newsletter/Blocks/Renderer.php
Normal file
107
lib/Newsletter/Blocks/Renderer.php
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
<?php namespace MailPoet\Newsletter\Blocks;
|
||||||
|
|
||||||
|
class Renderer {
|
||||||
|
|
||||||
|
static $typeFace = array(
|
||||||
|
'Arial' => "Arial, 'Helvetica Neue', Helvetica, sans-serif",
|
||||||
|
'Comic Sans MS' => "'Comic Sans MS', 'Marker Felt-Thin', Arial, sans-serif",
|
||||||
|
'Courier New' => "'Courier New', Courier, 'Lucida Sans Typewriter', 'Lucida Typewriter', monospace",
|
||||||
|
'Georgia' => "Georgia, Times, 'Times New Roman', serif",
|
||||||
|
'Lucida' => "'Lucida Sans Unicode', 'Lucida Grande', sans-serif",
|
||||||
|
'Tahoma' => "Tahoma, Verdana, Segoe, sans-serif",
|
||||||
|
'Times New Roman' => "'Times New Roman', Times, Baskerville, Georgia, serif",
|
||||||
|
'Trebuchet MS' => "'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, sans-serif",
|
||||||
|
'Verdana' => "Verdana, Geneva, sans-serif"
|
||||||
|
);
|
||||||
|
|
||||||
|
static $cssAtributesTable = array(
|
||||||
|
'backgroundColor' => 'background-color',
|
||||||
|
'fontColor' => 'color',
|
||||||
|
'fontFamily' => 'font-family',
|
||||||
|
'textDecoration' => 'text-decoration',
|
||||||
|
'textAlign' => 'text-align',
|
||||||
|
'fontSize' => 'font-size',
|
||||||
|
'borderWidth' => 'border-width',
|
||||||
|
'borderStyle' => 'border-style',
|
||||||
|
'borderColor' => 'border-color',
|
||||||
|
'borderRadius' => 'border-radius',
|
||||||
|
'lineHeight' => 'line-height'
|
||||||
|
);
|
||||||
|
|
||||||
|
static function render($data, $column = null) {
|
||||||
|
$blockContent = '';
|
||||||
|
$blockCount = count($data['blocks']);
|
||||||
|
|
||||||
|
foreach ($data['blocks'] as $i => $block) {
|
||||||
|
$blockContent .= self::createElementFromBlockType($block);
|
||||||
|
if(isset($block['blocks']) && is_array($block['blocks'])) {
|
||||||
|
$blockContent = self::render($block);
|
||||||
|
}
|
||||||
|
|
||||||
|
// vertical orientation denotes column container
|
||||||
|
if($block['type'] == 'container' && $block['orientation'] == 'vertical') {
|
||||||
|
$columns[] = $blockContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (isset($columns)) ? $columns : $blockContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function createElementFromBlockType($block) {
|
||||||
|
switch ($block['type']) {
|
||||||
|
case 'header':
|
||||||
|
$element = Header::render($block);
|
||||||
|
break;
|
||||||
|
case 'image':
|
||||||
|
$element = Image::render($block);
|
||||||
|
break;
|
||||||
|
case 'text':
|
||||||
|
$element = Text::render($block);
|
||||||
|
break;
|
||||||
|
case 'button':
|
||||||
|
$element = Button::render($block);
|
||||||
|
break;
|
||||||
|
case 'divider':
|
||||||
|
$element = Divider::render($block);
|
||||||
|
break;
|
||||||
|
case 'spacer':
|
||||||
|
$element = Spacer::render($block);
|
||||||
|
break;
|
||||||
|
case 'social':
|
||||||
|
$element = Social::render($block);
|
||||||
|
break;
|
||||||
|
case 'footer':
|
||||||
|
$element = Footer::render($block);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$element = '';//'UNRECOGNIZED ELEMENT';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $element;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function getBlockStyles($element, $ignore = false) {
|
||||||
|
if(!isset($element['styles']['block'])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::getStyles($element['styles'], 'block', $ignore);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function getStyles($styles, $type, $ignore = false) {
|
||||||
|
$css = '';
|
||||||
|
foreach ($styles[$type] as $attribute => $style) {
|
||||||
|
if($ignore && in_array($attribute, $ignore)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$css .= self::translateCSSAttribute($attribute) . ': ' . $style . ' !important;';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $css;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function translateCSSAttribute($attribute) {
|
||||||
|
return (isset(self::$cssAtributesTable[$attribute])) ? self::$cssAtributesTable[$attribute] : $attribute;
|
||||||
|
}
|
||||||
|
}
|
23
lib/Newsletter/Blocks/Social.php
Normal file
23
lib/Newsletter/Blocks/Social.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php namespace MailPoet\Newsletter\Blocks;
|
||||||
|
|
||||||
|
class Social {
|
||||||
|
|
||||||
|
static function render($element) {
|
||||||
|
$iconsBlock = '';
|
||||||
|
if(is_array($element['icons'])) {
|
||||||
|
foreach ($element['icons'] as $icon) {
|
||||||
|
$iconsBlock .= '<a href="' . $icon['link'] . '"><img src="' . $icon['image'] . '" width = "32" height = "32" style="width: 32px; height: 32px;" alt="' . $icon['iconType'] . '"></a><img src="http://mp3.mailpoet.net/spacer.gif" width = "10" height = "1" style=" width: 10px; height: 1px;">';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$template = '<tr>
|
||||||
|
<td class="mailpoet_col mailpoet_social" valign="top">
|
||||||
|
<div class="mailpoet_social-icon mailpoet_padded">
|
||||||
|
' . $iconsBlock . '
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>';
|
||||||
|
|
||||||
|
return $template;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
22
lib/Newsletter/Blocks/Spacer.php
Normal file
22
lib/Newsletter/Blocks/Spacer.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php namespace MailPoet\Newsletter\Blocks;
|
||||||
|
|
||||||
|
use MailPoet\Newsletter\Blocks\Renderer as BlocksRenderer;
|
||||||
|
|
||||||
|
class Spacer {
|
||||||
|
|
||||||
|
static function render($element) {
|
||||||
|
// if the parent container (column) has background set and the divider element has a transparent background,
|
||||||
|
// it will assume the newsletter background, not that of the parent container
|
||||||
|
if($element['styles']['block']['backgroundColor'] === 'transparent') {
|
||||||
|
unset($element['styles']['block']['backgroundColor']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$template = '<tr>
|
||||||
|
<td class="mailpoet_col mailpoet_spacer" style="' . BlocksRenderer::getBlockStyles($element) . '" valign="top">
|
||||||
|
</td>
|
||||||
|
</tr>';
|
||||||
|
|
||||||
|
return $template;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
74
lib/Newsletter/Blocks/Text.php
Normal file
74
lib/Newsletter/Blocks/Text.php
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<?php namespace MailPoet\Newsletter\Blocks;
|
||||||
|
|
||||||
|
class Text {
|
||||||
|
|
||||||
|
static function render($element) {
|
||||||
|
// convert <blockquote> elements to tables
|
||||||
|
$blockquoteTemplate = '<table cellpadding="0" cellspacing="0" border="0" class="mailpoet_blockquote">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td valign="top">
|
||||||
|
$1
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<br>';
|
||||||
|
$element['text'] = preg_replace('/<blockquote>(.*?)<\/blockquote>/s', $blockquoteTemplate, $element['text']);
|
||||||
|
|
||||||
|
// add line breaks after tags
|
||||||
|
$element['text'] = preg_replace('/(<\/(ul|ol|h\d)>)/', '$1<br>', $element['text']);
|
||||||
|
|
||||||
|
$element['text'] = self::removeEmptyHTMLTags($element['text']);
|
||||||
|
|
||||||
|
// convert empty <p> tags to line breaks
|
||||||
|
$element['text'] = preg_replace('/<p(?:.+style=\".*?\")?><\/p>/', '<br>', $element['text']);
|
||||||
|
|
||||||
|
// convert <p> to <span>
|
||||||
|
$element['text'] = preg_replace('/<p>(.*?)<\/p>/', '<table cellpadding="0" cellspacing="0" border="0"><tr><td><span class="paragraph">$1</span></td></tr></table>', $element['text']);
|
||||||
|
$element['text'] = preg_replace('/<p(.+style=\".*?\")?>(.*?)<\/p>/', '<table cellpadding="0" cellspacing="0" border="0"><tr><td $1><span class="paragraph">$2</span></td></tr></table>', $element['text']);
|
||||||
|
|
||||||
|
// remove the last break line
|
||||||
|
$element['text'] = preg_replace('/<br>([^<br>]*)$/s', '', $element['text']);
|
||||||
|
|
||||||
|
$template = '<tr>
|
||||||
|
<td class="mailpoet_col mailpoet_text mailpoet_padded" valign="top">
|
||||||
|
' . $element['text'] . '
|
||||||
|
</td>
|
||||||
|
</tr>';
|
||||||
|
|
||||||
|
return $template;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function removeEmptyHTMLTags($html) {
|
||||||
|
$pattern = <<<'EOD'
|
||||||
|
~
|
||||||
|
<
|
||||||
|
(?:
|
||||||
|
!--[^-]*(?:-(?!->)[^-]*)*-->[^<]*(*SKIP)(*F) # skip comments
|
||||||
|
|
|
||||||
|
( # group 1
|
||||||
|
(span|em|strong) # tag name in group 2
|
||||||
|
[^"'>]* #'"# all that is not a quote or a closing angle bracket
|
||||||
|
(?: # quoted attributes
|
||||||
|
"[^\\"]*(?:\\.[^\\"]*)*+" [^"'>]* #'"# double quote
|
||||||
|
|
|
||||||
|
'[^\\']*(?:\\.[^\\']*)*+' [^"'>]* #'"# single quote
|
||||||
|
)*+
|
||||||
|
>
|
||||||
|
\s*
|
||||||
|
(?:
|
||||||
|
<!--[^-]*(?:-(?!->)[^-]*)*+--> \s* # html comments
|
||||||
|
|
|
||||||
|
<(?1) \s* # recursion with the group 1
|
||||||
|
)*+
|
||||||
|
</\2> # closing tag
|
||||||
|
) # end of the group 1
|
||||||
|
)
|
||||||
|
~sxi
|
||||||
|
EOD;
|
||||||
|
|
||||||
|
return preg_replace($pattern, '', $html);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
65
lib/Newsletter/Columns/Renderer.php
Normal file
65
lib/Newsletter/Columns/Renderer.php
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<?php namespace MailPoet\Newsletter\Columns;
|
||||||
|
|
||||||
|
class Renderer {
|
||||||
|
|
||||||
|
static function render($columnsCount, $columnsData) {
|
||||||
|
$columnWidths = array(
|
||||||
|
1 => 600,
|
||||||
|
2 => 300,
|
||||||
|
3 => 200
|
||||||
|
);
|
||||||
|
$columnClasses = array(
|
||||||
|
1 => 'mailpoet_col-one',
|
||||||
|
2 => 'mailpoet_col-two',
|
||||||
|
3 => 'mailpoet_col-three'
|
||||||
|
);
|
||||||
|
$columnWidth = $columnWidths[$columnsCount];
|
||||||
|
$columnClass = $columnClasses[$columnsCount];
|
||||||
|
|
||||||
|
// open column container
|
||||||
|
$columnContainerTemplate = '<tr>
|
||||||
|
<td class="mailpoet_content" align="left" style="border-collapse: collapse;">
|
||||||
|
<table width="100%" border="0" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="mailpoet_cols-wrapper" style="border-collapse: collapse; padding-left: 0px; padding-right: 0px;">
|
||||||
|
<!--[if mso]>
|
||||||
|
<table border="0" width="100%" cellpadding="0" cellspacing="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td width="' . $columnWidth . '" style="width: ' . $columnWidth . 'px;" valign="top">
|
||||||
|
<![endif]-->';
|
||||||
|
$columnOpenTemplate = '<table width="' . $columnWidth . '" border="0" cellpadding="0" cellspacing="0" align="left" class="mailpoet_force-row ' . $columnClass . ' mailpoet_col" style="width: ' . $columnWidth . 'px; border-spacing: 0; mso-table-lspace: 0pt; mso-table-rspace: 0pt; table-layout: fixed; margin-left: auto; margin-right: auto;" bgcolor="#999999"><tbody>';
|
||||||
|
$columnCloseTemplate = '</tbody></table>
|
||||||
|
<!--[if mso]>
|
||||||
|
</td>
|
||||||
|
<td width="' . $columnWidth . '" style="width: ' . $columnWidth . 'px;" valign="top">
|
||||||
|
<![endif]-->';
|
||||||
|
|
||||||
|
foreach ($columnsData as $index => $columnData) {
|
||||||
|
$index++;
|
||||||
|
$columnContainerTemplate .= $columnOpenTemplate . $columnData;
|
||||||
|
if($columnsCount > 1 && $index != $columnsCount) {
|
||||||
|
$columnContainerTemplate .= $columnCloseTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// close column container
|
||||||
|
$columnContainerTemplate .= ' </tbody>
|
||||||
|
</table>
|
||||||
|
<!--[if mso]>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<![endif]-->
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>';
|
||||||
|
|
||||||
|
return $columnContainerTemplate;
|
||||||
|
}
|
||||||
|
}
|
1
lib/Newsletter/NewsletterData.json
Normal file
1
lib/Newsletter/NewsletterData.json
Normal file
File diff suppressed because one or more lines are too long
266
lib/Newsletter/NewsletterTemplate.html
Normal file
266
lib/Newsletter/NewsletterTemplate.html
Normal file
@@ -0,0 +1,266 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="format-detection" content="telephone=no">
|
||||||
|
<title>MailPoet Newsletter Template</title>
|
||||||
|
</head>
|
||||||
|
<body style="-ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; mso-line-height-rule: exactly; font-family: Helvetica, Arial, sans-serif; text-align: left; color: #333333; margin: 0; padding: 0;"
|
||||||
|
bgcolor="#F0F0F0" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
-ms-text-size-adjust: 100%;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
mso-line-height-rule: exactly;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
p,
|
||||||
|
ol,
|
||||||
|
ul,
|
||||||
|
li {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol,
|
||||||
|
ul,
|
||||||
|
li {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ExternalClass {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ExternalClass,
|
||||||
|
.ExternalClass p,
|
||||||
|
.ExternalClass span,
|
||||||
|
.ExternalClass font,
|
||||||
|
.ExternalClass td,
|
||||||
|
.ExternalClass div {
|
||||||
|
line-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ReadMsgBody {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #ebebeb;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-spacing: 0;
|
||||||
|
mso-table-lspace: 0pt;
|
||||||
|
mso-table-rspace: 0pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td {
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
-ms-interpolation-mode: bicubic;
|
||||||
|
margin: 0;
|
||||||
|
border: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.mailpoet_button, .mailpoet_image, .mailpoet_text, .mailpoet_social {
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_button div {
|
||||||
|
padding: 8px 0 8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yshortcuts a {
|
||||||
|
border-bottom: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_container {
|
||||||
|
width: 600px;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_col,
|
||||||
|
.mailpoet_cols-wrapper {
|
||||||
|
padding-left: 0px;
|
||||||
|
padding-right: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_col-one,
|
||||||
|
.mailpoet_col-two,
|
||||||
|
.mailpoet_col-three {
|
||||||
|
table-layout: fixed;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_col-one,
|
||||||
|
.mailpoet_col-two,
|
||||||
|
.mailpoet_col-three,
|
||||||
|
.mailpoet_header,
|
||||||
|
.mailpoet_footer {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_footer div, .mailpoet_header div {
|
||||||
|
margin: 5px 0 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .mailpoet_col-one ol,*/
|
||||||
|
.mailpoet_col-one ul {
|
||||||
|
margin-left: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*.mailpoet_col-two ol,*/
|
||||||
|
.mailpoet_col-two ul {
|
||||||
|
margin-left: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_col-two li {
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*.mailpoet_col-three ol,*/
|
||||||
|
.mailpoet_col-three ul {
|
||||||
|
margin-left: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_col-three li {
|
||||||
|
padding-left: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_content-wrapper a {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_padded {
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
word-break: break-word;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_centered {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_justify {
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_blockquote {
|
||||||
|
border-left: 2px #565656 solid;
|
||||||
|
padding-left: 10px;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_blockquote p.mailpoet_signature {
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_social {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_social img {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_social div {
|
||||||
|
padding: 5px 0 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ios-footer a {
|
||||||
|
color: #aaaaaa !important;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 400px) and (-webkit-min-device-pixel-ratio: 1) {
|
||||||
|
[class="mailpoet_cols-wrapper"] {
|
||||||
|
padding-left: 0 !important;
|
||||||
|
padding-right: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 599px) and (-webkit-min-device-pixel-ratio: 1) {
|
||||||
|
[class~="mailpoet_force-row"],
|
||||||
|
[class="mailpoet_container"] {
|
||||||
|
width: 100% !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
a[class="mailpoet_button"] {
|
||||||
|
width: 100% !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
padding: 5px 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
td[class="mailpoet_col"] {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class=mailpoet_wrapper] ol,
|
||||||
|
[class=mailpoet_wrapper] ul {
|
||||||
|
margin-left: 18px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class=mailpoet_wrapper] li {
|
||||||
|
padding-left: 2px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_social img {
|
||||||
|
height: 32x !important;
|
||||||
|
width: 32px !important;
|
||||||
|
padding-bottom: 20px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{{newsletter_editor_styles}}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<table border="0" width="100%" height="100%" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td align="center" class="mailpoet_content-wrapper" valign="top" style="border-collapse:collapse;" bgcolor="#333333">
|
||||||
|
|
||||||
|
<table border="0" width="600" cellpadding="0" cellspacing="0" class="mailpoet_container" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;max-width:600px">
|
||||||
|
<tbody>
|
||||||
|
{{newsletter_editor_content}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
89
lib/Newsletter/Renderer.php
Normal file
89
lib/Newsletter/Renderer.php
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Newsletter;
|
||||||
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
class Renderer {
|
||||||
|
|
||||||
|
public $template = 'NewsletterTemplate.html';
|
||||||
|
|
||||||
|
function __construct($newsletterData) {
|
||||||
|
$this->data = $newsletterData;
|
||||||
|
$this->template = file_get_contents(dirname(__FILE__) . '/' . $this->template);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderAll() {
|
||||||
|
$newsletterContent = $this->renderContent($this->data['data']);
|
||||||
|
$newsletterStyles = $this->renderStyles($this->data['styles']);
|
||||||
|
|
||||||
|
$renderedTemplate = $this->renderTemplate($this->template, array(
|
||||||
|
$newsletterStyles,
|
||||||
|
$newsletterContent
|
||||||
|
));
|
||||||
|
$renderedTemplateWithInlinedStyles = $this->inlineCSSStyles($renderedTemplate);
|
||||||
|
|
||||||
|
return $this->postProcessRenderedTemplate($renderedTemplateWithInlinedStyles);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderContent($content) {
|
||||||
|
$newsletterContent = '';
|
||||||
|
foreach ($content['blocks'] as $contentBlock) {
|
||||||
|
if(isset($contentBlock['blocks']) && is_array($contentBlock['blocks'])) {
|
||||||
|
$columnCount = count($contentBlock['blocks']);
|
||||||
|
$columnData = Blocks\Renderer::render($contentBlock);
|
||||||
|
$newsletterContent .= Columns\Renderer::render($columnCount, $columnData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $newsletterContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderStyles($styles) {
|
||||||
|
$newsletterStyles = '';
|
||||||
|
foreach ($styles as $selector => $style) {
|
||||||
|
switch ($selector) {
|
||||||
|
case 'text':
|
||||||
|
$selector = 'span.paragraph, ul, ol';
|
||||||
|
break;
|
||||||
|
case 'background':
|
||||||
|
$selector = '.mailpoet_content-wrapper';
|
||||||
|
break;
|
||||||
|
case 'link':
|
||||||
|
$selector = '.mailpoet_content-wrapper a';
|
||||||
|
break;
|
||||||
|
case 'newsletter':
|
||||||
|
$selector = '.mailpoet_container, .mailpoet_col-one, .mailpoet_col-two, .mailpoet_col-three';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$newsletterStyles .= $selector . '{' . PHP_EOL;
|
||||||
|
foreach ($style as $attribute => $individualStyle) {
|
||||||
|
$newsletterStyles .= Blocks\Renderer::translateCSSAttribute($attribute) . ':' . $individualStyle . ';' . PHP_EOL;
|
||||||
|
}
|
||||||
|
$newsletterStyles .= '}' . PHP_EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $newsletterStyles;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderTemplate($template, $data) {
|
||||||
|
return preg_replace_callback('/{{\w+}}/', function ($matches) use (&$data) {
|
||||||
|
return array_shift($data);
|
||||||
|
}, $template);
|
||||||
|
}
|
||||||
|
|
||||||
|
function inlineCSSStyles($template) {
|
||||||
|
$inliner = new \MailPoet\Util\CSS();
|
||||||
|
|
||||||
|
return $inliner->inlineCSS(null, $template);
|
||||||
|
}
|
||||||
|
|
||||||
|
function postProcessRenderedTemplate($template) {
|
||||||
|
// remove padding from last element inside each column
|
||||||
|
$DOM = \pQuery::parseStr($template);
|
||||||
|
$lastColumnElement = $DOM->query('.mailpoet_col > tbody > tr:last-child > td');
|
||||||
|
foreach ($lastColumnElement as $element) {
|
||||||
|
$element->setAttribute('style', str_replace('padding-bottom:20px;', '', $element->attributes['style']));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $DOM->__toString();
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user