Como estruturar um plugin


41

Esta não é uma pergunta sobre como criar um plugin para WordPress. Em vez disso, o que, se houver, guias poderia ser aplicado a como montar a arquitetura de arquivo de qualquer plug-in.

Algumas outras linguagens de programação ou bibliotecas têm maneiras muito controladas de organizar diretórios e arquivos. Às vezes, isso é irritante e destaca a liberdade que o PHP oferece, mas, por outro lado, os plug-ins do WordPress são reunidos de qualquer maneira, conforme determinado pelo autor.

Não há uma resposta certa , mas minha esperança é refinar como eu e outros construímos plug-ins para torná-los mais amigáveis ​​para outros desenvolvedores, mais fáceis de depurar, mais fáceis de depurar, mais fáceis de navegar e possivelmente mais eficientes.

A pergunta final: qual você acha que é a melhor maneira de organizar um plugin?

Abaixo estão algumas estruturas de amostra, mas de maneira alguma é uma lista exaustiva. Sinta-se livre para adicionar suas próprias recomendações.

Estrutura padrão assumida

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

Método Model View Controller (MVC)

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

As três partes do MVC:

  • O modelo interage com o banco de dados, consultando e salvando dados, e contém lógica.
  • O controlador conteria tags de modelo e funções que a visualização utilizaria.
  • A visualização é responsável por exibir os dados fornecidos pelo modelo, conforme construído pelo controlador.

Organizado pelo método de tipo

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

Disponível no Github

Com base na API do plug - in , nos padrões de codificação e nos padrões de documentação .

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

Método fracamente organizado

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

Esta não é uma pergunta real, mas não vou fechar a votação, mas sinalizada para fazer deste um Wiki da comunidade. Btw: Eu acho que não faz sentido perfilar os nomes dos arquivos.
Kaiser #

Obrigado, prefiro que seja um wiki da comunidade de qualquer maneira. Também não acho que prefixar arquivos dessa maneira faça muito sentido, mas já o vi muito.
developdaly

11
Outro lado ponto: talvez mais semanticamente correto nomes para as pastas css/, images/e js/seria styles/, images/e scripts/.
Andrew Odri 6/12/12

Respostas:


16

Observe que os plugins são todos "controladores" pelos padrões WP.

Depende do que o plugin deve fazer, mas em todos os casos eu tentaria separar o máximo possível a saída da tela do código PHP.

Aqui está uma maneira de fazer isso facilmente - primeiro, defina uma função que carrega o modelo:

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;
}

Agora, se o plug-in usa um widget para exibir dados:

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;
  }
  ...

}

O modelo:

<?php while($posts->have_posts()): $posts->the_post(); ?>

<p><?php the_title(); ?></p> 

<?php endwhile; ?>

Arquivos:

/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

Onde você coloca suas CSS, JS, imagens ou como você projeta o contêiner para os ganchos é menos importante. É uma questão de preferência pessoal, eu acho.


6

Depende do plugin. Esta é minha estrutura básica para quase todos os plugins:

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

Isso seria algo que iria para a libpasta.

Se for um plugin particularmente complexo, com muitas funcionalidades da área administrativa, eu adicionaria uma adminpasta para conter todos esses arquivos PHP. Se o plugin fizer algo como substituir os arquivos de tema incluídos , talvez também haja uma pasta templateou theme.

Portanto, uma estrutura de diretórios pode ser assim:

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

Você também incluiria os arquivos css e js do administrador na pasta / admin? Portanto, tendo outro / css e / js dentro de / admin?
Urok93 12/08/12

6

IMHO, a rota mais fácil, mais poderosa e mais sustentável é usar uma estrutura MVC, e o WP MVC foi projetado para facilitar a escrita de plug-ins MVC (embora eu seja um pouco tendencioso ...). Com o WP MVC, você simplesmente cria os modelos, visualizações e controladores, e tudo o mais é tratado nos bastidores para você.

Controladores e visualizações separados podem ser feitos para as seções pública e administrativa, e toda a estrutura aproveita muitos dos recursos nativos do WordPress. A estrutura do arquivo e grande parte da funcionalidade são exatamente as mesmas das estruturas MVC mais populares (Rails, CakePHP, etc).

Mais informações e um tutorial podem ser encontrados aqui:


5

Estamos usando uma mistura de todos os métodos. Primeiro, estamos usando o Zend Framework 1.11 em nossos plugins e, portanto, tivemos que usar uma estrutura semelhante para os arquivos de classe por causa do mecânico de carregamento automático.

A estrutura do nosso plugin principal (que é usado por todos os nossos plugins como base) é semelhante a esta:

webeo-core/
    css/
    images/
    js/
    languages/
    lib/
        Webeo/
            Core.php
        Zend/
            /** ZF files **/
        Loader.php
    views/
    readme.txt
    uninstall.php
    webeo-core.php
  1. O WordPress chama o webeo-core.phparquivo na pasta raiz do plug-in.
  2. Neste arquivo, vamos definir o caminho de inclusão do PHP e registrar os ganchos de ativação e desativação do plug-in.
  3. Também temos uma Webeo_CoreLoaderclasse dentro desse arquivo, que define algumas constantes do plugin, inicializa o carregador automático de classes e faz uma chamada para o método de configuração da Core.phpclasse dentro da lib/Webeopasta. Isso é executado no plugins_loadedgancho de ação com prioridade de 9.
  4. A Core.phpclasse é o nosso arquivo de inicialização do plugin. O nome é baseado no nome dos plugins.

Como você pode ver, temos um subdiretório dentro da libpasta para todos os nossos pacotes de fornecedores ( Webeo, Zend). Todos os subpacotes dentro de um fornecedor são estruturados pelo próprio módulo. Para um novo Mail Settingsformulário de administração, teríamos a seguinte estrutura:

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

Nossos sub-plugins têm a mesma estrutura, com uma exceção. Aproximamos ainda mais a pasta do fornecedor devido à resolução de conflitos de nomes durante o evento de carregamento automático. Também chamamos a classe boostrap de plugins E.g. Faq.phpcom prioridade 10dentro do plugins_loadedgancho.

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

Provavelmente vou renomear a libpasta vendorse mover todas as pastas públicas (css, imagens, js, idiomas) para uma pasta nomeada publicno próximo lançamento.


5

Como muitos aqui já responderam Realmente depende do que o plug-in deve fazer, mas aqui está minha estrutura básica:

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

Sou parcial com o seguinte layout de plug-in, no entanto, ele geralmente muda dependendo dos requisitos dos plug-ins.

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 

Ainda tenho que criar um plug-in do WordPress que exija uma arquitetura no estilo MVC, mas se eu fizesse isso, colocaria em um diretório MVC separado, que contém visualizações / controladores / modelos.


4

Minha lógica, quanto maior o plugin, mais estrutura eu uso.
Para plugins grandes, costumo usar o MVC.
Uso isso como ponto de partida e pulo o que não é necessário.

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

Todos os meus plugins seguem essa estrutura, que parece ser muito semelhante ao que a maioria dos outros desenvolvedores está fazendo:

plugin-folder/
    admin/
        css/
            images/
        js/
    core/
    css/
        images/
    js/
    languages/
    library/
    templates/
    plugin-folder.php
    readme.txt
    changelog.txt
    license.txt

O plugin-folder.php é geralmente uma classe que carrega todos os arquivos necessários do núcleo / pasta. Geralmente, no gancho init ou plugins_loaded.

Eu costumava prefixar todos os meus arquivos também, mas como o @kaiser observou acima, é realmente redundante e recentemente decidi removê-lo de qualquer plug-in futuro.

A biblioteca / pasta contém todas as bibliotecas auxiliares externas das quais o plug-in pode depender.

Dependendo do plugin, pode haver um arquivo uninstall.php na raiz do plugin. Na maioria das vezes, isso está sendo tratado através de register_uninstall_hook ().

Obviamente, alguns plug-ins podem não exigir arquivos ou modelos de administração, etc., mas a estrutura acima funciona para mim. No final, você apenas precisa encontrar uma estrutura que funcione para você e depois ficar com ela.

Eu também tenho um plug-in inicial, baseado na estrutura acima que eu uso como ponto de partida para todos os meus plugins. Tudo o que preciso fazer é pesquisar / substituir prefixos de função / classe e pronto. Quando eu ainda estava prefixando meus arquivos, era uma etapa extra que eu tinha que fazer (e bastante irritante), mas agora só preciso renomear a pasta do plugin e o arquivo principal do plugin.



0

Uma abordagem menos comum para estruturar os arquivos e diretórios de um plug-in é a abordagem de tipo de arquivo. Vale a pena mencionar aqui a integridade:

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

Cada diretório contém apenas arquivos desse tipo. Vale a pena notar que essa abordagem é insuficiente quando você tem muitos tipos de arquivos .png .gif .jpgque podem ser arquivados mais logicamente em um único diretório, images/por exemplo.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.