Учебники

Добавление шаблонов страниц в WordPress с помощью плагина

Добавление шаблонов страниц в WordPress с помощью плагина

Обновление: код был недавно обновлен для работы на WordPress 4.7+.

Вы когда-нибудь хотели создать свои собственные шаблоны страниц, но не имели доступа к самой теме? Я, как автор плагина WordPress, обнаружил, что эта проблема особенно раздражает при разработке моих плагинов. К счастью, решение довольно простое! Я собираюсь быстро провести вас по нескольким строкам кода, которые вам понадобятся для динамического создания шаблонов страниц WordPress непосредственно через PHP.

Вдохновение для этой статьи и гениальность решения кода исходят от Тома МакФарлина: я использую свою отредактированную версию его исходного кода, которую вы можете найти на его GitHub. Я сохранил его комментарии (а также добавил свои собственные), так как считаю их очень полезными в объяснении происходящего – я сам не мог бы сказать этого лучше!

Вы можете найти код целиком и пример плагина в самом низу этого поста.

Начнем?

КОД

Мы создадим нашу функцию PHP, используя класс PHP. Для тех из вас, кто плохо разбирается в классах PHP, класс определяется как объект, содержащий набор функций и переменных, которые работают вместе. Ознакомьтесь с введением PHP.net для получения более подробной информации о синтаксисе и теории.

Нашей обертке потребуется всего 3 переменные:

  1. Слаг плагина: он просто используется как уникальный идентификатор для плагина.
  2. Экземпляр класса: поскольку мы добавляем экземпляр этого класса в заголовок WordPress, нам лучше сохранить его.
  3. Массив шаблонов: как вы, наверное, догадались, это массив, содержащий имена и заголовки шаблонов.

Вот они в коде:

class PageTemplater { /** * A Unique Identifier */ protected $plugin_slug; /** * A reference to an instance of this class. */ private static $instance; /** * The array of templates that this plugin tracks. */ protected $templates;

Получить экземпляр класса

Как я сказал ранее, мы добавим экземпляр нашего класса в заголовок WordPress с помощью функции add_filter(). Поэтому нам понадобится метод, который вернет (или создаст) этот экземпляр для нас.

Для этого нам понадобится простой метод, который будет называться get_instance. Проверьте это ниже;

/** * Returns an instance of this class. */ public static function get_instance() { if( null == self::$instance) { self::$instance = new PageTemplater(); } return self::$instance; }

Это будет метод, вызываемый при добавлении нашего класса в заголовок WordPress с помощью add_action ().

Фильтры WordPress

Теперь мы разобрались с методом get_instance, нам нужно разобраться, что происходит, когда он фактически создается.

Мы будем использовать встроенную функцию WordPress add_filter (), чтобы добавить экземпляр нашего класса в ключевые точки на временной шкале инициализации WordPress. Используя этот метод, мы вставим данные наших шаблонов страниц в соответствующие слоты, например, сообщим WordPress, какой файл использовать в качестве шаблона при вызове страницы, и заголовок, который будет отображаться в раскрывающемся меню в редакторе страниц.

Для этого нам нужно использовать метод __construct (он будет запущен при создании экземпляра класса).

/** * Initializes the plugin by setting filters and administration functions. */ private function __construct() { $this->templates = array(); // Add a filter to the attributes metabox to inject template into the cache. if (version_compare( floatval( get_bloginfo( 'version') ), '4.7', '<') ) { // 4.6 and older add_filter( 'page_attributes_dropdown_pages_args', array( $this, 'register_project_templates') ); } else { // Add a filter to the wp 4.7 version attributes metabox add_filter( 'theme_page_templates', array( $this, 'add_new_template') ); } // Add a filter to the save post to inject out template into the page cache add_filter( 'wp_insert_post_data', array( $this, 'register_project_templates') ); // Add a filter to the template include to determine if the page has our // template assigned and return it's path add_filter( 'template_include', array( $this, 'view_project_template') ); // Add your templates to this array. $this->templates = array( 'goodtobebad-template.php' => 'It's Good to Be Bad', ); }

Здесь происходят 4 разные вещи (игнорируя ‘$ this-> templates = array ();’, который просто подготавливает переменную к использованию);

  1. Строки 9–13: этот фильтр добавляет ‘register_project_templates’ к ловушке ‘page_attributes_dropdown_pages_args’. Это заполняет кеш WordPress нашими новыми шаблонами, «обманывая» WordPress, заставляя его поверить в то, что файлы шаблонов страниц действительно существуют в каталоге шаблонов. Это добавляет шаблоны страниц в раскрывающийся список в мета-поле атрибутов страницы в редакторе страницы.
  2. Строки 16–20: Здесь мы делаем то же самое, что и в предыдущем блоке кода, за исключением того, что на этот раз мы также добавляем наш шаблон страницы (если он выбран) к сохраненным данным публикации.
  3. Строки 23–28: этот фильтр добавляет «template_include» к «view_project_template». Это очень важная функция; это сообщает WordPress, где на самом деле находится файл шаблона вашей страницы. WordPress будет использовать предоставленный путь для рендеринга последней страницы.
  4. Строки 31 – 34: Хотя это просто, но очень важно. Здесь вы указываете шаблоны страниц, которые хотите добавить, и путь относительно файла, в котором находится файл шаблона страницы (например, «something.php»). Я включил один пример (который будет использоваться в примере плагина). Ниже приведен общий пример:
$this->templates = array( 'FILE_PATH_AND_NAME' => 'TEMPLATE_TITLE', 'awesome-template.php' => 'Awesome', 'templates/organised-template.php' => 'Organised', );

(Ешьте, спите) Кодируйте, повторяйте при необходимости.

register_project_templates ()

Я уже упоминал об этом методе ранее; посмотрим, что он на самом деле делает.

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

public function register_project_templates( $atts) { // Create the key used for the themes cache $cache_key = 'page_templates-'. md5( get_theme_root(). '/'. get_stylesheet() ); // Retrieve the cache list. // If it doesn't exist, or it's empty prepare an array $templates = wp_get_theme()->get_page_templates(); if (empty( $templates) ) { $templates = array(); } // New cache, therefore remove the old one wp_cache_delete( $cache_key, 'themes'); // Now add our template to the list of templates by merging our templates // with the existing templates array from the cache. $templates = array_merge( $templates, $this->templates ); // Add the modified cache to allow WordPress to pick it up for listing // available templates wp_cache_add( $cache_key, $templates, 'themes', 1800 ); return $atts; }

Прямо тогда. Строка 4 – это первое, куда нужно смотреть. Как вы уже догадались, мы генерируем «ключ кеша». Он будет использоваться как уникальный идентификатор для данных шаблона нашей страницы. Использование функции md5 () просто создает уникальный строковый идентификатор, чтобы избежать конфликтов.

Затем, в строке 8, мы ищем и извлекаем кеш шаблона страницы (если он уже существует): это вернет массив путей и заголовков. В строках 9-11 мы проверяем, есть ли какие-либо выходные данные из запроса кеша. Если да, отлично. Если нет, создайте локальный массив для хранения данных, которые мы будем объединять в кеш.

Следующий шаг очень важен. В строке 14 мы удаляем существующий кеш шаблонов страниц. Не волнуйтесь, данные не теряются – они хранятся в переменной $ templates.

В строке 18 мы объединяем существующий кеш шаблонов страниц с нашими новыми записями, а в строке 22 мы повторно вставляем весь кеш шаблонов страниц в систему WordPress.

Просто!

view_project_template ()

Теперь мы подошли к нашему последнему методу; здесь мы сообщаем WordPress, где находится настоящий файл шаблона страницы.

/** * Checks if the template is assigned to the page */ public function view_project_template( $template) { // Get global post global $post; // Return template if post is empty if (! $post) { return $template; } // Return default template if we don't have a custom one defined if (!isset( $this->templates[get_post_meta( $post->ID, '_wp_page_template', true )]) ) { return $template; } $file = plugin_dir_path(__FILE__). get_post_meta( $post->ID, '_wp_page_template', true ); // Just to be safe, we check if the file exist first if (file_exists( $file) ) { return $file; } else { echo $file; } // Return template return $template; }

Хорошо, тогда этот метод будет проверять по глобальной переменной $ post (строка 6). Он проверяет, установлен ли шаблон страницы (‘_wp_page_template’) для публикации (то есть это должна быть страница). Если нет, то ничего – не страницы не могут иметь шаблоны страниц.

Строка 16 определяет расположение файла шаблона страницы. Как я указал выше, он проверяет указанный файл шаблона страницы в корневом каталоге вашего плагина. (Это можно легко изменить; см. Ниже.)

// Just changing the page template path // WordPress will now look for page templates in the subfolder 'templates', // instead of the root $file = plugin_dir_path(__FILE__). 'templates/' .get_post_meta( $post->ID, '_wp_page_template', true );

После этого в строках 21–24 у нас есть лишь небольшая часть проверки, которая проверяет, действительно ли файл существует. Если да, то отлично! Если нет, о боже… Вы, скорее всего, получите сообщение об ошибке PHP, если WordPress не может найти файл шаблона или даже пустой экран. Если какой-либо из этих симптомов кажется вам знакомым, просто проверьте путь к файлу шаблона, выведя на экран переменную $ file.

Если вы планируете использовать этот код в коммерческих целях (что вы можете делать по своему усмотрению – моя версия кода не имеет лицензии, поэтому вы можете поступать с ним по своему усмотрению), я действительно рекомендую потратить некоторое время на обработку ошибок для достижения максимальной надежность.

Вот и все. Когда наш класс завершен, осталось сделать только одно – добавить его в заголовок WordPress.

add_action( 'plugins_loaded', array( 'PageTemplater', 'get_instance') );

Поздравляю, если вы прошли его полностью! Надеюсь, вы нашли то, что я сказал, полезным и извлекли из этого пользу в будущем!

ВЕСЬ КОД

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

<?php /* Plugin Name: Page Template Plugin: 'Good To Be Bad' Plugin URI: http://www.wpexplorer.com/wordpress-page-templates-plugin/ Version: 1.1.0 Author: WPExplorer Author URI: http://www.wpexplorer.com/ */ class PageTemplater { /** * A reference to an instance of this class. */ private static $instance; /** * The array of templates that this plugin tracks. */ protected $templates; /** * Returns an instance of this class. */ public static function get_instance() { if (null == self::$instance) { self::$instance = new PageTemplater(); } return self::$instance; } /** * Initializes the plugin by setting filters and administration functions. */ private function __construct() { $this->templates = array(); // Add a filter to the attributes metabox to inject template into the cache. if (version_compare( floatval( get_bloginfo( 'version') ), '4.7', '<') ) { // 4.6 and older add_filter( 'page_attributes_dropdown_pages_args', array( $this, 'register_project_templates') ); } else { // Add a filter to the wp 4.7 version attributes metabox add_filter( 'theme_page_templates', array( $this, 'add_new_template') ); } // Add a filter to the save post to inject out template into the page cache add_filter( 'wp_insert_post_data', array( $this, 'register_project_templates') ); // Add a filter to the template include to determine if the page has our // template assigned and return it's path add_filter( 'template_include', array( $this, 'view_project_template') ); // Add your templates to this array. $this->templates = array( 'goodtobebad-template.php' => 'It's Good to Be Bad', ); } /** * Adds our template to the page dropdown for v4.7+ * */ public function add_new_template( $posts_templates) { $posts_templates = array_merge( $posts_templates, $this->templates ); return $posts_templates; } /** * Adds our template to the pages cache in order to trick WordPress * into thinking the template file exists where it doens't really exist. */ public function register_project_templates( $atts) { // Create the key used for the themes cache $cache_key = 'page_templates-'. md5( get_theme_root(). '/'. get_stylesheet() ); // Retrieve the cache list. // If it doesn't exist, or it's empty prepare an array $templates = wp_get_theme()->get_page_templates(); if (empty( $templates) ) { $templates = array(); } // New cache, therefore remove the old one wp_cache_delete( $cache_key, 'themes'); // Now add our template to the list of templates by merging our templates // with the existing templates array from the cache. $templates = array_merge( $templates, $this->templates ); // Add the modified cache to allow WordPress to pick it up for listing // available templates wp_cache_add( $cache_key, $templates, 'themes', 1800 ); return $atts; } /** * Checks if the template is assigned to the page */ public function view_project_template( $template) { // Get global post global $post; // Return template if post is empty if (! $post) { return $template; } // Return default template if we don't have a custom one defined if (! isset( $this->templates[get_post_meta( $post->ID, '_wp_page_template', true )]) ) { return $template; } $file = plugin_dir_path( __FILE__ ). get_post_meta( $post->ID, '_wp_page_template', true ); // Just to be safe, we check if the file exist first if (file_exists( $file) ) { return $file; } else { echo $file; } // Return template return $template; } } add_action( 'plugins_loaded', array( 'PageTemplater', 'get_instance') );

ПЛАГИН

Вы также можете скачать полный код в виде плагина на Github.

ПОСЛЕ РЕДАКТОРА КРУПНЫЙ ПЛАН

Вот крупный план плагина в действии. См. Шаблон страницы, добавленный в Атрибуты страницы?

Добавление шаблонов страниц в WordPress с помощью плагина

Источник записи: https://www.wpexplorer.com

Похожие сообщения
Windows инструкцииWordPressПлагиныУчебники

Плюсы и минусы многосайтового WordPress (и как установить на локальный Xampp)

WordPressВедение блоговУчебники

5 советов по устранению дублированного контента в Wordpress

WordPressПлагиныУчебники

Форумы bbPress для WordPress: краткое руководство

Учебники

Создайте портал агрегирования новостей RSS с помощью WordPress