Open source · Ata
Geef je WordPress-plugin een boost.
Met een MVC-S-structuur.
ATA helpt ontwikkelaars van WordPress-plugins om groeiende codebases georganiseerd en onderhoudbaar te houden met het MVC-ontwerppatroon.
Voor ontwikkelaars van WordPress-plugins
Alles heeft zijn eigen map.
ATA geeft elke plugin dezelfde voorspelbare structuur, zodat groeiende codebases georganiseerd en onderhoudbaar blijven.
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
De kernprincipes van Ata.
Standaard gestructureerd
ATA biedt een vooraf gedefinieerde mappenstructuur die de onderdelen van je plugin logisch van elkaar scheidt.
Objectgeoriënteerd voorop
Het stimuleert code in klassen in plaats van procedurele functies, wat herbruikbaarheid en overzicht ten goede komt.
Heldere scheiding van verantwoordelijkheden
Het gebruikt een variant van het MVC-patroon, zodat logica, data en presentatie strikt gescheiden blijven.
Eenvoudige routing
ATA heeft een ingebouwde router waarmee je eigen REST API-endpoints of eigen URL’s eenvoudig en declaratief registreert.
De belangrijkste verschillen
Wat is MVC-S?
ATA hanteert een variant van het Model-View-Controller-patroon (MVC), die wij MVC-S (Model-View-Controller-Services) noemen.
Controller (de centrale motor)
De Controller is het hart van je plugin. Hij verwerkt binnenkomende requests, registreert alle WordPress-hooks en -filters en stuurt de flow van de applicatie aan. Bij eenvoudige plugins kan de Controller alle logica en datatoegang zelf afhandelen. In complexere applicaties wordt hij een regisseur: hij roept een Service aan voor de bedrijfslogica of een Model voor data, en geeft het resultaat door aan een View om te renderen.
View (de presentatielaag)
De View is een optionele laag die HTML-output genereert. Hij ontvangt data van de Controller en rendert die. Een View bevat zo min mogelijk PHP-logica en richt zich alleen op het tonen van de data die hij krijgt.
Model (de datalaag)
Het Model heeft maar één taak: rechtstreekse interactie met de database. In een Model-klasse benader je het WordPress-databaseobject via $this->db (bijv. $this->db->get_results(...)). Deze laag is optioneel; communiceert je plugin niet met de database, dan heb je hem niet nodig.
Service (de logicalaag)
De Service-laag is een optionele maar aanbevolen plek voor de kernlogica van je plugin. Wordt de logica te complex voor een Controller, verplaats haar dan naar een Service. Zo blijven Controllers slank en gericht op het afhandelen van requests.
Voorbeeldplugin
Polylang RestAPI Helper
De plugin polylang-restapi-helper is een perfect, doelgericht voorbeeld van het ATA-framework.
Zo geef je je WordPress-plugin een ATA MVC-structuur
Documentatie
Snel en eenvoudig aan de slag met ATA in je plugin
De levenscyclus van de plugin & de hoofdcontroller
Elke ATA-plugin wordt aangestuurd door één centrale Controller. Deze hoofdcontroller is het startpunt voor alle functionaliteit van de plugin en beheert de levenscyclus ervan.
1. Het hoofdbestand van de plugin (your-plugin-name.php) Dit bestand is uiterst minimaal. Het definieert alleen de essentiële constanten, laadt het ATA-framework en instantieert je hoofdcontroller.
// 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. De hoofdcontroller (app/controllers/main-controller.php) Deze controller bevat de logica voor activeren en deactiveren en laadt, het belangrijkste, alle andere controllers. Hier kun je functies voorwaardelijk laden, afhankelijk van welke andere plugins actief zijn. Dat bespaart geheugen en voorkomt fouten.
// 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 ...
}
}
Een pagina of tab toevoegen aan het WordPress-beheerpaneel
ATA biedt een fluent interface waarmee je eenvoudig beheerpagina’s met meerdere tabs maakt. Dit regel je vanuit een 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
}
}
Inhaken op een WordPress-hook (action)
ATA heeft in de basiscontroller een handige helpermethode on() om action-hooks te registreren. De constructor of een main() methode in je controller is de ideale plek om alle hooks te registreren.
// 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 "";
}
}
WordPress-filters gebruiken
Net als bij actions kun je met de helpermethode filter() data aanpassen.
// 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;
}
}
Een WordPress REST API-endpoint toevoegen
Stap 1: registreer de route in app/routes/main-routes.php. Zo weet WordPress dat je URL bestaat en welke methode hem afhandelt.
// 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');
Stap 2: maak een API-klasse in app/apis/ met de logica voor het 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' => '...']);
}
}
Hoe werkt routing?
Het routebestand (app/routes/main-routes.php) is een krachtige maar optionele functie. Het fungeert uitsluitend als schakelbord dat WordPress vertelt hoe bepaalde eigen URL’s moeten worden afgehandeld. Heeft je plugin geen eigen URL’s of REST API nodig, dan hoef je het niet te gebruiken.
- Voor REST API’s: gebruik de methode
api(). Die registreert een nieuw endpoint onder/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'); - Voor eigen frontend-URL’s: gebruik de methode
page(). Die maakt een virtuele pagina zonder dat je een WordPress-pagina nodig hebt.// Registers: example.com/my-custom-url/ $ata_router->page('/my-custom-url')->call('MyPageController::show_page');
Waarvoor dienen de optionele kernmappen?
app/views
Deze map bevat je HTML-templates. Hij is alleen nodig als je plugin een gebruikersinterface genereert, zoals een instellingenpagina in de beheeromgeving of een eigen frontendpagina. Plugins die alleen achtergrondfunctionaliteit of een REST API bieden, hebben doorgaans geen views map.
models/structures (DTO’s)
Deze map is bedoeld voor Data Transfer Objects (DTO’s). Een DTO is een eenvoudige klasse die de vorm vastlegt van de data die wordt doorgegeven. Deze map is optioneel en voor veel plugins overbodig. Hij komt vooral van pas als je een strikte datastructuur wilt afdwingen, met name bij communicatie met een externe API.
Jouw succesverhaal kan het volgende zijn.
Vragen? We helpen je graag de juiste keuze te maken.