
n. 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 ดังต่อไปนี้:
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 จะรักษาแอตทริบิวต์ "style" ทั้งหมดบนแท็กใน HTML ที่คุณส่งไป อย่างไรก็ตาม หากคุณต้องการละทิ้งสไตล์อินไลน์ที่มีอยู่ใน HTML ก่อนที่จะใช้ CSS คุณควรใช้ตัวเลือกนี้->addAllowedMediaType(string $mediaName) - ตามค่าเริ่มต้น CssInliner จะเก็บเฉพาะประเภทสื่อ all , screen และ print หากคุณต้องการเก็บบางรายการไว้ คุณสามารถใช้วิธีนี้เพื่อกำหนดรายการเหล่านั้นได้->removeAllowedMediaType(string $mediaName) - คุณสามารถใช้วิธีนี้เพื่อลบประเภทสื่อที่ Emogrifier เก็บไว้ได้->addExcludedSelector(string $selector) - ป้องกันไม่ให้องค์ประกอบได้รับผลกระทบจากการแทรก CSS โปรดทราบว่าเฉพาะองค์ประกอบที่ตรงกับตัวเลือกที่ให้มาเท่านั้นที่จะถูกแยกออกจาก CSS inline โดยไม่จำเป็นต้องเป็นองค์ประกอบที่สืบทอด หากคุณต้องการยกเว้นแผนผังย่อยทั้งหมด คุณควรระบุตัวเลือกที่จะจับคู่องค์ประกอบทั้งหมดในแผนผังย่อย เช่น โดยใช้ตัวเลือกสากล: $ 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 ให้ชี้ไปที่การเปิดตัว หลังจาก การเปิดตัวที่กำลังจะมาถึง