تابع locate_template یکی از توابع پایه‌ای وردپرس برای یافتن مسیر فایل قالب با اولویت Child Theme است. این تابع پایه توابعی مانند get_template_part، get_header و get_footer محسوب می‌شود و امکان Override را در Child Theme فراهم می‌کند. استفاده درست از آن، ساختار قالب را پویا و قابل نگهداری می‌سازد. اشتباهات رایجی مانند نبود بررسی وجود، نبود fallback و نبود تست می‌تواند به خطای Fatal Error یا نبود فایل منجر شود. تسلط بر این تابع برای قالب‌نویسی پیشرفته و افزونه‌نویسی ضروری است و در Child Theme کاربرد گسترده دارد.

چرا یافتن مسیر فایل یک مهارت پایه است؟

در توسعه وردپرس، یکی از پرتکرارترین کارها، بارگذاری فایل‌های قالب است. اما مسیر این فایل‌ها ثابت نیست: با فعال بودن Child Theme، فایل‌های سفارشی باید در اولویت باشند. اگر این اولویت رعایت نشود، تغییرات کاربر در Child Theme نادیده گرفته می‌شود و تجربه توسعه‌دهنده و کاربر آسیب می‌بیند. تابع locate_template() دقیقاً برای حل همین مسئله ساخته شده است. این تابع فهرستی از نام فایل‌ها می‌گیرد و اولین فایلی که در Child Theme یا Parent Theme پیدا شود را برمی‌گرداند. این تابع پایه توابعی مانند get_template_part، get_header و get_footer است و شناخت آن برای هر توسعه‌دهنده جدی وردپرس ضروری است.

تابع locate_template چیست؟

تابع locate_template() یک تابع هسته وردپرس است که در فایل wp-includes/template.php تعریف شده است. این تابع یک یا چند نام فایل را جستجو می‌کند و اولین فایلی که پیدا شود را در قالب مسیر کامل برمی‌گرداند. نکته مهم این است که این تابع به‌صورت پیش‌فرض فایل را بارگذاری نمی‌کند؛ تنها مسیر آن را برمی‌گرداند. برای بارگذاری، باید پارامتر سوم ($load) را روی true تنظیم کنید. ترتیب جستجو همیشه به این شکل است: ابتدا Child Theme، سپس Parent Theme. این ترتیب، پایه الگوی Override در وردپرس است.

امضای تابع و پارامترها

امضای این تابع به‌شکل زیر است:
function locate_template( $template_names, $load = false, $load_once = true, $args = array() ) {
    $located = '';
    foreach ( (array) $template_names as $template_name ) {
        if ( ! $template_name ) {
            continue;
        }
        if ( file_exists( STYLESHEETPATH . '/' . $template_name ) ) {
            $located = STYLESHEETPATH . '/' . $template_name;
            break;
        } elseif ( file_exists( TEMPLATEPATH . '/' . $template_name ) ) {
            $located = TEMPLATEPATH . '/' . $template_name;
            break;
        }
    }

    if ( $load && '' !== $located ) {
        if ( $load_once ) {
            require_once $located;
        } else {
            require $located;
        }
    } elseif ( $load && '' === $located ) {
        // fallback به index.php
    }

    return $located;
}
پارامتر اول می‌تواند یک رشته یا آرایه از نام فایل‌ها باشد. پارامتر دوم تعیین می‌کند که فایل بارگذاری شود یا نه. پارامتر سوم تعیین می‌کند که require_once استفاده شود یا require. پارامتر چهارم از وردپرس ۵.۵ امکان پاس دادن آرگومان به فایل را فراهم می‌کند.

سازوکار داخلی و ترتیب جستجو

تابع locate_template() بر پایه دو ثابت مهم وردپرس کار می‌کند: STYLESHEETPATH که مسیر فیزیکی Child Theme (یا قالب فعال در صورت نبود Child Theme) را نشان می‌دهد و TEMPLATEPATH که مسیر فیزیکی Parent Theme را نشان می‌دهد. برای هر نام فایل در فهرست ورودی، تابع مراحل زیر را اجرا می‌کند: - بررسی می‌کند که آیا فایل در Child Theme وجود دارد - اگر بله، همان مسیر را برمی‌گرداند و از حلقه خارج می‌شود - اگر نه، بررسی می‌کند که آیا فایل در Parent Theme وجود دارد - اگر بله، همان مسیر را برمی‌گرداند - اگر هیچ فایلی پیدا نشد، رشته خالی برمی‌گردد نکته مهم این است که نام فایل‌ها باید به‌صورت رشته باشد، حتی اگر فقط یک فایل مدنظر است. این تابع برای آرایه طراحی شده است.

پارامترهای load و require_once

پارامتر دوم ($load) تعیین می‌کند که آیا فایل بارگذاری شود یا نه. مقدار پیش‌فرض false است. پارامتر سوم ($load_once) تعیین می‌کند که require_once استفاده شود یا require. مقدار پیش‌فرض true است که به معنای استفاده از require_once است. تفاوت این دو در رفتار با فراخوانی مکرر است. require_once از بارگذاری مکرر جلوگیری می‌کند، در حالی که require هر بار فایل را بارگذاری می‌کند. نمونه بارگذاری با require_once:
locate_template( 'parts/header-hero.php', true, true );
نمونه بارگذاری با require:
locate_template( 'parts/footer-newsletter.php', true, false );

کاربردهای عملی در قالب و افزونه

الگوی بررسی وجود فایل پیش از فراخوانی:
if ( locate_template( 'template-parts/hero.php' ) ) {
    get_template_part( 'template-parts/hero' );
}
الگوی fallback زنجیره‌ای در افزونه‌ها:
$template = locate_template( array(
    'myplugin/single-book.php',
    'single-book.php',
) );

if ( $template ) {
    load_template( $template, false );
}
نکته مهم: در افزونه‌ها، معمولاً ابتدا قالب کاربر را بررسی می‌کنند و اگر وجود داشت، همان را استفاده می‌کنند. اگر نه، از قالب پیش‌فرض افزونه استفاده می‌کنند. الگوی بارگذاری مستقیم با آرگومان (از وردپرس ۵.۵):
locate_template(
    'template-parts/card-product.php',
    true,
    true,
    array( 'show_price' => true )
);

تفاوت با get_template_part

تابع locate_template و get_template_part معمولاً با هم اشتباه گرفته می‌شوند: - locate_template: تنها مسیر فایل را برمی‌گرداند (مگر آنکه با $load=true فراخوانی شود). امکان بررسی وجود فایل را فراهم می‌کند. - get_template_part: فایل را بارگذاری می‌کند. اگر فایل وجود نداشته باشد، هیچ خطایی نمی‌دهد. در عمل، get_template_part روی locate_template ساخته شده است. برای بررسی وجود فایل، از locate_template استفاده کنید. برای بارگذاری ساده، از get_template_part استفاده کنید. راهنمای تابع دیگر در صفحه get_template_part آمده است.

نقش در Child Theme

تابع locate_template همیشه ابتدا در Child Theme جستجو می‌کند. این رفتار، پایه الگوی Override در وردپرس است. اگر فایل در Child Theme وجود داشته باشد، همان بارگذاری می‌شود، حتی اگر فایل مشابهی در Parent Theme وجود داشته باشد. این الگو به کاربران اجازه می‌دهد بدون تغییر فایل‌های Parent Theme، بخش‌های خاصی از قالب را سفارشی کنند. برای مطالعه بیشتر درباره ساختار Child Theme به راهنمای get_stylesheet_directory و راهنمای get_template_directory مراجعه کنید.

نکات امنیتی و اشتباهات رایج

اشتباه اول، نبود بررسی وجود فایل است. اگر locate_template را با $load=true فراخوانی کنید و فایل وجود نداشته باشد، ممکن است خطای Warning یا Fatal Error رخ دهد. اشتباه دوم، نبود fallback است. اگر فایل اصلی وجود نداشته باشد، باید fallback مناسبی تعریف شود. این نکته در افزونه‌ها حیاتی است. اشتباه سوم، استفاده از مسیر مطلق به‌جای مسیر نسبی است. نام فایل باید نسبی باشد، نه مطلق. برای نمونه، 'parts/header.php' درست است، نه '/var/www/html/wp-content/themes/mytheme/parts/header.php'. اشتباه چهارم، نبود escape در فایل بارگذاری‌شده است. اگر فایل داده‌های پویا چاپ می‌کند، از توابع escape استفاده کنید. راهنمای این تابع در صفحه esc_html آمده است. اشتباه پنجم، نبود تست در Child Theme است. باید رفتار کد را در هر دو حالت Parent و Child بررسی کنید. اشتباه ششم، استفاده از این تابع برای بارگذاری فایل‌های غیرقالبی است. برای include فایل‌های PHP در inc، از require با get_template_directory استفاده کنید. اشتباه هفتم، نبود توجه به ترتیب نام‌ها در آرایه است. ترتیب نام‌ها در آرایه به معنای اولویت است. همیشه مهم‌ترین نام را اول بیاورید.

تحلیل فنی پیشرفته

در نگاه مهندسی، تابع locate_template() یک نقطه معماری در لایه رندر است که بر چند جنبه از سیستم اثر می‌گذارد. لایه اول لایه Override است. مکانیزم STYLESHEETPATH و TEMPLATEPATH امکان اولویت‌دهی به Child Theme را فراهم می‌کند و یکی از پایه‌ای‌ترین اصول توسعه پایدار در وردپرس محسوب می‌شود. لایه دوم لایه fallback است. الگوی زنجیره‌ای جستجو امکان تعریف چند سطح از فایل‌ها را می‌دهد. اگر فایل خاصی وجود نداشت، به فایل عمومی‌تر برمی‌گردد. این الگو در پروژه‌های بزرگ بسیار کاربردی است. لایه سوم لایه کشینگ است. نتیجه این تابع معمولاً کش نمی‌شود، اما فایل HTML نهایی ممکن است کش شود. اگر محتوای فایل بر اساس وضعیت کاربر تغییر کند، باید استراتژی کش مناسب انتخاب شود. لایه چهارم لایه امنیت است. مسیر فایل ممکن است در خروجی HTML چاپ شود و این می‌تواند به افشای اطلاعات ساختار سرور منجر شود. همیشه از escape استفاده کنید. لایه پنجم لایه Performance است. فراخوانی مکرر locate_template با آرایه‌های بزرگ می‌تواند تأثیر محسوسی داشته باشد. برای بهینه‌سازی، می‌توانید نتیجه را در متغیر ذخیره کنید. لایه ششم لایه Integration است. در افزونه‌ها، این تابع نقش محوری در بارگذاری قالب‌های سفارشی دارد. الگوی رایج در افزونه‌های حرفه‌ای، ابتدا جستجو در قالب کاربر و سپس استفاده از قالب پیش‌فرض افزونه است. لایه هفتم لایه Multisite است. در شبکه‌های Multisite، هر سایت می‌تواند قالب متفاوتی داشته باشد و locate_template همیشه بر پایه قالب سایت جاری کار می‌کند. لایه هشتم لایه تست است. تست‌های End-to-End باید همه حالت‌ها را پوشش دهند: Parent Theme، Child Theme، فایل وجود دارد، فایل وجود ندارد. مفاهیم پایه‌ای فایل سیستم در File System در ویکی‌پدیا توضیح داده شده است. برای مطالعه بیشتر روی توابع مرتبط، می‌توانید به راهنمای get_template_part، راهنمای get_header، راهنمای get_footer، راهنمای get_sidebar، راهنمای get_template_directory، راهنمای get_stylesheet_directory و راهنمای add_theme_support مراجعه کنید.

پرسش‌های پرتکرار

تفاوت locate_template و get_template_part چیست؟ اولی مسیر فایل را برمی‌گرداند و دومی فایل را بارگذاری می‌کند. آیا می‌توان چند نام فایل به locate_template داد؟ بله، با پاس دادن آرایه. ترتیب جستجو در locate_template چیست؟ ابتدا Child Theme، سپس Parent Theme. چطور از locate_template برای بررسی وجود فایل استفاده کنیم؟ با فراخوانی locate_template بدون $load و بررسی مقدار بازگشتی. آیا این تابع در افزونه‌ها کاربرد دارد؟ بله، به‌ویژه در افزونه‌هایی که قالب سفارشی برای نمایش محتوا دارند.

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

تابع locate_template() ابزار پایه‌ای برای یافتن مسیر فایل قالب با اولویت Child Theme است. استفاده درست از آن یعنی درک دقیق ترتیب جستجو، توجه به آرایه نام‌ها، بررسی وجود فایل پیش از بارگذاری و رعایت escape در فایل‌های بارگذاری‌شده. اشتباه‌های کوچک در این تابع اغلب به خطای Fatal Error یا نبود فایل منجر می‌شوند. اگر این تابع را در پروژه‌ای واقعی به کار برده‌اید و رفتار غیرمنتظره‌ای دیده‌اید — به‌خصوص در ترکیب با Child Theme یا در افزونه‌های پیچیده — تجربه‌تان می‌تواند راهگشای دیگران باشد. کدام بخش بیشترین زمان را از شما گرفت؟ دیدگاه خود را بنویسید.