
ن. 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 للإشارة إلى الإصدار بعد الإصدار القادم.