Open Source · Ata
Dai una marcia in più al tuo plugin WordPress.
Con la struttura MVC-S.
ATA aiuta gli sviluppatori di plugin WordPress a mantenere ordinate e manutenibili basi di codice in crescita, grazie al design pattern MVC.
Per gli sviluppatori di plugin WordPress
Ogni cosa al suo posto.
ATA dà a ogni plugin la stessa struttura prevedibile, così le basi di codice in crescita restano ordinate e manutenibili.
ATA Folder STRUCTURE
your-plugin-name/
├── app/
│ ├── apis/ # REST API endpoint classes
│ ├── controllers/ # Controller classes
│ ├── helpers/ # Global helper functions
│ ├── models/ # Data logic (database interaction)
│ │ └── structures/ # Optional: DTOs/data structure classes
│ ├── routes/ # API and custom URL definitions
│ ├── services/ # Business logic layer
│ └── views/ # View files (HTML/PHP templates)
│
├── base/ # Base classes your app classes extend
├── config/ # Plugin-wide configuration
├── constants/ # Custom constant definitions
├── inc/ # Bootstrapping and initialization files
├── vendor/ # Composer dependencies (includes the core ATA framework)
│
└── your-plugin-name.php # The main plugin entry file
I principi fondamentali di Ata.
Strutturato per impostazione predefinita
ATA fornisce una struttura di directory predefinita che separa in modo logico le diverse parti del tuo plugin.
Prima di tutto, orientato agli oggetti
Incoraggia a scrivere codice in classi anziché in funzioni procedurali, migliorando riusabilità e organizzazione del codice.
Netta separazione delle responsabilità
Implementa una variante del pattern MVC per mantenere separati i livelli di logica, dati e presentazione.
Routing semplificato
ATA include un router integrato che rende semplice e dichiarativa la registrazione di endpoint REST API personalizzati o di URL personalizzati.
Le differenze chiave
Che cos’è MVC-S?
ATA promuove una variante del pattern Model-View-Controller (MVC), che chiamiamo MVC-S (Model-View-Controller-Services).
Controller (il motore centrale)
Il Controller è il cuore del funzionamento del tuo plugin. Si occupa di gestire le richieste in arrivo, registrare tutti gli hook e i filtri di WordPress e controllare il flusso dell’applicazione. Nei plugin semplici, il Controller può gestire direttamente tutta la logica e l’accesso ai dati. Nelle applicazioni più complesse, il suo ruolo evolve in quello di orchestratore: chiama un Service per la logica di business o un Model per i dati, quindi passa i risultati a una View per il rendering.
View (il livello di presentazione)
La View è un livello facoltativo per generare l’output HTML. Riceve i dati dal Controller e li visualizza. Una View dovrebbe contenere una logica PHP minima, limitandosi a mostrare i dati che riceve.
Model (il livello dei dati)
L’unica responsabilità del Model è l’interazione diretta con il database. All’interno di una classe Model puoi accedere all’oggetto database di WordPress tramite $this->db (ad es. $this->db->get_results(...)). Questo livello è facoltativo: se il tuo plugin non interagisce con il database, non ti serve.
Service (il livello della logica)
Il livello Service è il posto facoltativo ma consigliato per la logica di business principale del tuo plugin. Quando la logica diventa troppo complessa per un Controller, conviene estrarla in un Service. Così i Controller restano snelli e concentrati sulla gestione delle richieste.
Plugin di esempio
Polylang RestAPI Helper
Il plugin polylang-restapi-helper è un esempio perfetto e mirato del framework ATA.
Come strutturare il tuo plugin WordPress in MVC con ATA
Documentazione
Come iniziare a usare ATA nel tuo plugin, in modo semplice e rapido
Il ciclo di vita del plugin e il Controller principale
Ogni plugin ATA è gestito da un Controller centrale, alla radice. Questo controller principale è il punto d’ingresso di tutte le funzionalità del plugin e si occupa di gestirne il ciclo di vita.
1. Il file principale del plugin (your-plugin-name.php) Questo file è minimale. Ha un solo compito: definire le costanti essenziali, caricare il framework ATA e istanziare il controller principale.
// in your-plugin-name.php
namespace YourPluginNamespace;
// ... define constants ...
// Load the framework and all its dependencies
require_once PLUGIN_PATH . '/inc/main.php';
// Instantiate the one and only root controller
$my_plugin = new MainController();
// Hook into WordPress's activation/deactivation events
register_activation_hook(PLUGIN_FILE, [$my_plugin, 'activate']);
register_deactivation_hook(PLUGIN_FILE, [$my_plugin, 'deactivate']);
2. Il Controller principale (app/controllers/main-controller.php) Questo controller contiene la logica di attivazione/disattivazione e, soprattutto, carica tutti gli altri controller. Qui puoi caricare funzionalità in modo condizionale, a seconda che altri plugin siano attivi, risparmiando memoria ed evitando errori.
// in app/controllers/main-controller.php
namespace YourPluginNamespace;
class MainController extends Controller
{
public function __construct()
{
parent::__construct();
$this->load_features();
}
// Load other controllers for specific features
private function load_features()
{
// Always load the admin UI and asset controllers
(new AdminUiController())->main();
(new AssetsController())->main();
// **Conditionally load features**
// Only load the WooCommerce compatibility layer if WooCommerce is active
if (is_plugin_active('woocommerce/woocommerce.php')) {
(new WooCommerceController())->main();
}
}
// Logic for when the plugin is activated (e.g., create DB tables)
public function activate()
{
// ... your activation code ...
}
// Logic for when the plugin is deactivated (e.g., remove DB tables)
public function deactivate()
{
// ... your deactivation code ...
}
}
Aggiungere una pagina o una scheda al pannello di amministrazione di WordPress
ATA offre un’interfaccia fluente per creare facilmente pagine di amministrazione con più schede. Il tutto si gestisce da un controller.
// in app/controllers/admin-ui-controller.php
namespace YourPluginNamespace;
class AdminUiController extends Controller
{
public function main()
{
$this->add_wp_admin_pages();
}
private function add_wp_admin_pages()
{
// Create a top-level page titled "My Plugin"
$this->admin_page('My Plugin')
// Only users who can 'manage_options' can see it
->permission('manage_options')
// Add a "Dashboard" tab (calls the 'dashboard_page' method)
->add_tab('Dashboard', 'dashboard_page')
// Add a "Settings" tab (calls the 'settings_page' method)
->add_tab('Settings', 'settings_page')
// Register the page and all its tabs
->register();
}
// This method is called when the 'Dashboard' tab is active
public function dashboard_page()
{
$this->view = 'dashboard'; // Renders views/dashboard-view.php
}
// This method is called when the 'Settings' tab is active
public function settings_page()
{
$this->view = 'settings'; // Renders views/settings-view.php
}
}
Agganciarsi a un hook di WordPress (Action)
ATA offre un comodo metodo helper on() nel suo controller di base per registrare gli action hook. Il costruttore o un metodo main() del tuo controller è il posto ideale per registrare tutti gli hook.
// in app/controllers/footer-message-controller.php
namespace YourPluginNamespace;
class FooterMessageController extends Controller
{
public function main()
{
// Hook into 'wp_footer' to call the 'add_message' method
$this->on('wp_footer', 'add_message');
}
public function add_message()
{
echo "";
}
}
Usare i filtri di WordPress
Come per le action, puoi usare il metodo helper filter() per modificare i dati.
// in app/controllers/content-controller.php
namespace YourPluginNamespace;
class ContentController extends Controller
{
public function main()
{
// Hook into 'the_content' to modify post content
$this->filter('the_content', 'add_author_bio');
}
public function add_author_bio($content)
{
if (is_single() && in_the_loop() && is_main_query()) {
$author_bio = '';
return $content . $author_bio;
}
return $content;
}
}
Aggiungere un endpoint REST API di WordPress
Passo 1: registra la route in app/routes/main-routes.php. Così WordPress sa che il tuo URL esiste e quale metodo deve gestirlo.
// in app/routes/main-routes.php
namespace YourPluginNamespace;
$ata_router->api_version('my-plugin/v1');
$ata_router->api_method('GET')->api('/products')->call('ProductsApi::get_all_products');
Passo 2: crea una classe API in app/apis/ che contenga la logica dell’endpoint.
// in app/apis/products-api.php
namespace YourPluginNamespace;
class ProductsApi extends Api {
public function get_all_products() {
// ... logic to get products ...
return $this->send_success('Products retrieved.', ['products' => '...']);
}
}
Come funziona il routing?
Il file delle route (app/routes/main-routes.php) è una funzionalità potente ma facoltativa. Il suo unico compito è fare da centralino, indicando a WordPress come gestire determinati URL personalizzati. Se il tuo plugin non ha bisogno di URL personalizzati né di una REST API, non devi usarlo.
- Per le REST API: usa il metodo
api(). Registra un nuovo endpoint sotto/wp-json/.// Registers: example.com/wp-json/my-plugin/v1/orders $ata_router->api_version('my-plugin/v1'); $ata_router->api('/orders')->call('MyOrdersApi::get_orders'); - Per gli URL frontend personalizzati: usa il metodo
page(). Crea una pagina virtuale senza bisogno di un post di tipo Pagina in WordPress.// Registers: example.com/my-custom-url/ $ata_router->page('/my-custom-url')->call('MyPageController::show_page');
A cosa servono le directory core facoltative?
app/views
Questa directory contiene i tuoi template HTML. È necessaria solo se il tuo plugin genera un’interfaccia utente, come una pagina di impostazioni nell’admin o una pagina frontend personalizzata. I plugin che offrono solo funzionalità in background o una REST API probabilmente non avranno una directory views.
models/structures (DTO)
Questa directory è dedicata ai Data Transfer Object (DTO). Un DTO è una classe semplice che definisce la forma dei dati scambiati. Questa directory è facoltativa e per molti plugin potrebbe non servire. È particolarmente utile quando devi imporre una struttura dati rigorosa, soprattutto nella comunicazione con un’API esterna.
La prossima storia di successo potrebbe essere la tua.
Hai domande? Siamo qui per aiutarti a fare la scelta giusta.