چرا نوشتهها در قالب وردپرس نمایش داده نمیشوند و چگونه آن را اصولی برطرف کنیم؟
راهنمای عمیق و تجربهمحور برای شناسایی، تحلیل و رفع خطای عدم نمایش نوشتهها در قالب وردپرس؛ از کالبدشکافی حلقه اصلی و سلسلهمراتب single.php تا نقش تنظیمات خواندن، صفحه اصلی، تعارض با افزونهها و کش در سایتهای وردپرسی و ووکامرسی.
is_home() را در فایل index.php بهشکلی نادرست پیادهسازی کرده بود که در آن، حلقه اصلی فقط برای صفحه اصلی اجرا میشد. آن روز فهمیدم که در وردپرس، «نمایش نیافتن» میتواند پنج لایه مختلف داشته باشد: لایه تنظیمات، لایه کوئری، لایه قالب، لایه هوک، و لایه کش.
در این مقاله میخواهم دقیقاً بگویم این خطا از کجا میآید، چطور ریشهاش را پیدا کنید، و چه الگویی برای ساختار قالب وجود دارد که احتمال بروز این مشکل را در بلندمدت به حداقل برساند.
عدم نمایش نوشتهها دقیقاً به چه معناست؟
وقتی میگوییم نوشتهها در قالب نمایش داده نمیشوند، در واقع یکی از این پنج سناریو رخ داده است: نوشتهها اصلاً در صفحه اصلی سایت نمایش داده نمیشوند، نوشتهها در آرشیو (دستهبندی، برچسب، آرشیو نویسنده) نمایش داده نمیشوند، نوشتهها در صفحه تکنوشته با خطای ۴۰۴ مواجه میشوند، نوشتهها نمایش داده میشوند اما با قالب اشتباه (مثلاً قالب برگه بهجای نوشته)، یا نوشتهها فقط در بخشهایی از سایت (مثلاً صفحه اصلی) دیده میشوند. تشخیص این پنج سناریو از هم، اولین قدم در حل مشکل است.
در وردپرس، نوشته (Post) یکی از دو نوع محتوای اصلی است. برخلاف برگهها که ساختار سلسلهمراتبی دارند، نوشتهها بهطور پیشفرض در آرشیو و بر اساس ترتیب زمانی (معمولاً نزولی) نمایش داده میشوند. این تفاوت ماهوی، منبع بسیاری از سردرگمیهاست — بهخصوص در قالبهایی که توسعهدهنده این تفاوت را در ساختار فایلهای قالب رعایت نکرده است. برای درک دقیقتر تفاوت نوشته و برگه، مقاله چگونه اولین پست خود را در وردپرس منتشر کنیم را توصیه میکنم.
یک سوءبرداشت رایج این است که تصور کنیم نوشتهها همیشه از یک فایل قالب مشخص رندر میشوند. اینطور نیست. وردپرس یک سلسلهمراتب قالب (Template Hierarchy) پیچیده دارد که در آن، برای هر بافت (Context) — صفحه اصلی، آرشیو، تکنوشته، جستجو، و غیره — یکی از چند فایل ممکن انتخاب میشود. اگر یکی از این فایلها در قالب وجود نداشته باشد، وردپرس به فایل بعدی در سلسلهمراتب میرود و در نهایت به index.php میرسد. اما اگر فایل انتخابشده خطا داشته باشد یا حلقه اصلی را نداشته باشد، نوشتهها ممکن است ناقص یا خالی نمایش داده شوند. برای درک جایگاه این مکانیزم در معماری کلی، مقاله قالب وردپرس چیست و چگونه انتخاب کنیم نقطه شروع خوبی است.
نکته دوم: «نمایش نیافتن نوشتهها» همیشه بهمعنی «نبود نوشته» نیست. گاهی ریشه در تنظیمات صفحه اصلی، در کوئری سفارشی، در قالبهای شرطی، یا در تعارض با افزونههای امنیتی است. برای فهم بهتر ساختار WordPress و مکانیزم حلقه اصلی، ویکیپدیا نقطه شروع خوبی است.
نوشتهای که در پیشخوان هست اما در سایت دیده نمیشود، لزوماً حذف نشده؛ به احتمال زیاد در یک حلقه اشتباه، منتظر رندر شدن است.
هشت ریشه اصلی این خطا
در تجربهام، این خطا تقریباً همیشه یکی از هشت ریشه زیر را دارد. هر کدام امضای مشخص خودش را در رفتار سایت یا لاگ دارد:
۱. تنظیمات اشتباه در «تنظیمات ← خواندن»
شایعترین علت. در وردپرس، در بخش «تنظیمات ← خواندن»، گزینهای وجود دارد که تعیین میکند صفحه اصلی سایت چه چیزی را نمایش دهد. اگر روی «یک برگه استاتیک» تنظیم شده باشد، نوشتهها در صفحه اصلی دیده نمیشوند و به آرشیو منتقل میشوند. این رفتار، از نظر معماری درست است، اما بسیاری از مدیران سایت انتظار دارند که نوشتهها در صفحه اصلی نمایش داده شوند. برای تغییر این رفتار، کافی است گزینه «آخرین نوشتهها» را انتخاب کنید. برای مطالعه بیشتر، مقاله چگونه یک سایت وردپرسی راهاندازی کنیم را ببینید.
۲. مشکل در حلقه اصلی (Main Loop)
اگر فایل index.php یا home.php قالب شما فاقد حلقه اصلی باشد، هیچ نوشتهای نمایش داده نمیشود. حلقه اصلی در وردپرس معمولاً به این شکل است:
<?php if ( have_posts() ) : ?>
<?php while ( have_posts() ) : the_post(); ?>
<article><?php the_title(); ?></article>
<?php endwhile; ?>
<?php else : ?>
<p>هیچ نوشتهای یافت نشد.</p>
<?php endif; ?>
اگر have_posts() یا the_post() حذف شده باشد، حلقه اجرا نمیشود و صفحه خالی نمایش داده میشود. این حالت در قالبهای سفارشی که توسعهدهنده از صفر همهچیز را نوشته، شایع است. برای مطالعه بیشتر درباره ساختار فایل قالب، مقاله ساختار فایلهای یک قالب استاندارد وردپرس را توصیه میکنم.
۳. استفاده نادرست از WP_Query سفارشی
اگر قالب شما از WP_Query سفارشی استفاده میکند اما پارامترهای آن نادرست تنظیم شدهاند، ممکن است هیچ نوشتهای برگردانده نشود. مثلاً اگر post_type روی page تنظیم شده باشد، نوشتهها نمایش داده نمیشوند. یا اگر post_status روی یک وضعیت غیرمعمول تنظیم شده باشد، فقط نوشتههای آن وضعیت نمایش داده میشوند. این حالت در قالبهایی که از کوئریهای پیچیده برای نمایش محتوای شرطی استفاده میکنند، شایع است. برای مطالعه دقیقتر، مقاله کدنویسی کوئریهای سفارشی در وردپرس را ببینید.
۴. حذف wp_reset_postdata() بعد از کوئری سفارشی
این یکی از ظریفترین و کمشناختهشدهترین دلایل است. اگر بعد از یک WP_Query سفارشی، فراخوانی wp_reset_postdata() را فراموش کنید، متغیرهای گلوبال وردپرس (مثل $post) به نوشته آخر آن کوئری اشاره میکنند. نتیجه این است که حلقه اصلی که بعداً اجرا میشود، با دادههای اشتباه کار میکند و ممکن است نوشتهای نمایش ندهد. این حالت در قالبهایی که چند کوئری سفارشی دارند، بسیار شایع است.
۵. تعارض با افزونههای امنیتی یا عضویت
افزونههایی مثل Members، User Role Editor یا Restrict Content Pro میتوانند دسترسی به نوشتهها را بر اساس نقش کاربری محدود کنند. اگر تنظیمات این افزونهها با قالب جدید تعارض داشته باشند، ممکن است نوشتهها برای کاربران ناشناس یا غیرمجاز ناپدید شوند. این حالت در سایتهای عضویتمحور یا فروشگاهی که نقشهای کاربری مختلف دارند، شایع است. برای مطالعه بیشتر، مقاله تنظیمات کاربران و نقشها در وردپرس را توصیه میکنم.
۶. تعارض با افزونههای کش
افزونههای کش مثل WP Rocket یا LiteSpeed Cache، صفحات آرشیو را بهعنوان HTML استاتیک ذخیره میکنند. اگر این کش بهدرستی مدیریت نشود، بعد از انتشار نوشتههای جدید، آرشیو همچنان نسخه قدیمی را نمایش میدهد و به نظر میرسد که نوشتهها نمایش داده نمیشوند. این حالت شایعترین دلیل «مشکل در ساعات پیک» است — همان چیزی که در بهترین افزونههای کش وردپرس به آن پرداختهام.
۷. مشکل در پیوندهای یکتا یا ساختار URL
اگر پیوندهای یکتا (Permalinks) بهدرستی تنظیم نشده باشند، آرشیوها ممکن است با خطای ۴۰۴ مواجه شوند. همچنین اگر ساختار پیوند شامل %category% باشد اما نوشتهها دستهبندی نداشته باشند، ممکن است در آرشیو نمایش داده نشوند. راهحل سریع، رفتن به «تنظیمات ← پیوندهای یکتا» و ذخیره مجدد بدون هیچ تغییری است. برای مطالعه بیشتر، مقاله URL را حرفهای بسازید: ساختار و سئو را ببینید.
۸. تعارض با قالبهای شرطی (Conditional Tags)
قالب شما ممکن است از تگهای شرطی مثل is_home()، is_archive()، یا is_front_page() استفاده کند. اگر این تگها بهدرستی اعمال نشوند یا با تنظیمات صفحه اصلی سایت تعارض داشته باشند، ممکن است حلقه اصلی هرگز اجرا نشود. این حالت بهخصوص در قالبهایی که از چند قالب شرطی برای نمایش محتوای مختلف استفاده میکنند، شایع است.
در وردپرس، نوشتهای که در حلقه اصلی ظاهر نمیشود، لزوماً وجود ندارد؛ فقط در یک شرط نامناسب پنهان شده است.
نشانهها و علائم تشخیص
این خطا در همه موارد بهشکل یک پیام صریح ظاهر نمیشود. در تجربهام، این نشانهها ظاهر میشوند و اگر به آنها توجه کنید، میتوانید بهموقع اقدام کنید:
- خالی بودن صفحه اصلی سایت: اگر صفحه اصلی سایت هیچ نوشتهای نمایش نمیدهد اما در پیشخوان همه نوشتهها هستند، احتمالاً تنظیمات خواندن یا حلقه اصلی مقصر است.
- خطای ۴۰۴ در آرشیوها: اگر با کلیک روی یک دستهبندی یا برچسب، خطای ۴۰۴ میگیرید، مشکل در پیوندهای یکتا یا ساختار آرشیو است.
- نمایش صفحهای خالی یا نیمهخالی: اگر آرشیو رندر میشود اما نوشتهها دیده نمیشوند، احتمالاً کوئری سفارشی یا
wp_reset_postdata()مقصر است. - نمایش قالب اشتباه: اگر نوشتهای نمایش داده میشود اما با قالب برگه یا آرشیو، یعنی سلسلهمراتب قالب بهدرستی اجرا نمیشود.
- نمایش ناهماهنگ در مرورگرهای مختلف: اگر نوشتهها در یک مرورگر نمایش داده میشوند و در دیگری نه، مشکل در کش مرورگر یا CDN است.
- نمایش نوشتهها فقط در ساعات خاص: اگر نوشتهها در ساعات پیک نمایش داده نمیشوند، احتمالاً مشکل در کش یا کوئریهای سنگین است — همان موضوعی که در چگونه مشکل سرعت سایت را عیبیابی کنیم توضیح دادهام.
- خطاهای PHP در لاگ: اگر آرشیو باعث خطای PHP میشود، احتمالاً یک فایل قالب یا افزونه با آن تعارض دارد.
نکته مهم: نبود نوشته در سایت، همیشه بهمعنی «نبود نوشته در دیتابیس» نیست. اگر نوشته در بخش «نوشتهها ← همه نوشتهها» پیشخوان دیده میشود، یعنی در دیتابیس موجود است و مشکل در لایه نمایش یا لایه کوئری است. این تشخیص ساده، اولین قدم در حل مسئله است. برای مطالعه بیشتر درباره عیبیابی سیستماتیک قالب، مقاله چگونه خطای قالب وردپرس را عیبیابی کنیم را توصیه میکنم.
پروتکل تشخیص گامبهگام
برای رسیدن به ریشه مشکل، این پروتکل را در تجربهام مفید یافتهام. مرحلهبهمرحله پیش بروید:
گام اول: بررسی وضعیت پیشخوان
به پیشخوان وردپرس بروید، مسیر «نوشتهها ← همه نوشتهها» را باز کنید. اگر نوشتهها را در این فهرست میبینید و وضعیتشان «منتشرشده» است، یعنی در دیتابیس موجودند و ریشه مشکل در لایه نمایش است. اگر وضعیت «پیشنویس» یا «سطل زباله» است، مشکل در وضعیت انتشار است، نه در قالب.
گام دوم: بررسی تنظیمات خواندن
به «تنظیمات ← خواندن» بروید و بررسی کنید:
- در بخش «صفحه اصلی نمایش میدهد»، کدام گزینه انتخاب شده است؟
- اگر «یک برگه استاتیک» انتخاب شده، آیا برگه نوشتهها (Posts Page) بهدرستی انتخاب شده است؟
- اگر «آخرین نوشتهها» انتخاب شده، آیا قالب شما برای نمایش این حالت طراحی شده است؟
این گام را جدی بگیرید. در بیش از ۲۵٪ مواردی که با این خطا مواجه شدهام، ریشه در همین تنظیمات بوده است.
گام سوم: بررسی فایل index.php و home.php قالب
با FTP یا File Manager، به پوشه قالب فعلی بروید. بررسی کنید که آیا فایل index.php وجود دارد یا نه. این فایل، نقطه بازگشت نهایی وردپرس است و همیشه باید وجود داشته باشد. محتوایش را باز کنید و مطمئن شوید که شامل حلقه اصلی است:
<?php get_header(); ?>
<main id="primary" class="site-main">
<?php if ( have_posts() ) : ?>
<?php while ( have_posts() ) : the_post(); ?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<div class="entry-summary"><?php the_excerpt(); ?></div>
</article>
<?php endwhile; ?>
<?php the_posts_pagination(); ?>
<?php else : ?>
<p>هیچ نوشتهای یافت نشد.</p>
<?php endif; ?>
</main>
<?php get_sidebar(); ?>
<?php get_footer(); ?>
اگر have_posts() یا the_post() در فایل نبود، احتمالاً هیچ نوشتهای نمایش داده نمیشود. برای مطالعه بیشتر، مقاله توابع وردپرس چیست و چگونه از آنها استفاده کنیم را توصیه میکنم.
گام چهارم: بررسی WP_Query سفارشی
اگر قالب شما از WP_Query سفارشی استفاده میکند، پارامترهای آن را بررسی کنید. بهخصوص این پارامترها:
$args = array(
'post_type' => 'post', // باید post باشد، نه page یا custom
'post_status' => 'publish', // باید publish باشد
'posts_per_page' => 10,
'orderby' => 'date',
'order' => 'DESC',
);
$query = new WP_Query( $args );
اگر post_type روی page تنظیم شده باشد، هیچ نوشتهای برگردانده نمیشود. اگر post_status روی یک وضعیت غیرمعمول باشد، فقط نوشتههای آن وضعیت نمایش داده میشوند. بعد از کوئری سفارشی، حتماً wp_reset_postdata() را فراموش نکنید — این یکی از شایعترین باگهای پنهان در قالبهاست.
گام پنجم: بازنشانی پیوندهای یکتا
به «تنظیمات ← پیوندهای یکتا» بروید و بدون هیچ تغییری، روی «ذخیره تغییرات» کلیک کنید. این کار باعث میشود که وردپرس قوانین بازنویسی URL را دوباره بسازد و مشکل ۴۰۴ در آرشیوها حل شود.
گام ششم: تعویض قالب به قالب پیشفرض
اگر مشکل حل نشد، قالب را به یکی از قالبهای پیشفرض وردپرس (مثل Twenty Twenty-Five) تغییر دهید و سایت را بررسی کنید. اگر نوشتهها در قالب پیشفرض نمایش داده میشوند، مطمئن میشوید که مقصر خودِ قالب فعلی است. اگر مشکل ادامه داشت، احتمالاً یک افزونه یا تنظیمات سراسری مقصر است.
گام هفتم: غیرفعالسازی افزونهها
تمام افزونهها را غیرفعال کنید و سایت را بررسی کنید. اگر مشکل حل شد، افزونهها را یکییکی فعال کنید و بعد از هر فعالسازی، سایت را تست کنید. اولین افزونهای که مشکل را برگرداند، مقصر است. این پروتکل در چگونه افزونه مشکلساز وردپرس را پیدا کنیم تفصیل داده شده است.
گام هشتم: بررسی کش
اگر همهچیز در دیتابیس و قالب درست است، کش را پاک کنید. ترتیب اصولی: کش مرورگر، کش افزونه، کش سرور، و در نهایت کش CDN. همیشه بعد از پاک کردن کش مرورگر (با Ctrl+Shift+R) شروع کنید.
تفاوت با خطاهای مشابه
عدم نمایش نوشتهها اغلب با خطاهای دیگری قاطی میشود. این جدول به شما کمک میکند تفاوتها را سریع تشخیص دهید:
| خطا | علت اصلی | نشانه کلیدی |
|---|---|---|
| عدم نمایش نوشتهها | تنظیمات خواندن یا حلقه اصلی | نوشته در پیشخوان هست اما در سایت نه |
| عدم نمایش برگهها | تنظیمات یا فایل page.php | مشکل مشابه، ولی در لایه برگه |
| خطای ۴۰۴ در آرشیو | پیوندهای یکتا یا rewrite rules | URL اشتباه یا ۴۰۴ مستقیم |
| نمایش صفحه خالی | نبود have_posts یا حلقه اصلی | قالب بارگذاری میشود اما محتوا خالی است |
| عدم نمایش دستهبندیها | نبود archive.php یا category.php | دستهبندی در پیشخوان هست اما در سایت نه |
| عدم نمایش ابزارکها | نبود register_sidebar | سایدبار خالی میشود |
| عدم نمایش منو | نبود register_nav_menus | منو در پیشخوان تعریف شده اما نمایش داده نمیشود |
نکته ظریف: عدم نمایش نوشته و عدم نمایش برگه، اگرچه از نظر ظاهری مشابهند اما از نظر ریشهای متفاوتند. نوشتهها از سلسلهمراتب قالب جداگانهای استفاده میکنند (index.php، home.php، single.php، archive.php) و بهطور پیشفرض در حلقه اصلی نمایش داده میشوند. برگهها از فایلهای page.php و page-{slug}.php استفاده میکنند. برای مطالعه دقیقتر درباره ساختار قالب، مقاله ساخت قالب اختصاصی وردپرس چه مراحلی دارد را ببینید.
راهحلهای عملی برای هر ریشه
حالا که مقصر را شناسایی کردید، وقت درمان است. راهحلها را بر اساس ریشه مشکل دستهبندی کردهام:
راهحل ریشه اول: اصلاح تنظیمات خواندن
به «تنظیمات ← خواندن» بروید و بررسی کنید که کدام گزینه انتخاب شده است. اگر قصد دارید نوشتهها در صفحه اصلی نمایش داده شوند، گزینه «آخرین نوشتهها» را انتخاب کنید. اگر قصد دارید یک برگه استاتیک بهعنوان صفحه اصلی و یک برگه دیگر بهعنوان صفحه نوشتهها داشته باشید، هر دو را بهدرستی انتخاب کنید.
راهحل ریشه دوم: بازسازی حلقه اصلی
اگر فایل index.php مشکل دارد، آن را با یک نسخه استاندارد جایگزین کنید. این یک الگوی حداقلی کارآمد است:
<?php get_header(); ?>
<main id="primary" class="site-main">
<?php if ( have_posts() ) : ?>
<?php while ( have_posts() ) : the_post(); ?>
<?php get_template_part( 'template-parts/content', get_post_type() ); ?>
<?php endwhile; ?>
<?php the_posts_pagination(); ?>
<?php else : ?>
<?php get_template_part( 'template-parts/content', 'none' ); ?>
<?php endif; ?>
</main>
<?php get_sidebar(); ?>
<?php get_footer(); ?>
اگر میخواهید تغییرات را در چایلد تم اعمال کنید، همان اصل را رعایت کنید: فایل والد را کپی کنید و تغییرات را روی نسخه چایلد اعمال کنید. برای مطالعه بیشتر، مقاله چگونه قالب آماده را سفارشی کنیم را توصیه میکنم.
راهحل ریشه سوم: بازنشانی پیوندهای یکتا
به «تنظیمات ← پیوندهای یکتا» بروید و بدون تغییر، روی «ذخیره تغییرات» کلیک کنید. این کار قوانین بازنویسی را دوباره میسازد. اگر این کار جواب نداد، با دسترسی به هاست، فایل .htaccess را در ریشه سایت بررسی کنید — این فایل در سرورهای Apache مسئول بازنویسی URL است.
راهحل ریشه چهارم: مدیریت تعارض افزونهها
اگر افزونهای مثل Members یا Restrict Content Pro دسترسی به نوشتهها را محدود کرده، تنظیمات نقشهای کاربری را بررسی کنید. مطمئن شوید که نوشتهها برای نقش «مهمان» قابل مشاهده هستند، اگر اینطور میخواهید. اگر افزونه سئو نوشتهها را noindex علامتگذاری کرده، تنظیمات «انواع محتوا» را بررسی کنید.
راهحل ریشه پنجم: رفع باگ wp_reset_postdata
بعد از هر WP_Query سفارشی، همیشه wp_reset_postdata() را فراخوانی کنید:
$custom_query = new WP_Query( $args );
if ( $custom_query->have_posts() ) :
while ( $custom_query->have_posts() ) : $custom_query->the_post();
// کد شما
endwhile;
wp_reset_postdata(); // این خط را فراموش نکنید
endif;
این الگو در همه قالبهای حرفهای رعایت میشود — همان اصلی که در بررسی مهمترین امکانات یک قالب حرفهای به آن اشاره کردهام.
راهحل ریشه ششم: پاک کردن کش
ترتیب اصولی پاک کردن کش: کش مرورگر، کش افزونه، کش سرور، و در نهایت کش CDN. اگر از افزونه کش استفاده میکنید، حتماً صفحات آرشیو را در تنظیمات آن پیدا کنید و دستی پاکشان کنید. برای مطالعه بیشتر درباره کش، مقاله بهینهسازی سرعت سایت چیست را ببینید.
راهحل ریشه هفتم: بازبینی قالبهای شرطی
اگر قالب شما از تگهای شرطی مثل is_home() استفاده میکند، مطمئن شوید که این شرطها با تنظیمات صفحه اصلی سایت سازگار هستند. مثلاً اگر is_home() را در index.php استفاده کردهاید اما صفحه اصلی سایت یک برگه استاتیک است، این شرط هرگز اجرا نمیشود. برای مطالعه بیشتر درباره تگهای شرطی، مقاله هوکهای وردپرس چیستند و چگونه کار میکنند را توصیه میکنم.
راهحل ریشه هشتم: بازبینی سلسلهمراتب قالب
اگر نوشتهها در آرشیو نمایش داده نمیشوند، فایل archive.php قالب را بررسی کنید. این فایل، قالب عمومی برای همه آرشیوها است. اگر وجود ندارد یا حلقه اصلی را ندارد، وردپرس به index.php برمیگردد و اگر این فایل هم مشکل داشته باشد، آرشیو خالی نمایش داده میشود.
در حل مشکل نمایش نوشتهها، همیشه از لایه تنظیمات شروع کنید، سپس به لایه کوئری، و در نهایت به لایه قالب برسید؛ چون این ترتیب، از ارزان به گران میرود.
کالبدشکافی WP_Query: سفارشیسازی بدون شکستن حلقه
یکی از بزرگترین منابع خطا در نمایش نوشتهها، استفاده نادرست از WP_Query است. برای درک عمیق، باید بدانید که وردپرس چطور کوئری اصلی را در حافظه نگه میدارد.
وقتی کاربری URL یک آرشیو را درخواست میکند، وردپرس بر اساس URL، یک کوئری اصلی (Main Query) میسازد که شامل یک شیء WP_Query است. این شیء در متغیر گلوبال $wp_query ذخیره میشود. متغیرهای $post، $posts، و $wp_the_query هم بهعنوان متغیرهای کمکی نگه داشته میشوند. این ساختار، چهار متغیر کلیدی دارد:
- $wp_query: شیء اصلی که همه اطلاعات کوئری را نگه میدارد.
- $wp_the_query: یک نسخه پشتیبان از
$wp_queryکه دستنخورده باقی میماند. - $posts: آرایهای از نوشتههای برگرداندهشده در کوئری جاری.
- $post: اشارهگر به نوشته جاری در حین اجرای حلقه.
اگر شما در قالب خود یک WP_Query سفارشی میسازید و آن را روی $wp_query بازنویسی میکنید، تمام کوئری اصلی را از بین میبرید. راهحل اصولی، استفاده از یک متغیر جداگانه است:
$my_custom_query = new WP_Query( $args );
if ( $my_custom_query->have_posts() ) :
while ( $my_custom_query->have_posts() ) : $my_custom_query->the_post();
// نمایش محتوا
endwhile;
wp_reset_postdata(); // بازیابی $wp_query و $post
endif;
نکته کلیدی: wp_reset_postdata() در واقع کوئری اصلی را بازیابی میکند، نه کوئری سفارشی. اگر این تابع را فراموش کنید، حلقه اصلی که بعداً اجرا میشود، همچنان با دادههای کوئری سفارشی کار میکند و ممکن است نوشتههای اشتباه یا هیچ نوشتهای را نمایش ندهد.
نکته دوم: اگر میخواهید کوئری اصلی را تغییر دهید (مثلاً تعداد نوشتهها در صفحه اصلی را کم کنید)، راهحل درست استفاده از هوک pre_get_posts است، نه استفاده از WP_Query سفارشی:
function my_theme_adjust_home_query( $query ) {
if ( ! is_admin() && $query->is_main_query() && $query->is_home() ) {
$query->set( 'posts_per_page', 5 );
$query->set( 'cat', 3 );
}
}
add_action( 'pre_get_posts', 'my_theme_adjust_home_query' );
این الگو، استاندارد وردپرس است و بدون شکستن حلقه اصلی، کوئری را تغییر میدهد. برای مطالعه بیشتر درباره کوئریهای سفارشی، مقاله بهینهسازی کوئریهای وردپرس با کدنویسی را توصیه میکنم.
سلسلهمراتب قالب: نقشه راه درست نوشتهها
برای درک عمیق این مشکل، باید سلسلهمراتب قالب وردپرس برای نوشتهها را بشناسید. وردپرس بسته به بافت، فایلهای متفاوتی را برای رندر انتخاب میکند:
بافت صفحه اصلی (Home)
front-page.php— اگر وجود داشته باشد، هم برای صفحه اصلی استاتیک و هم برای صفحه اصلی آرشیوhome.php— قالب اختصاصی صفحه اصلی آرشیوindex.php— نقطه بازگشت نهایی
بافت تکنوشته (Single Post)
single-post-{slug}.php— اگر نوشته slug مشخصی داشته باشدsingle-post.php— قالب اختصاصی نوشتههای نوع postsingle.php— قالب عمومی برای همه تکمحتواهاsingular.php— قالب برای همه محتواهای تکindex.php— نقطه بازگشت نهایی
بافت آرشیو دستهبندی (Category Archive)
category-{slug}.php— اگر دستهبندی slug مشخصی داشته باشدcategory-{id}.php— اگر دستهبندی شناسه مشخصی داشته باشدcategory.php— قالب عمومی برای همه دستهبندیهاarchive.php— قالب عمومی برای همه آرشیوهاindex.php— نقطه بازگشت نهایی
نکته کلیدی: اگر فایل قالب در سطح بالای سلسلهمراتب وجود دارد اما خطا دارد یا حلقه اصلی را ندارد، وردپرس به سطح بعدی نمیرود. یعنی اگر home.php وجود دارد اما خالی است، وردپرس به index.php برنمیگردد — بلکه همان فایل خالی را نمایش میدهد. این رفتار، یکی از شایعترین دلایل نمایش نیافتن نوشتهها است.
نکته دوم: در قالبهای FSE (Full Site Editing)، بهجای فایلهای PHP، از فایلهای HTML در پوشه templates استفاده میشود. در این حالت، فایلهایی مثل index.html، home.html، single.html، و archive.html نقش فایلهای PHP را ایفا میکنند. اگر این فایلها بهدرستی ساخته نشده باشند، نوشتهها نمایش داده نمیشوند. برای مطالعه بیشتر درباره گوتنبرگ و آینده ویرایش محتوا در وردپرس، این مقاله را توصیه میکنم.
استراتژیهای پیشگیری در بلندمدت
پیشگیری از این خطا، نیازمند نظم در چرخه توسعه و انتخاب است. در تجربهام، رعایت این نکات بیشترین بازدهی را داشته:
۱. نگهداری استاندارد فایلهای قالب
همیشه فایلهای index.php، home.php، single.php، و archive.php را در قالب خود داشته باشید. این فایلها بهعنوان نقطه بازگشت عمل میکنند و اگر بافتی فایل اختصاصی نداشت، به این فایلها رجوع میشود.
۲. استفاده از چایلد تم برای سفارشیسازی
هرگونه تغییر در ساختار قالب را در چایلد تم انجام دهید. این کار تضمین میکند که با آپدیت والد، تغییرات شما باقی میماند و در صورت بروز مشکل، میتوانید با غیرفعال کردن چایلد تم، به حالت اولیه برگردید — همان اصلی که در قالب وردپرس چایلد چیست و چه زمانی به آن نیاز داریم توضیح دادهام.
۳. استفاده از pre_get_posts بهجای WP_Query سفارشی
هر وقت میخواهید کوئری اصلی را تغییر دهید، از هوک pre_get_posts استفاده کنید، نه از یک WP_Query سفارشی که کوئری اصلی را بازنویسی میکند. این الگو، استاندارد وردپرس است و ریسک باگ را به حداقل میرساند.
۴. فراموش نکردن wp_reset_postdata
بعد از هر WP_Query سفارشی، همیشه wp_reset_postdata() را فراخوانی کنید. اگر از این تابع استفاده نکنید، حلقه اصلی که بعداً اجرا میشود، با دادههای اشتباه کار میکند و ممکن است نوشتهها ناپدید شوند.
۵. تست بعد از هر تغییر تنظیمات
هر بار که تنظیمات خواندن را تغییر میدهید، سایت را در incognito تست کنید. کش میتواند تغییرات را پنهان کند و شما را به اشتباه بیندازد.
۶. استفاده از ابزارهای حرفهای
افزونههایی مثل Query Monitor یا Debug Bar به شما نشان میدهند که کدام فایل قالب بارگذاری شده و کوئری اصلی چه بوده است. این اطلاعات در عیبیابی سریع بسیار ارزشمند است. برای مطالعه بیشتر درباره ابزارهای توسعه، مقاله افزونههای ضروری مرورگر برای توسعهدهندگان را ببینید.
۷. مدیریت کش با درایت
اگر از افزونه کش استفاده میکنید، صفحات آرشیو را در فهرست استثنا (Exclude) قرار دهید تا در حین توسعه، تغییرات بلافاصله اعمال شوند. بعد از اتمام توسعه، این استثنا را حذف کنید.
۸. مستندسازی کوئریهای سفارشی
اگر قالب شما از کوئریهای سفارشی استفاده میکند، یک فایل مستندات ساده در قالب خود داشته باشید که در آن مشخص شده باشد هر کوئری برای چه هدفی نوشته شده و چه پارامترهایی دارد. این کار در آینده از سردرگمی جلوگیری میکند.
پرسشهای پرتکرار درباره نمایش نوشتهها
چرا نوشتهها در پیشخوان میبینم اما در سایت نمایش داده نمیشوند؟
این نشانه کلاسیک عدم رندر در حلقه اصلی است. سه احتمال: تنظیمات خواندن، فایل index.php یا home.php، یا کوئری سفارشی. ابتدا تنظیمات خواندن را بررسی کنید، سپس فایل قالب، و در نهایت کوئریهای سفارشی.
چرا آرشیو دستهبندی من خالی نمایش داده میشود؟
سه احتمال: فایل category.php یا archive.php مشکل دارد، پیوندهای یکتا درست تنظیم نشدهاند، یا یک کوئری سفارشی روی همان آرشیو اعمال شده که نتیجهاش خالی است. برای تشخیص، با قالب پیشفرض وردپرس تست کنید.
تفاوت pre_get_posts با WP_Query سفارشی چیست؟
هوک pre_get_posts به شما اجازه میدهد قبل از اجرای کوئری اصلی، پارامترهای آن را تغییر دهید. این الگو، بدون شکستن حلقه اصلی کار میکند. اما WP_Query سفارشی، یک کوئری جدید میسازد که بهطور جداگانه اجرا میشود. اگر این کوئری را روی $wp_query بازنویسی کنید، کوئری اصلی از بین میرود.
آیا مشکل میتواند از افزونه کش باشد؟
بله، و این حالت شایع است. اگر افزونه کش صفحات آرشیو را ذخیره کرده باشد، ممکن است بعد از انتشار نوشتههای جدید، آرشیو همچنان نسخه قدیمی را نمایش دهد. در تنظیمات افزونه کش، بخش «Purge» یا «Clear Cache» را اجرا کنید.
چطور بفهمم کدام فایل قالب برای نوشته من بارگذاری میشود؟
از افزونه Query Monitor یا Debug Bar استفاده کنید. در بخش Template، نام فایل قالب بارگذاریشده را میبینید. همچنین میتوانید در فایل functions.php از هوک template_include استفاده کنید تا فایل قالب فعلی را در نوار ابزار نمایش دهید.
آیا استفاده از قالبهای FSE میتواند باعث این مشکل شود؟
بله. در قالبهای FSE، نوشتهها از فایلهای HTML در پوشه templates استفاده میکنند. اگر این فایلها وجود نداشته باشند یا خطا داشته باشند، نوشتهها نمایش داده نمیشوند. فایلهای index.html، home.html، single.html، و archive.html را بررسی کنید.
چرا بعد از مهاجرت سایت، آرشیو من ناپدید شده است؟
دو احتمال: پیوندهای یکتا بهدرستی منتقل نشدهاند یا فایل .htaccess بهروز نشده است. راهحل: به «تنظیمات ← پیوندهای یکتا» بروید و بدون تغییر، ذخیره کنید. اگر مشکل حل نشد، فایل .htaccess را با نسخه پیشفرض وردپرس جایگزین کنید.
آیا نوشتهها میتوانند بهخاطر تنظیمات کاربری مخفی شوند؟
بله. اگر از افزونههایی مثل Members یا Restrict Content Pro استفاده میکنید، ممکن است نوشتهها برای بعضی نقشهای کاربری محدود شده باشند. تنظیمات این افزونهها را بررسی کنید یا موقتاً غیرفعال کنید و سایت را تست کنید.
کالبدشکافی فنی: وردپرس چطور حلقه نوشتهها را رندر میکند؟
برای درک عمیق این مکانیزم، باید بدانید وردپرس چطور یک درخواست آرشیو را پردازش میکند. وقتی کاربری URL یک آرشیو مثل example.com/category/news/ را وارد میکند، این چرخه طی میشود:
- URL Parsing: مرورگر درخواست را به سرور ارسال میکند. سرور (معمولاً Apache یا Nginx) درخواست را به
index.phpریشه سایت هدایت میکند. - WP Bootstrap: فایل
wp-load.phpبارگذاری میشود که خودشwp-settings.phpرا فراخوانی میکند. - URL Rewriting: وردپرس از قوانین بازنویسی URL (که در جدول
wp_optionsبا کلیدrewrite_rulesذخیره شده) استفاده میکند تا URL درخواست را به پارامترهای کوئری تبدیل کند. - Query Parsing: وردپرس یک شیء
WP_Queryمیسازد و بر اساس URL، نوع محتوای درخواستی را تشخیص میدهد — در اینجا، یک آرشیو دستهبندی. - Query Execution: کوئری اصلی اجرا میشود و نوشتههای منطبق با پارامترها استخراج میشوند. این کوئری در متغیر گلوبال
$wp_queryذخیره میشود. - Template Resolution: وردپرس از تابع
get_query_template()استفاده میکند تا بر اساس سلسلهمراتب قالب، فایل مناسبی برای رندر انتخاب کند. - Template Loading: فایل انتخابشده بارگذاری میشود. این فایل باید شامل
get_header()، حلقه اصلی (while ( have_posts() ))، وget_footer()باشد. - Output Rendering: خروجی به HTML تبدیل و به کاربر ارسال میشود.
نکته مهم و کمتر شناختهشده: در مرحله چهارم، وردپرس پارامترهای کوئری را بر اساس URL و تنظیمات سراسری میسازد. اگر تنظیمات «صفحه اصلی» روی «یک برگه استاتیک» باشد، برای URL ریشه سایت، وردپرس کوئری برگه را اجرا میکند نه کوئری نوشتهها. این رفتار، یکی از شایعترین دلایل «خالی بودن صفحه اصلی» است.
نکته دوم: در مرحله ششم، اگر وردپرس فایل قالب مناسبی پیدا نکند، به ترتیب سلسلهمراتب به عقب برمیگردد. اگر در نهایت به index.php برسد و این فایل هم حلقه اصلی را نداشته باشد، صفحه خالی نمایش داده میشود. این موضوع، یکی از شایعترین دلایل نمایش نیافتن نوشتهها در قالبهای سفارشی است.
نکته سوم و بسیار مهم: در وردپرس، متغیرهای $wp_query، $post، و $posts بهطور گلوبال در دسترس هستند. اما اگر در قالب خود یک WP_Query سفارشی بسازید و آن را روی $wp_query بازنویسی کنید، کوئری اصلی از بین میرود. به همین دلیل است که استفاده از pre_get_posts یا wp_reset_postdata استاندارد است — این دو، تنها راهحلهای امن برای تغییر رفتار حلقه اصلی هستند. برای مطالعه بیشتر درباره چرخه هوکها، مقاله ساختار هسته وردپرس چگونه کار میکند را توصیه میکنم.
نکته چهارم: در قالبهای FSE (Full Site Editing)، مرحله ششم کاملاً متفاوت است. بهجای فایلهای PHP، وردپرس از فایلهای HTML در پوشه templates استفاده میکند و یک موتور رندر مبتنی بر بلاک، این فایلها را به خروجی تبدیل میکند. این موتور از خود فایل theme.json و ساختار بلاکها استفاده میکند. اگر این فایلها بهدرستی ساخته نشده باشند، نوشتهها نمایش داده نمیشوند. برای مطالعه بیشتر درباره کدنویسی در قالبهای FSE، مقاله کدنویسی وردپرس چیست و از کجا شروع کنیم را توصیه میکنم.
مطالعه موردی: احیای آرشیو یک سایت محتوایی
یک سایت محتوایی با حدود ۸۰۰۰ نوشته و ۳۰ هزار بازدید روزانه، بعد از آپدیت قالب به نسخه جدید، با مشکل جدی مواجه شد: صفحه اصلی سایت همچنان کار میکرد و نوشتههای جدید را نمایش میداد، اما تمام صفحات آرشیو (دستهبندی، برچسب، آرشیو نویسنده، آرشیو تاریخ) کاملاً خالی نمایش داده میشدند.
علائم:
- همه نوشتهها در پیشخوان سرجایشان بودند
- صفحه اصلی سایت کار میکرد
- آرشیوها با خطای ۴۰۴ یا صفحه خالی مواجه میشدند
- هیچ خطای PHP در لاگ نبود
- مشکل بعد از آپدیت قالب به نسخه جدید ظاهر شد
تشخیص:
با بررسی دقیق، مشخص شد که قالب جدید فایل archive.php را با یک نسخه بهروز جایگزین کرده. اما در نسخه جدید، توسعهدهنده یک شرط اشتباه اضافه کرده بود:
if ( is_category() && ! is_paged() ) {
// نمایش فقط برای صفحه اول دستهبندی
} else {
// هیچ چیزی نمایش نده
}
این کد باعث میشد که در صفحه دوم به بعد آرشیو دستهبندی، هیچ نوشتهای نمایش داده نشود. و چون کاربران از طریق پیجینیشن وارد صفحات بعدی میشدند، به نظر میرسید که کل آرشیو خالی است. تیم توسعه اصلاً متوجه این شرط نشده بود، چون در نسخه قدیمی این شرط وجود نداشت.
درمان:
- ابتدا این شرط را حذف کردیم.
- سپس با استفاده از یک بکاپ از نسخه قبل، فایل را با استفاده از
diffمقایسه کردیم تا مطمئن شویم تغییرات ناخواسته دیگری وجود ندارد. - در نهایت، یک تست جامع روی همه آرشیوها با پیجینیشن، فیلترها و جستجو انجام دادیم.
درسآموخته:
عدم نمایش نوشتهها همیشه بهمعنی نبود نوشته نیست؛ گاهی بهمعنی وجود یک شرط اشتباه در فایل قالب است. همیشه در آپدیت قالب، تغییرات را مرحلهبهمرحله تست کنید و اگر امکان دارد، از محیط استجینگ استفاده کنید. برای مطالعه موردی مشابه، مقاله چگونه قالب وردپرس را بدون آسیب به سایت تغییر دهیم را توصیه میکنم.
سخن پایانی: کوئری هوشمند، حلقه پایدار
عدم نمایش نوشتهها در قالب وردپرس، در نگاه اول یک خطای ناامیدکننده است، اما در واقع یک پیام دقیق معماری است: یکی از پنج لایه تنظیمات، کوئری، قالب، هوک، یا کش در جایی پاره شده. سؤال درست این نیست «چطور نوشتهها را برگردانم»، بلکه این است «کدام لایه از این زنجیره در پروژه من ضعیف است».
از تجربهام، هفت اصل عملی بیشترین بازدهی را داشتهاند: اول، همیشه از لایه تنظیمات شروع کنید — بیش از ۲۵٪ مشکلات در همین لایه پنهان است. دوم، فایل index.php را در قالب خود داشته باشید، حتی اگر از فایلهای اختصاصی استفاده میکنید. سوم، برای تغییر کوئری اصلی از pre_get_posts استفاده کنید، نه WP_Query سفارشی. چهارم، بعد از هر WP_Query سفارشی، wp_reset_postdata() را فراموش نکنید. پنجم، در مهاجرت قالب، فایلهای قالب را مرحلهبهمرحله تست کنید و از diff استفاده کنید. ششم، همیشه از چایلد تم برای سفارشیسازی استفاده کنید. هفتم، بعد از هر تغییر، کش را پاک کنید و در incognito تست کنید.
در نهایت، اگر سایت شما حجم بالایی از محتوا دارد — مثل یک وبلاگ با هزاران نوشته — توصیه میکنم کوئریهای اصلی را با ابزار Query Monitor و با EXPLAIN در MySQL بررسی کنید. کوئریهای کند در آرشیو، هم باعث میشوند نوشتهها دیرتر نمایش داده شوند و هم کاربران را فراری میدهند. برای مطالعه دقیقتر درباره بهینهسازی کوئری، مقاله بهینهسازی کوئریهای MySQL را توصیه میکنم. اگر هم قصد ساخت یک قالب اختصاصی برای سایت محتوایی دارید، مقاله ساخت قالب اختصاصی وردپرس چه مراحلی دارد نقشه راه دقیقی ارائه میدهد.
اگر روی پروژهای با این مشکل مواجه شدهاید و روش خاصی برای حلش پیدا کردهاید — بهخصوص اگر با قالبهای FSE، چایلد تم، یا کوئریهای سفارشی پیچیده سر و کار داشتهاید — خوشحال میشوم تجربهتان را بشنوم. بگویید در آن پروژه، مقصر اصلی چه بود: تنظیمات خواندن، حلقه اصلی، کوئری سفارشی، یا wp_reset_postdata()؟ و اگر در تشخیص آن به نکتهای رسیدید که در این مقاله نبود، بگویید تا در نسخه بعدی همان زاویه را عمیقتر باز کنم. 📝