17713433920 info@mac163.com
使用插件将页面模板添加到wordpress
使用插件将页面模板添加到wordpress
更新:该代码最近已更新,可以在WordPress 4.7+上运行

您是否曾经想过创建自己的页面模板,但是没有访问主题本身的权限?作为WordPress插件作者,我发现在开发我的插件时,这个问题特别令人讨厌。幸运的是,解决方案非常简单!我将带您快速通过几行代码,您将需要直接通过PHP动态创建WordPress页面模板。

本文的灵感和代码解决方案背后的天才来自Tom McFarlin:我正在使用他原始代码的编辑版本,您可以在他的GitHub上找到该代码。我一直在评论他(以及添加一些自己的评论),因为我发现它对解释正在发生的事情非常有帮助–我自己也不能说得更好!

您可以在本文的最底部找到完整的代码和示例插件。

让我们开始?

代码

我们将使用PHP类创建PHP函数。对于那些不熟悉PHP类的人,将类定义为一个对象,其中包含可一起使用的函数和变量的集合。请查看PHP.net简介,以获取有关语法和理论的更多详细信息。

我们的包装器只需要3个变量:

  1. Plugin Slug:这只是用作插件的唯一标识符。
  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;

获取类实例

如前所述,我们将使用add_filter()函数将类的实例添加到WordPress标头中。因此,我们需要一个为我们返回(或创建)此实例的方法。

为此,我们需要一个简单的方法,称为“ get_instance”。在下面查看;

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

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

	return self::$instance;

}

这是使用“ add_action()”将我们的类添加到WordPress头时调用的方法。

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认为页面模板文件实际上存在于template目录中。这会将页面模板添加到页面编辑器中页面属性元框上的下拉列表中。
  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行,我们进行了一些验证,以检查文件是否实际存在。如果是的话,太棒了!如果没有,哦,亲爱的……如果WordPress无法找到模板文件甚至黑屏,您很可能会收到一条PHP错误消息。如果这些症状听起来很熟悉,只需通过在屏幕上打印$ 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上将完整代码作为插件下载

后期编辑特写

这是运行中的插件的特写。请参阅在页面属性下添加的页面模板?

后期编辑特写
后期编辑特写

微信二维码

微信扫描二维码联系我们!
我们在微信上24小时期待你的声音
提供外贸路由器设备产品,轻松翻墙,解答:WP主题推荐,WP网站建设,Google SEO,百度SEO,专业服务器环境搭建等!


需要提供WordPress主题/插件的汉化服务可以随时联系我们!另外成品WordPress网站以及半成品WordPress网站建设,海外Google SEO优化托管服务,百度SEO优化托管服务,Centos/Debian服务器WP专用环境搭建,WP缓存服务器搭建,我们都是你的首选,拥有多年WP开源程序服务经验,我们一直在坚持客户体验,没有最好,只有更好!
回到顶部