ساختار پوشه و فایل‌های یک افزونه

وقتی یک افزونه وردپرس در ابتدای کار فقط چند فایل دارد، مرتب نگه‌داشتن آن ساده به نظر می‌رسد؛ اما با اضافه‌شدن تنظیمات، شورت‌کدها، درخواست‌های AJAX، فایل‌های ترجمه و کدهای مدیریتی، همان پروژه کوچک خیلی زود به مجموعه‌ای نامنظم تبدیل می‌شود....

Picture of هانیه مجللی
هانیه مجللی

وقتی یک افزونه وردپرس در ابتدای کار فقط چند فایل دارد، مرتب نگه‌داشتن آن ساده به نظر می‌رسد؛ اما با اضافه‌شدن تنظیمات، شورت‌کدها، درخواست‌های AJAX، فایل‌های ترجمه و کدهای مدیریتی، همان پروژه کوچک خیلی زود به مجموعه‌ای نامنظم تبدیل می‌شود. اینجاست که دانستن ساختار پوشه و فایل افزونه اهمیت پیدا می‌کند؛ چون محل قرارگیری هر فایل، روش بارگذاری کدها و حتی امنیت افزونه را تحت تأثیر قرار می‌دهد.

اگر می‌خواهید افزونه‌ای بسازید که بعداً بتوانید آن را توسعه دهید، خطایابی کنید یا در پروژه‌های مختلف به کار ببرید، نباید همه کدها را داخل یک فایل PHP قرار دهید. یک ساختار اصولی، وظایف را جدا می‌کند: فایل اصلی افزونه نقطه شروع است، پوشه‌های مدیریتی مسئول پنل تنظیمات هستند، پوشه‌های عمومی فایل‌های CSS و JavaScript را نگه می‌دارند و کلاس‌ها یا ماژول‌ها نیز هرکدام نقش مشخصی دارند. در این راهنما، علاوه بر معرفی ساختار پیشنهادی، نمونه واقعی، مزایا و معایب روش‌های مختلف و نکات وردپرس‌محور را بررسی می‌کنیم تا بتوانید از همان ابتدا معماری قابل نگهداری‌تری بسازید.

ساختار پوشه و فایل افزونه

ساختار پوشه و فایل افزونه در وردپرس باید به شکلی طراحی شود که هر بخش، مسئولیت مشخصی داشته باشد. وردپرس برای شناسایی یک افزونه، به وجود فایل PHP اصلی و هدر استاندارد افزونه نیاز دارد؛ اما برای توسعه حرفه‌ای، همین یک فایل کافی نیست. بهتر است فایل اصلی فقط نقش راه‌اندازی را بر عهده بگیرد و منطق اصلی در فایل‌ها و پوشه‌های جداگانه قرار داشته باشد.

یک ساختار قابل قبول برای افزونه‌ای متوسط می‌تواند به شکل زیر باشد:

my-plugin/

├── my-plugin.php

├── uninstall.php

├── readme.txt

├── includes/

│ ├── class-my-plugin.php

│ ├── class-my-plugin-loader.php

│ └── functions.php

├── admin/

│ ├── class-my-plugin-admin.php

│ ├── views/

│ │ └── settings-page.php

│ ├── css/

│ │ └── admin.css

│ └── js/

│ └── admin.js

├── public/

│ ├── class-my-plugin-public.php

│ ├── css/

│ │ └── public.css

│ └── js/

│ └── public.js

├── languages/

│ └── my-plugin-fa_IR.mo

├── templates/

│ └── notice.php

└── assets/

└── icon.svg

این ساختار اجباری نیست، اما برای بیشتر افزونه‌های اختصاصی و تجاری، نقطه شروع مناسبی محسوب می‌شود. در پروژه‌های کوچک می‌توان تعداد فایل‌ها را کمتر کرد؛ بااین‌حال، جداکردن بخش مدیریت، خروجی سایت، منطق مشترک و فایل‌های نمایشی از همان ابتدا، در آینده زمان زیادی ذخیره می‌کند.

اگر پروژه شما در کنار افزونه به تغییرات ظاهری نیز نیاز دارد، بهتر است وظایف افزونه و قالب را با هم ترکیب نکنید. برای بخش‌های مربوط به رابط کاربری سایت، راهنمای طراحی قالب وردپرس می‌تواند مسیر مناسبی برای تفکیک مسئولیت‌های قالب و افزونه نشان دهد.

فهرست مطالب

فایل اصلی افزونه چه نقشی دارد؟

هدر استاندارد افزونه

فایل اصلی معمولاً نامی مشابه نام پوشه افزونه دارد؛ برای نمونه my-plugin.php. این فایل باید در ابتدای خود هدر استاندارد وردپرس را داشته باشد. وردپرس با خواندن همین اطلاعات، نام افزونه، نسخه، نویسنده و توضیحات آن را در صفحه افزونه‌ها نمایش می‌دهد.

<?php

/**

* Plugin Name: My Plugin

* Plugin URI: https://example.com

* Description: افزونه‌ای برای مدیریت امکانات اختصاصی سایت

* Version: 1.0.0

* Author: Your Name

* Text Domain: my-plugin

*/

defined( 'ABSPATH' ) || exit;

عبارت defined( 'ABSPATH' ) || exit; مانع اجرای مستقیم فایل از خارج وردپرس می‌شود. این خط به‌تنهایی امنیت کامل ایجاد نمی‌کند، اما یک لایه حفاظتی پایه و ضروری است.

فایل اصلی نباید محل تمام منطق افزونه باشد

یکی از اشتباهات رایج این است که تمام هوک‌ها، کوئری‌های دیتابیس، فرم‌ها و توابع در فایل اصلی نوشته شوند. چنین فایلی در ابتدا سریع‌تر آماده می‌شود، اما بعد از مدتی به کدی طولانی و پرریسک تبدیل خواهد شد. فایل اصلی بهتر است فقط ثابت‌های افزونه را تعریف کند، فایل‌های لازم را فراخوانی کند و هوک‌های راه‌اندازی را ثبت نماید.

define( 'MY_PLUGIN_VERSION', '1.0.0' );

define( 'MY_PLUGIN_FILE', __FILE__ );

define( 'MY_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );

define( 'MY_PLUGIN_URL', plugin_dir_url( __FILE__ ) );

require_once MY_PLUGIN_PATH . 'includes/class-my-plugin.php';

function my_plugin_run() {

$plugin = new My_Plugin();

$plugin->run();

}

my_plugin_run();

در پروژه‌های حرفه‌ای، همین تفکیک ساده باعث می‌شود توسعه‌دهنده بتواند بدون جست‌وجوی طولانی، محل هر قابلیت را پیدا کند. اگر هدف شما ساخت محصولی قابل توسعه است، خدمات طراحی پلاگین وردپرس نیز معمولاً بر همین اصل، یعنی جداسازی منطق و رعایت استانداردهای کدنویسی، بنا می‌شود.

معرفی پوشه‌های مهم افزونه

پوشه includes

پوشه includes معمولاً محل نگهداری منطق مشترک افزونه است؛ یعنی کدهایی که هم در پنل مدیریت و هم در بخش عمومی سایت استفاده می‌شوند. کلاس‌های اصلی، سرویس‌های اتصال به API، توابع کمکی و مدیریت هوک‌ها معمولاً در این بخش قرار می‌گیرند.

برای نام‌گذاری کلاس‌ها از پیشوند اختصاصی استفاده کنید. نامی مثل Plugin_Settings احتمال تداخل کمتری با افزونه‌های دیگر دارد، درحالی‌که نام عمومی Settings می‌تواند در پروژه‌های بزرگ مشکل‌ساز شود.

پوشه admin

تمام فایل‌هایی که فقط در پیشخوان وردپرس کاربرد دارند، بهتر است در پوشه admin قرار بگیرند. صفحه تنظیمات، ستون‌های سفارشی نوشته‌ها، اعلان‌های مدیریتی و فایل‌های CSS و JavaScript پنل نمونه‌هایی از این بخش هستند.

فایل‌های نمایشی پنل را نیز می‌توان در پوشه‌ای مانند views قرار داد. این کار باعث می‌شود کد PHP مربوط به منطق صفحه با HTML فرم‌ها درهم آمیخته نشود.

پوشه public

پوشه public به فایل‌هایی اختصاص دارد که در سمت کاربر سایت اجرا می‌شوند. برای مثال، اگر افزونه یک فرم ثبت‌نام، گالری یا ابزارک نمایشی دارد، فایل‌های CSS و JavaScript آن در این قسمت قرار می‌گیرند.

نکته مهم این است که فایل‌های عمومی را در تمام صفحات سایت بارگذاری نکنید. استفاده از wp_enqueue_script و شرط‌هایی مانند is_page() یا بررسی وجود شورت‌کد، از افزایش درخواست‌های غیرضروری جلوگیری می‌کند. در سایت‌های پرترافیک، همین جزئیات روی عملکرد اثر می‌گذارد و موضوع افزایش سرعت وردپرس را جدی‌تر می‌کند.

پوشه languages

اگر افزونه قرار است برای کاربران فارسی یا چندزبان استفاده شود، فایل‌های ترجمه را در پوشه languages نگه دارید. برای متن‌های قابل ترجمه از توابعی مانند __()، _e() و esc_html__() استفاده کنید و برای آن‌ها Text Domain یکسان در نظر بگیرید.

پوشه templates و assets

پوشه templates برای فایل‌های HTML یا PHP نمایشی مناسب است؛ درحالی‌که assets معمولاً محل آیکون‌ها، تصاویر، فونت‌ها و فایل‌های خامی است که مستقیماً منطق اجرایی ندارند. این جداسازی در زمان طراحی رابط کاربری و بسته‌بندی نسخه نهایی افزونه بسیار کاربردی است.

ساختار پوشه و فایل افزونه در معماری حرفه‌ای

تفکیک بخش مدیریت و بخش عمومی

یکی از اصول مهم در ساختار پوشه و فایل افزونه، جلوگیری از اجرای کدهای غیرضروری است. کلاس مدیریت نباید در هر درخواست کاربر عادی فعال شود و کدهای عمومی نیز نباید فقط برای بازشدن یک صفحه در پیشخوان بارگذاری شوند.

برای این کار می‌توان در زمان اجرای افزونه بررسی کرد که درخواست مربوط به مدیریت است یا نه:

if ( is_admin() ) {

require_once MY_PLUGIN_PATH . 'admin/class-my-plugin-admin.php';

} else {

require_once MY_PLUGIN_PATH . 'public/class-my-plugin-public.php';

}

البته is_admin() همیشه به معنای کاربر مدیر نیست؛ بلکه مشخص می‌کند درخواست مربوط به محیط مدیریت وردپرس است. برای کنترل دسترسی واقعی باید از بررسی قابلیت کاربر مانند current_user_can() نیز استفاده شود.

استفاده از کلاس‌ها و هوک‌ها

در افزونه‌های کوچک، توابع procedural می‌توانند کافی باشند؛ اما با افزایش قابلیت‌ها، کلاس‌ها خوانایی و توسعه‌پذیری بیشتری فراهم می‌کنند. ساختار شی‌گرا کمک می‌کند وابستگی‌ها مشخص باشند و نام متغیرها یا توابع با افزونه‌های دیگر تداخل پیدا نکند.

در یک پروژه واقعی، زمانی که قابلیت ارسال اعلان ایمیلی، صفحه تنظیمات و شورت‌کد در یک فایل قرار گرفته بودند، کوچک‌ترین تغییر در فرم تنظیمات باعث اختلال در خروجی شورت‌کد می‌شد. پس از جداکردن کلاس‌ها، خطایابی سریع‌تر شد و هر قابلیت بدون دست‌کاری بخش‌های دیگر توسعه پیدا کرد. این تجربه نشان می‌دهد معماری منظم فقط یک موضوع زیبایی‌شناختی نیست؛ مستقیماً هزینه نگهداری را کاهش می‌دهد.

لودر یا مدیریت‌کننده هوک‌ها

در افزونه‌های متوسط و بزرگ، می‌توان ثبت اکشن‌ها و فیلترها را در یک کلاس Loader قرار داد. این کلاس فهرست هوک‌ها، نام متد و اولویت اجرا را مدیریت می‌کند. چنین الگویی در پروژه‌هایی که تعداد زیادی هوک دارند، از پراکندگی کد جلوگیری خواهد کرد.

برای توسعه افزونه اختصاصی، انتخاب معماری باید متناسب با اندازه پروژه باشد. استفاده از الگوهای سنگین در یک افزونه کوچک، سرعت توسعه را کم می‌کند؛ اما چسباندن همه چیز به یک فایل نیز برای محصولی که قرار است سال‌ها نگهداری شود، تصمیم مناسبی نیست.

نکات امنیتی در سازمان‌دهی فایل‌ها

جلوگیری از دسترسی مستقیم

هر فایل PHP که ممکن است مستقیماً در مرورگر فراخوانی شود، باید دسترسی مستقیم را بررسی کند. این موضوع مخصوصاً برای فایل‌هایی که عملیات دیتابیس، خروجی اطلاعات یا پردازش فرم انجام می‌دهند، اهمیت دارد.

defined( 'ABSPATH' ) || exit;

بااین‌حال، داده‌های ورودی فرم را نیز باید پاک‌سازی و اعتبارسنجی کنید. برای فرم‌های مدیریتی از nonce استفاده کنید و پیش از اجرای عملیات، قابلیت کاربر را بررسی نمایید.

امنیت خروجی و درخواست‌ها

    • برای خروجی متن از esc_html() استفاده کنید.
    • برای ویژگی‌های HTML از esc_attr() کمک بگیرید.
    • آدرس‌ها را با esc_url() ایمن کنید.
    • برای فرم‌ها و درخواست‌های AJAX از nonce استفاده کنید.
    • پیش از ذخیره داده، نوع و مقدار آن را اعتبارسنجی کنید.
    • اطلاعات حساس مانند کلید API را در فایل‌های عمومی یا JavaScript قرار ندهید.

پوشه‌بندی منظم به‌تنهایی افزونه را امن نمی‌کند، اما باعث می‌شود محل بررسی ورودی‌ها، خروجی‌ها و دسترسی‌ها روشن باشد. تیم‌هایی که هم‌زمان روی نگهداری و توسعه سایت کار می‌کنند، با استفاده از خدمات پشتیبانی وردپرس می‌توانند خطاهای امنیتی و ناسازگاری‌های افزونه را زودتر شناسایی کنند.

مدیریت CSS و JavaScript

بارگذاری استاندارد فایل‌ها

هرگز فایل CSS یا JavaScript را با تگ دستی در فایل PHP چاپ نکنید. روش استاندارد وردپرس استفاده از wp_enqueue_style() و wp_enqueue_script() است. این توابع وابستگی‌ها، نسخه فایل و محل مناسب بارگذاری را مدیریت می‌کنند.

function my_plugin_enqueue_assets() {

wp_enqueue_style(

'my-plugin-public',

MY_PLUGIN_URL . 'public/css/public.css',

array(),

MY_PLUGIN_VERSION

);

wp_enqueue_script(

'my-plugin-public',

MY_PLUGIN_URL . 'public/js/public.js',

array( 'jquery' ),

MY_PLUGIN_VERSION,

true

);

}

add_action( 'wp_enqueue_scripts', 'my_plugin_enqueue_assets' );

بارگذاری شرطی

اگر فایل‌های افزونه فقط در یک صفحه استفاده می‌شوند، آن‌ها را در تمام سایت بارگذاری نکنید. می‌توانید وجود شورت‌کد یا نوع صفحه را بررسی کنید. همچنین، نسخه فایل را به‌صورت ثابت در کد قرار ندهید؛ استفاده از نسخه افزونه یا زمان تغییر فایل، کش مرورگر را بهتر مدیریت می‌کند.

فعال‌سازی، غیرفعال‌سازی و حذف افزونه

هوک فعال‌سازی

ساخت جدول اختصاصی، ثبت گزینه‌های اولیه یا زمان‌بندی یک رویداد باید هنگام فعال‌سازی افزونه انجام شود، نه در هر بار بارگذاری سایت. برای این کار از register_activation_hook() استفاده کنید.

function my_plugin_activate() {

add_option( 'my_plugin_version', MY_PLUGIN_VERSION );

}

register_activation_hook( __FILE__, 'my_plugin_activate' );

هوک غیرفعال‌سازی و حذف

در زمان غیرفعال‌سازی، رویدادهای زمان‌بندی‌شده را پاک کنید و فرایندهایی را که نباید ادامه پیدا کنند متوقف نمایید. اگر قرار است اطلاعات افزونه هنگام حذف کامل پاک شود، این منطق را در uninstall.php یا تابع حذف اختصاصی قرار دهید. حذف اطلاعات بدون اطلاع کاربر تصمیم مناسبی نیست؛ بهتر است این گزینه شفاف و قابل کنترل باشد.

فایل یا پوشهکاربرد اصلینکته مهم
my-plugin.phpنقطه ورود افزونه و معرفی آن به وردپرسفقط راه‌اندازی و فراخوانی فایل‌ها را انجام دهد
includesمنطق مشترک، کلاس‌ها و توابع اصلینام‌گذاری اختصاصی برای جلوگیری از تداخل
adminتنظیمات و امکانات پیشخوانفقط در محیط مدیریت بارگذاری شود
publicفایل‌ها و قابلیت‌های سمت کاربرCSS و JavaScript به‌صورت شرطی لود شوند
languagesفایل‌های ترجمهText Domain در تمام رشته‌ها یکسان باشد
uninstall.phpپاک‌سازی داده‌ها هنگام حذف افزونهحذف اطلاعات باید آگاهانه و قابل پیش‌بینی باشد

اشتباهات رایج در ساختار افزونه

استفاده از نام‌های عمومی

نام‌هایی مانند helper.php، functions.php یا تابعی با نام save_data() ممکن است با قالب یا افزونه دیگری تداخل داشته باشند. پیشوند اختصاصی، یکی از ساده‌ترین راه‌های کاهش این ریسک است.

قرار دادن اطلاعات حساس در افزونه

کلیدهای API، رمز عبور سرویس‌ها و توکن‌های خصوصی نباید در فایل‌هایی قرار بگیرند که در مخزن عمومی یا بسته قابل دانلود منتشر می‌شوند. برای این اطلاعات از تنظیمات امن سرور یا گزینه‌های محافظت‌شده استفاده کنید.

ترکیب منطق، HTML و کوئری‌های دیتابیس

وقتی یک فایل هم‌زمان کوئری دیتابیس اجرا می‌کند، فرم HTML چاپ می‌کند و پیام موفقیت نمایش می‌دهد، تغییر آن دشوار می‌شود. بهتر است پردازش، نمایش و ذخیره‌سازی تا حد امکان از هم جدا باشند. این تفکیک هم خوانایی را افزایش می‌دهد و هم تست‌کردن را ساده‌تر می‌کند.

کپی‌کردن ساختار پروژه‌های بزرگ

همه افزونه‌ها به معماری پیچیده نیاز ندارند. اگر افزونه فقط یک شورت‌کد ساده دارد، ساخت ده‌ها کلاس و پوشه ممکن است زمان توسعه را بی‌دلیل افزایش دهد. ساختار باید با تعداد قابلیت‌ها، تعداد اعضای تیم و طول عمر پروژه هماهنگ باشد.

فرایند پیشنهادی برای ساخت افزونه

از قابلیت‌ها شروع کنید، نه از فایل‌ها

قبل از ساخت پوشه، قابلیت‌های افزونه را روی کاغذ مشخص کنید: چه چیزی در مدیریت اجرا می‌شود؟ چه چیزی در سایت نمایش داده می‌شود؟ آیا جدول اختصاصی لازم است؟ آیا ترجمه، AJAX یا اتصال به سرویس خارجی وجود دارد؟ پاسخ این پرسش‌ها معماری مناسب را روشن می‌کند.

ساخت نسخه اولیه و تست

در نسخه اول، فایل اصلی، پوشه منطق مشترک و بخش‌های مدیریت و عمومی را ایجاد کنید. سپس هر قابلیت را جداگانه اضافه و تست کنید. افزونه را فقط روی سایت اصلی آزمایش نکنید؛ یک محیط staging یا نصب محلی داشته باشید تا خطاهای PHP، ناسازگاری نسخه‌ها و مشکلات قالب روی سایت واقعی اثر نگذارند.

بازبینی پیش از انتشار

    • نام تمام توابع و کلاس‌ها پیشوند اختصاصی داشته باشد.
    • ورودی‌ها اعتبارسنجی و خروجی‌ها escape شده باشند.
    • فایل‌های CSS و JavaScript فقط در صفحات ضروری بارگذاری شوند.
    • فعال‌سازی، غیرفعال‌سازی و حذف افزونه بررسی شده باشد.
    • پیام‌ها و رشته‌های قابل نمایش از قابلیت ترجمه پشتیبانی کنند.
    • افزونه با نسخه‌های پشتیبانی‌شده PHP و وردپرس آزمایش شود.
    • فایل‌های اضافی، اطلاعات آزمایشی و کلیدهای حساس از بسته نهایی حذف شوند.

در نهایت، ساختار پوشه و فایل افزونه زمانی ارزشمند است که به توسعه سریع‌تر، خطایابی ساده‌تر و تجربه بهتر کاربر کمک کند. یک معماری تمیز قرار نیست فقط ظاهر پروژه را حرفه‌ای نشان دهد؛ باید مشخص کند هر قابلیت کجا قرار دارد، چه زمانی اجرا می‌شود و چه وابستگی‌هایی دارد.

سؤالات متداول

آیا برای ساخت یک افزونه ساده به چندین پوشه نیاز داریم؟

خیر. برای افزونه‌ای که فقط یک شورت‌کد یا یک فیلتر ساده دارد، یک فایل اصلی و در صورت نیاز یک فایل کمکی کافی است. با افزایش قابلیت‌ها، پوشه‌های جداگانه را مرحله‌به‌مرحله اضافه کنید.

آیا نام پوشه افزونه باید با نام فایل اصلی یکسان باشد؟

اجباری نیست، اما هماهنگ‌بودن نام پوشه و فایل اصلی، مدیریت پروژه و تشخیص فایل ورود را ساده‌تر می‌کند. بهتر است نام انتخابی کوتاه، انگلیسی، منحصربه‌فرد و بدون فاصله باشد.

تفاوت پوشه admin و public چیست؟

پوشه admin برای کدها و فایل‌های مورد استفاده در پیشخوان وردپرس است و پوشه public برای امکانات قابل مشاهده در سمت کاربر سایت استفاده می‌شود. این تفکیک از بارگذاری کدهای غیرضروری جلوگیری می‌کند.

آیا استفاده از معماری شی‌گرا برای همه افزونه‌ها ضروری است؟

ضروری نیست، اما در افزونه‌های متوسط و بزرگ مزایای زیادی دارد. کلاس‌ها از تداخل نام‌ها جلوگیری می‌کنند و توسعه، تست و نگهداری قابلیت‌های مختلف را آسان‌تر می‌سازند.

فایل uninstall.php چه زمانی لازم است؟

زمانی که افزونه داده‌ای در دیتابیس ذخیره می‌کند، داشتن فرایند حذف مشخص اهمیت دارد. در این فایل می‌توانید گزینه‌ها، جدول‌ها یا داده‌های مرتبط را طبق تصمیم کاربر پاک کنید؛ البته حذف خودکار اطلاعات باید شفاف و قابل پیش‌بینی باشد.

آیا قرار دادن همه کدها در فایل اصلی باعث سریع‌تر شدن افزونه می‌شود؟

خیر. تعداد فایل‌ها به‌تنهایی معیار سرعت نیست. بارگذاری هوشمند، اجرای کوئری‌های بهینه، استفاده درست از کش و enqueue کردن شرطی منابع، تأثیر بیشتری بر عملکرد دارند. فایل اصلی فقط باید نقش هماهنگ‌کننده داشته باشد.

امتیاز دادن
  ایجاد آزمون آنلاین در وردپرس با افزونه Wp Pro Quiz

نظرات با ارزش کاربران

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

فهرست مطالب