خطای عدم پشتیبانی قالب از ویژگیهای وردپرس
چرا قالب وردپرس شما از ویژگیهای هسته مثل تصویر شاخص، لوگوی سفارشی یا فهرست منو پشتیبانی نمیکند و در فهرست قالبها ناقص بهنظر میرسد؟ این راهنما دوازده علت ریشهای — از فراموشی add_theme_support تا قالبهای بلوکی و کلاسیک — را با راهحل عملی بررسی میکند.
اولین بار که با این دسته از خطاها مواجه شدم، در یک قالب سفارشی بود که برای مشتری نوشته بودم. همهچیز خوب کار میکرد تا وقتی مشتری گفت گزینه تصویر شاخص در ویرایشگر نمیبیند. سراغ کد رفتم و دیدم خط add_theme_support('post-thumbnails') را فراموش کردهام. از آن روز فهمیدم که در وردپرس، قالبها یک سری از قابلیتهای هسته را بهطور خودکار ندارند؛ باید صریحاً درخواستشان کنند. اگر این درخواست انجام نشود، آن قابلیت در قالب ظاهر نمیشود، ولی خود وردپرس بینقص کار میکند. این مقاله، همه آن چیزی است که در این سالها از این دسته از خطاها یاد گرفتهام.
چرا قالب باید صریحاً از ویژگیهای هسته پشتیبانی کند؟
وردپرس از ابتدا با یک فلسفه طراحی شده: هسته باید سبک و قابل تعمیم باشد. یعنی تصمیمات مربوط به ظاهر و ساختار نمایش، نه در هسته، بلکه در قالب گرفته میشود. به همین دلیل، بسیاری از قابلیتها بهطور پیشفرض در قالب فعال نیستند و باید از طریق تابع add_theme_support اعلام شوند. اگر قالب این اعلام را انجام ندهد، ویژگی در آن قالب بهکار نمیرود، حتی اگر در هسته وردپرس کاملاً آماده باشد.
این فلسفه درست است، ولی در عمل باعث میشود قالبهایی که نویسندهشان این خطوط اعلام را فراموش کرده، بهنظر ناقص و خراب بیایند. مشتری گمان میکند سایت مشکل دارد، ولی در واقع فقط قالب یک خط کد را اعلام نکرده. اگر با ساختار کلی قالب آشنا نیستید، پیشنهاد میکنم ابتدا قالب وردپرس چیست و چگونه انتخاب کنیم را بخوانید تا تصویر روشنی از لایههای قالب داشته باشید. برای درک دقیقتر نقش توابع در قالب، قالب وردپرس از نگاه توسعهدهنده عمیقتر به این لایه میپردازد.
قالب وردپرس مثل یک قرارداد دوطرفه است: از یک طرف میگوید چه چیزی را نمایش میدهم، از طرف دیگر باید بگوید از چه چیزی پشتیبانی میکنم. اگر بخش دوم فراموش شود، هسته هیچ قابلیتی را به آن قالب تحمیل نمیکند.
نشانههای عدم پشتیبانی قالب از ویژگیها
پیش از ورود به علتها، بگذارید نشانههای رایجی را که در پروندههای واقعی دیدهام فهرست کنم. این نشانهها به شما میگویند احتمالاً با این دسته از خطا روبهرو هستید، نه با یک باگ دیگر:
| نشانه | ویژگی احتمالاً اعلام نشده |
|---|---|
| گزینه تصویر شاخص در ویرایشگر نیست | post-thumbnails |
| گزینه لوگو در Customizer نیست | custom-logo |
| هیچ فهرست منویی در نمایش ← فهرستها نیست | menus |
| تگ title دوبار در هدر HTML تولید میشود | title-tag |
| خروجی HTML با تگهای قدیمی مثل XHTML است | html5 |
| گزینه هدر سفارشی در Customizer نیست | custom-header |
| گزینه پسزمینه سفارشی در Customizer نیست | custom-background |
| بلوکها بهدرستی در سایت نمایش داده نمیشوند | align-wide / wp-block-styles |
| در قالب چایلد ویژگیها ناپدید میشوند | اعلام نکردن در Child |
| در قالب بلوکی، رنگ و تایپوگرافی کار نمیکند | theme.json ناقص |
اگر یکی از این نشانهها را در سایت خود میبینید، احتمالاً علت در یکی از دوازده موردی است که در ادامه به آنها میپردازم. هر علت را با مثال کد و راهحل عملی توضیح میدهم.
علت اول: فراخوانی نشدن add_theme_support
شایعترین علت، سادهترین علت است: نویسنده قالب، خطوط اعلام پشتیبانی را در فایل functions.php ننوشته یا فراموش کرده. برای حل این مسئله، باید در فایل functions.php قالب یا بهتر، در فایل functions.php قالب چایلد، تابع after_setup_theme را فراخوانی کنید و درون آن، ویژگیهای موردنیاز را اعلام کنید. الگوی استاندارد به این شکل است:
<?php
function my_theme_setup() {
add_theme_support( 'post-thumbnails' );
add_theme_support( 'title-tag' );
add_theme_support( 'custom-logo', array(
'height' => 80,
'width' => 240,
'flex-height' => true,
) );
register_nav_menus( array(
'primary' => 'منوی اصلی',
'footer' => 'منوی فوتر',
) );
}
add_action( 'after_setup_theme', 'my_theme_setup' );
نکته مهم این است که این کد را هرگز در قالب والد نگذارید، چون در آپدیت بعدی از بین میرود. همیشه این قبیل سفارشیسازیها را در قالب چایلد قرار دهید. اگر با مفهوم قالب چایلد آشنا نیستید، قالب چایلد وردپرس چیست گامبهگام این ساختار را توضیح میدهد.
علت دوم: قرار دادن add_theme_support در هوک اشتباه
گاهی نویسنده قالب کد add_theme_support را نوشته، ولی در هوک اشتباهی قرار داده. این ویژگی فقط در هوک after_setup_theme بهدرستی اجرا میشود. اگر آن را در init یا wp_loaded یا در بالای فایل functions.php بدون هوک قرار دهید، وردپرس ممکن است آن را نادیده بگیرد یا با تاخیر اعمال کند. این نوع خطا شایع است چون در نگاه اول کد کاملاً درست بهنظر میرسد ولی در عمل کار نمیکند.
راه تشخیص سریع: در فایل functions.php، جستجو کنید برای add_theme_support و ببینید در چه هوکی فراخوانی شده. اگر در after_setup_theme نبود، آن را داخل این هوک منتقل کنید. مسیر کامل عیبیابی این نوع از خطاها در عیبیابی خطای قالب وردپرس آمده است.
علت سوم: نبود پشتیبانی از تصویر شاخص
تصویر شاخص یا Featured Image، یکی از آن قابلیتهایی است که اگر پشتیبانی نشود، در ویرایشگر نوشته اصلاً ظاهر نمیشود. مشتری گمان میکند ویرایشگر وردپرس مشکل دارد، ولی در واقع فقط یک خط add_theme_support('post-thumbnails') کم است. این خط را در همان هوک after_setup_theme قرار دهید تا گزینه تصویر شاخص در کنار ویرایشگر ظاهر شود.
علاوه بر آن، در فایلهای تمپلیت مثل single.php و archive.php باید تابع the_post_thumbnail() را در جای درست فراخوانی کنید تا تصویر در صفحه هم نمایش داده شود. بعضی قالبها این خط را در functions.php دارند ولی در تمپلیتها فراخوانی نمیکنند. این نوع اشتباه در ساختار قالب را در فایلهای ضروری یک قالب وردپرس توضیح دادهام.
علت چهارم: نبود پشتیبانی از لوگوی سفارشی
لوگوی سفارشی یا Custom Logo یکی دیگر از قابلیتهای هسته است که در نسخههای جدید وردپرس اضافه شده. اگر قالب پشتیبانیاش را اعلام نکند، گزینه مربوطه در Customizer ظاهر نمیشود و شما نمیتوانید لوگو را از رابط کاربری مدیریت کنید. الگوی اعلام:
add_theme_support( 'custom-logo', array(
'height' => 100,
'width' => 400,
'flex-height' => true,
'flex-width' => true,
) );
در تمپلیت، بهجای یک تصویر لوگوی هاردکد شده، از the_custom_logo() استفاده کنید تا لوگوی اعلامشده نمایش داده شود. همین الگو برای هدر سفارشی و پسزمینه سفارشی هم صدق میکند. اگر با مفهوم Customizer آشنایی بیشتری میخواهید، مسیر کاملش در مستندات رسمی وردپرس آمده است.
علت پنجم: نبود پشتیبانی از فهرست منو
فهرست منو یا Navigation Menus از آن قابلیتهایی است که باید با register_nav_menus صریحاً اعلام شود. اگر این خط نباشد، در پنل مدیریت، بخش نمایش ← فهرستها خالی است و شما نمیتوانید فهرست جدیدی بسازید. الگوی اعلام:
register_nav_menus( array(
'primary' => 'منوی اصلی',
'footer' => 'منوی فوتر',
) );
بعد از ثبت، باید در تمپلیت هدر، تابع wp_nav_menu با پارامتر theme_location فراخوانی شود تا فهرست نمایش داده شود. اگر فهرست را ثبت کردهاید ولی نمایش داده نمیشود، احتمالاً پارامتر theme_location اشتباه است یا فهرست در پنل به آن موقعیت اختصاص داده نشده. مشابه همین دسته از خطاها را در رفع خطای Template file missing بهعنوان چارچوب کلی بررسی کردهام.
در وردپرس، هر ویژگی که در قالب بهکار میرود، اول باید اعلام شود و بعد فراخوانی. اعلام بدون فراخوانی یعنی قابلیت هست ولی استفاده نمیشود؛ فراخوانی بدون اعلام یعنی کد درست است ولی جواب نمیدهد.
علت ششم: نبود پشتیبانی از تگ title خودکار
تگ title در هدر HTML، از نسخه ۴.۱ وردپرس به بعد میتواند بهطور خودکار توسط هسته مدیریت شود. اگر قالب این پشتیبانی را اعلام نکند، هسته تگ title را تولید نمیکند و شما باید خودتان در header.php آن را بنویسید. اگر هم اعلام شده و هم خودتان دستی نوشته باشید، نتیجه دو تگ title در هدر HTML است که از دید سئو مشکل جدیای است.
الگوی اعلام:
add_theme_support( 'title-tag' );
بعد از اعلام این ویژگی، تگ <title> را از header.php حذف کنید. یک بار در View Source چک کنید که فقط یک تگ title وجود داشته باشد. این موضوع از دید سئو اهمیت زیادی دارد و در SEO تکنیکال: از خزش تا ایندکس هم بهعنوان بخشی از ساختار درست HTML تحلیلش کردهام.
علت هفتم: نبود پشتیبانی از HTML5 و ساختار معنایی
وردپرس بهطور پیشفرض از تگهای قدیمی HTML مثل <div id="header"> استفاده میکند. اگر قالب از HTML5 پشتیبانی اعلام کند، هسته بهجای این تگها از تگهای معنایی مثل <header>، <footer>، <nav> و <article> استفاده میکند. این کار هم از دید سئو بهتر است، هم از دید دسترسپذیری. الگوی اعلام:
add_theme_support( 'html5', array(
'search-form',
'comment-form',
'comment-list',
'gallery',
'caption',
'style',
'script',
) );
بدون این خط، بسیاری از قابلیتهای مدرن HTML5 در خروجی شما غیرفعال میشوند. نشانهاش این است که مثلاً فرم جستجو یا فرم دیدگاهها با ساختار قدیمی رندر میشود.
علت هشتم: نبود پشتیبانی از هدر و پسزمینه سفارشی
این دو قابلیت، از دوران قالبهای کلاسیک باقی ماندهاند ولی همچنان در قالبهای امروزی هم کاربرد دارند. اگر قالب از هدر سفارشی یا پسزمینه سفارشی پشتیبانی اعلام نکند، گزینه مربوطه در Customizer ظاهر نمیشود و مشتری نمیتواند تصویر یا رنگ پسزمینه را مدیریت کند. الگوها:
add_theme_support( 'custom-header', array(
'default-image' => get_template_directory_uri() . '/images/header.jpg',
'width' => 1200,
'height' => 300,
'flex-height' => true,
) );
add_theme_support( 'custom-background', array(
'default-color' => 'ffffff',
) );
البته در قالبهای بلوکی، این دو قابلیت جای خود را به theme.json دادهاند که در ادامه به آن میپردازم.
علت نهم: نبود پشتیبانی از بلوکهای گوتنبرگ
اگر قالب شما برای نمایش بلوکهای گوتنبرگ آماده نیست، ممکن است بلوکها بهدرستی نمایش داده نشوند یا استایلهای پیشفرض گوتنبرگ در فرانتاند اعمال نشوند. الگوی اعلام پشتیبانی:
add_theme_support( 'align-wide' );
add_theme_support( 'wp-block-styles' );
add_theme_support( 'responsive-embeds' );
add_theme_support( 'editor-styles' );
add_editor_style( 'editor-style.css' );
هر یک از این خطوط، یک قابلیت مشخص را فعال میکند: align-wide برای بلوکهای عریض، wp-block-styles برای استایلهای پیشفرض بلوکها، responsive-embeds برای ویدیوهای واکنشگرا، و editor-styles برای اعمال استایل قالب در ویرایشگر. اگر با مفهوم گوتنبرگ و بلوکها آشنا نیستید، گوتنبرگ و آینده ویرایش محتوا در وردپرس تصویر کاملی میدهد.
علت دهم: قالب چایلد بدون اعلام صریح پشتیبانی
این علت، در نگاه اول عجیب بهنظر میرسد ولی در پروژههای واقعی زیاد دیدهام. وقتی قالب چایلد فعال میشود، تابع after_setup_theme قالب والد بهطور خودکار اجرا نمیشود اگر قالب چایلد خودش هوکی برای فراخوانی آن ثبت نکرده باشد. یعنی قابلیتهایی که در والد اعلام شده بودند، در فرزند بهطور خودکار ارث نمیرسند. باید در functions.php قالب چایلد، همان توابع اعلام را مجدداً فراخوانی کنید.
مثال: اگر قالب والد post-thumbnails را اعلام کرده ولی قالب چایلد functions.php خودش را داشته باشد و آن را اعلام نکند، ممکن است ویژگی بهدرستی کار نکند. الگوی درست، فراخوانی صریح تمام add_theme_supportهای والد در فرزند است. توضیح کامل این رفتار در قالب چایلد وردپرس چیست آمده است.
علت یازدهم: قالب بلوکی بدون theme.json کامل
در قالبهای بلوکی نسل جدید وردپرس، جای add_theme_support را فایل theme.json گرفته است. در این قالبها، اگر فایل theme.json ناقص باشد یا نباشد، بخشهایی از قابلیتهای هسته غیرفعال میشوند. مثلاً رنگهای پالت، تایپوگرافی، اندازههای عرض، و پشتیبانی از اسپیسینگ، همه از طریق این فایل مدیریت میشوند. اگر مشتری میگوید قالب بلوکی است ولی گزینههای رنگ و تایپوگرافی در ویرایشگر نیست، ابتدا به theme.json نگاه کنید.
ساختار پایه این فایل به شکل زیر است:
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {
"color": {
"palette": []
},
"typography": {
"fontSizes": []
},
"layout": {
"contentSize": "720px",
"wideSize": "1200px"
}
}
}
اگر قالب بلوکی است و این فایل ناقص، بسیاری از تنظیمات ظاهری از کار میافتد. مسیر انتقال از قالب کلاسیک به بلوکی، نیازمند یک پروژه مستقل است که در فرصت دیگر به آن میپردازم. برای درک عمیقتر لایه بلاک، قالب وردپرس از نگاه توسعهدهنده نقطه شروع خوبی است.
علت دوازدهم: قالبهای قدیمی و ساختار ناسازگار
قالبهایی که قبل از نسخه ۵.۰ وردپرس نوشته شدهاند، اغلب از قابلیتهای جدید بیخبرند. مثلاً پشتیبانی از لوگوی سفارشی، align-wide، responsive-embeds و بقیه ویژگیهای نسل گوتنبرگ در آنها وجود ندارد. اگر یک قالب قدیمی را روی نسخه جدید وردپرس نصب کنید، این قابلیتها در پنل ظاهر نمیشوند و بهنظر میرسد قالب ناقص است.
راهحل معمولاً دو گزینه دارد: یا قالب را آپدیت کنید (اگر نسخه جدیدی وجود دارد) یا از طریق قالب چایلد، قابلیتهای موردنیاز را اعلام کنید. حالت دوم همیشه کار میکند ولی باید با دقت انجام شود تا با کد اصلی قالب تعارض نداشته باشد. مسیر آپدیت و رفع خطاهای آپدیت قالب را در خطای بروزرسانی قالب وردپرس و رفع خطای ناسازگاری قالب با نسخه وردپرس آوردهام.
چگونه تشخیص دهیم قالب از چه ویژگیهایی پشتیبانی میکند
سه روش را در پروژههای خودم بهکار میبرم:
- ابزار سلامت سایت وردپرس: در پیشخوان ← ابزارها ← سلامت سایت ← گزارش. این ابزار فهرست قابلیتهای اعلامشده و اعلامنشده قالب را میدهد.
- مشاهده کد در فایل functions.php: فایل قالب و چایلد را باز کنید و همه فراخوانیهای
add_theme_supportرا فهرست کنید. - تست در Customizer و ویرایشگر: هر ویژگی نشانه ظاهری مشخصی دارد. اگر گزینهاش در Customizer یا ویرایشگر نیست، اعلام نشده.
در بعضی قالبها، فهرست قابلیتها در فایل readme یا در مستندات سازنده ذکر میشود. اگر شک دارید، ابتدا مستندات را ببینید و بعد کد را بررسی کنید. مسیر کامل تست قالب را در بهترین روش تست قالب وردپرس آوردهام.
پروتکل رفع امن در پروژههای واقعی
وقتی با این دسته از خطاها مواجه میشوم، مسیر شخصیام یک الگوی ثابت دارد:
- ابتدا فهرست ویژگیهای موردنیاز پروژه را مینویسم: کدامیک از قابلیتهای هسته برای این پروژه ضروری است.
- در قالب فعلی، بررسی میکنم کدامیک اعلام شده و کدام نه.
- قبل از هر تغییری، بکاپ کامل فایل و دیتابیس میگیرم.
- هر ویژگی اعلامنشده را در فایل
functions.phpقالب چایلد اضافه میکنم، نه والد. - اگر قالب چایلد ندارم، اول میسازم و بعد ویژگیها را به آن منتقل میکنم.
- پس از افزودن کد، در محیط استجینگ تست میکنم و سپس روی سایت زنده اعمال میکنم.
یکی از پروندههایی که در این سالها با آن مواجه شدم، قالب قدیمی شرکتی بود که از هیچیک از قابلیتهای گوتنبرگ پشتیبانی نمیکرد. با ساخت یک قالب چایلد و اضافه کردن پنج خط اعلام، تمام مسائل حل شد و دیگر نیازی به تغییر قالب نبود. مسیر ساخت و انتقال این نوع تغییرات را در قالب چایلد وردپرس گامبهگام آوردهام. اگر قالب بسیار قدیمی بود و ارزش نگه داشتنش را نداشت، مسیر امن تغییر قالب در رفع قالب خراب بدون از دست دادن محتوا و رفع صفحه سفید بعد از تغییر قالب آمده است.
سه عادت پیشگیرانه
سه عادتی که در این سالها بیشترین اثر را روی کاهش پروندههای این دسته داشتهاند:
اول، هر قالب چایلد را با یک قالب پایه شروع میکنم که همه ویژگیهای ممکن را اعلام کرده. این قالب پایه شخصی من، حاوی تمام add_theme_supportهای رایج است. با این کار، هر پروژهای که با آن شروع میشود، از روز اول همه قابلیتها را دارد.
دوم، در روز اول راهاندازی قالب، فهرست قابلیتها را با ابزار سلامت سایت چک میکنم. اگر ویژگیای که مشتری لازم دارد اعلام نشده، همان روز اصلاحش میکنم. این کار هفتهها بعد به یک پرونده پشتیبانی تبدیل نمیشود.
سوم، اگر قالب جدیدی انتخاب میکنم، پیش از خرید یا نصب، فایل functions.php آن را بررسی میکنم تا ببینم چه قابلیتهایی را اعلام کرده. این یک بررسی دو دقیقهای، از خرید قالبهایی که ویژگیهای ضروری شما را ندارند جلوگیری میکند.
نگاه عمیقتر: قالب بهعنوان اعلامیه قابلیتها
برای مهندسانی که با معماری نرمافزار سروکار دارند، ارزش دارد قالب وردپرس را بهعنوان یک اعلامیه قابلیت (Capability Declaration) نگاه کنند، نه فقط مجموعهای از فایلها. در معماریهای مدرن نرمافزار، هر کامپوننت صریحاً اعلام میکند از چه قابلیتهایی پشتیبانی میکند تا هسته بداند چه چیزی را به آن تحمیل کند. همین الگو در وردپرس با add_theme_support پیاده شده، ولی چون بهصورت پیشفرض اجباری نیست، خیلی از توسعهدهندگان آن را فراموش میکنند.
سه مشاهده دقیقتر از تجربههای میدانی: اول، در پروژههای بزرگ با چندین قالب (مثلاً یک سایت اصلی و چند زیرسایت)، عدم اعلام صریح قابلیتها باعث میشود هر قالب رفتار متفاوتی داشته باشد. کاربر نمیداند کدام ویژگی در کدام قالب هست و پشتیبانی به یک پرونده پیچیده تبدیل میشود. تیمهای بالغ، یک ماژول مشترک setup.php برای همه قالبهای خود دارند تا همهشان یک استاندارد قابلیت داشته باشند.
دوم، در معماری قالبهای بلوکی، مفهوم اعلام قابلیت از PHP به JSON منتقل شده. یعنی در theme.json بهجای add_theme_support، با کلیدهای داخل ساختار JSON اعلام میشود که قالب از چه چیزی پشتیبانی میکند. این تغییر پارادایم باعث میشود کدهای قدیمی که با add_theme_support کار میکردند در قالبهای بلوکی کار نکنند. اگر در حال مهاجرت هستید، این نکته را جدی بگیرید.
سوم، در معماری Headless که فرانتاند جدا از وردپرس سرو میشود، مفهوم قابلیتهای قالب تقریباً از بین میرود چون نمایش در لایه فرانتاند مدیریت میشود. اما حتی در این معماری، بعضی از قابلیتها مثل title-tag و align-wide روی خروجی REST API اثر میگذارند. یعنی اگر این ویژگیها در قالب اعلام نشده باشند، ممکن است دادهای که به فرانتاند میرسد ناقص باشد و شما ندانید چرا فرانتاند رفتار عجیبی دارد.
چهارم، در پروژههای CI/CD (Continuous Integration / Continuous Deployment یا یکپارچهسازی و استقرار پیوسته)، قابلیتهای قالب باید بخشی از تست خودکار باشند. یعنی پیش از استقرار هر نسخه از قالب، یک تست خودکار بررسی کند که همه قابلیتهای موردنیاز پروژه اعلام شدهاند. این نوع انضباط، از پروندههای پشتیبانی آینده جلوگیری میکند و برای تیمهای حرفهای، هزینهاش در برابر فایدهاش صفر است.
آنچه از دفتر تجربه ماند
اگر بخواهم کل این مقاله را در سه نکته فشرده کنم: اول، عدم پشتیبانی قالب از ویژگیهای هسته، تقریباً همیشه یک فراموشی است، نه یک باگ پیچیده؛ و رفعش معمولاً چند خط کد در Child Theme است. دوم، همیشه این خطوط را در قالب چایلد بگذارید نه والد، چون در آپدیت بعدی قالب، همه چیز از بین میرود. سوم، اگر قالب شما در سطح بنیادین از قابلیتهای هسته پشتیبانی نمیکند و با افزودن چند خط در Child هم حل نمیشود، وقت خودتان را روی قالبهای جدیدتر بگذارید؛ هزینه مهاجرت در بلندمدت کمتر از اصرار بر نگه داشتن یک قالب کهنه است.
اگر در پروژهای با نوعی از عدم پشتیبانی قالب مواجه شدهاید که در این فهرست نبوده — بهخصوص اگر در قالبهای بلوکی، multisite یا معماری Headless بوده — برایم بنویسید کدام قابلیت بود و چطور به جواب رسیدید. تجربههای واقعی شما همان چیزی است که این فهرست را برای نفر بعدی دقیقتر میکند. 🎨