問題描述

這不是一個關於如何構建 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,也可能有一個 templatetheme 文件夾。

因此,目錄結構可能如下所示:

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
  1. WordPress 在插件根文件夾中調用 webeo-core.php 文件。
  2. 在這個文件中,我們將設置 PHP 包含的路徑並註冊插件的激活和停用鈎子。
  3. 我們還在這個文件中有一個 Webeo_CoreLoader 類,它設置一些插件常量,初始化類自動裝載器,並調用 lib/Webeo 文件夾內的 Core.php 類的安裝方法。它運行在 plugins_loaded 動作鈎子上,優先級為 9
  4. Core.php 類是我們的插件引導文件。該名稱基於插件名稱。

如您所見,我們在 lib 文件夾中有一個子目錄,用於所有供應商的軟件包 (WebeoZend) 。供應商內的所有子包都由模塊本身構成。對於新的 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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。