如何构建插件


40

这不是关于如何构建WordPress插件的问题。相反,如果有的话,什么指南可以应用于如何组合任何插件的文件体系结构。

其他一些编程语言或库具有组织目录和文件的受控方式。有时,这很烦人,并且突显了PHP提供的自由,但是在另一方面,WordPress插件以其作者确定的任何方式组合在一起。

没有一个正确的答案,但是我的希望是完善我和其他人构建插件的方式,以使它们对其他开发人员更友好地进行剖析,更易于调试,更易于导航,并且可能更加高效。

最后一个问题:什么认为是组织的一个插件的最佳方式?

以下是一些示例结构,但绝不是详尽的列表。随时添加自己的建议。

假定默认结构

  • /wp-content
    • /plugins
      • /my-plugin
        • my-plugin.php

模型视图控制器(MVC)方法

  • /wp-content
    • /plugins
      • /my-plugin
        • /controller
          • Controller.php
        • /model
          • Model.php
        • /view
          • view.php
        • my-plugin.php

MVC的三个部分:

  • 模型与数据库交互,查询和保存数据,并包含逻辑。
  • 控制器将包含模板标签和功能视图将利用。
  • 视图负责显示由控制器构造的模型提供的数据。

按类型组织

  • /wp-content
    • /plugins
      • /my-plugin
        • /admin
          • admin.php
        • /assets
          • css/
          • images/
        • /classes
          • my-class.php
        • /lang
          • my-es_ES.mo
        • /templates
          • my-template.php
        • /widgets
          • my-widget.php
        • my-plugin.php

WordPress插件样板

Github上可用

基于插件API编码标准文档标准

  • /wp-content
    • /plugins
      • /my-plugin
        • /admin
          • /css
          • /js
          • /partials
          • my-plugin-admin.php
        • /includes
          • my_plugin_activator.php
          • my_plugin_deactivator.php
          • my_plugin_i18n.php
          • my_plugin_loader.php
          • my_plugin.php
        • /languages
          • my_plugin.pot
        • /public
          • /css
          • /js
          • /partials
          • my-plugin-public.php
        • LICENSE.txt
        • README.txt
        • index.php
        • my-plugin.php
        • uninstall.php

松散的组织方法

  • /wp-content
    • /plugins
      • /my-plugin
        • css/
        • images/
        • js/
        • my-admin.php
        • my-class.php
        • my-template.php
        • my-widget.php
        • my-plugin.php

这不是一个真正的问题,但我不会结束投票,但已标记为将其成为社区Wiki。顺便说一句:我认为对文件名进行固定没有任何意义。
kaiser 2012年

谢谢,我还是希望这是社区Wiki。我认为以这种方式添加文件前缀也没有太大意义,但是我已经看到了很多。
2012年

1
另一侧点:也许更语义正确的文件夹名称css/images/js/将是styles/images/scripts/
安德鲁·奥德里

Answers:


16

请注意,按照WP标准,插件都是“控制器”。

这取决于插件的功能,但是在所有情况下,我都将尝试将屏幕输出与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,图像放在何处或如何设计用于挂钩的容器并不重要。我猜这是个人喜好问题。


6

这取决于插件。这是几乎每个插件的基本结构:

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

将放在lib文件夹中。

如果它是特别复杂的插件,并且具有很多管理区域功能,那么我将添加一个admin文件夹来包含所有这些PHP文件。如果插件做了类似替换包含的主题文件之类的操作,则可能还有一个templatetheme文件夹。

因此,目录结构可能如下所示:

my-plugin/
    inc/
    lib/
    admin/
    templates/
    css/
    js/
    images/
    lang/
    my-plugin.php
    readme.txt

您还会在/ admin文件夹中包含管理员的css和js文件吗?因此在/ admin中有另一个/ css和/ js?
urok93

6

恕我直言,最简单,最强大,最易维护的方法是使用MVC结构,而WP MVC旨在使编写MVC插件变得非常容易(不过,我有些偏见...)。使用WP MVC,您只需创建模型,视图和控制器,其他所有内容就可以在后台处理。

可以为public和admin部分创建单独的控制器和视图,并且整个框架利用了许多WordPress的本机功能。文件结构和许多功能与最流行的MVC框架(Rails,CakePHP等)完全相同。

更多信息和教程可以在这里找到:


5

我们混合使用了所有方法。首先,我们在插件中使用了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
  1. WordPress会webeo-core.php在插件根文件夹中调用该文件。
  2. 在此文件中,我们将设置PHP包含路径,并注册插件的激活和停用钩子。
  3. 我们Webeo_CoreLoader在此文件内还有一个类,该类设置一些插件常量,初始化类自动加载器并Core.phplib/Webeo文件夹内调用该类的设置方法。这在plugins_loaded优先级为的动作挂钩上运行9
  4. Core.php班是我们的插件引导文件。该名称基于插件名称。

正如你所看到的,我们有一个子目录lib文件夹为我们所有的供应商包(WebeoZend)。供应商内部的所有子包均由模块本身构成。对于新的Mail Settings管理表单,我们将具有以下结构:

webeo-core/
    ...
    lib/
        Webeo/
            Form/
                Admin/
                    MailSettings.php
                Admin.php
            Core.php
            Form.php

除了一个例外,我们的子插件具有相同的结构。由于在自动加载事件期间解决了命名冲突,因此我们在供应商文件夹内更深入。我们还在挂钩内E.g. Faq.php优先调用插件boostrap类。10plugins_loaded

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,图像,js,语言)移动到public下一个版本中命名的文件夹。


5

就像这里已经回答的许多问题一样,这实际上取决于插件的功能,但这是我的基本结构:

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

4

我只喜欢以下插件布局,但是它通常根据插件要求而变化。

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目录对其进行布局,该目录本身包含视图/控制器/模型。


4

我的逻辑是,插件越大,我使用的结构越多。
对于大型插件,我倾向于使用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

3

我所有的插件都遵循这种结构,这似乎与大多数其他开发人员所做的非常相似:

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通常是一个从core /文件夹加载所有必需文件的类。最常见的是init或plugins_loaded挂钩。

我以前也给所有文件加上前缀,但是正如上面@kaiser所指出的那样,它确实是多余的,我最近决定从将来的任何插件中删除它。

library /文件夹包含该插件可能依赖的所有外部帮助程序库。

根据插件的不同,插件根目录中可能还会有一个uninstall.php文件。不过,大多数情况下,这是通过register_uninstall_hook()处理的。

显然,某些插件可能不需要任何管理文件或模板等,但是上面的结构对我有用。最后,您只需要找到适合您的结构,然后坚持使用即可。

基于上面的结构,我也有一个入门插件,我将其用作所有插件的起点。然后,我要做的就是搜索/替换函数/类前缀,然后关闭。当我仍在给文件加上前缀时,这是我必须做的一个额外步骤(这很烦人),但是现在我只需要重命名插件文件夹和主插件文件即可。



0

构造插件文件和目录的一种不太常用的方法是文件类型方法。在这里值得一提的是完整性:

plugin-name/
    js/
        sparkle.js
        shake.js
    css/
        style.css
    scss/
        header.scss
        footer.scss
    php/
        class.php
        functions.php
    plugin-name.php
    uninstall.php
    readme.txt

每个目录仅包含该类型的文件。值得注意的是,例如,当您有许多文件类型.png .gif .jpg可能更合乎逻辑地放在单个目录下时,此方法就不够用了images/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.