当我们安装主题和插件时,都会向…
更新:该代码最近已更新,可以在WordPress 4.7+上运行
您是否曾经想过创建自己的页面模板,但是没有访问主题本身的权限?作为WordPress插件作者,我发现在开发我的插件时,这个问题特别令人讨厌。幸运的是,解决方案非常简单!我将带您快速通过几行代码,您将需要直接通过PHP动态创建WordPress页面模板。
本文的灵感和代码解决方案背后的天才来自Tom McFarlin:我正在使用他原始代码的编辑版本,您可以在他的GitHub上找到该代码。我一直在评论他(以及添加一些自己的评论),因为我发现它对解释正在发生的事情非常有帮助–我自己也不能说得更好!
您可以在本文的最底部找到完整的代码和示例插件。
让我们开始?
代码
我们将使用PHP类创建PHP函数。对于那些不熟悉PHP类的人,将类定义为一个对象,其中包含可一起使用的函数和变量的集合。请查看PHP.net简介,以获取有关语法和理论的更多详细信息。
我们的包装器只需要3个变量:
- Plugin Slug:这只是用作插件的唯一标识符。
- 类实例:在将此类的实例添加到WordPress的头部时,我们最好将其存储。
- 模板数组:您可能会猜到,这是一个包含模板名称和标题的数组。
它们在代码中:
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();’,这只是准备使用变量)。
- 第9 – 13行:此过滤器将’register_project_templates’添加到’page_attributes_dropdown_pages_args’挂钩中。这是用我们的新模板填充WordPress缓存,“诱使” WordPress认为页面模板文件实际上存在于template目录中。这会将页面模板添加到页面编辑器中页面属性元框上的下拉列表中。
- 第16至20行:此处的操作与上一个代码块基本相同,除了这次我们还将页面模板(如果已选择)添加到已保存的帖子数据中。
- 第23 – 28行:该过滤器将’template_include’添加到’view_project_template’钩子中。这是非常重要的功能。这告诉WordPress您的页面模板文件实际上在哪里。WordPress将使用由此提供的路径来呈现最终页面。
- 第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' ) );
插件
后期编辑特写
这是运行中的插件的特写。请参阅在页面属性下添加的页面模板?
微信扫描二维码联系我们!
我们在微信上24小时期待你的声音
提供外贸路由器设备产品,轻松翻墙,解答:WP主题推荐,WP网站建设,Google SEO,百度SEO,专业服务器环境搭建等!
需要提供WordPress主题/插件的汉化服务可以随时联系我们!另外成品WordPress网站以及半成品WordPress网站建设,海外Google SEO优化托管服务,百度SEO优化托管服务,Centos/Debian服务器WP专用环境搭建,WP缓存服务器搭建,我们都是你的首选,拥有多年WP开源程序服务经验,我们一直在坚持客户体验,没有最好,只有更好!