Данный вопрос возникает при верстке писем т.к. стили прописанные в <head>
в почтовых сервисах и программах не работают, а в ручную прописывать стили каждому тегу вручную долго и не удобно. Далее представлены варианты как автоматизировать этот процесс.
Пример HTML кода в котором нужно добавить стили.
$html = '
<p>Текст <span>1</span></p>
<p style="text-align: center">Текст 2</p>
<img src="/uploads/logo.png">
';
Массив тегов и стилей которые нужно добавить.
Функция ищет теги, из них достает атрибуты, дописывает их и делает замену в тексте.
function add_html_style($html, $tags)
{
foreach ($tags as $tag => $style) {
preg_match_all('/<' . $tag . '([\s].*?)?>/i', $html, $matchs, PREG_SET_ORDER);
foreach ($matchs as $match) {
$attrs = array();
if (!empty($match[1])) {
preg_match_all('/[ ]?(.*?)=[\"|\'](.*?)[\"|\'][ ]?/', $match[1], $chanks);
if (!empty($chanks[1]) && !empty($chanks[2])) {
$attrs = array_combine($chanks[1], $chanks[2]);
}
}
if (empty($attrs['style'])) {
$attrs['style'] = $style;
} else {
$attrs['style'] = rtrim($attrs['style'], '; ') . '; ' . $style;
}
$compile = array();
foreach ($attrs as $name => $value) {
$compile[] = $name . '="' . $value . '"';
}
$html = str_replace($match[0], '<' . $tag . ' ' . implode(' ', $compile) . '>', $html);
}
}
return $html;
}
echo add_html_style($html, $tags);
Результат работы функции
<p style="padding: 0;">Текст <span style="color: #000;">1</span></p>
<p style="text-align: center; padding: 0;">Текст 2</p>
<img src="/uploads/logo.png" style="border: none">
Особенности:
- Приводит HTML код к валидному виду - закрывает незакрытые теги, удаляет лишние пробелы, переводит названия тегов и атрибутов в нижний регистр.
- Заменяет мнемоники на символы.
require '/phpQuery.php';
$dom = phpQuery::newDocument($html);
foreach ($tags as $tag => $style) {
$elements = $dom->find($tag);
foreach ($elements as $element) {
$pq = pq($element);
$attrs = $pq->attr('style');
if (empty($attrs)) {
$pq->attr('style', $style);
} else {
$pq->attr('style', rtrim($attrs, '; ') . '; ' . $style);
}
}
}
echo (string) $dom;
Результат
<p style="padding: 0;">Текст <span style="color: #000;">1</span></p>
<p style="text-align: center; padding: 0;">Текст 2</p>
<img src="/uploads/logo.png" style="border: none">
В данном случаи не подходит т.к. к верстке добавляется теги <html>
, <head>
, <body>
.
$doc = new DOMDocument('1.0', 'UTF-8');
@$doc->loadHTML($html);
foreach ($tags as $tag => $style) {
$elements = $doc->getElementsByTagName($tag);
foreach ($elements as $element) {
$attrs = $element->getAttribute('style');
if (empty($attrs)) {
$element->setAttribute('style', $style);
} else {
$element->setAttribute('style', rtrim($attrs, '; ') . '; ' . $style);
}
}
}
echo html_entity_decode($doc->saveHTML());
Результат
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<body>
<p style="padding: 0;">Текст <span style="color: #000;">1</span></p>
<p style="text-align: center; padding: 0;">Текст 2</p>
<img src="/uploads/logo.png" style="border: none">
</body>
</html>