
н. e•mog•ri•fi•er [ē-'mä-grƏ-,fī-Ər] — утилита для полного изменения характера или внешнего вида электронной почты в формате HTML, особенно. особенно фантастическим или причудливым образом
Emogrifier преобразует стили CSS во встроенные атрибуты стиля в вашем HTML-коде. Это обеспечивает правильное отображение в программах чтения электронной почты и мобильных устройствах, на которых отсутствует поддержка таблиц стилей.
Эта утилита была разработана как часть Intervals для решения проблем, возникающих у некоторых почтовых клиентов (а именно Outlook 2007 и GoogleMail), когда дело касается способа обработки стилей, содержащихся в электронных письмах в формате HTML. Как уже знают многие веб-разработчики и дизайнеры, некоторые почтовые клиенты печально известны отсутствием поддержки CSS. Хотя предпринимаются попытки разработать общие стандарты электронной почты, до их реализации еще далеко.
Основная проблема несовместимых почтовых клиентов заключается в том, что большинство из них склонны учитывать только встроенный CSS, отбрасывая все элементы <style> и ссылки на таблицы стилей в элементах <link> . Emogrifier решает эту проблему, преобразуя стили CSS во встроенные атрибуты стиля в вашем HTML-коде.
Emogrifier автоматически преобразует ваш HTML, анализируя CSS и вставляя определения CSS в теги HTML на основе ваших селекторов CSS.
Чтобы установить emogrifier, либо добавьте pelago/emogrifier в раздел require в composer.json вашего проекта, либо вы можете использовать композитор, как показано ниже:
composer require pelago/emogrifierСм. https://getcomposer.org/ для получения дополнительной информации и документации.
Самый простой способ использования класса CssInliner — создать экземпляр с исходным HTML, встроить внешний CSS и затем получить полученный HTML:
use Pelago Emogrifier CssInliner ;
…
$ visualHtml = CssInliner:: fromHtml ( $ html )-> inlineCss ( $ css )-> render (); Если внешнего файла CSS нет и весь CSS находится внутри элементов <style> в HTML, вы можете опустить параметр $css :
$ visualHtml = CssInliner:: fromHtml ( $ html )-> inlineCss ()-> render (); Если вы хотите получить только содержимое элемента <body> вместо всего HTML-документа, вместо этого вы можете использовать метод renderBodyContent :
$ bodyContent = $ visualHtml = CssInliner:: fromHtml ( $ html )-> inlineCss ()
-> renderBodyContent ();Если вы хотите изменить процесс встраивания с помощью любой из доступных опций, вам нужно будет вызвать соответствующие методы перед встраиванием CSS. Тогда код будет выглядеть так:
$ visualHtml = CssInliner:: fromHtml ( $ html )-> disableStyleBlocksParsing ()
-> inlineCss ( $ css )-> render (); Также доступны некоторые другие классы обработки HTML (все они являются подклассами AbstractHtmlProcessor ), которые вы можете использовать для дальнейшего изменения HTML после встраивания CSS. (Более подробную информацию о классах можно найти в разделах ниже.) CssInliner и все классы обработки HTML могут использовать один и тот же экземпляр DOMDocument для работы:
use Pelago Emogrifier CssInliner ;
use Pelago Emogrifier HtmlProcessor CssToAttributeConverter ;
use Pelago Emogrifier HtmlProcessor HtmlPruner ;
…
$ cssInliner = CssInliner:: fromHtml ( $ html )-> inlineCss ( $ css );
$ domDocument = $ cssInliner -> getDomDocument ();
HtmlPruner:: fromDomDocument ( $ domDocument )-> removeElementsWithDisplayNone ()
-> removeRedundantClassesAfterCssInlined ( $ cssInliner );
$ finalHtml = CssToAttributeConverter:: fromDomDocument ( $ domDocument )
-> convertCssToVisualAttributes ()-> render (); Класс HtmlNormalizer нормализует заданный HTML следующими способами:
Класс можно использовать следующим образом:
use Pelago Emogrifier HtmlProcessor HtmlNormalizer ;
…
$ cleanHtml = HtmlNormalizer:: fromHtml ( $ rawHtml )-> render (); CssToAttributeConverter преобразует несколько значений атрибутов стиля в визуальные атрибуты HTML. Это позволяет получить хотя бы немного визуального оформления для почтовых клиентов, которые плохо поддерживают CSS. Например, style="width: 100px" будет преобразовано в width="100" .
Класс можно использовать следующим образом:
use Pelago Emogrifier HtmlProcessor CssToAttributeConverter ;
…
$ visualHtml = CssToAttributeConverter:: fromHtml ( $ rawHtml )
-> convertCssToVisualAttributes ()-> render (); Вы также можете использовать CssToAttributeConverter для работы с DOMDocument :
$ visualHtml = CssToAttributeConverter:: fromDomDocument ( $ domDocument )
-> convertCssToVisualAttributes ()-> render (); Класс CssVariableEvaluator можно использовать для применения значений переменных CSS, определенных в атрибутах встроенного стиля, к свойствам встроенного стиля, которые их используют.
Например, следующий CSS определяет и использует пользовательское свойство:
: root {
--text-color : green;
}
p {
color : var ( --text-color );
} После того, как CssInliner встроит этот CSS в (надуманный) HTML <html><body><p></p></body></html> , он будет выглядеть так:
< html style =" --text-color: green; " >
< body >
< p style =" color: var(--text-color); " >
< p >
</ body >
</ html > Метод CssVariableEvaluator evaluateVariables применит значение --text-color , чтобы атрибут style абзаца стал color: green; .
Его можно использовать следующим образом:
use Pelago Emogrifier HtmlProcessor CssVariableEvaluator ;
…
$ evaluatedHtml = CssVariableEvaluator:: fromHtml ( $ html )
-> evaluateVariables ()-> render (); Вы также можете использовать CssVariableEvaluator для работы с DOMDocument :
$ evaluatedHtml = CssVariableEvaluator:: fromDomDocument ( $ domDocument )
-> evaluateVariables ()-> render (); Класс HtmlPruner может уменьшить размер HTML, удалив элементы с объявлением стиля display: none и/или удалив классы из необязательных атрибутов class .
Его можно использовать следующим образом:
use Pelago Emogrifier HtmlProcessor HtmlPruner ;
…
$ prunedHtml = HtmlPruner:: fromHtml ( $ html )-> removeElementsWithDisplayNone ()
-> removeRedundantClasses ( $ classesToKeep )-> render (); Метод removeRedundantClasses принимает список разрешенных имен классов, которые следует сохранить. Если это этап постобработки после встраивания CSS, вы можете альтернативно использовать removeRedundantClassesAfterCssInlined , передав ему экземпляр CssInliner , встроивший CSS (и заставив HtmlPruner работать с DOMDocument ). При этом будет использоваться информация из CssInliner чтобы определить, какие классы все еще необходимы (а именно те, которые используются в невстраиваемых правилах, которые были скопированы в элемент <style> ):
$ prunedHtml = HtmlPruner:: fromDomDocument ( $ cssInliner -> getDomDocument ())
-> removeElementsWithDisplayNone ()
-> removeRedundantClassesAfterCssInlined ( $ cssInliner )-> render (); Метод removeElementsWithDisplayNone не удалит элементы, имеющие класс -emogrifier-keep . Так что, если, например, есть элементы, которые по умолчанию имеют display: none , но раскрываются правилом @media , или которые предназначены для использования в качестве прехедера, вы можете добавить этот класс к этим элементам. Абзац в этом фрагменте HTML не будет удален, даже если он имеет display: none (который предположительно был применен CssInliner::inlineCss() из правила CSS .preheader { display: none; } ):
< p class =" preheader -emogrifier-keep " style =" display: none; " >
Hello World!
</ p > Метод removeRedundantClassesAfterCssInlined (или removeRedundantClasses ), если он вызван после removeElementsWithDisplayNone , удалит класс -emogrifier-keep .
Существует несколько параметров, которые вы можете установить для экземпляра CssInliner перед вызовом метода inlineCss :
->disableStyleBlocksParsing() — по умолчанию CssInliner захватывает все блоки <style> в HTML и применяет стили CSS как встроенные атрибуты «style» к HTML. Блоки <style> будут удалены из HTML. Если вы хотите отключить эту функцию, чтобы CssInliner оставил эти блоки <style> в HTML и не анализировал их, вам следует использовать эту опцию. Если вы используете эту опцию, содержимое блоков <style> не будет применяться как встроенные стили, и любой CSS, который вы хотите использовать CssInliner , должен быть передан, как описано в разделе «Использование» выше.->disableInlineStyleAttributesParsing() — по умолчанию CssInliner сохраняет все атрибуты «стиля» в тегах HTML-кода, который вы ему передаете. Однако, если вы хотите удалить все существующие встроенные стили в HTML до применения CSS, вам следует использовать эту опцию.->addAllowedMediaType(string $mediaName) — по умолчанию CssInliner сохраняет только типы мультимедиа all , screen и print . Если вы хотите сохранить некоторые другие, вы можете использовать этот метод для их определения.->removeAllowedMediaType(string $mediaName) — этот метод можно использовать для удаления типов мультимедиа, хранящихся в Emogrifier.->addExcludedSelector(string $selector) — защищает элементы от влияния встраивания CSS. Обратите внимание, что из встраивания CSS будут исключены только элементы, соответствующие предоставленному селектору, а не обязательно их потомки. Если вы хотите исключить все поддерево, вам следует предоставить селекторы, которые будут соответствовать всем элементам в поддереве, например, с помощью универсального селектора: $ cssInliner -> addExcludedSelector ( ' .message-preview ' );
$ cssInliner -> addExcludedSelector ( ' .message-preview * ' );->addExcludedCssSelector(string $selector) — в отличие от addExcludedSelector , который исключает узлы HTML, этот метод исключает встраивание селекторов CSS. Это, например, полезно, если вы не хотите, чтобы правила сброса CSS были встроены в каждый узел HTML (например, * { margin: 0; padding: 0; font-size: 100% } ). Обратите внимание, что эти селекторы должны точно соответствовать селекторам, которые вы хотите исключить. Это означает, что исключение .example не исключает p .example . $ cssInliner -> addExcludedCssSelector ( ' * ' );
$ cssInliner -> addExcludedCssSelector ( ' form ' );->removeExcludedCssSelector(string $selector) — удаляет ранее добавленные исключенные селекторы, если таковые имеются. $ cssInliner -> removeExcludedCssSelector ( ' form ' );Emogrifier в класс CssInliner Старый код с использованием Emogrifier :
$ emogrifier = new Emogrifier ( $ html );
$ html = $ emogrifier -> emogrify (); Новый код с использованием CssInliner :
$ html = CssInliner:: fromHtml ( $ html )-> inlineCss ()-> render (); NB: В этом примере старый код удаляет элементы с display: none; в то время как новый код этого не делает, поскольку поведение по умолчанию старого и нового класса в этом отношении различается.
Старый код с использованием Emogrifier :
$ emogrifier = new Emogrifier ( $ html , $ css );
$ emogrifier -> enableCssToHtmlMapping ();
$ html = $ emogrifier -> emogrify (); Новый код с использованием CssInliner и семейства:
$ domDocument = CssInliner:: fromHtml ( $ html )-> inlineCss ( $ css )-> getDomDocument ();
HtmlPruner:: fromDomDocument ( $ domDocument )-> removeElementsWithDisplayNone ();
$ html = CssToAttributeConverter:: fromDomDocument ( $ domDocument )
-> convertCssToVisualAttributes ()-> render ();Emogrifier в настоящее время поддерживает следующие селекторы CSS:
~ (одно слово в списке слов, разделенных пробелами)| (либо точное совпадение значений, либо префикс, за которым следует дефис)^ (совпадение префикса)$ (совпадение суффикса)* (совпадение подстроки)p:first-of-type , но не *:first-of-type )Следующие селекторы еще не реализованы:
<style> в HTML – включая (но не обязательно ограничиваясь) следующее: Правила, включающие следующие селекторы, нельзя применять как встроенные стили. Однако они будут сохранены и скопированы в элемент <style> в HTML:
:hover )::after ) @media . Медиа-запросы могут быть очень полезны при создании адаптивного дизайна электронной почты. См. поддержку медиа-запросов. Однако для того, чтобы они были эффективными, вам может потребоваться добавить !important к некоторым объявлениям внутри них, чтобы они переопределяли встроенные стили CSS. Например, в следующем CSS объявление font-size в правиле @media не будет переопределять размер шрифта для элементов p из предыдущего правила после того, как оно было встроено как <p style="font-size: 16px;"> в HTML без директивы !important (хотя в !important не было бы необходимости, если бы CSS не был встроенным): p {
font-size : 16 px ;
}
@media ( max-width : 640 px ) {
p {
font-size : 14 px !important ;
}
}@media , нельзя применять к значениям свойств CSS, которые были встроены и оценены. Однако правила @media использующие настраиваемые свойства (с помощью var() ), по-прежнему смогут получать свои значения (из встроенных определений или правил @media ) в почтовых клиентах, поддерживающих настраиваемые свойства.::after ) или динамическими псевдоклассами (такими как :hover ) — это невозможно. Однако такие правила будут сохранены и скопированы в элемент <style> , как и правила @media , с теми же оговорками.<style> из вашего HTML, но он не будет захватывать файлы CSS, указанные в элементах <link> или правилах @import (хотя он оставит их нетронутыми для почтовых клиентов, которые их поддерживают).Пожалуйста, ознакомьтесь с нашим API и политикой прекращения поддержки.
Вклад в виде отчетов об ошибках, запросов на добавление функций или запросов на включение более чем приветствуется. Пожалуйста, ознакомьтесь с нашими правилами участия, чтобы узнать больше о том, как внести свой вклад в Emogrifier.
branch-alias , чтобы она указывала на выпуск после предстоящего выпуска.