Статьи

Создание плагина Post Series для WordPress

Плагин WordPress Post Series позволяет вам систематизировать ваши посты, чтобы создать книгу или курс. Он предоставляет пользователям путь для обучения. Плагины серии сообщений также можно использовать для разбиения длинного сообщения на несколько частей.

В этом уроке я покажу вам, как создать плагин для отображения серии сообщений. Вы также можете интегрировать тот же код в тему, что и функциональность темы.

Таксономии против серии пост

В WordPress таксономии используются для группировки или организации похожих сообщений. Но WordPress не позволяет отображать все сообщения определенной таксономии в индивидуальном, последовательном порядке. Таксономии WordPress отображаются с использованием файла archive.php , поэтому мы не можем создать серию публикаций как один индексируемый пост.

Итак, нам нужна серия публикаций, которая на самом деле представляет собой одну публикацию, которая содержит другие сообщения в последовательном порядке.

Как создать серию сообщений

Существует много разных способов создания серии статей. Популярные плагины пост-серии, найденные на WordPress.org, используют пользовательские таксономии на постах WordPress для создания серии постов, но в этом уроке я буду использовать вместо них пользовательские типы постов.

Структура файла плагина

Создайте каталог плагинов с именем sitepoint-post-series и поместите в него два файла с именами sitepoint-post-series.php и sitepoint-post-series.css .

В файле sitepoint-post-series.php поместите приведенный ниже код, чтобы WordPress распознал каталог как плагин и позволил вам установить его.

 <?php  

Вы также можете добавить функциональность серии сообщений в тему. В этом случае вам нужно будет поместить весь код, указанный в этом руководстве, в файл functions.php темы.

Как создать пользовательский тип записей серии сообщений

Во-первых, нам нужно создать собственный тип записи, где каждый пользовательский тип записи представляет серию записей.

Поместите приведенный ниже код в файл с именем sitepoint-post-series.php :

 function sitepoint_post_series_custom_post_type() { register_post_type("sitepoint-postseries", array( "labels" => array("name" => __("Post Series"), "singular_name" => __("Post Series")), "public" => true, "has_archive" => true, "rewrite" => array("slug"=> "post-series"), "supports" => array("editor", "title", "excerpt", "thumbnail", "comments"), "capability_type" => "post", "publicly_queryable" => true, "taxonomies" => array("category", "post_tag"), ) ); } add_action("init", "sitepoint_post_series_custom_post_type", 2); /* Flush Rewrite Rules */ function sitepoint_post_series_activation() { sitepoint_post_series_custom_post_type(); flush_rewrite_rules(); } register_activation_hook( __FILE__, "sitepoint_post_series_activation"); register_deactivation_hook( __FILE__, "sitepoint_post_series_activation"); 

Здесь мы создали собственный тип записей с теми же таксономиями, которые используются в сообщениях WordPress. Это так, что вы также можете создать серию публикаций категории.

Мы также добавили хуки активации и деактивации для сброса правил перезаписи. Это сделано для того, чтобы серию публикаций можно было увидеть на переднем крае.

Вот как выглядит наш пользовательский тип записи на экране администратора:

Серия постов

Добавление мета-бокса серии постов в посты

Теперь нам нужно добавить мета-блоки в интерфейс администратора WordPress Posts. Это сделано для того, чтобы авторы могли прикрепить сообщение к серии публикаций и предоставить серийный номер для сортировки записей внутри серии публикаций.

Вот код для добавления мета-поля в серию публикаций:

 /* Add Custom Meta Boxes in WordPress Posts */ function sitepoint_post_series_meta_box_markup($object) { wp_nonce_field(basename(__FILE__), "sitepoint-postseries"); ?> <div> <label for="sitepoint-postseries-serial-number">Serial Number</label> <br> <input name="sitepoint-postseries-serial-number" type="text" value="<?php echo get_post_meta($object->ID, "sitepoint-postseries-serial-number", true); ?>"> <br> <label for="sitepoint-postseries-id">Name</label> <br> <select name="sitepoint-postseries-id"> <option value="">-</option> <?php $posts = get_posts("post_type=sitepoint-postseries"); $selected_series = get_post_meta($object->ID, "sitepoint-postseries-id", true); foreach($posts as $post) { $id_post = $post->ID; if($id_post == $selected_series) { ?> <option selected value="<?php echo $post->ID; ?>"><?php echo $post->post_title; ?></option> <?php } else { ?> <option value="<?php echo $post->ID; ?>"><?php echo $post->post_title; ?></option> <?php } } ?> </select> </div> <?php } function sitepoint_post_series_custom_meta_box() { add_meta_box("sitepoint-postseries", "Post Series", "sitepoint_post_series_meta_box_markup", "post", "side", "low", null); } add_action("add_meta_boxes", "sitepoint_post_series_custom_meta_box"); 

Здесь мы добавляем два поля в мета-поле. Текстовое поле используется автором для ввода серийного номера, а выпадающий список используется для выбора названия серии сообщений, к которой принадлежит сообщение. Если вы не хотите добавлять сообщение в серию сообщений, то одно или оба поля следует оставить пустыми.

Вот как это выглядит на экране администратора:

WordPress Post Series

Теперь нам нужно сохранить поля мета-поля при сохранении формы. Вот код для этого:

 /* Callback to Save Meta Data */ function sitepoint_post_series_save_custom_meta_box($post_id, $post, $update) { if(!isset($_POST["sitepoint-postseries"]) || !wp_verify_nonce($_POST["sitepoint-postseries"], basename(__FILE__))) return $post_id; if(!current_user_can("edit_post", $post_id)) return $post_id; if(defined("DOING_AUTOSAVE") && DOING_AUTOSAVE) return $post_id; $slug = "post"; if($slug != $post->post_type) return; $serial_number = null; if(isset($_POST["sitepoint-postseries-serial-number"])) { $serial_number = $_POST["sitepoint-postseries-serial-number"]; } else { $serial_number = ""; } update_post_meta($post_id, "sitepoint-postseries-serial-number", $serial_number); $series_id = null; if(isset($_POST["sitepoint-postseries-id"])) { $series_id = $_POST["sitepoint-postseries-id"]; } else { $series_id = ""; } $previous_series_id = get_post_meta($post_id, "sitepoint-postseries-id", true); update_post_meta($post_id, "sitepoint-postseries-id", $series_id); //no series, removing series, adding new series or changing series if($previous_series_id == "" && $series_id == "") { sitepoint_post_series_save_settings($series_id, $serial_number, $post_id); } else if($previous_series_id != "" && $series_id == "") { sitepoint_post_series_save_settings($previous_series_id, "", $post_id); } else if($previous_series_id == "" && $series_id != "") { sitepoint_post_series_save_settings($series_id, $serial_number, $post_id); } else if($previous_series_id != "" && $series_id != "") { sitepoint_post_series_save_settings($previous_series_id, "", $post_id); sitepoint_post_series_save_settings($series_id, $serial_number, $post_id); } } add_action("save_post", "sitepoint_post_series_save_custom_meta_box", 10, 3); 

Здесь мы сохраняем содержимое мета-блока и затем вызываем функцию sitepoint_post_series_save_settings с различными значениями аргументов в зависимости от того, удаляет ли пользователь серию, добавляет серию или изменяет серию.

Вот код для функции sitepoint_post_series_save_settings

 /* Store WordPress posts and Post Series CTY relations as WordPress Settings. */ function sitepoint_post_series_save_settings($series_id, $serial_number, $post_id) { if($series_id != "" && $serial_number != "") { $post_series_list = get_option("post_series_" . $series_id . "_ids", ""); if($post_series_list == "") { $post_series_list_array = array($post_id); $post_series_list = implode (", ", $post_series_list_array); update_option("post_series_" . $series_id . "_ids", $post_series_list); } else { $post_series_list_array = explode(',', $post_series_list); if(in_array($post_id, $post_series_list_array)) { //do nothing } else { $post_series_list_array[] = $post_id; $post_series_list = implode (", ", $post_series_list_array); update_option("post_series_" . $series_id . "_ids", $post_series_list); } } } else if($series_id == "" || $serial_number == "") { $post_series_list = get_option("post_series_" . $series_id . "_ids", ""); if($post_series_list == "") { } else { $post_series_list_array = explode(',', $post_series_list); if(in_array($post_id, $post_series_list_array)) { //here remove the post id from array. if(($key = array_search($post_id, $post_series_list_array)) !== false) { unset($post_series_list_array[$key]); } $post_series_list = implode (", ", $post_series_list_array); update_option("post_series_" . $series_id . "_ids", $post_series_list); } else { } } } } с /* Store WordPress posts and Post Series CTY relations as WordPress Settings. */ function sitepoint_post_series_save_settings($series_id, $serial_number, $post_id) { if($series_id != "" && $serial_number != "") { $post_series_list = get_option("post_series_" . $series_id . "_ids", ""); if($post_series_list == "") { $post_series_list_array = array($post_id); $post_series_list = implode (", ", $post_series_list_array); update_option("post_series_" . $series_id . "_ids", $post_series_list); } else { $post_series_list_array = explode(',', $post_series_list); if(in_array($post_id, $post_series_list_array)) { //do nothing } else { $post_series_list_array[] = $post_id; $post_series_list = implode (", ", $post_series_list_array); update_option("post_series_" . $series_id . "_ids", $post_series_list); } } } else if($series_id == "" || $serial_number == "") { $post_series_list = get_option("post_series_" . $series_id . "_ids", ""); if($post_series_list == "") { } else { $post_series_list_array = explode(',', $post_series_list); if(in_array($post_id, $post_series_list_array)) { //here remove the post id from array. if(($key = array_search($post_id, $post_series_list_array)) !== false) { unset($post_series_list_array[$key]); } $post_series_list = implode (", ", $post_series_list_array); update_option("post_series_" . $series_id . "_ids", $post_series_list); } else { } } } } 

Эта функция создает строку, в которой хранятся идентификаторы постов WordPress, которые принадлежат определенной серии. А затем он сохраняет строки в качестве настройки WordPress.

Теперь мы закончили со всем кодом области администратора. Теперь вы сможете создавать посты и назначать их в серию. А также назначьте категории и теги для каждой серии.

Теперь давайте закодируем интерфейс для отображения серии статей.

Как сделать серию публикаций видимой на главной странице и страницах архива

Пользовательский тип записи еще не виден на страницах индекса и архива. Чтобы сделать это видимым и на этих страницах, вам просто нужно добавить код ниже:

 /* Displaying Custom Post Types on Index Page */ function sitepoint_post_series_pre_posts($q) { if(is_admin() || !$q->is_main_query() || is_page()) return; $q->set("post_type", array("post", "sitepoint-postseries")); } add_action("pre_get_posts", "sitepoint_post_series_pre_posts"); 

Здесь мы используем хук pre_get_posts для добавления серии pre_get_posts в переменную $q , которая используется основным циклом для отображения записей.

Отображение сообщений серии сообщений

Нам нужно отфильтровать содержимое типа серии публикаций и добавить записи, принадлежащие серии.

Вот код для добавления сообщений серии сообщений на страницу серии сообщений.

 function sitepoint_post_series_content_filter($content) { $slug = "sitepoint-postseries"; if($slug != get_post_type()) return $content; $post_series_list = get_option("post_series_" . get_the_ID() . "_ids", ""); $post_series_list_array = explode(',', $post_series_list); $post_series_serial_number = array(); foreach($post_series_list_array as $key => $value) { $serial_number = get_post_meta($value, "sitepoint-postseries-serial-number", true); $post_series_serial_number[$value] = $serial_number; } asort($post_series_serial_number); $html = "<ul class='sitepoint-post-series'>"; foreach($post_series_serial_number as $key => $value) { $post = get_post($key); $title = $post->post_title; $excerpt = $post->post_content; $shortcode_pattern = get_shortcode_regex(); $excerpt = preg_replace('/' . $shortcode_pattern . '/', '', $excerpt); $excerpt = strip_tags($excerpt); $excerpt = esc_attr(substr($excerpt, 0, 150)); $img = ""; if(has_post_thumbnail($key)) { $temp = wp_get_attachment_image_src(get_post_thumbnail_id($key), array(150, 150)); $img = $temp[0]; } else { $img = "http://lorempixel.com/150/150/abstract"; } $html = $html . "<li><h3><a href='" . get_permalink($key) . "'>" . $title . "</a></h3><div><div class='sitepoint-post-series-box1'><img src='" . $img . "' /></div><div class='sitepoint-post-series-box2'><p>" . $excerpt . " ...</p></div></div><div class='clear'></div></li>"; } $html = $html . "</ul>"; return $content . $html; } add_filter("the_content", "sitepoint_post_series_content_filter"); 

Это отображает сообщения с использованием неупорядоченного тега списка HTML. Для постов без изображения мы загружаем изображение из облачного сервиса Lorempixel для генерации случайных текстурных изображений.

Мы извлекаем сообщения серии публикаций из установочной строки, которую мы сохранили при сохранении метаданных.

Добавление серии сообщений в сообщения

Мы также можем добавить поле серии сообщений к сообщениям, которые принадлежат серии сообщений, чтобы указать пользователю, что сообщение относится к определенной серии сообщений. Вот код для этого:

 /* Adding Content to WordPress Posts which belong to a Series */ function sitepoint_post_series_post_content_filter($content) { $slug = "post"; if($slug != get_post_type()) return $content; $serial_number = get_post_meta(get_the_ID(), "sitepoint-postseries-serial-number", true); $series_id = get_post_meta(get_the_ID(), "sitepoint-postseries-id", true); if(get_post_status($series_id) == "publish") { $html = ""; if($series_id != "" || $serial_number != "") { $html = "<div class='sitepoint-post-series-post-content'><div>This post is a part " . $serial_number . " of <a href='" . get_permalink($series_id) . "'>" . get_the_title($series_id) . "</a> post series.</div></div>"; } $content = $html . $content; } return $content; } 

Здесь мы просто показываем название серии статей и какая часть этой статьи относится к серии.

Вы также можете добавить следующий и предыдущий пост серии, используя приведенную ниже реализацию функции sitepoint_post_series_post_content_filter :

 function sitepoint_post_series_post_content_filter($content) { $slug = "post"; if($slug != get_post_type()) return $content; $serial_number = get_post_meta(get_the_ID(), "sitepoint-postseries-serial-number", true); $series_id = get_post_meta(get_the_ID(), "sitepoint-postseries-id", true); if($serial_number != "" && $series_id != "") { //find next and previous post too. $post_series_list = get_option("post_series_" . $series_id . "_ids", ""); $post_series_list_array = explode(',', $post_series_list); $post_series_serial_number = array(); foreach($post_series_list_array as $key => $value) { $serial_number = get_post_meta($value, "sitepoint-postseries-serial-number", true); $post_series_serial_number[$value] = $serial_number; } asort($post_series_serial_number); $post_series_serial_number_reverse = array(); $iii = 1; foreach($post_series_serial_number as $key => $value) { $post_series_serial_number_reverse[$iii] = $key; $iii++; } $index = array_search(get_the_ID(), $post_series_serial_number_reverse); if($index == 1) { $html = "<div class='sitepoint-post-series-post-content'><div>This post is a part of <a href='" . get_permalink($series_id) . "'>" . get_the_title($series_id) . "</a> post series.</div><div>&#9112; Next: <a href='" . get_permalink($post_series_serial_number_reverse[$index + 1]) . "'>" . get_the_title($post_series_serial_number_reverse[$index + 1]) . "</a></div></div>"; $content = $html . $content; } else if($index > 1 && $index < sizeof($post_series_serial_number_reverse)) { $html = "<div class='sitepoint-post-series-post-content'><div>This post is a part of <a href='" . get_permalink($series_id) . "'>" . get_the_title($series_id) . "</a> post series.</div><div>&#9112; Next post in the series is <a href='" . get_permalink($post_series_serial_number_reverse[$index + 1]) . "'>" . get_the_title($post_series_serial_number_reverse[$index + 1]) . "</a></div><div>&#9111; Previous post in the series is <a href='" . get_permalink($post_series_serial_number_reverse[$index - 1]) . "'>" . get_the_title($post_series_serial_number_reverse[$index - 1]) . "</a></div></div>"; $content = $html . $content; } else if($index == sizeof($post_series_serial_number_reverse)) { $html = "<div class='sitepoint-post-series-post-content'><div>This post is a part of <a href='" . get_permalink($series_id) . "'>" . get_the_title($series_id) . "</a> post series.</div><div>&#9111; Previous: <a href='" . get_permalink($post_series_serial_number_reverse[$index - 1]) . "'>" . get_the_title($post_series_serial_number_reverse[$index - 1]) . "</a></div></div>"; $content = $html . $content; } } return $content; } 

Проблема с этой реализацией состоит в том, что код достигает MySQL количество раз, равное количеству сообщений в серии. Существует проблема с производительностью, если у вас есть много постов для определенной серии статей, но я включил ее в образовательных целях.

Сравнение нашего плагина с другими плагинами серии Post

Вот некоторые из плагинов на WordPress.org, которые позволяют вам создавать серии публикаций. Я сравнил каждый с плагином, который мы создали выше.

  1. Organize Series : Organize Series добавляет пользовательскую таксономию к сообщениям WordPress. При просмотре пользовательской таксономии она добавляет заголовок на страницу архива, который выглядит как заголовок серии статей. А посты в серии постов отображаются как таксономии, что может быть не очень хорошо с точки зрения пользователя. Для сравнения, наш плагин использует настраиваемые типы записей для отображения отдельных серий публикаций, так что вы можете добавлять избранные изображения, текст или контент разметки (и многое другое) в серию публикаций. Посты серии постов выглядят иначе, чем страница архива в нашем плагине.
  2. WP Post Series : он также ведет себя как плагин Organize Series. Одно из отличий состоит в том, что он не предоставляет никаких настроек для страницы серии публикаций.

Наш плагин очень настраиваемый и не включает в себя никаких хаков WordPress. Как таковая, она гораздо более совместима.

Вывод

Если у вас есть блог для разработчиков, то вы можете использовать этот плагин для создания своих собственных публикаций, которые могут повысить вашу вовлеченность и коэффициент конверсии. Вы даже можете использовать его, чтобы разделить ваши большие сообщения на несколько сообщений.

Не стесняйтесь комментировать свой опыт с плагином ниже.