Cum să structurezi un plugin

8 apr. 2012, 19:13:30
Vizualizări: 32.7K
Voturi: 55

Aceasta nu este o întrebare despre cum să construiești un plugin WordPress. Mai degrabă, ce ghiduri, dacă există, ar putea fi aplicate pentru organizarea arhitecturii de fișiere a oricărui plugin.

Unele alte limbaje de programare sau biblioteci au modalități foarte stricte de organizare a directoarelor și fișierelor. Uneori acest lucru este deranjant și evidențiază libertatea pe care o oferă PHP, dar pe de altă parte plugin-urile WordPress sunt construite în orice mod determinat de autorul lor.

Nu există un răspuns corect, dar speranța mea este să rafinăm modul în care eu și alții construim plugin-uri pentru a le face mai prietenoase pentru alți dezvoltatori să le analizeze, mai ușor de depanat, mai ușor de navigat și posibil mai eficiente.

Întrebarea finală: care crezi că este cea mai bună modalitate de a organiza un plugin?

Mai jos sunt câteva structuri exemplu, dar în niciun caz nu este o listă exhaustivă. Simțiți-vă liberi să adăugați propriile recomandări.

Structura Implicită Presupusă

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

Metoda Model View Controller (MVC)

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

Cele trei părți ale MVC:

  • Modelul interacționează cu baza de date, interogând și salvând date, și conține logica.
  • Controlerul ar conține tag-uri de șablon și funcții pe care le-ar utiliza view-ul.
  • View-ul este responsabil pentru afișarea datelor furnizate de model așa cum sunt construite de controller.

Metoda organizată pe tipuri

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

Disponibil pe Github

Bazat pe API-ul pentru Plugin-uri, Standarde de Codare, și Standarde de Documentație.

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

Metoda organizată liber

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

Aceasta nu este o întrebare reală, dar nu voi vota pentru închidere, ci am marcat-o pentru a o face Wiki Comunitar. Apropo: Cred că nu are niciun sens să prefixăm numele fișierelor.

kaiser kaiser
8 apr. 2012 19:19:06

Mulțumesc, aș prefera ca aceasta să fie Wiki Comunitar oricum. Nu cred că prefixarea fișierelor în acest fel are prea mult sens, dar am văzut-o des.

developdaly developdaly
8 apr. 2012 19:25:16

Un alt punct lateral: Poate că nume mai semantice pentru folderele css/, images/, și js/ ar fi styles/, images/, și scripts/.

Andrew Odri Andrew Odri
6 dec. 2012 02:59:40
Toate răspunsurile la întrebare 11
0
19

Rețineți că toate plugin-urile sunt "controlere" conform standardelor WordPress.

Depinde de ce ar trebui să facă plugin-ul, dar în toate cazurile aș încerca să separ afișarea pe ecran de codul PHP cât mai mult posibil.

Iată o modalitate ușoară de a face acest lucru - mai întâi, definiți o funcție care încarcă template-ul:

function my_plugin_load_template(array $_vars){

  // nu puteți lăsa locate_template să încarce template-ul vostru
  // deoarece dezvoltatorii WP au făcut să nu puteți transmite
  // variabile în template :(
  $_template = locate_template('my_plugin', false, false);

  // folosiți cel implicit dacă tema nu îl are
  if(!_$template)
    $_template = 'views/template.php';

  // încărcați-l
  extract($_vars);        
  require $template;
}

Acum, dacă plugin-ul folosește un widget pentru a afișa date:

class Your_Widget extends WP_Widget{

  ...      
  public function widget($args, $instance){

    $title = apply_filters('widget_title', $instance['title'], $instance, $this->id_base);

    // acest widget afișează ultimele 5 "filme"
    $posts = new WP_Query(array('posts_per_page' => 5, 'post_type' => 'movie')); 

    if($title)
      print $before_title . $title . $after_title;

    // aici ne bazăm pe template pentru a afișa datele pe ecran
    my_plugin_load_template(array(

      // variabile pe care doriți să le expuneți în template
     'posts'    => $posts,          
    ));

    print $before_widget;
  }
  ...

}

Template-ul:

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

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

<?php endwhile; ?>

Fișiere:

/plugins/my_plugin/plugin.php           <-- doar hook-uri 
/plugins/my_plugin/widget.php           <-- clasa widget, dacă aveți un widget
/themes/twentyten/my_plugin.php         <-- template
/plugins/my_plugin/views/template.php   <-- template de rezervă

Unde puneți CSS-ul, JS-ul, imaginile sau cum proiectați containerul pentru hook-uri este mai puțin important. Cred că este o chestiune de preferință personală.

9 apr. 2012 16:21:26
2

Depinde de plugin. Acesta este structura mea de bază pentru aproape fiecare plugin:

my-plugin/
    inc/
        Orice fișiere PHP suplimentare specifice plugin-ului se află aici
    lib/
        Clase de bibliotecă, fișiere css, js și alte fișiere pe care le folosesc cu multe
        plugin-uri se află aici
    css/
    js/
    images/
    lang/
        Fișiere de traducere
    my-plugin.php
    readme.txt

Acesta ar fi ceva care ar merge în folderul lib.

Dacă este un plugin deosebit de complex, cu multă funcționalitate în zona de administrare, aș adăuga un folder admin pentru a conține toate acele fișiere PHP. Dacă plugin-ul face ceva precum înlocuirea fișierelor de temă incluse, poate exista și un folder template sau theme.

Deci, o structură de directoare ar putea arăta astfel:

my-plugin/
    inc/
    lib/
    admin/
    templates/
    css/
    js/
    images/
    lang/
    my-plugin.php
    readme.txt
9 apr. 2012 08:13:15
Comentarii

Ai include și fișierele CSS și JS ale administratorului în folderul /admin? Astfel, având un alt /css și /js în /admin?

urok93 urok93
12 aug. 2012 10:52:14

Hei Chris, Uau, acum peste un deceniu, dar încă un răspuns destul de bun! Cu toate acestea, aș dori să aud și răspunsul tău la întrebarea lui @urok93

Eric Hepperle - CodeSlayer2010 Eric Hepperle - CodeSlayer2010
14 feb. 2024 15:36:52
0

După părerea mea, cea mai ușoară, puternică și ușor de întreținut cale este utilizarea unei structuri MVC, iar WP MVC este conceput să facă scrierea plugin-urilor MVC foarte simplă (deși sunt puțin părtinitor...). Cu WP MVC, pur și simplu creezi modelele, view-urile și controllerele, iar restul este gestionat în spatele scenei pentru tine.

Se pot crea controllere și view-uri separate pentru secțiunile publice și cele de administrare, iar întregul cadru beneficiază de multe dintre caracteristicile native ale WordPress. Structura fișierelor și mare parte din funcționalitate sunt exact la fel ca în cele mai populare framework-uri MVC (Rails, CakePHP, etc).

Mai multe informații și un tutorial pot fi găsite aici:

14 apr. 2012 17:29:44
0

Folosim un mix al tuturor metodelor. În primul rând, utilizăm Zend Framework 1.11 în pluginurile noastre și, din această cauză, a trebuit să folosim o structură similară pentru fișierele de clasă datorită mecanismului de autoload.

Structura pluginului nostru principal (care este folosit ca bază de toate pluginurile noastre) arată astfel:

webeo-core/
    css/
    images/
    js/
    languages/
    lib/
        Webeo/
            Core.php
        Zend/
            /** fișiere ZF **/
        Loader.php
    views/
    readme.txt
    uninstall.php
    webeo-core.php
  1. WordPress apelează fișierul webeo-core.php din directorul rădăcină al pluginului.
  2. În acest fișier setăm calea de includere PHP și înregistrăm hook-urile de activare și dezactivare pentru plugin.
  3. De asemenea, avem o clasă Webeo_CoreLoader în acest fișier, care setează unele constante ale pluginului, inițializează autoloaderul de clasă și face un apel către metoda de setup a clasei Core.php din folderul lib/Webeo. Acest lucru rulează pe hook-ul de acțiune plugins_loaded cu o prioritate de 9.
  4. Clasa Core.php este fișierul nostru de bootstrap pentru plugin. Numele este bazat pe numele pluginului.

După cum puteți vedea, avem un subdirector în folderul lib pentru toate pachetele noastre de furnizori (Webeo, Zend). Toate subpachetele din cadrul unui furnizor sunt structurate după modulul în sine. Pentru un nou formular de administrare Mail Settings, am avea următoarea structură:

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

Subpluginurile noastre au aceeași structură cu o singură excepție. Mergem cu un nivel mai adânc în folderul furnizorului pentru a rezolva conflictele de nume în timpul evenimentului de autoload. De asemenea, apelăm clasa de bootstrap a pluginului De ex. Faq.php cu prioritatea 10 în cadrul hook-ului plugins_loaded.

webeo-faq/ (folosește/extinde webeo-core)
    css/
    images/
    js/
    languages/
    lib/
        Webeo/
            Faq/
                Faq.php
                /** toate fișierele de clasă relevante pentru plugin **/
    views/
    readme.txt
    uninstall.php
    webeo-faq.php

Probabil voi redenumi folderul lib în vendors și voi muta toate folderele publice (css, images, js, languages) într-un folder numit public în următoarea versiune.

13 apr. 2012 11:51:01
0

Ca mulți au răspuns deja, chiar depinde de ceea ce ar trebui să facă plugin-ul, dar iată structura mea de bază:

my-plugin/
    admin/
        conține toate fișierele pentru administrare din back-end
        js/
            conține toate fișierele JavaScript pentru back-end
        css/                    
            conține toate fișierele CSS pentru back-end
        images/
            conține toate imaginile pentru back-end
        admin_file_1.php        fișier de funcționalități pentru back-end
        admin_file_2.php        alt fișier de funcționalități pentru back-end 
    js/
        conține toate fișierele JavaScript pentru front-end
    css/
        conține toate fișierele CSS pentru front-end
    inc/
        conține toate clasele helper
    lang/                   
        conține toate fișierele de traducere
    images/
        conține toate imaginile pentru front-end
    my-plugin.php               fișierul principal al plugin-ului cu meta informații, include mostly, action și filter hooks
    readme.txt                  
    changelog.txt
    license.txt
13 apr. 2012 19:43:40
0

Prefer următoarea structură pentru plugin-uri, deși de obicei aceasta se schimbă în funcție de cerințele specifice ale plugin-ului.

wp-content/
    plugins/
        my-plugin/
            inc/
                Fișiere specifice doar pentru acest plugin
                admin/ 
                    Fișiere pentru gestionarea sarcinilor administrative
            lib/
                Clase de bibliotecă/ajutătoare se află aici
            css/
                Fișiere CSS pentru plugin
            js/
                Fișiere JavaScript
            images/
                Imagini pentru pluginul meu
            lang/
                Fișiere de traducere
        plugin.php 
            Acesta este fișierul principal care include/apelează alte fișiere 
        README 
            De obicei pun aici detalii despre licență, plus informații utile 

Încă nu am creat un plugin WordPress care să necesite o arhitectură în stil MVC, dar dacă ar fi să o fac, aș organiza-o cu un director MVC separat, care să conțină view-uri/controlere/modele.

13 apr. 2012 09:02:48
0

Toate plugin-urile mele urmează această structură, care pare să fie foarte asemănătoare cu ce fac majoritatea altor dezvoltatori:

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 este de obicei o clasă care încarcă toate fișierele necesare din folderul core/. Cel mai adesea pe hook-ul init sau plugins_loaded.

Obișnuiam să prefixez toate fișierele mele, dar așa cum a menționat @kaiser mai sus, este cu adevărat redundant și am decis recent să renunț la această practică pentru viitoarele plugin-uri.

Folderul library/ conține toate bibliotecile externe de ajutor de care ar putea depinde plugin-ul.

În funcție de plugin, poate exista și un fișier uninstall.php în rădăcina plugin-ului. Totuși, de cele mai multe ori acest lucru este gestionat prin register_uninstall_hook().

Evident, unele plugin-uri s-ar putea să nu necesite fișiere de administrare sau template-uri etc., dar structura de mai sus funcționează pentru mine. În final, trebuie doar să găsești o structură care funcționează pentru tine și apoi să te ții de ea.

De asemenea, am un plugin de pornire, bazat pe structura de mai sus, pe care îl folosesc ca punct de plecare pentru toate plugin-urile mele. Tot ce trebuie să fac apoi este să caut și să înlocuiesc prefixele funcțiilor/claselor și să încep. Când mai prefixam fișierele, acesta era un pas în plus pe care trebuia să-l fac (și destul de enervant), dar acum trebuie doar să redenumesc folderul plugin-ului și fișierul principal al plugin-ului.

13 apr. 2012 13:28:34
0

Logica mea este că, cu cât este mai mare plugin-ul, cu atât mai multă structură folosesc.
Pentru plugin-uri mari tind să folosesc MVC.
Folosesc acest punct de plecare și omit ceea ce nu este necesar.

controller/
    frontend.php
    wp-admin.php
    widget1.php
    widget2.php
model/
    standard-wp-tables.php // dacă este necesar, împărțit în fișiere separate
    custom-tabel1.php
    custom-tabel2.php
view/
    helper.php
    frontend/
        fisiere...php
    wp-admin/
        fisiere...php
    widget1/
        fisier...php
    widget2/
        fisier...php
css/
js/
imagini/
library/  //doar php, în principal pentru Zend Framework, din nou dacă este necesar
constants.php //tind să o folosesc des
plugin.php //fișier de inițializare
install-unistall.php  //doar pentru plugin-uri mari
18 apr. 2012 15:20:46
0

De asemenea, consultă acest boilerplate excelent pentru widget-uri WP. Oferă indicații valoroase privind structurile (chiar dacă nu există o clasă sau un folder pentru modele separate).

17 iun. 2013 11:42:52
1

O abordare mai puțin comună pentru structurarea fișierelor și directorelor unui plugin este cea bazată pe tipul de fișier. Merită menționată aici pentru completitudine:

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

Fiecare director conține doar fișiere de acel tip. Este important de menționat că această abordare are limitări atunci când aveți mai multe tipuri de fișiere .png .gif .jpg care ar putea fi mai bine organizate într-un singur director, de exemplu images/.

8 nov. 2015 01:40:00
Comentarii

Bravo pentru contribuția la completitudine

Eric Hepperle - CodeSlayer2010 Eric Hepperle - CodeSlayer2010
14 feb. 2024 15:39:59
0

Am dezvoltat un șablon de repository GitHub pentru plugin-uri WordPress, încapsulând peste 10 ani de experiență într-o structură bine definită!

https://github.com/EdwardBock/wordpress-plugin-starterkit

Șablonul respectă standardele PSR-4 pentru a minimiza includerea de șiruri de caractere și utilizează namespace-uri pentru o denumire concisă a claselor și o clasă componentă de templating. De asemenea, include un fișier docker compose pentru a permite dezvoltarea plugin-ului în izolare. Dar poate fi plasat și într-un proiect existent, funcționând la fel de bine.

Bucurați-vă să explorați și nu ezitați să contribuiți!

11 iul. 2024 23:07:34