如果您随插件一起提供前端输出,那么其他开发人员可以出于主题目的对其进行修改,这一点很重要。这可以通过过滤器或操作来完成,但我认为最简单和最常见的方法是提供可以覆盖的模板路径。
定义可在主题中使用的路径和文件命名约定是常见的做法。通过这种方式,WordPress 本身可以让您修改其模板,而 WooCommerce 等其他大公司也可以这样做。它简单直观。主题开发人员可以将模板文件复制粘贴到他们的主题中,然后开始更改输出。不需要额外的样板代码。
寻找路径
对于我们的意图来说,最重要的是寻路。有几个地方可能很有趣。
- 活跃主题
- 父主题
- 其他插件
- 默认模板
此列表还将反映模板查找的优先级。
活跃主题
我们可以使用locate_template函数在活动主题中搜索模板文件。如果没有找到,它将返回一个路径字符串或 false
。
<?php
namespace PublicFunctionOrg\WordPress;
class Templates {
private $theme_dir = "/my-plugin-templates/";
public function get_template_path($template){
if ( $overridden_template = locate_template( $this->theme_dir.$template ) ) {
return $overridden_template;
}
return false;
}
}
$templates = new Templates();
$filepath = $templates->get_template_path("my-template.php");
父主题
通常,locate_template 函数还应该在父主题目录中查找模板文件。但我遇到过没有的情况。这就是为什么我总是为父主题模板文件明确添加第二次查找。
<?php
namespace PublicFunctionOrg\WordPress;
class Templates {
private $theme_dir = "/my-plugin-templates/";
public function get_template_path($template){
$path = $this->theme_dir.$template;
if( is_file( get_template_directory().$path)){
return get_template_directory().$path;
}
return false;
}
}
$templates = new Templates();
$filepath = $templates->get_template_path("my-template.php");
其他插件
如果其他插件可能有兴趣覆盖我们的插件模板,我们首先需要提供一个过滤器来允许插件注册它们的模板路径。然后我们将在查找中包含这些路径。
<?php
add_filter("my_plugin_add_template_paths", function($paths){
$paths[] = plugin_file_path(__FILE__)."/my-templates-dir/";
return $paths;
});
<?php
namespace PublicFunctionOrg\WordPress;
class Templates {
public function get_template_path($template){
$paths = apply_filters("my_plugin_add_template_paths", []);
foreach ($paths as $path){
if(is_file("$path/$template")){
return "$path/$template";
}
}
return false;
}
}
// find templates
$templates = new Templates();
$filepath = $templates->get_template_path("my-template.php");
默认模板
最后的查找是最简单的。只需使用您的插件默认模板。
<?php
namespace PublicFunctionOrg\WordPress;
class Templates {
public function get_template_path($template){
$path = plugin_file_path(__FILE__)."/templates/";
if(is_file("$path/$template")){
return "$path/$template";
}
return false;
}
}
// find templates
$templates = new Templates();
$filepath = $templates->get_template_path("my-template.php");
合并所有代码
现在我们已经为每个可以找到模板的单独位置找到了解决方案,让我们组合这些目的地来创建组合模板查找类。
<?php
namespace PublicFunctionOrg\WordPress;
class Templates {
const THEME_DIR = "/my-plugin-templates/";
const FILTER_ADD_TEMPLATES_PATHS = "my_plugin_add_template_paths";
public function get_template_path($template){
if ( $overridden_template = locate_template( self::THEME_DIR.$template ) ) {
return $overridden_template;
}
$path = self::THEME_DIR.$template;
if( is_file( get_template_directory().$path)){
return get_template_directory().$path;
}
$paths = apply_filters(self::FILTER_ADD_TEMPLATES_PATHS, []);
foreach ($paths as $path){
if(is_file("$path/$template")){
return "$path/$template";
}
}
$path = plugin_file_path(__FILE__)."/templates/";
if(is_file("$path/$template")){
return "$path/$template";
}
return false;
}
}
渲染模板
如果我们想在插件中渲染一个模板,我们应该首先将默认模板文件templates/my-template.php
添加到我们插件的模板目录中。这将是主副本,因此在环境文档中详细说明是非常有帮助的。
<?php
//... some other plugin stuff
add_filter("the_content", function($content){
$data = new MyModel();
$templates = new PublicFunctionOrg\Wordpress\Templates();
$filepath = $templates->get_template_path("my-template.php");
if($filepath){
ob_start();
include $filepath;
$content.= ob_get_contents();
ob_end_clean();
}
return $content;
});
<?php
/**
* @var SomeClass $this
* @var MyModel $data
*/
echo $data->getDescription();
总结
这些是我的模板类的起点的基础知识。您可以在 GitHub 上的wp-components 存储库中找到模板类的主副本。它有一些额外的特性和配置方法,但基本上它的工作方式是一样的。
注:本文来自 medium.com,作者为 Edward Bock,由 WordPress大学 翻译整理。
拓展阅读:
- WordPress 插件开发教程
- WordPress 插件开发时在插件列表页的几个常用Hook及用例
- WordPress插件开发 之 添加自动检测更新和一键升级功能
- 根据另一个插件的激活状态停用 WordPress 插件