Passer au contenu principal




Mettre à jour: El código se ha actualizado recientemente para funcionar en WordPress 4.7+

¿Alguna vez ha querido crear sus propias plantillas de página, pero no ha tenido acceso al tema en sí? Yo, como autor de complementos de WordPress, he encontrado que este problema es particularmente molesto al desarrollar mis complementos. ¡Por suerte, la solución es bastante simple! Lo llevaré 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 de forma directa a través de PHP.

L'inspiration pour cet article et le génie derrière la solution de code vient de Tom Mcfarlin: J'utilise ma version modifiée de votre code d'origine, que vous pouvez trouver sur votre GitHub. J'ai enregistré vos commentaires (et j'en ai ajouté quelques-uns) car je trouve cela très utile pour expliquer ce qui se passe. Je n'aurais pas pu mieux le dire moi-même!

Vous pouvez trouver le code dans son intégralité et un exemple de plugin à la fin de cet article.

Devrions-nous commencer?

LE CODE

Nous allons créer notre fonction PHP en utilisant une classe PHP. Pour ceux d'entre vous qui ne connaissent pas bien les classes PHP, une classe est définie comme un objet contenant une collection de fonctions et de variables qui fonctionnent ensemble. Revoir le Introduction à PHP.net pour plus de détails sur la syntaxe et la théorie.

Notre conteneur n'aura besoin que de 3 variables:

  1. le brancher Slug: Esto simplemente se usa como un Identifiant unique para el complemento.
  2. Instance de classe: Puisque nous ajoutons une instance de cette classe à l'en-tête WordPress, nous ferons mieux de la stocker.
  3. Matrice de modèle: Comme vous pouvez probablement le deviner, il s'agit d'un tableau contenant les noms et les titres des modèles.

Les voici en code:

class PageTemplater {/ ** * Un identifiant unique * / protected $plugin_slug; / ** * Une référence à une instance de cette classe. * / $instance statique privée; / ** * Le tableau de modèles que ce plugin suit. * / $templates protégés;

Obtenir une instance de classe

Comme je l'ai dit précédemment, nous allons ajouter une instance de notre classe à l'en-tête WordPress en utilisant le Ajouter un filtre () une fonction. Par conséquent, nous aurons besoin d'une méthode qui nous renvoie (ou crée) cette instance.

Pour cela, nous aurons besoin d'une méthode simple, qui s'appellera 'get_instance'. Vérifiez-le ci-dessous;

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

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

	return self::$instance;

}

Ce sera la méthode appelée lorsque notre classe est ajoutée à l'en-tête WordPress en utilisant 'add_action ()'.

Filtres WordPress

Maintenant que nous avons résolu la méthode 'get_instance', nous devons clarifier ce qui se passe lorsqu'une instance est réellement créée.

Usaremos el Logiciel incorporado de WordPress. Ajouter un filtre () pour ajouter une instance de notre classe à des points clés le long de la chronologie d'initialisation de WordPress. Avec cette méthode, nous insérerons les données de nos modèles de page dans des espaces appropriés, comme indiquer à WordPress quel fichier utiliser comme modèle lorsque la page est appelée et le titre à afficher dans le menu déroulant de l'éditeur de page.

Pour cela, nous devons utiliser le '__construire' método (esto se ejecutará cuando la clase être instanciada).

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

}

Ici, 4 choses différentes se produisent (en ignorant '$ this-> templates = array ();', qui prépare juste la variable pour l'utilisation);

  1. Lignes 9 à 13: Este filtro agrega ‘register_project_templates’ al gancho ‘page_attributes_dropdown_pages_args’. Esto está llenando el cache de WordPress con nuestras nuevas plantillas, ‘engañando’ a WordPress haciéndole creer que los archivos de plantilla de página existen realmente en el directorio de plantillas. Esto agrega las plantillas de página a la lista desplegable en el meta cuadro de atributos de página en el editor de páginas.
  2. Lignes 16 à 20: Ici, nous faisons essentiellement la même chose que le bloc de code ci-dessus, sauf que cette fois, nous ajoutons notre modèle de page (s'il est sélectionné) aux données de sauvegarde de l'article en même temps.
  3. Lignes 23-28: Ce filtre ajoute le 'template_include' au hook 'view_project_template'. C'est une fonction très importante; cela indique à WordPress où se trouve réellement votre fichier de modèle de page. WordPress utilisera le chemin fourni par celui-ci pour rendre la page finale.
  4. Lignes 31 à 34: Bien que ce soit simple, c'est très important. C'est ici que vous spécifiez les modèles de page que vous souhaitez ajouter et le chemin relatif vers le fichier où se trouve le fichier de modèle de page (par exemple 'something.php'). J'ai inclus un exemple (à utiliser dans l'exemple de plugin). Voir ci-dessous pour un exemple général:
$this-> templates = array ('FILE_PATH_AND_NAME' => 'TEMPLATE_TITLE', 'awesome-template.php' => 'Génial', 'templates / organisé-template.php' => 'Organisé',);

(Mangez, dormez) Code, répétez au besoin.

register_project_templates ()

J'ai fait allusion à cette méthode précédemment; voyons ce qu'il fait réellement.

Fondamentalement, le but de cette méthode est de manipuler le cache WordPress, en insérant les données pertinentes sur nos modèles de page aux bons endroits. Jetez d'abord un œil au code, puis je vous expliquerai.

public function register_project_templates ($atts) {// Crée la clé utilisée pour le cache des thèmes $cache_key = 'page_templates-'. md5 (get_theme_root (). '/'. get_stylesheet ()); // Récupère la liste de cache. // S'il n'existe pas ou s'il est vide, préparez un tableau $templates = wp_get_theme () -> get_page_templates (); if (vide ($templates)) {$templates = array (); } // Nouveau cache, supprimez donc l'ancien wp_cache_delete ($cache_key, 'themes'); // Ajoutez maintenant notre modèle à la liste des modèles en fusionnant nos modèles // avec le tableau de modèles existant du cache. $templates = array_merge ($templates, $this-> templates); // Ajouter le cache modifié pour permettre à WordPress de le récupérer pour lister // les modèles disponibles wp_cache_add ($cache_key, $templates, 'themes', 1800); return $atts; }

À ce moment précis. La ligne 4 est le premier endroit à regarder. Comme vous l'avez peut-être deviné, nous générons une «clé de cache». Il sera utilisé comme identifiant unique pour notre données de modèle de page. L'utilisation de la fonction md5 () crée simplement un identifiant de chaîne unique pour éviter les conflits.

Ensuite, à la ligne 8, nous recherchons et récupérons le cache du modèle de page (s'il existe déjà) - cela renverra un tableau de chemins et de titres. Aux lignes 9 à 11, nous vérifions s'il y a eu des résultats de la requête de cache. Si oui, tant mieux. Sinon, créez un tableau local pour contenir les données que nous mettrons en cache.

La prochaine étape est cruciale. Sur la ligne 14 nous Effacer le cache de modèle de page existant. Ne vous inquiétez pas, aucune donnée n'est perdue, elle est stockée dans la variable des modèles $.

À la ligne 18, nous fusionnons le cache de modèle de page existant avec nos nouvelles entrées, et à la ligne 22, nous réinsérons le cache de modèle de page entier dans le système WordPress.

Facile!

view_project_template ()

Nous sommes maintenant dans notre méthode finale; C'est là que nous indiquons à WordPress où se trouve le fichier de modèle de page réel.

/ ** * Vérifie si le modèle est affecté à la page * / public function view_project_template ($template) {// Get global post global $post; // Renvoie le modèle si l'article est vide if (! $post) {return $template; } // Retourne le modèle par défaut si nous n'avons pas de modèle personnalisé défini 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); // Juste pour être sûr, nous vérifions si le fichier existe en premier if (file_exists ($file)) {return $file; } else {echo $file; } // Modèle de retour return $template; }

D'accord, cette méthode sera comparée à la variable globale post $ (ligne 6). Vérifie si un modèle de page ('_wp_page_template') a été configuré pour le message (ce qui signifie qu'il doit s'agir d'une page). Sinon, cela n'a pas d'importance: les non-pages ne peuvent pas avoir de modèles de page.

La línea 16 especifica la ubicación del archivo de plantilla de página. Como he establecido previamente, verifica el archivo de plantilla de página especificado en el répertoire racine de su complemento. (A pesar de todo, esto se puede cambiar fácilmente; consulte a continuación).

// Il suffit de changer le chemin du modèle de page // WordPress recherchera maintenant les modèles de page dans le sous-dossier 'templates', // au lieu de la racine $file = plugin_dir_path (__ FILE__). 'templates /' .get_post_meta ($post-> ID, '_wp_page_template', true);

Après cela, aux lignes 21-24, nous avons juste un peu de validation qui vérifie si le fichier existe réellement. Si oui, super! Sinon, oups ... Vous obtiendrez probablement un message d'erreur PHP si WordPress ne trouve pas le fichier modèle, ou même un écran vide. Si l'un de ces symptômes vous semble familier, vérifiez simplement le chemin du fichier modèle en imprimant la variable de fichier $ à l'écran.

Si vous envisagez d'utiliser ce code dans le commerce (ce qui est gratuit, ma version du code est sans licence, vous pouvez donc en faire ce que vous voulez), je vous recommande vraiment de passer un peu de temps sur la gestion des erreurs pour en tirer le meilleur parti. fiabilité.

C'est ça. Une fois notre cours terminé, il ne reste plus qu'une chose à faire: l'ajouter à l'en-tête WordPress.

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

Félicitations si vous l'avez fait! J'espère que vous avez trouvé ce que j'ai à dire utile et que vous en bénéficierez à l'avenir.

CODE COMPLET

Vous trouverez ci-dessous le code complet du plugin pour un copier-coller facile.

<?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: R Marketing Digital
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' ) );

LE PLUGIN

En même temps, vous pouvez télécharger le code complet en tant que plugin sur Github.

CLOSE-UP DE LA RÉDACTION

Voici un gros plan du plugin en action. Voir le modèle de page ajouté dans Attributs de page?

gtbb1-9342144