Когда дело доходит до манипулирования DOM, первое, о чем многие из нас, вероятно, думают, это использовать JavaScript для выполнения всего, что нам нужно.
Мало того, что язык изначально поддерживает функции для этого, новые функции ES6 дают нам более мощные способы создания скриптов на стороне клиента. И если вы используете jQuery с WordPress, то у вас есть та же библиотека функций для, гм, запросов к DOM, которая у нас была в течение многих лет.
Но манипулирование DOM на стороне клиента — не всегда лучший вариант. Вместо этого вы можете сделать это на стороне сервера. И из-за некоторых функций, встроенных в PHP, он не сильно отличается от того, как мы делаем что-то с помощью JavaScript.
Кроме, конечно, того, что мы делаем на сервере.
Поэтому, если вы когда-либо работали с содержимым сообщения (тип сообщения или пользовательский тип сообщения, если на то пошло) и вам нужно манипулировать тегами так же, как в JavaScript, то использование DomDocumentбиблиотеки является одним из самых мощных способов. инструменты в вашем распоряжении.
Скажем, например, вы хотите перебрать все элементы абзаца, которые существуют в содержании сообщения.
Это легко сделать с помощью указанной библиотеки. Во- первых, вы должны убедиться, что у вас настроена библиотека в вашем классе (или просто в вашей коллекции функций):
Затем настройте хук для содержимого:
<?php
add_filter('the_content', __NAMESPACE__. 'updateParagraphElements');
И внутри этой функции обязательно загрузите содержимое поста в библиотеку, а затем найдите все pэлементы, как если бы вы использовали JavaScript (с одним важным примечанием: вам необходимо правильно кодировать информацию, если надстрочные индексы или смайлики использовал):
<?php
function updateParagraphElements($content)
{
/* If we're not on a single page or it's not the main query,
* we won't do anything.
*/
if (!is_single() || !is_main_query()) {
return $content;
}
// Make sure there is content to parse (and properly encode the HTML entities).
$domDocument = new DOMDocument();
$domContent = $domDocument->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES'));
if (false === $domContent) {
return $content;
}
$paragraphs = $domDocument->getElementsByTagName('p');
if (0 === count($paragraphs)) {
return $content;
}
// More to come...
}
Отсюда вы можете сделать несколько разных вещей, таких как добавление идентификатора сообщения к пользовательскому атрибуту каждого элемента абзаца. Тогда полная функция будет выглядеть примерно так:
<?php
namespace Acme;
use DOMDocument;
add_filter('the_content', __NAMESPACE__. 'updateParagraphElements');
/**
* Updates the content by locating all of the `p` elements in the content,
* then adds a class attribute of the post ID to them.
*
* The gist of the work is done in this function.
*
* @param string $content the post content
*
* @return string the updated post content with the aforemented markup.
*/
function updateParagraphElements($content)
{
/* If we're not on a single page or it's not the main query,
* we won't do anything.
*/
if (!is_single() || !is_main_query()) {
return $content;
}
// Make sure there is content to parse (and properly encode the HTML entities).
$domDocument = new DOMDocument();
$domContent = $domDocument->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES'));
if (false === $domContent) {
return $content;
}
$paragraphs = $domDocument->getElementsByTagName('p');
if (0 === count($paragraphs)) {
return $content;
}
// If so, iterate through the elements and add the post ID as a custom attribute.
$updatedContent = '';
foreach ($paragraphs as $paragraph) {
$paragraph->setAttribute('data-id', get_the_ID());
}
return wp_kses_post($domDocument->saveHTML());
}
Конечно, есть и другие вещи, которые вы можете сделать. Одно дело манипулировать разметкой перед ее отправкой в браузер. Другое дело — добавить атрибуты к данным, если они еще не существуют.
Это не каламбур — за исключением, может быть, только своего рода контента для другого поста.