ن. 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 >
ستطبق خاصية evaluateVariables
الخاصة بأسلوب CssVariableEvaluator
قيمة --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 كسمات "نمط" مضمنة في 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 ();
ملاحظة: في هذا المثال، يقوم الكود القديم بإزالة العناصر ذات 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
للإشارة إلى الإصدار بعد الإصدار القادم.