问题描述
这不是一个关于如何构建 WordPress 插件的问题。相反,如果有的话,指南可以应用于如何组合任何插件的文件架构。
一些其他编程语言或库具有非常受控的组织目录和文件的方式。有时这是恼人的,突出了 PHP 提供的自由,但是在 flip-side 上,WordPress 插件以其作者确定的任何方式放在一起。
没有一个正确的答案,但我希望改进我和其他人如何构建插件,使他们对其他开发人员更加友善,更容易调试,更容易导航,并可能更有效率。
最后一个问题:你认为组织插件最好的方法是什么?
以下是几个示例结构,但绝对不是详尽的列表。随意添加您自己的建议。
假设默认结构
-
/ wp-content
-
/插件
-
/ my-plugin
-
my-plugin.php
-
-
-
模型视图控制器 (MVC) 方法
-
/ wp-content
-
/插件
-
/ my-plugin
-
/控制器
-
Controller.php
-
-
/模型
-
Model.php
-
-
/视图
-
view.php
-
-
my-plugin.php
-
-
-
MVC 的三个部分:
- 该模型与数据库交互,查询和保存数据,并包含逻辑。
- 控制器将包含视图将使用的模板标签和功能。
- 视图负责显示由控制器构造的模型提供的数据。
按类型方式组织
-
/ wp-content
-
/插件
-
/ my-plugin
-
/管理员
-
admin.php
-
-
/资产
-
css/
-
images/
-
-
/班
-
my-class.php
-
-
/郎
-
my-es_ES.mo
-
-
/模板
-
my-template.php
-
-
/部件
-
my-widget.php
-
-
my-plugin.php
-
-
-
松散组织的方法
-
/ wp-content
-
/插件
-
/ my-plugin
-
css/
-
images/
-
js/
-
my-admin.php
-
my-class.php
-
my-template.php
-
my-widget.php
-
my-plugin.php
-
-
-
最佳解决方案
请注意,插件都是 WP 标准的”controllers” 。
这取决于插件应该做什么,但在任何情况下,我尽量将屏幕输出与 PHP 代码分开。
这里有一种方法可以轻松实现 – 首先,定义一个加载模板的函数:
function my_plugin_load_template(array $_vars){
// you cannot let locate_template to load your template
// because WP devs made sure you can't pass
// variables to your template :(
$_template = locate_template('my_plugin', false, false);
// use the default one if the theme doesn't have it
if(!_$template)
$_template = 'views/template.php';
// load it
extract($_vars);
require $template;
}
现在,如果插件使用小工具来显示数据:
class Your_Widget extends WP_Widget{
...
public function widget($args, $instance){
$title = apply_filters('widget_title', $instance['title'], $instance, $this->id_base);
// this widget shows the last 5 "movies"
$posts = new WP_Query(array('posts_per_page' => 5, 'post_type' => 'movie'));
if($title)
print $before_title . $title . $after_title;
// here we rely on the template to display the data on the screen
my_plugin_load_template(array(
// variables you wish to expose in the template
'posts' => $posts,
));
print $before_widget;
}
...
}
模板:
<?php while($posts->have_posts()): $posts->the_post(); ?>
<p><?php the_title(); ?></p>
<?php endwhile; ?>
文件:
/plugins/my_plugin/plugin.php <-- just hooks
/plugins/my_plugin/widget.php <-- widget class, if you have a widget
/themes/twentyten/my_plugin.php <-- template
/plugins/my_plugin/views/template.php <-- fallback template
你把 CSS,JS,图像放在哪里,或者如何设计钩子的容器是不那么重要的。这是我个人喜好的问题。
次佳解决方案
IMHO,最简单,最强大,最可维护的路由是使用 MVC 结构,WP MVC 旨在使 MVC 插件变得非常简单 (我有点偏见,但…) 。使用 WP MVC,您只需使模型,视图和控制器,以及其他一切在幕后处理。
可以为公共和管理部分分开控制器和视图,整个框架利用了许多 WordPress 的本机功能。文件结构和大部分功能与最受欢迎的 MVC 框架 (Rails,CakePHP 等) 完全相同。
更多信息和教程可以在这里找到:
第三种解决方案
这取决于插件。这是我几乎每个插件的基本结构:
my-plugin/
inc/
Any additional plugin-specific PHP files go here
lib/
Library classes, css, js, and other files that I use with many
plugins go here
css/
js/
images/
lang/
Translation files
my-plugin.php
readme.txt
This 将会在 lib
文件夹中出现。
如果它是特别复杂的插件,具有很多管理区域功能,我将添加一个 admin
文件夹来包含所有这些 PHP 文件。如果插件执行类似替换的 theme files,也可能有一个 template
或 theme
文件夹。
因此,目录结构可能如下所示:
my-plugin/
inc/
lib/
admin/
templates/
css/
js/
images/
lang/
my-plugin.php
readme.txt
第四种方案
我们正在使用所有方法的混合。首先,我们在我们的插件中使用了 Zend Framework 1.11,因此由于自动加载机制,我们不得不为类文件使用类似的结构。
我们的核心插件 (所有我们的插件作为基础使用) 的结构看起来类似于:
webeo-core/
css/
images/
js/
languages/
lib/
Webeo/
Core.php
Zend/
/** ZF files **/
Loader.php
views/
readme.txt
uninstall.php
webeo-core.php
- WordPress 在插件根文件夹中调用
webeo-core.php
文件。 - 在这个文件中,我们将设置 PHP 包含的路径并注册插件的激活和停用钩子。
- 我们还在这个文件中有一个
Webeo_CoreLoader
类,它设置一些插件常量,初始化类自动装载器,并调用lib/Webeo
文件夹内的Core.php
类的安装方法。它运行在plugins_loaded
动作钩子上,优先级为9
。 Core.php
类是我们的插件引导文件。该名称基于插件名称。
如您所见,我们在 lib
文件夹中有一个子目录,用于所有供应商的软件包 (Webeo
,Zend
) 。供应商内的所有子包都由模块本身构成。对于新的 Mail Settings
管理表单,我们将具有以下结构:
webeo-core/
...
lib/
Webeo/
Form/
Admin/
MailSettings.php
Admin.php
Core.php
Form.php
我们的 sub-plugins 具有相同的结构,但有一个例外。由于在自动加载事件期间解决命名冲突,我们在供应商文件夹内更深入一级。我们还在 plugins_loaded
钩子的优先级 10
中调用了插件类型为 E.g. Faq.php
的插件。
webeo-faq/ (uses/extends webeo-core)
css/
images/
js/
languages/
lib/
Webeo/
Faq/
Faq.php
/** all plugin relevant class files **/
views/
readme.txt
uninstall.php
webeo-faq.php
我可能会将 lib
文件夹重命名为 vendors
,并将所有公用文件夹 (css,images,js,languages) 移动到下一个版本中名为 public
的文件夹。
第五种方案
像许多这里已经回答了这真的取决于插件应该做什么,但这里是我的基础结构:
my-plugin/
admin/
holds all back-end administrative files
js/
holds all back-end JavaScript files
css/
holds all back-end CSS files
images/
holds all back-end images
admin_file_1.php back-end functionality file
admin_file_2.php another back-end functionality file
js/
holds all front end JavaScript files
css/
holds all fronted CSS files
inc/
holds all helper classes
lang/
holds all translation files
images/
holds all fronted images
my-plugin.php main plugin file with plugin meta, mostly includes,action and filter hooks
readme.txt
changelog.txt
license.txt
第六种方案
我局限于以下插件布局,但是它通常会根据插件的要求而改变。
wp-content/
plugins/
my-plugin/
inc/
Specific files for only this plugin
admin/
Files for dealing with administrative tasks
lib/
Library/helper classes go here
css/
CSS files for the plugin
js/
JS files
images/
Images for my plugin
lang/
Translation files
plugin.php
This is the main file that calls/includes other files
README
I normally put the license details in here in addition to helpful information
我还没有创建一个需要 MVC 风格架构的 WordPress 插件,但是如果我要这样做,我会用一个单独的 MVC 目录来排列,该目录本身包含 views / controllers / models 。
第七种方案
我的逻辑,插件越大,我使用的结构越多。对于大的插件,我倾向于使用 MVC 。我用这个作为起点,跳过什么是不需要的。
controller/
frontend.php
wp-admin.php
widget1.php
widget2.php
model/
standard-wp-tables.php // if needed split it up
custom-tabel1.php
custom-tabel2.php
view/
helper.php
frontend/
files...php
wp-admin/
files...php
widget1/
file...php
widget2/
file...php
css/
js/
image/
library/ //php only, mostly for Zend Framework, again if needed
constants.php //tend to use it often
plugin.php //init file
install-unistall.php //only on big plugins
第八种方案
所有我的插件都遵循这个结构,这似乎与其他大多数开发人员的工作非常相似:
plugin-folder/
admin/
css/
images/
js/
core/
css/
images/
js/
languages/
library/
templates/
plugin-folder.php
readme.txt
changelog.txt
license.txt
然后,plugin-folder.php 通常是从核心/文件夹加载所有需要的文件的类。最常见的是 init 或 plugins_loaded 钩子。
我曾经在我的所有文件前缀,但正如上面 @kaiser 所说,这真的是多余的,我最近决定从任何未来的插件中删除它。
库/文件夹保存插件可能依赖的所有外部帮助程序库。
根据插件,插件根目录中可能还有一个 uninstall.php 文件。大部分时间是通过 register_uninstall_hook() 来处理的。
显然,一些插件可能不需要任何管理员文件或模板等,但上面的结构适用于我。最后你只需要找到一个适合你的结构,然后坚持下去。
我也有一个启动器插件,基于上面的结构,我用作所有我的插件的起点。所有我需要做的是做一个搜索/替换功能/类前缀和关闭我去。当我仍然是我的文件前缀,这是一个额外的步骤,我不得不做 (和相当烦人的),但现在我只需要重命名插件文件夹和主要的插件文件。
参考文献
注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。