Як маніпулювати DOM за допомогою PHP
Коли справа доходить до маніпулювання 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());
}
Звичайно, ви можете робити й інші речі. Одна справа маніпулювати розміткою перед тим, як відправити її в браузер. Інша справа, однак, додати атрибути до даних, якщо вони ще не існують.
Тобто без каламбуру – за винятком, можливо, лише свого роду – вмісту для іншої публікації.