Skip to content
Snippets Groups Projects
Commit 310a2804 authored by Piotr Potrebka's avatar Piotr Potrebka
Browse files

feat: email abstract

parent 867d3d33
No related branches found
No related tags found
1 merge request!2Devel
Pipeline #152602 passed with stages
in 58 seconds
...@@ -6,7 +6,6 @@ use WPDesk\View\Renderer\Renderer; ...@@ -6,7 +6,6 @@ use WPDesk\View\Renderer\Renderer;
interface ConditionInterface { interface ConditionInterface {
public function is_valid(): bool; public function is_valid(): bool;
} }
<?php <?php
namespace WPDesk\Library\WPEmail\Parser; namespace WPDesk\Library\WPEmail\Helpers;
use Pelago\Emogrifier\CssInliner; use Pelago\Emogrifier\CssInliner;
use Pelago\Emogrifier\HtmlProcessor\CssToAttributeConverter; use Pelago\Emogrifier\HtmlProcessor\CssToAttributeConverter;
use Pelago\Emogrifier\HtmlProcessor\HtmlPruner; use Pelago\Emogrifier\HtmlProcessor\HtmlPruner;
class HTMLDecorator { class HTML {
public static function style_inline( $content, $styles = '' ) { public static function style_inline( $content, $styles = '' ) {
if ( class_exists( 'DOMDocument' ) ) { if ( class_exists( 'DOMDocument' ) ) {
......
<?php
namespace WPDesk\Library\WPEmail\Helpers;
class Template {
/**
* Determine whether a hex color is light.
*
* @param mixed $color Color.
*
* @return bool True if a light color.
*/
public static function is_hex_light( $color ) {
$hex = str_replace( '#', '', $color );
$c_r = hexdec( substr( $hex, 0, 2 ) );
$c_g = hexdec( substr( $hex, 2, 2 ) );
$c_b = hexdec( substr( $hex, 4, 2 ) );
$brightness = ( ( $c_r * 299 ) + ( $c_g * 587 ) + ( $c_b * 114 ) ) / 1000;
return $brightness > 155;
}
public static function light_or_dark( $color, $dark = '#000000', $light = '#FFFFFF' ) {
return self::is_hex_light( $color ) ? $dark : $light;
}
/**
* Convert RGB to HEX.
*
* @param mixed $color Color.
*
* @return array
*/
public static function rgb_from_hex( $color ) {
$color = str_replace( '#', '', $color );
// Convert shorthand colors to full format, e.g. "FFF" -> "FFFFFF".
$color = preg_replace( '~^(.)(.)(.)$~', '$1$1$2$2$3$3', $color );
$rgb = [];
$rgb['R'] = hexdec( $color[0] . $color[1] );
$rgb['G'] = hexdec( $color[2] . $color[3] );
$rgb['B'] = hexdec( $color[4] . $color[5] );
return $rgb;
}
/**
* Make HEX color darker.
*
* @param mixed $color Color.
* @param int $factor Darker factor.
* Defaults to 30.
*
* @return string
*/
public static function hex_darker( $color, $factor = 30 ) {
$base = self::rgb_from_hex( $color );
$color = '#';
foreach ( $base as $k => $v ) {
$amount = $v / 100;
$amount = self::round( $amount * $factor );
$new_decimal = $v - $amount;
$new_hex_component = dechex( $new_decimal );
if ( strlen( $new_hex_component ) < 2 ) {
$new_hex_component = '0' . $new_hex_component;
}
$color .= $new_hex_component;
}
return $color;
}
/**
* Make HEX color lighter.
*
* @param mixed $color Color.
* @param int $factor Lighter factor.
* Defaults to 30.
*
* @return string
*/
public static function hex_lighter( $color, $factor = 30 ) {
$base = self::rgb_from_hex( $color );
$color = '#';
foreach ( $base as $k => $v ) {
$amount = 255 - $v;
$amount = $amount / 100;
$amount = self::round( $amount * $factor );
$new_decimal = $v + $amount;
$new_hex_component = dechex( $new_decimal );
if ( strlen( $new_hex_component ) < 2 ) {
$new_hex_component = '0' . $new_hex_component;
}
$color .= $new_hex_component;
}
return $color;
}
/**
* @param $val
* @param int $precision
* @param int $mode
*
* @return float
*/
public static function round( $val, int $precision = 0, int $mode = PHP_ROUND_HALF_UP ): float {
if ( ! is_numeric( $val ) ) {
$val = floatval( $val );
}
return round( $val, $precision, $mode );
}
}
...@@ -3,14 +3,14 @@ ...@@ -3,14 +3,14 @@
namespace WPDesk\Library\WPEmail; namespace WPDesk\Library\WPEmail;
use WPDesk\Library\WPEmail\Abstracts\EmailInterface; use WPDesk\Library\WPEmail\Abstracts\EmailInterface;
use WPDesk\Library\WPEmail\Parser\HTMLDecorator; use WPDesk\Library\WPEmail\Helpers\HTML;
use WPDesk\View\Renderer\Renderer; use WPDesk\View\Renderer\Renderer;
use WPDesk\View\Renderer\SimplePhpRenderer; use WPDesk\View\Renderer\SimplePhpRenderer;
use WPDesk\View\Resolver\ChainResolver; use WPDesk\View\Resolver\ChainResolver;
use WPDesk\View\Resolver\DirResolver; use WPDesk\View\Resolver\DirResolver;
use WPDesk\View\Resolver\WPThemeResolver; use WPDesk\View\Resolver\Resolver;
class EmailSender { class Mailer {
/** /**
* @var EmailInterface[] * @var EmailInterface[]
...@@ -20,12 +20,12 @@ class EmailSender { ...@@ -20,12 +20,12 @@ class EmailSender {
/** /**
* @var string * @var string
*/ */
private $from = 'wordpress@wordpress.org'; private $from;
/** /**
* @var string * @var string
*/ */
private $from_name = 'WordPress'; private $from_name;
/** /**
* @var Renderer * @var Renderer
...@@ -33,36 +33,89 @@ class EmailSender { ...@@ -33,36 +33,89 @@ class EmailSender {
private $renderer; private $renderer;
/** /**
* @param $from * @var array
* @param $from_name
*/ */
public function __construct() { protected $placeholders = [];
$this->init_renderer();
/**
* @param string $from
* @param string $from_name
* @param Resolver[] $dir_resolvers
*/
public function __construct(
string $from = 'wordpress@wordpress.org',
string $from_name = 'WordPress',
array $dir_resolvers = []
) {
$this->from = $from;
$this->from_name = $from_name;
$this->set_renderer( $this->init_renderer( $dir_resolvers ) );
} }
public function init_renderer() { /**
* @param array $dir_resolvers
*
* @return Renderer
*/
private function init_renderer( array $dir_resolvers ): Renderer {
$resolver = new ChainResolver(); $resolver = new ChainResolver();
foreach ( $dir_resolvers as $dir_resolver ) {
if ( $dir_resolver instanceof Resolver ) {
$resolver->appendResolver( $dir_resolver );
}
}
$resolver->appendResolver( new DirResolver( __DIR__ ) ); $resolver->appendResolver( new DirResolver( __DIR__ ) );
$this->renderer = new SimplePhpRenderer( $resolver ); return new SimplePhpRenderer( $resolver );
} }
/**
* @param Renderer $renderer
*
* @return void
*/
public function set_renderer( Renderer $renderer ) { public function set_renderer( Renderer $renderer ) {
$this->renderer = $renderer; $this->renderer = $renderer;
} }
/**
* @param EmailInterface $email
*
* @return void
*/
public function add_email( EmailInterface $email ) { public function add_email( EmailInterface $email ) {
$this->emails[ $email->get_id() ] = $email; $this->emails[ $email->get_id() ] = $email;
} }
/**
* @return EmailInterface[]
*/
public function get_emails(): array { public function get_emails(): array {
return $this->emails; return $this->emails;
} }
public function set_from( string $from ) {
$this->from = $from; /**
* Set placeholders.
*
* @param array $placeholders
*
* @return self
*/
public function set_placeholders( array $placeholders = [] ): self {
$this->placeholders = array_merge( $this->placeholders, $placeholders );
return $this;
} }
/**
* Get defined placeholders.
*
* @return string[]
*/
public function get_placeholders(): array {
return $this->placeholders;
}
/** /**
* WordPress callback for setting the from email * WordPress callback for setting the from email
...@@ -71,7 +124,7 @@ class EmailSender { ...@@ -71,7 +124,7 @@ class EmailSender {
* *
* @return string * @return string
*/ */
public function from( $email ): string { public function from_filter( string $email ): string {
if ( ! empty( $this->from ) && is_email( $this->from ) ) { if ( ! empty( $this->from ) && is_email( $this->from ) ) {
$email = $this->from; $email = $this->from;
} }
...@@ -80,11 +133,6 @@ class EmailSender { ...@@ -80,11 +133,6 @@ class EmailSender {
} }
public function set_from_name( string $from_name ) {
$this->from_name = $from_name;
}
/** /**
* WordPress callback for setting the from name * WordPress callback for setting the from name
* *
...@@ -92,7 +140,7 @@ class EmailSender { ...@@ -92,7 +140,7 @@ class EmailSender {
* *
* @return string * @return string
*/ */
public function from_name( $name ) { public function from_name_filter( string $name ): string {
if ( ! empty( $this->from_name ) ) { if ( ! empty( $this->from_name ) ) {
$name = html_entity_decode( sanitize_text_field( $this->from_name ) ); $name = html_entity_decode( sanitize_text_field( $this->from_name ) );
} }
...@@ -105,41 +153,40 @@ class EmailSender { ...@@ -105,41 +153,40 @@ class EmailSender {
* *
* @return void * @return void
*/ */
private function before_wp_mail() { protected function before_wp_mail() {
add_filter( 'wp_mail_from', array( $this, 'from' ) ); add_filter( 'wp_mail_from', array( $this, 'from_filter' ) );
add_filter( 'wp_mail_from_name', array( $this, 'from_name' ) ); add_filter( 'wp_mail_from_name', array( $this, 'from_name_filter' ) );
} }
public function send( array $placeholders = [] ) { public function send() {
$this->before_wp_mail();
foreach ( $this->get_emails() as $email ) { foreach ( $this->get_emails() as $email ) {
$template = $this->get_template( $email, $placeholders ); $subject = $this->replace_placeholders( $email->get_subject() );
if ( $email->get_is_enable() ) { if ( $email->get_is_enable() ) {
$this->before_wp_mail();
wp_mail( wp_mail(
$email->get_recipients(), $email->get_subject(), $this->css_inline( $template ), $email->get_headers(), $email->get_attachments() $email->get_recipients(), $subject, $this->get_body( $email ), $email->get_headers(), $email->get_attachments()
); );
$this->after_wp_mail();
} }
} }
$this->after_wp_mail();
} }
public function get_template( EmailInterface $email, $placeholders = [] ): string { protected function get_body( EmailInterface $email ): string {
$content = $this->replace_placeholders( $email->get_content(), $placeholders ); $content = $this->replace_placeholders( $email->get_content() );
$output = $this->renderer->render( 'html/email-header', [ 'heading' => $email->get_heading(), 'logo' => '' ] ); $output = $this->renderer->render( 'html/email-header', [ 'heading' => $email->get_heading(), 'logo' => '' ] );
$output .= $this->renderer->render( 'html/' . $email->get_id(), [ 'content' => $content ] ); $output .= $this->renderer->render( 'html/' . $email->get_id(), [ 'content' => $content ] );
$output .= $this->renderer->render( 'html/email-footer', [] ); $output .= $this->renderer->render( 'html/email-footer', [ 'footer' => '' ] );
return $output; return $this->css_inline( $output );
} }
/** /**
* @param string $content * @param string $string
* @param array $placeholders
* *
* @return array|string|string[] * @return array|string|string[]
*/ */
private function replace_placeholders( string $content, array $placeholders = [] ): string { protected function replace_placeholders( string $string ): string {
return str_replace( array_keys( $placeholders ), array_values( $placeholders ), $content ); return (string) str_replace( array_keys( $this->placeholders ), array_values( $this->placeholders ), $string );
} }
/** /**
...@@ -147,10 +194,10 @@ class EmailSender { ...@@ -147,10 +194,10 @@ class EmailSender {
* *
* @return mixed|string * @return mixed|string
*/ */
private function css_inline( string $content ): string { protected function css_inline( string $content ): string {
$styles = $this->renderer->render( 'html/email-styles', [] ); $styles = $this->renderer->render( 'html/email-styles', [] );
return HTMLDecorator::style_inline( $content, $styles ); return HTML::style_inline( $content, $styles );
} }
/** /**
...@@ -158,9 +205,9 @@ class EmailSender { ...@@ -158,9 +205,9 @@ class EmailSender {
* *
* @return void * @return void
*/ */
private function after_wp_mail() { protected function after_wp_mail() {
remove_filter( 'wp_mail_from', array( $this, 'from' ) ); remove_filter( 'wp_mail_from', array( $this, 'from_filter' ) );
remove_filter( 'wp_mail_from_name', array( $this, 'from_name' ) ); remove_filter( 'wp_mail_from_name', array( $this, 'from_name_filter' ) );
} }
} }
<?php
declare( strict_types=1 );
namespace WPDesk\Library\WPEmail;
class MailerException extends \RuntimeException {
public static function with_wp_error( \WP_Error $error ): self {
$errors = $error->get_error_messages( 'wp_mail_failed' );
$message = implode( "\n", $errors );
return new self( sprintf( 'wp_mail() failure. Message [%s]', $message ) );
}
}
...@@ -40,7 +40,7 @@ defined( 'ABSPATH' ) || exit; ...@@ -40,7 +40,7 @@ defined( 'ABSPATH' ) || exit;
<table border="0" cellpadding="10" cellspacing="0" width="100%"> <table border="0" cellpadding="10" cellspacing="0" width="100%">
<tr> <tr>
<td colspan="2" valign="middle" id="credit"> <td colspan="2" valign="middle" id="credit">
<?php echo wp_kses_post( wpautop( wptexturize( apply_filters( 'wpdesk/wp_mail/template/footer', '' ) ) ) ); ?> <?php echo $params['footer'] ?? ''; ?>
</td> </td>
</tr> </tr>
</table> </table>
......
...@@ -47,7 +47,7 @@ $params = isset( $params ) ? $params : []; ...@@ -47,7 +47,7 @@ $params = isset( $params ) ? $params : [];
<table border="0" cellpadding="0" cellspacing="0" width="100%" id="template_header"> <table border="0" cellpadding="0" cellspacing="0" width="100%" id="template_header">
<tr> <tr>
<td id="header_wrapper"> <td id="header_wrapper">
<h1><?php echo $params['heading']; ?></h1> <h1><?php echo $params['heading'] ?? 'Header'; ?></h1>
</td> </td>
</tr> </tr>
</table> </table>
......
<?php <?php
/**
* Email Styles use WPDesk\Library\WPEmail\Helpers\Template;
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/email-styles.php. $params = isset( $params ) ? $params : [];
*
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see https://docs.woocommerce.com/document/template-structure/
* @package WooCommerce\Templates\Emails
* @version 4.0.0
*/
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
// Load colors. // Load colors.
$bg = get_option( 'woocommerce_email_background_color' ); $bg = $params['bg'] ?? '#f9f9f9';
$body = get_option( 'woocommerce_email_body_background_color' ); $body = $params['body'] ?? '#ffffff';
$base = get_option( 'woocommerce_email_base_color' ); $base = $params['base'] ?? '#d15291';
$base_text = wc_light_or_dark( $base, '#202020', '#ffffff' ); $base_text = Template::light_or_dark( $base, '#171717', '#ffffff' );
$text = get_option( 'woocommerce_email_text_color' ); $text = $params['text'] ?? '#303030';
// Pick a contrasting color for links. // Pick a contrasting color for links.
$link_color = wc_hex_is_light( $base ) ? $base : $base_text; $link_color = Template::is_hex_light( $base ) ? $base : $base_text;
if ( wc_hex_is_light( $body ) ) { if ( Template::is_hex_light( $body ) ) {
$link_color = wc_hex_is_light( $base ) ? $base_text : $base; $link_color = Template::is_hex_light( $base ) ? $base_text : $base;
} }
$bg_darker_10 = wc_hex_darker( $bg, 10 ); $bg_darker_10 = Template::hex_darker( $bg, 10 );
$body_darker_10 = wc_hex_darker( $body, 10 ); $body_darker_10 = Template::hex_darker( $body, 10 );
$base_lighter_20 = wc_hex_lighter( $base, 20 ); $base_lighter_20 = Template::hex_lighter( $base, 20 );
$base_lighter_40 = wc_hex_lighter( $base, 40 ); $base_lighter_40 = Template::hex_lighter( $base, 40 );
$text_lighter_20 = wc_hex_lighter( $text, 20 ); $text_lighter_20 = Template::hex_lighter( $text, 20 );
$text_lighter_40 = wc_hex_lighter( $text, 40 ); $text_lighter_40 = Template::hex_lighter( $text, 40 );
// !important; is a gmail hack to prevent styles being stripped if it doesn't like something. // !important; is a gmail hack to prevent styles being stripped if it doesn't like something.
// body{padding: 0;} ensures proper scale/positioning of the email in the iOS native email app. // body{padding: 0;} ensures proper scale/positioning of the email in the iOS native email app.
?> ?>
body { body {
padding: 0; padding: 0;
} }
#wrapper { #wrapper {
background-color: <?php echo esc_attr( $bg ); ?>; background-color: <?php echo esc_attr( $bg ); ?>;
margin: 0; margin: 0;
padding: 70px 0; padding: 70px 0;
-webkit-text-size-adjust: none !important; -webkit-text-size-adjust: none !important;
width: 100%; width: 100%;
} }
#template_container { #template_container {
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1) !important; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1) !important;
background-color: <?php echo esc_attr( $body ); ?>; background-color: <?php echo esc_attr( $body ); ?>;
border: 1px solid <?php echo esc_attr( $bg_darker_10 ); ?>; border: 1px solid <?php echo esc_attr( $bg_darker_10 ); ?>;
border-radius: 3px !important; border-radius: 3px !important;
} }
#template_header { #template_header {
background-color: <?php echo esc_attr( $base ); ?>; background-color: <?php echo esc_attr( $base ); ?>;
border-radius: 3px 3px 0 0 !important; border-radius: 3px 3px 0 0 !important;
color: <?php echo esc_attr( $base_text ); ?>; color: <?php echo esc_attr( $base_text ); ?>;
border-bottom: 0; border-bottom: 0;
font-weight: bold; font-weight: bold;
line-height: 100%; line-height: 100%;
vertical-align: middle; vertical-align: middle;
font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif;
} }
#template_header h1, #template_header h1,
#template_header h1 a { #template_header h1 a {
color: <?php echo esc_attr( $base_text ); ?>; color: <?php echo esc_attr( $base_text ); ?>;
background-color: inherit; background-color: inherit;
} }
#template_header_image img { #template_header_image img {
margin-left: 0; margin-left: 0;
margin-right: 0; margin-right: 0;
} }
#template_footer td { #template_footer td {
padding: 0; padding: 0;
border-radius: 6px; border-radius: 6px;
} }
#template_footer #credit { #template_footer #credit {
border: 0; border: 0;
color: <?php echo esc_attr( $text_lighter_40 ); ?>; color: <?php echo esc_attr( $text_lighter_40 ); ?>;
font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif;
font-size: 12px; font-size: 12px;
line-height: 150%; line-height: 150%;
text-align: center; text-align: center;
padding: 24px 0; padding: 24px 0;
} }
#template_footer #credit p { #template_footer #credit p {
margin: 0 0 16px; margin: 0 0 16px;
} }
#body_content { #body_content {
background-color: <?php echo esc_attr( $body ); ?>; background-color: <?php echo esc_attr( $body ); ?>;
} }
#body_content table td { #body_content table td {
padding: 48px 48px 32px; padding: 48px 48px 32px;
} }
#body_content table td td { #body_content table td td {
padding: 12px; padding: 12px;
} }
#body_content table td th { #body_content table td th {
padding: 12px; padding: 12px;
} }
#body_content td ul.wc-item-meta { #body_content td ul.wc-item-meta {
font-size: small; font-size: small;
margin: 1em 0 0; margin: 1em 0 0;
padding: 0; padding: 0;
list-style: none; list-style: none;
} }
#body_content td ul.wc-item-meta li { #body_content td ul.wc-item-meta li {
margin: 0.5em 0 0; margin: 0.5em 0 0;
padding: 0; padding: 0;
} }
#body_content td ul.wc-item-meta li p { #body_content td ul.wc-item-meta li p {
margin: 0; margin: 0;
} }
#body_content p { #body_content p {
margin: 0 0 16px; margin: 0 0 16px;
} }
#body_content_inner { #body_content_inner {
color: <?php echo esc_attr( $text_lighter_20 ); ?>; color: <?php echo esc_attr( $text_lighter_20 ); ?>;
font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif;
font-size: 14px; font-size: 14px;
line-height: 150%; line-height: 150%;
text-align: <?php echo is_rtl() ? 'right' : 'left'; ?>; text-align: <?php echo is_rtl() ? 'right' : 'left'; ?>;
} }
.td { .td {
color: <?php echo esc_attr( $text_lighter_20 ); ?>; color: <?php echo esc_attr( $text_lighter_20 ); ?>;
border: 1px solid <?php echo esc_attr( $body_darker_10 ); ?>; border: 1px solid <?php echo esc_attr( $body_darker_10 ); ?>;
vertical-align: middle; vertical-align: middle;
} }
.address { .address {
padding: 12px; padding: 12px;
color: <?php echo esc_attr( $text_lighter_20 ); ?>; color: <?php echo esc_attr( $text_lighter_20 ); ?>;
border: 1px solid <?php echo esc_attr( $body_darker_10 ); ?>; border: 1px solid <?php echo esc_attr( $body_darker_10 ); ?>;
} }
.text { .text {
color: <?php echo esc_attr( $text ); ?>; color: <?php echo esc_attr( $text ); ?>;
font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif;
} }
.link { .link {
color: <?php echo esc_attr( $link_color ); ?>; color: <?php echo esc_attr( $link_color ); ?>;
} }
#header_wrapper { #header_wrapper {
padding: 36px 48px; padding: 36px 48px;
display: block; display: block;
} }
h1 { h1 {
color: <?php echo esc_attr( $base ); ?>; color: <?php echo esc_attr( $base ); ?>;
font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif;
font-size: 30px; font-size: 30px;
font-weight: 300; font-weight: 300;
line-height: 150%; line-height: 150%;
margin: 0; margin: 0;
text-align: <?php echo is_rtl() ? 'right' : 'left'; ?>; text-align: <?php echo is_rtl() ? 'right' : 'left'; ?>;
text-shadow: 0 1px 0 <?php echo esc_attr( $base_lighter_20 ); ?>; text-shadow: 0 1px 0 <?php echo esc_attr( $base_lighter_20 ); ?>;
} }
h2 { h2 {
color: <?php echo esc_attr( $base ); ?>; color: <?php echo esc_attr( $base ); ?>;
display: block; display: block;
font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif;
font-size: 18px; font-size: 18px;
font-weight: bold; font-weight: bold;
line-height: 130%; line-height: 130%;
margin: 0 0 18px; margin: 0 0 18px;
text-align: <?php echo is_rtl() ? 'right' : 'left'; ?>; text-align: <?php echo is_rtl() ? 'right' : 'left'; ?>;
} }
h3 { h3 {
color: <?php echo esc_attr( $base ); ?>; color: <?php echo esc_attr( $base ); ?>;
display: block; display: block;
font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif;
font-size: 16px; font-size: 16px;
font-weight: bold; font-weight: bold;
line-height: 130%; line-height: 130%;
margin: 16px 0 8px; margin: 16px 0 8px;
text-align: <?php echo is_rtl() ? 'right' : 'left'; ?>; text-align: <?php echo is_rtl() ? 'right' : 'left'; ?>;
} }
a { a {
color: <?php echo esc_attr( $link_color ); ?>; color: <?php echo esc_attr( $link_color ); ?>;
font-weight: normal; font-weight: normal;
text-decoration: underline; text-decoration: underline;
} }
img { img {
border: none; border: none;
display: inline-block; display: inline-block;
font-size: 14px; font-size: 14px;
font-weight: bold; font-weight: bold;
height: auto; height: auto;
outline: none; outline: none;
text-decoration: none; text-decoration: none;
text-transform: capitalize; text-transform: capitalize;
vertical-align: middle; vertical-align: middle;
margin-<?php echo is_rtl() ? 'left' : 'right'; ?>: 10px; margin-<?php echo is_rtl() ? 'left' : 'right'; ?>: 10px;
max-width: 100%; max-width: 100%;
} }
<?php <?php
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment