オープンソース · Ata
WordPressプラグインを、さらに強力に。
MVC-S構造で。
ATAは、MVCデザインパターンによって、成長し続けるコードベースを整理された保守しやすい状態に保てるよう、WordPressプラグイン開発者を支援します。
WordPressプラグイン開発者へ
すべてに、専用のフォルダーを。
ATAはすべてのプラグインに同じ予測可能な構造を与えるため、コードベースが成長しても整理された保守しやすい状態を保てます。
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
Ataの基本原則。
標準で構造化
ATAは、プラグインのさまざまな部分を論理的に分離する、あらかじめ定義されたディレクトリ構造を提供します。
オブジェクト指向ファースト
手続き型の関数ではなくクラスでコードを書くことを推奨し、コードの再利用性と整理性を高めます。
明確な関心の分離
MVCパターンのバリエーションを採用し、ロジック、データ、プレゼンテーションの各レイヤーを確実に分離します。
シンプルなルーティング
ATAには組み込みのルーターがあり、カスタムREST APIエンドポイントやカスタムURLの登録をシンプルかつ宣言的に行えます。
主な違い
MVC-Sとは?
ATAは、Model-View-Controller(MVC)パターンの派生形を推奨しています。私たちはこれを MVC-S(Model-View-Controller-Services)と呼んでいます。
コントローラー(中枢エンジン)
コントローラーは、プラグインの動作の中核です。受信したリクエストの処理、すべてのWordPressフックとフィルターの登録、アプリケーションのフロー制御を担います。シンプルなプラグインでは、コントローラーがすべてのロジックとデータアクセスを直接処理できます。より複雑なアプリケーションでは、その役割はオーケストレーターへと進化します。ビジネスロジックには サービス を、データには モデル を呼び出し、その結果をレンダリングのために ビュー へ渡します。
ビュー(プレゼンテーション層)
ビューは、HTML出力を生成するための 任意 のレイヤーです。コントローラーからデータを受け取り、レンダリングします。ビューに含めるPHPロジックは最小限にとどめ、渡されたデータの表示だけに集中すべきです。
モデル(データ層)
モデルの唯一の役割は、データベースとの直接のやり取りです。モデルクラス内では、 $this->db を通じてWordPressのデータベースオブジェクトにアクセスできます(例: $this->db->get_results(...))。このレイヤーは 任意 です。プラグインがデータベースを扱わない場合は不要です。
サービス(ロジック層)
サービス層は、プラグインの中核となるビジネスロジックを置くための、 任意ですが推奨される 場所です。ロジックがコントローラーにとって複雑になりすぎたら、サービスに切り出しましょう。これにより、コントローラーはスリムに保たれ、リクエスト処理に集中できます。
サンプルプラグイン
Polylang RestAPI Helper
polylang-restapi-helper プラグインは、ATAフレームワークの要点を押さえた、まさに理想的なサンプルです。
WordPressプラグインをATAでMVC化する方法
ドキュメント
プラグインでATAを使い始める方法、素早く、簡単に
プラグインのライフサイクル & メインコントローラー
すべてのATAプラグインは、中心となるルートの コントローラー によって管理されます。このメインコントローラーは、プラグインのすべての機能のエントリーポイントであり、プラグインのライフサイクル管理を担います。
1. メインプラグインファイル(your-plugin-name.php) このファイルはごく最小限です。役割は、必須の定数を定義し、ATAフレームワークを読み込み、メインコントローラーをインスタンス化することだけです。
// 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. メインコントローラー(app/controllers/main-controller.php) このコントローラーには有効化/無効化のロジックが含まれ、最も重要な点として、他のすべてのコントローラーを読み込みます。ほかのプラグインが有効かどうかに応じて機能を条件付きで読み込めるため、メモリを節約し、エラーを防げます。
// 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 ...
}
}
WordPress管理画面にページやタブを追加する
ATAは、複数のタブを持つ管理ページを簡単に作成できるフルーエントインターフェースを提供します。これはコントローラーから管理します。
// 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
}
}
WordPressフックにフックする(アクション)
ATAは、アクションフックを登録するための便利な on() ヘルパーメソッドをベースコントローラーに備えています。すべてのフックを登録するのに最適な場所は、コントローラーのコンストラクター、または main() メソッドです。
// 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フィルターを使う
アクションと同様に、 filter() ヘルパーメソッドを使ってデータを変更できます。
// 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;
}
}
WordPress REST APIエンドポイントを追加する
ステップ1:ルートを登録する app/routes/main-routes.php で登録します。これにより、URLが存在すること、そしてどのメソッドがそれを処理するかをWordPressに伝えます。
// 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');
ステップ2:APIクラスを作成する app/apis/ に、エンドポイントのロジックを格納するクラスを作成します。
// 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' => '...']);
}
}
ルーティングの仕組み
ルートファイル(app/routes/main-routes.php)は、強力ですが任意の機能です。その唯一の役割は 交換台 として機能し、特定のカスタムURLをどう処理するかをWordPressに伝えることです。プラグインにカスタムURLやREST APIが不要であれば、使う必要はありません。
- REST APIの場合:
api()メソッドを使用します。これにより、/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'); - カスタムフロントエンドURLの場合:
page()メソッドを使用します。WordPressの固定ページを作成することなく、仮想ページを作成できます。// Registers: example.com/my-custom-url/ $ata_router->page('/my-custom-url')->call('MyPageController::show_page');
任意のコアディレクトリの役割は?
app/views
このディレクトリにはHTMLテンプレートを格納します。管理画面の設定ページやカスタムフロントエンドページなど、プラグインがユーザーインターフェースを生成する場合に のみ必要 です。バックグラウンド機能やREST APIのみを提供するプラグインには、通常 views ディレクトリはありません。
models/structures (DTO)
このディレクトリは データ転送オブジェクト(DTO) 用です。DTOは、受け渡しされるデータの形を定義するためのシンプルなクラスです。このディレクトリは 任意 で、多くのプラグインでは不要な場合があります。特に外部APIと通信する際など、厳密なデータ構造を強制する必要がある場合に最も役立ちます。