How to structure a plugin

时间:2012-04-08 作者:developdaly

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

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

没有一个正确的答案,但我希望改进我和其他人构建插件的方式,使它们对其他开发人员更友好,更容易调试,更容易导航,可能更高效。

最后一个问题:what do you think is the best way to organize a plugin?

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

Assumed Default Structure

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

Model View Controller (MVC) method

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

          model 与数据库交互,查询和保存数据,并包含逻辑

        • controller 将包含视图将使用的模板标记和函数
        • view 负责显示控制器构建的模型提供的数据

        Organized by type method

        • /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.phpWordPress Plugin Boilerplate

              可用时间:Github

              基于Plugin API, Coding Standards, 和Documentation Standards.

              • /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

              Loosely organized method

              • /wp-content
              • /plugins
                • /my-plugin
                  • css/
                  • images/
                  • js/
                  • my-admin.php
                  • my-class.php
                  • my-template.php
                  • my-widget.php
                  • my-plugin.php
10 个回复
最合适的回答,由SO网友:onetrickpony 整理而成

请注意,根据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、图像放在哪里,或者你如何为钩子设计容器就不那么重要了。我想这是个人喜好的问题。

SO网友:chrisguitarguy

这取决于插件。这是我几乎所有插件的基本结构:

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, 可能有templatetheme 文件夹。

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

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

SO网友:Tom

依我看,最简单、最强大、最可维护的方法是使用MVC结构,而WP MVC旨在使编写MVC插件变得非常容易(尽管我有点偏颇……)。使用WP-MVC,您只需创建模型、视图和控制器,其他一切都在幕后为您处理。

可以为公共和管理部分创建单独的控制器和视图,整个框架利用了WordPress的许多本地特性。文件结构和大部分功能与最流行的MVC框架(Rails、CakePHP等)完全相同。

更多信息和教程可在此处找到:

SO网友:Roman

我们混合使用各种方法。首先,我们在插件中使用了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 插件根文件夹中的文件Webeo_CoreLoader 类,该类设置一些插件常量,初始化类autoloader并调用Core.php 类内部lib/Webeo 文件夹这在plugins_loaded 优先级为的操作挂钩9.
  • Core.php 类是我们的插件引导文件。该名称基于插件名称lib 所有供应商软件包的文件夹(Webeo, Zend). 供应商内部的所有子包都是由模块本身构成的。对于新的Mail Settings 管理表单,我们将具有以下结构:

    webeo-core/
        ...
        lib/
            Webeo/
                Form/
                    Admin/
                        MailSettings.php
                    Admin.php
                Core.php
                Form.php
    
    我们的子插件具有相同的结构,只有一个例外。由于解决了自动加载事件期间的命名冲突,我们在供应商文件夹中深入了一层。我们也将插件称为boostrap类E.g. Faq.php 在优先级上10 内部plugins_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 在下一版本中。

  • SO网友:Bainternet

    就像这里的很多人已经回答了一样真的depends 关于插件应该做什么,但这里是我的基本结构:

    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
    

    SO网友:mystline

    我倾向于下面的插件布局,但是它通常会根据插件需求的不同而变化。

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

    SO网友:shabushabu

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

    plugin-folder/
        admin/
            css/
                images/
            js/
        core/
        css/
            images/
        js/
        languages/
        library/
        templates/
        plugin-folder.php
        readme.txt
        changelog.txt
        license.txt
    
    插件文件夹。php通常是一个从核心/文件夹加载所有必需文件的类。通常在init或plugins\\u加载的钩子上。

    我以前也会给我的所有文件加前缀,但正如上面提到的@kaiser,这确实是多余的,我最近决定将其从任何未来的插件中删除。

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

    根据插件的不同,可能会进行卸载。插件根目录中的php文件。但大多数情况下,这是通过register\\u uninstall\\u hook()处理的。

    显然,一些插件可能不需要任何管理文件或模板等,但上面的结构适合我。最后,你只需要找到一个适合你的结构,然后坚持下去。

    我还有一个初学者插件,基于上面的结构,我将其作为我所有插件的起点。然后我需要做的就是搜索/替换函数/类前缀,然后关闭。当我还在为我的文件添加前缀时,这是一个额外的步骤,我不得不这么做(这让我很恼火),但现在我只需要重命名插件文件夹和主插件文件。

    SO网友:janw

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

    SO网友:Cedric

    此外,请参见this great WP widget boilerplate . 它为结构提供了很好的提示(即使没有用于单独模型的类或文件夹)。

    SO网友:henrywright

    构建插件文件和目录的一种不太常见的方法是文件类型方法。为了完整起见,这里值得一提:

    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/ 例如

    结束

    相关推荐

    是什么原因会导致get_style heet_directory_uri()失败?

    在我的新worpress安装中,我有如下代码<img src=\"<?php get_stylesheet_directory_uri(); ?>/images/logo.jpg\" />这段代码一直有效,直到我开始使用子域(从example.com/dev转到dev.example.com),并在常规设置中更改了这些URL。现在get_stylesheet_directory_uri() 不输出任何内容:<img src=\"/images/logo.jpg\" />