Я пишу простой редактор HTML-редакторов электронной почты на PHP, а также показываю демонстрацию того, как это будет выглядеть.
Я думаю, было бы очень полезно показать пользователю, как это будет выглядеть в почтовом клиенте, таком как gmail с отключенными изображениями.
Каков мой лучший подход для этого? Кто-нибудь знает, как это делается в gmail / hotmail и т. Д.?
Я просто удаляю img -> src
и css background: url
с выражением reg?
Я хотел бы удалить фоновые части из: background="url"
используемого в таблицах и background-image:url(url);
Использованный встроенный css
Я нашел этот вопрос, который имеет такую же идею, хотя я бы хотел удалить удаленные img и backrgound-изображения из текста HTML.
Или этот код может быть изменен для работы с фоновыми изображениями?
Я бы также предложил использовать PHP DOM вместо регулярного выражения, которые часто бывают неточными. Вот пример кода, который вы можете использовать, чтобы удалить все теги img и все фоновые атрибуты из вашей строки:
// ...loading the DOM $dom = new DOMDocument(); @$dom->loadHTML($string); // Using @ to hide any parse warning sometimes resulting from markup errors $dom->preserveWhiteSpace = false; // Here we strip all the img tags in the document $images = $dom->getElementsByTagName('img'); $imgs = array(); foreach($images as $img) { $imgs[] = $img; } foreach($imgs as $img) { $img->parentNode->removeChild($img); } // This part strips all 'background' attribute in (all) the body tag(s) $bodies = $dom->getElementsByTagName('body'); $bodybg = array(); foreach($bodies as $bg) { $bodybg[] = $bg; } foreach($bodybg as $bg) { $bg->removeAttribute('background'); } $str = $dom->saveHTML();
Я выбрал теги body вместо таблицы, так как сама <table>
не имеет атрибута background
, она имеет только bgcolor
. Чтобы разделить фоновое встроенное свойство css, вы можете использовать PHP Sarserworm PHP Parser для анализа CSS, извлеченного из DOM: попробуйте это
// Selecting all the elements since each one could have a style attribute $alltags = $dom->getElementsByTagName('*'); $tags = array(); foreach($alltags as $tag) { $tags[] = $tag; } $css = array(); foreach($tags as &$tag) { $oParser = new CSSParser("p{".$tag->getAttribute('style')."}"); $oCss = $oParser->parse(); foreach($oCss->getAllRuleSets() as $oRuleSet) { $oRuleSet->removeRule('background'); $oRuleSet->removeRule('background-image'); } $css = $oCss->__toString(); $css = substr_replace($css, '', 0, 3); $css = substr_replace($css, '', -2, 2); if($css) $tag->setAttribute('style', $css); }
Используя весь этот код для переключения, например, если у вас есть
$string = '<!DOCTYPE html> <html><body background="http://yo.ur/background/dot/com" etc="an attribute value"> <img src="http://your.pa/th/to/image"><img src="http://anoth.er/path/to/image"> <div style="background-image:url(http://inli.ne/css/background);border: 1px solid black">div content...</div> <div style="background:url(http://inli.ne/css/background);border: 1px solid black">2nd div content...</div> </body></html>';
PHP выведет
<!DOCTYPE html> <html><body etc="an attribute value"> <div style="border: 1px solid black;">div content...</div> <div style="border: 1px solid black;">2nd div content...</div> </body></html>
Для того, чтобы полностью имитировать поведение gmail или подобных веб-писем, было бы заменить теги и атрибуты background: css соответственно, чтобы они отображали местозаполнитель, делая ясно пользователю, что здесь лежит изображение.
Поскольку, как правило, сообщение загружается в iframe, я считаю, что ваша лучшая догадка состоит в том, чтобы очистить сторону сервера сообщений, удаляя все нежелательные теги и соответственно заменяя изображения при предварительном просмотре.
Я соглашусь с Михалом, что нецелесообразно использовать только регулярное выражение для проверки вашего HTML-кода, и вы, вероятно, должны пройти дерево DOM, чтобы быть в безопасности.
Почему бы вам не взглянуть на стирку Фредериком Моттом, используемым круглым кубком, чтобы вы начали?
Использование регулярных выражений для синтаксического анализа html обычно не рекомендуется.
Я считаю, что лучше всего будет разбирать серверную часть html и манипулировать им, чтобы удалить изображения или атрибуты src изображения. У библиотеки, с которой у меня был успех, есть http://simplehtmldom.sourceforge.net/ , но я думаю, вы можете использовать официальные расширения PHP DOM.
Удаление фоновых изображений может быть более сложным. Возможно, вам придется использовать что-то вроде http://www.pelagodesign.com/sidecar/emogrifier/, чтобы применить что-то вроде {background: none} к элементам html. Тем не менее, фоновые изображения CSS не поддерживаются в последних версиях Microsoft Outlook, поэтому я бы рекомендовал не использовать их вообще с помощью get-go, чтобы электронные письма были согласованы для большинства почтовых клиентов.
Как упоминалось tkone: возможно, JavaScript / jQuery – это ответ.
Это просмотрит все изображения в области предварительного просмотра и изменит исходный код на изображение-заполнитель. Класс «placeholder» также устанавливает фоновое изображение на местозаполнитель
JQuery
$("#previewArea img").each(function(){ $(this).attr("src","placeholder.jpg"); $(this).addClass("hideBG"); });
CSS
.hideBG{ background: url("placeholder.jpg"); }
Не проверен, но должен работать – в зависимости от ваших настроек и потребностей.
Я задал аналогичный вопрос (в решении, а не в реальной проблеме): как удалить определенные теги и конкретные атрибуты из строки? ( Решение )
Это серверная библиотека, которая очищает (и форматирует) ввод HTML в соответствии с предопределенными настройками. Удалите все атрибуты src
и все свойства background
.
Вы всегда можете сделать это и на стороне клиента.
Используя этот гипотетический код, вы должны сделать что-то вроде этого, делая вид, что современные браузеры работают одинаково: (или используйте jQuery или что-то еще)
var email; var xhr = new XMLHttpRequest(); xhr.open('GET', URL_FOR_EMAIL, true); xhr.onreadystatechange = function(event){ if(xhr.readyState === 4 && xhr.status === 200){ email = HTMLParser(xhr.responseText); } } var imgs = email.getElementsByTagName('img'); for(var i = 0; i > imgs.length; i++){ email.removeChild(imgs[i]); } // attach the email body to the DOM // do something with the images
HTMLParser из MDN
function HTMLParser(aHTMLString){ var html = document.implementation.createDocument("http://www.w3.org/1999/xhtml", "html", null), body = document.createElementNS("http://www.w3.org/1999/xhtml", "body"); html.documentElement.appendChild(body); body.appendChild(Components.classes["@mozilla.org/feed-unescapehtml;1"] .getService(Components.interfaces.nsIScriptableUnescapeHTML) .parseFragment(aHTMLString, false, null, body)); return body; },
Я думаю, что лучший способ сделать это и сохранить изменение обратимым, используя тег, который не обрабатывает атрибут «src».
Пример: Измените все «img» на «br»
Поэтому напечатайте отфильтрованный HTML 1 и отмените его с помощью ajax, найдите все данные с атрибутом src.