Покращення читабельності WP_Query (для обслуговування)
Робота з WP_Query, особливо коли ви виконуєте певну роботу поза звичайним «отримати кілька дописів і відобразити їх у шаблоні», може бути потужною. Це особливо вірно щодо деяких розширених аргументів (наприклад, використання WP_Meta_Query ). .
Також приємно, що процес налаштування має стандартний спосіб виконання завдань. а саме:
- Визначте аргументи,
- Створення екземпляра WP_Query,
- Перевірте, чи є дописи,
- Перебирайте їх,
- Закінчити їх.
Але якщо ви дійдете до того, де ви виконуєте будь-яку просунуту роботу, як-от робота зі спеціальним типом публікації від стороннього рішення, необхідність завантажувати медіафайли, визначати, чи щось існує, перш ніж фактично виконувати будь-яку роботу з цим, тоді це може бути трохи складніше працювати, чи не так?
Я виявив, що, як і будь-яку іншу справу в програмуванні, розбиття її на більш зрозумілі модулі (або функції, частини або як би ви хотіли їх називати) може значно полегшити роботу.
Отже, ось один із способів, як я намагаюся покращити читабельність WP_Query у багатьох речах, які я зробив останнім часом.
Покращення читабельності WP_Query
Перш ніж розглядати будь-який приклад, варто зазначити, що є деякі речі, які ми не можемо зробити під час налаштування WP_Query.
Наприклад, після створення екземпляра запиту ми не зможемо робити з ним набагато складніші речі (я маю на увазі, що налаштувати будь-яке модульне тестування, яке не вимагає ядра WordPress, буде неможливо).
Це обличчя того, хто не може слідувати вашому коду.
З огляду на це, ось приклад того, як це може виглядати, коли ви починаєте, і як потім його можна рефакторингувати, щоб мати менші функції, кожна з яких є більш навмисною, ніж один довгий метод.
Приклад
Скажімо, для цієї публікації мені потрібно запитати в базі даних усі опубліковані публікації та публікації, і я хочу впорядкувати їх за ідентифікатором.
Далі я хочу визначити, чи якийсь сторонній інструмент призначив йому деякі метадані, які відповідають шаблону, який я згодом можу програмно призначити, враховуючи тему, яку я маю.
Можливо, початкова версія коду може виглядати приблизно так :
<?php
// Assume this is defined within the context of a class.
const MAPPING = [
'employers' => 'page-past-word.php',
'biography' => 'page-biography.php',
'accomplishments' => 'page-csv.php',
];
/* Snip the rest of the class for brevity */
public function map_templates() {
$args = [
'post_type' => array( 'post', 'page' ),
'post_status' => 'publish',
'orderby' => 'ID',
'order' => 'ASC',
'posts_per_page' => -1,
];
$template_query = new WP_Query( $args );
if ($template_query->have_posts()) {
while ($template_query->have_posts()) {
$template_query->the_post();
$template_id = get_post_meta( $post_id, 'third_party_template_id', true );
if ('' === $template_id) {
continue;
}
// The third-party's template post name can be used to map our custom template.
$template_info = get_post( $template_id );
$template_name = $template_info->post_name;
if (isset( self::MAPPING[ $template_name ])) {
$template_file = self::MAPPING[ $template_name ];
update_post_meta( $post_id, '_wp_page_template', $template_file );
}
}
}
}
Це багато коду, щоб виконати досить багато роботи для однієї функції. Принаймні, тут описано все, що має статися, чи не так?
Перш ніж читати далі, зауважте, що масив відображення є лише прикладом, але ключі представляють мета-ключ для його відображення, і це допомагає нам зіставляти визначення значення _wp_page_template, коли прийде час зіставляти його з фактичними файлами шаблону WordPress.
Отже, як це можна розбити?
1 Розпочніть все
Перше, що ми хочемо зробити, це створити функцію, яка приведе в рух усе. Для цього можна вибрати кілька способів.
Ось як я вирішив це зробити :
<?php
public function map_page_templates() {
$posts = $this->load_posts_and_pages();
if ($posts->have_posts()) {
$this->assign_templates( $posts );
}
}
Простіше кажучи, він використовуватиме кілька допоміжних функцій – усі з яких я задокументую нижче – а потім призначатиме будь-які шаблони, які ми маємо в масиві відображення, визначеному вище.
2 Завантажте дописи та сторінки
Звичайно, перше, що ми хочемо зробити, це налаштувати функцію для виклику, яка повертатиме використання результатів запиту:
<?php
private function load_posts_and_pages() {
$args = [
'post_type' => array( 'post', 'page' ),
'post_status' => 'publish',
'orderby' => 'ID',
'order' => 'ASC',
'posts_per_page' => -1,
];
$posts = new WP_Query( $args );
return $posts;
}
Це повертає результати запиту. Таким чином ми можемо визначити, чи потрібно нам виконати будь-яку додаткову роботу, про яку ми говоримо в суті на попередньому кроці:
<?php
public function map_page_templates() {
$posts = $this->load_posts_and_pages();
if ($posts->have_posts()) {
$this->assign_templates( $posts );
}
}
Якщо ні, тоді ми закінчили. В іншому випадку, очевидно, ми продовжуємо.
3 Отримайте ідентифікатор шаблону третьої сторони
Далі, ідея призначення шаблонів, як показано в коді вище, здається досить простою, але спочатку нам потрібно зробити кілька речей:
- переглядати повідомлення,
- отримати ідентифікатор третьої сторони шаблону,
- візьміть назву стороннього шаблону,
- призначити шаблон із константи відображення, визначеної раніше в класі.
Початкова ітерація функції може виглядати так :
<?php
private function assign_templates( WP_Query $posts) {
while ($posts->have_posts()) {
$posts->the_post();
$template_id = $this->get_template_id( get_the_ID() );
if ('' === $template_id) {
continue;
}
$template_name = $this->get_template_name( $template_id );
if (null === $template_name) {
continue;
}
$this->assign_template( get_the_ID(), $template_name );
}
wp_reset_postdata();
}
Але, як бачите, все ще є допоміжні функції, які потребують визначення. Такі речі, як можливість отримати ідентифікатор шаблону, назву шаблону та остаточне призначення шаблону.
Однак зауважте, що якщо будь-яка з допоміжних функцій не повертає корисне значення, ми продовжуємо цикл. Це необхідно хоча б не з іншої причини, ніж для того, щоб переконатися, що ми не намагаємося зіставити шаблони, яких не існує (але я вважаю, що це також полегшує читання).
4 Знайдіть файл, якому відповідає ідентифікатор шаблону
Далі за допомогою невеликої функції можна переглянути ідентифікатор стороннього шаблону та визначити, чи можна відобразити це значення на сторінках, які існують у нашій базі даних.
<?php
private function get_template_id( $post_id) {
$template_id = get_post_meta( $post_id, 'third_party_template_id', true );
return $template_id;
}
Якщо це не вдається, ми можемо повернути порожній рядок, а потім мати функцію, яка викликала цю перевірку, щоб побачити, чи варто продовжувати цикл, який ми визначили.
5 Візьміть назву шаблону
Припускаючи, що ми маємо дійсний ідентифікатор публікації, тепер нам потрібно отримати назву шаблону з масиву зіставлення, визначеного раніше в публікації:
<?php
private function get_template_name( $template_id) {
$template_info = get_post( $template_id );
$template_name = $template_info->post_name;
if (isset( self::MAPPING[ $template_name ])) {
return $template_name;
} else {
return null;
}
}
Справа ось у чому: ми або повернемо назву шаблону, або повернемо нульове значення. Знову ж таки, це для того, щоб ми могли визначити, чи потрібно нам продовжувати цикл призначення шаблонів чи ні.
6 Призначте шаблон
Нарешті, ми можемо отримати ідентифікатор шаблону, наданий третьою стороною, і використати його для зіставлення з файлом, який ми включили до нашої роботи, як описано раніше в публікації:
<?php
private function assign_template( $post_id, $template_name) {
$template_file = self::MAPPING[ $template_name ];
update_post_meta( $post_id, '_wp_page_template', $template_file );
}
І саме так ви можете створювати набагато менші, легші для читання та зручніші у використанні код і функції під час роботи з трохи складнішими запитами.
І таким чином, покращення читабельності
Для тих, хто звик писати, читати довгі методи або робити речі так, як більшість посібників в Інтернеті показують, як робити речі в WordPress, це може виглядати як багато безглуздого коду.
Але врахуйте це:
- Довші методи важче читати,
- Їх може бути важче налагодити,
- І вони не розбивають проблему на більш керовані частини.
Звичайно, я хотів би розбити це на ще більше класів із їхніми обов’язками, і я вірю, що це можна зробити, але, враховуючи природу WP_Query, це потребує трохи більше роботи.
Тож я намагався знайти якомога більше золотої середини.
Якщо ви працюєте з навіть трохи більш просунутим використанням WP_Query, тоді я рекомендую принаймні розглянути можливість розбити його на менші частини.
Це допомагає подбати про читабельність, потенційно про будь-яку зручність обслуговування, і писати чистіший код, а не один довгий метод із занадто великою кількістю умовних умов і опорою на безліч інших даних.