Agregue plantillas de página a WordPress con un complemento

Agregue plantillas de página a WordPress con un complemento

Poner al día: El código se actualizó recientemente para funcionar en WordPress 4.7+

¿Alguna vez ha querido crear sus propias plantillas de página, pero no tenía acceso al tema en sí? Como autor de complementos de WordPress, encontré este problema particularmente molesto mientras desarrollaba mis complementos. ¡Afortunadamente, la solución es bastante simple! Lo guiaré rápidamente a través de las pocas líneas de código que necesitará para crear dinámicamente plantillas de página de WordPress directamente a través de PHP.

La inspiración para este artículo y la genialidad detrás de la solución de código provienen de Tom mcfarlin: Estoy usando mi versión modificada de su código original, que puedes encontrar en su GitHub. He guardado sus comentarios (además de agregar algunos de los míos) porque lo encuentro muy útil para explicar lo que está sucediendo, ¡no podría haberlo dicho mejor yo mismo!

Puede encontrar el código en su totalidad y un complemento de muestra al final de este artículo.

¿Empezamos?

El código

Vamos a crear nuestra función PHP usando una clase PHP. Para aquellos que no están familiarizados con las clases de PHP, una clase se define como un objeto que contiene una colección de funciones y variables que trabajan juntas. Controlar Introducción a PHP.net para obtener más detalles sobre la sintaxis y la teoría.

Nuestro contenedor solo necesitará 3 variables:

  1. El complemento Slug: Esto simplemente se usa como un identificador único para el complemento.
  2. Instancia de clase: Como estamos agregando una instancia de esta clase al encabezado de WordPress, será mejor que la almacenemos.
  3. Tabla de modelos: Como probablemente pueda adivinar, esta es una matriz con los nombres y títulos de los modelos.

Aquí están en código:

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;

Obtener una instancia de clase

Como dije antes, agregaremos una instancia de nuestra clase al encabezado de WordPress usando el Añadir filtro () Una función. Por lo tanto, necesitaremos un método que nos devuelva (o cree) esta instancia.

Para eso, necesitaremos un método simple, que se llamará ‘get_instance’. Descúbrelo a continuación;

/**
 * Returns an instance of this class. 
 */
public static function get_instance() {

	if( null == self::$instance ) {
		self::$instance = new PageTemplater();
	} 

	return self::$instance;

}

Este será el método llamado cuando nuestra clase se agregue al encabezado de WordPress usando ‘add_action ()’.

Filtros de WordPress

Ahora que hemos ordenado el método ‘get_instance’, necesitamos resolver qué sucede cuando realmente se crea una instancia.

Usaremos los elementos incorporados de WordPress Añadir filtro () para agregar una instancia de nuestra clase en puntos clave a lo largo de la línea de tiempo de inicialización de WordPress. Usando este método, insertaremos los datos de nuestras plantillas de página en las ubicaciones apropiadas, como decirle a WordPress qué archivo usar como plantilla cuando se llama a la página, y el título para mostrar en el menú desplegable del editor de página.

Para esto tenemos que usar el ‘__construcción’ (se ejecutará cuando se cree una instancia de la clase).

/**
 * 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',
	);

}

Aquí están sucediendo 4 cosas diferentes (ignorando ‘$ this-> templates = array ();’, que solo prepara la variable para su uso);

  1. Líneas 9 a 13: Este filtro agrega ‘register_project_templates’ al gancho ‘page_attributes_dropdown_pages_args’. Esto llena el caché de WordPress con nuestras nuevas plantillas, “engañando” a WordPress haciéndole creer que los archivos de plantilla de página realmente existen en el directorio de plantillas. Esto agrega las plantillas de página a la lista desplegable del meta-cuadro de atributos de página en el editor de página.
  2. Líneas 16 a 20: Aquí básicamente estamos haciendo lo mismo que el bloque de código anterior, excepto que esta vez también agregamos nuestra plantilla de página (si está seleccionada) a los datos de publicación guardados.
  3. Líneas 23 a 28: Este filtro agrega el “template_include” al gancho “view_project_template”. Ésta es una función muy importante; esto le dice a WordPress dónde se encuentra realmente el archivo de plantilla de su página. WordPress utilizará la ruta proporcionada por él para representar la página final.
  4. Líneas 31 a 34: Aunque es simple, es muy importante. Aquí es donde especifica las plantillas de página que desea agregar y el ruta relativa al archivo donde se encuentra el archivo de plantilla de página (por ejemplo, ‘algo.php’). He incluido un ejemplo (que se utilizará en el complemento de ejemplo). Vea a continuación un ejemplo general:
$this->templates = array(
	'FILE_PATH_AND_NAME'               => 'TEMPLATE_TITLE',
	'awesome-template.php'             => 'Awesome',
	'templates/organised-template.php' => 'Organised',
);

(Comer, dormir) Codificar, repetir si es necesario.

register_project_templates ()

Ya he aludido a este método; veamos qué hace realmente.

Básicamente, el propósito de este método es manipular la caché de WordPress, insertando los datos relevantes en nuestras plantillas de página en los lugares correctos. Primero mira el código y luego te lo contaré.

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;

}

Bien entonces. La línea 4 es el primer lugar para buscar. Como habrás adivinado, generamos una “clave de caché”. Se utilizará como identificador único para nuestro datos de la plantilla de página. El uso de la función md5 () solo crea una identificación de cadena única para evitar conflictos.

Luego, en la línea 8, buscamos y recuperamos la caché de la plantilla de página (si ya existe): esto devolverá una matriz de rutas y títulos. En las líneas 9 a 11, verificamos si hubo algún resultado de la solicitud de caché. Si es así, perfecto. De lo contrario, cree una matriz local para contener los datos que fusionaremos en la caché.

El siguiente paso es crucial. En la línea 14 nosotros borrar la caché de plantilla de página existente. No se preocupe, no se pierden datos, se almacenan en la variable $ templates.

En la línea 18 fusionamos el caché de las plantillas de página existentes con nuestras nuevas entradas, y en la línea 22 reinsertamos todo el caché de plantillas de página en el sistema de WordPress.

¡Sencillo!

view_project_template ()

Ahora estamos en nuestro método final; aquí es donde le decimos a WordPress dónde se encuentra el archivo de plantilla de página real.

/**
 * 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;

}

Bien, entonces, este método se comparará con la variable global $ post (línea 6). Comprueba si se ha definido una plantilla de página (‘_wp_page_template’) para el mensaje (lo que significa que debe ser una página). De lo contrario, lástima, las no páginas no pueden tener plantillas de página.

La línea 16 especifica la ubicación del archivo de plantilla de página. Como dije anteriormente, verifica el archivo de plantilla de página especificado en el directorio raíz de su complemento. (Esto se puede cambiar fácilmente, ver más abajo).

// 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 
);

Después de eso, en las líneas 21-24 solo tenemos un poco de validación que verifica si el archivo realmente existe. Si es así, ¡genial! De lo contrario, oh cielos … Probablemente obtendrá un mensaje de error de PHP si WordPress no puede encontrar el archivo de plantilla, o incluso una pantalla en blanco. Si alguno de estos síntomas le suena familiar, simplemente verifique la ruta al archivo de plantilla imprimiendo la variable $ file en la pantalla.

Si planea usar este código comercialmente (lo cual es libre de hacer, mi versión del código no tiene licencia, por lo que puede hacerlo como desee), realmente recomiendo invertir un poco de tiempo en el manejo de errores para obtener la máxima confiabilidad. .

Eso es. Una vez que termina nuestro curso, solo queda una cosa por hacer: agregarlo al encabezado de WordPress.

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

¡Felicitaciones si ha tenido éxito todo el tiempo! Espero que haya encontrado útil lo que tengo que decir y se beneficie de ello en el futuro.

Código entero

A continuación se muestra el código del complemento completo para copiar y pegar fácilmente.

<?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' ) );

El complemento

También puede descargar el código completo como complemento en Github.

Primer plano del redactor

Aquí hay un primer plano del complemento en acción. ¿Ve la plantilla de página agregada en Atributos de página?

GTBB1

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Ir arriba