مفتوح المصدر · Ata
ارتقِ بإضافة WordPress الخاصة بك.
ببنية MVC-S.
تساعد ATA مطوّري إضافات WordPress على إبقاء قواعد الشيفرة المتنامية منظّمة وسهلة الصيانة باستخدام نمط التصميم MVC.
لمطوّري إضافات 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).
Controller (المحرّك المركزي)
الـ Controller هو قلب عمل إضافتك. فهو مسؤول عن معالجة الطلبات الواردة، وتسجيل جميع خطّافات WordPress ومرشّحاتها، والتحكم في مسار التطبيق. في الإضافات البسيطة، يمكن للـ Controller أن يتولّى كل المنطق والوصول إلى البيانات مباشرةً. أما في التطبيقات الأكثر تعقيدًا فيتطوّر دوره ليصبح منسّقًا: يستدعي Service لمنطق الأعمال أو Model للبيانات، ثم يمرّر النتائج إلى View لعرضها.
View (طبقة العرض)
الـ View طبقة اختيارية لتوليد مخرجات HTML. تتلقّى البيانات من الـ Controller وتعرضها. ينبغي أن يحتوي الـ View على الحد الأدنى من منطق PHP، وأن يقتصر على عرض البيانات التي يتلقّاها.
Model (طبقة البيانات)
مسؤولية الـ Model الوحيدة هي التعامل المباشر مع قاعدة البيانات. داخل صنف Model يمكنك الوصول إلى كائن قاعدة بيانات WordPress عبر $this->db (مثلًا: $this->db->get_results(...)). هذه الطبقة اختيارية؛ فإن لم تتعامل إضافتك مع قاعدة البيانات فلا حاجة لها.
Service (طبقة المنطق)
طبقة الـ Service مكان اختياري لكنه موصى به لمنطق الأعمال الأساسي في إضافتك. حين يصبح المنطق أعقد من أن يتحمّله الـ Controller، ينبغي استخراجه إلى Service. هكذا تبقى الـ Controllers خفيفة ومركّزة على معالجة الطلبات.
إضافة نموذجية
Polylang RestAPI Helper
إضافة polylang-restapi-helper مثال مثالي ومركّز على إطار عمل ATA.
كيف تبني إضافة WordPress بأسلوب ATA MVC
التوثيق
كيف تبدأ استخدام ATA في إضافتك، بسرعة وسهولة
دورة حياة الإضافة & الـ Controller الرئيسي
تُدار كل إضافة ATA بواسطة Controller جذري مركزي. هذا الـ Controller الرئيسي هو نقطة الدخول لكل وظائف الإضافة، وهو المسؤول عن إدارة دورة حياتها.
1. ملف الإضافة الرئيسي (your-plugin-name.php) هذا الملف بسيط للغاية. مهامه الوحيدة تعريف الثوابت الأساسية، وتحميل إطار عمل ATA، وإنشاء نسخة من الـ Controller الرئيسي.
// 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. الـ Controller الرئيسي (app/controllers/main-controller.php) يحتوي هذا الـ Controller على منطق التفعيل/إلغاء التفعيل، والأهم أنه يحمّل جميع الـ Controllers الأخرى. وهنا يمكنك تحميل الميزات بشروط بحسب ما إذا كانت إضافات أخرى مفعّلة، فتوفّر الذاكرة وتتجنّب الأخطاء.
// 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 واجهة سلسة لإنشاء صفحات إدارة متعددة التبويبات بسهولة، وتُدار من خلال 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
}
}
الربط بخطّاف WordPress (Action)
توفّر ATA في الـ Controller الأساسي دالة مساعدة عملية هي on() لتسجيل خطّافات الإجراءات. والمكان المثالي لتسجيل كل الخطّافات هو الدالة البانية أو دالة main() في الـ Controller الخاص بك.
// 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. هذا يُعلم WordPress بوجود عنوان URL الخاص بك وبالدالة التي ستعالجه.
// 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) ميزة قوية لكنها اختيارية. مهمته الوحيدة أن يعمل كلوحة تحويل تُخبر WordPress بكيفية التعامل مع عناوين URL مخصصة معينة. إن لم تحتج إضافتك إلى عناوين 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 (DTOs)
هذا المجلد مخصص لكائنات نقل البيانات (DTOs). الـ DTO صنف بسيط يُستخدم لتحديد شكل البيانات المتداولة. هذا المجلد اختياري وقد لا تحتاجه كثير من الإضافات، وتبرز فائدته حين تحتاج إلى فرض بنية بيانات صارمة، خاصةً عند التواصل مع API خارجية.
قصة نجاحك قد تكون التالية.
لديك أسئلة؟ نحن هنا لمساعدتك على اتخاذ الخطوة الصحيحة.