اضافه کردن نوار اعلان به هدر وبسایت
ساخت نوار اعلان متحرک و هوشمند در وردپرس بدون افزونه
در دنیای امروز طراحی وبسایت، ثانیهها تعیینکننده هستند. جذب مخاطب در همان نگاه اول (بالای هدر یا Above the Fold) نقشی حیاتی در کاهش نرخ پرش (Bounce Rate) و افزایش فروش ایفا میکند. یکی از ابزارهای فوقالعاده برای این کار، استفاده از نوار اعلان متحرک (Announcement Bar) است.
بسیاری از وبمسترها برای اضافه کردن این قابلیت به سراغ نصب افزونههای سنگین میروند، اما توسعهدهندگان حرفهای میدانند که نوشتن یک کد بهینه و سبک چقدر روی سرعت لود سایت (Core Web Vitals) تاثیر مثبت دارد. در این مقاله آموزشی، یک کد PHP و جاوااسکریپت کاملاً سفارشی، امن و بدون تداخل را بررسی میکنیم که با آن میتوانید یک نوار اعلان داینامیک با پنل تنظیمات اختصاصی در وردپرس بسازید.
چرا نباید برای هر ویژگی ساده در وردپرس افزونه نصب کنیم؟
هر افزونه اضافی که به وردپرس اضافه میشود، ممکن است فایلهای CSS و JS متعددی را به هدر سایت تحمیل کند. این موضوع سرعت بارگذاری سایت را کاهش داده و تجربه کاربری را خراب میکند.
کدی که در ادامه بررسی میکنیم، بهصورت کاملاً اختصاصی نوشته شده است:
- پنل مدیریت اختصاصی در پیشخوان برای کنترل رنگها، متنها و سرعت.
- عدم وابستگی به قالب به دلیل تزریق مستقیم به عنوان اولین فرزند تگ
<body>. - انیمیشن CSS روان (Seamless Loop) بدون ایجاد فشار روی پردازنده مرورگر کاربر.
- امنیت بالا با استفاده از نانِسها (Nonces) و اعتبارسنجی دقیق دادهها.
کد کامل ساخت نوار اعلان متحرک در وردپرس
شما میتوانید کد زیر را به فایل functions.php پوسته فرزند (Child Theme) خود یا به عنوان یک پلاگین اختصاصی در پوشه wp-content/plugins قرار دهید.
نکته توسعهدهنده: پیشنهاد میشود همیشه برای کدهای شخصیسازیشده خود از پیشوندهای اختصاصی استفاده کنید تا با توابع پیشفرض وردپرس یا سایر پلاگینها تداخل پیدا نکنند.
// اضافه کردن استایلها و ابزارهای مورد نیاز به بخش مدیریت
add_action('admin_enqueue_scripts', 'miladalizadeh_announcement_admin_scripts');
function miladalizadeh_announcement_admin_scripts($hook) {
if ($hook !== 'toplevel_page_header_announcement_settings') {
return;
}
wp_enqueue_style('wp-color-picker');
wp_enqueue_script('wp-color-picker');
}
// ساخت منو در پیشخوان وردپرس
add_action('admin_menu', 'miladalizadeh_announcement_admin_menu');
function miladalizadeh_announcement_admin_menu() {
add_menu_page(
'تنظیمات نوار بالای هدر',
'نوار بالای هدر',
'manage_options',
'header_announcement_settings',
'miladalizadeh_announcement_settings_page',
'dashicons-megaphone',
9
);
}
// صفحه تنظیمات افزونه در پیشخوان
function miladalizadeh_announcement_settings_page() {
if (!current_user_can('manage_options')) {
return;
}
if (isset($_POST['submit_announcement_settings'])) {
check_admin_referer('save_announcement_settings_action', 'announcement_settings_nonce');
$status = isset($_POST['announcement_status']) ? 'active' : 'inactive';
$bg_color_1 = sanitize_hex_color($_POST['announcement_bg_color_1']);
$bg_color_2 = sanitize_hex_color($_POST['announcement_bg_color_2']);
$text_color = sanitize_hex_color($_POST['announcement_text_color']);
$highlight_color = sanitize_hex_color($_POST['announcement_highlight_color']);
$duration = intval($_POST['announcement_duration']);
$texts = [];
if (isset($_POST['announcement_texts']) && is_array($_POST['announcement_texts'])) {
foreach ($_POST['announcement_texts'] as $text) {
$clean_text = sanitize_text_field($text);
if (!empty($clean_text)) {
$texts[] = $clean_text;
}
}
}
update_option('miladalizadeh_announcement_status', $status);
update_option('miladalizadeh_announcement_bg_color_1', $bg_color_1);
update_option('miladalizadeh_announcement_bg_color_2', $bg_color_2);
update_option('miladalizadeh_announcement_text_color', $text_color);
update_option('miladalizadeh_announcement_highlight_color', $highlight_color);
update_option('miladalizadeh_announcement_duration', $duration);
update_option('miladalizadeh_announcement_texts', $texts);
echo '<div class="updated"><p>تنظیمات با موفقیت ذخیره شدند.</p></div>';
}
$status = get_option('miladalizadeh_announcement_status', 'active');
$bg_color_1 = get_option('miladalizadeh_announcement_bg_color_1', '#1e293b');
$bg_color_2 = get_option('miladalizadeh_announcement_bg_color_2', '#0f172a');
$text_color = get_option('miladalizadeh_announcement_text_color', '#f8fafc');
$highlight_color = get_option('miladalizadeh_announcement_highlight_color', '#38bdf8');
$duration = get_option('miladalizadeh_announcement_duration', 25);
$texts = get_option('miladalizadeh_announcement_texts', [
"🔥 جشنواره فروش ویژه آغاز شد! تا ۵۰ درصد تخفیف روی تمامی محصولات",
"🚚 ارسال رایگان برای خریدهای بالای ۲ میلیون تومان به سراسر کشور"
]);
?>
<div class="wrap">
<h1>تنظیمات نوار بالای هدر</h1>
<hr>
<form method="post" action="">
<?php wp_nonce_field('save_announcement_settings_action', 'announcement_settings_nonce'); ?>
<table class="form-table" role="presentation">
<tbody>
<tr>
<th scope="row"><label for="announcement_status">وضعیت نمایش</label></th>
<td>
<label class="switch">
<input type="checkbox" id="announcement_status" name="announcement_status" value="active" <?php checked($status, 'active'); ?>>
<span class="slider round"></span>
</label>
<p class="description">فعال یا غیرفعال کردن نمایش نوار در بالای سایت</p>
</td>
</tr>
<tr>
<th scope="row"><label for="announcement_bg_color_1">رنگ اول پسزمینه (شروع گرادینت)</label></th>
<td>
<input type="text" id="announcement_bg_color_1" name="announcement_bg_color_1" class="color-picker" value="<?php echo esc_attr($bg_color_1); ?>">
</td>
</tr>
<tr>
<th scope="row"><label for="announcement_bg_color_2">رنگ دوم پسزمینه (پایان گرادینت)</label></th>
<td>
<input type="text" id="announcement_bg_color_2" name="announcement_bg_color_2" class="color-picker" value="<?php echo esc_attr($bg_color_2); ?>">
</td>
</tr>
<tr>
<th scope="row"><label for="announcement_text_color">رنگ متن اعلان</label></th>
<td>
<input type="text" id="announcement_text_color" name="announcement_text_color" class="color-picker" value="<?php echo esc_attr($text_color); ?>">
</td>
</tr>
<tr>
<th scope="row"><label for="announcement_highlight_color">رنگ جداکننده (نقطه میانی)</label></th>
<td>
<input type="text" id="announcement_highlight_color" name="announcement_highlight_color" class="color-picker" value="<?php echo esc_attr($highlight_color); ?>">
</td>
</tr>
<tr>
<th scope="row"><label for="announcement_duration">سرعت حرکت (ثانیه)</label></th>
<td>
<input type="number" id="announcement_duration" name="announcement_duration" min="5" max="100" value="<?php echo esc_attr($duration); ?>" class="small-text">
<span class="description">مدت زمان چرخه کامل حرکت متن (کمتر = سریعتر، بیشتر = آرامتر)</span>
</td>
</tr>
<tr>
<th scope="row"><label>لیست متنهای متحرک</label></th>
<td>
<div id="announcement-text-list">
<?php if (!empty($texts) && is_array($texts)) : ?>
<?php foreach ($texts as $index => $text) : ?>
<div class="text-row" style="margin-bottom: 8px; display: flex; align-items: center; gap: 10px;">
<input type="text" name="announcement_texts[]" value="<?php echo esc_attr($text); ?>" class="regular-text" style="width: 400px;" required>
<button type="button" class="button button-link-delete remove-text-btn">حذف</button>
</div>
<?php endforeach; ?>
<?php else : ?>
<div class="text-row" style="margin-bottom: 8px; display: flex; align-items: center; gap: 10px;">
<input type="text" name="announcement_texts[]" value="" class="regular-text" style="width: 400px;" required>
<button type="button" class="button button-link-delete remove-text-btn">حذف</button>
</div>
<?php endif; ?>
</div>
<button type="button" id="add-text-btn" class="button button-secondary" style="margin-top: 10px;">+ افزودن متن جدید</button>
</td>
</tr>
</tbody>
</table>
<p class="submit">
<input type="submit" name="submit_announcement_settings" id="submit" class="button button-primary" value="ذخیره تنظیمات">
</p>
</form>
</div>
<style>
.switch { position: relative; display: inline-block; width: 50px; height: 26px; }
.switch input { opacity: 0; width: 0; height: 0; }
.slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; transition: .4s; border-radius: 34px; }
.slider:before { position: absolute; content: ""; height: 18px; width: 18px; left: 4px; bottom: 4px; background-color: white; transition: .4s; border-radius: 50%; }
input:checked + .slider { background-color: #2271b1; }
input:checked + .slider:before { transform: translateX(24px); }
</style>
<script>
jQuery(document).ready(function($) {
$('.color-picker').wpColorPicker();
$('#add-text-btn').on('click', function(e) {
e.preventDefault();
var newRow = `
<div class="text-row" style="margin-bottom: 8px; display: flex; align-items: center; gap: 10px;">
<input type="text" name="announcement_texts[]" value="" class="regular-text" style="width: 400px;" required>
<button type="button" class="button button-link-delete remove-text-btn">حذف</button>
</div>
`;
$('#announcement-text-list').append(newRow);
});
$(document).on('click', '.remove-text-btn', function(e) {
e.preventDefault();
if ($('#announcement-text-list .text-row').length > 1) {
$(this).closest('.text-row').remove();
} else {
alert('حداقل باید یک متن وجود داشته باشد.');
}
});
});
</script>
<?php
}
// لود کردن نوار اعلان با استفاده از جاوااسکریپت در فوتر جهت تضمین لود شدن در 100% سناریوها
add_action('wp_footer', 'miladalizadeh_display_announcement_bar_js_injection');
function miladalizadeh_display_announcement_bar_js_injection() {
$status = get_option('miladalizadeh_announcement_status', 'active');
if ($status !== 'active') {
return;
}
$texts = get_option('miladalizadeh_announcement_texts', []);
if (empty($texts) || !is_array($texts)) {
return;
}
$bg_color_1 = get_option('miladalizadeh_announcement_bg_color_1', '#1e293b');
$bg_color_2 = get_option('miladalizadeh_announcement_bg_color_2', '#0f172a');
$text_color = get_option('miladalizadeh_announcement_text_color', '#f8fafc');
$highlight_color = get_option('miladalizadeh_announcement_highlight_color', '#38bdf8');
$duration = get_option('miladalizadeh_announcement_duration', 25);
// تکرار آرایه متنها برای چرخه بینقص و بدون افت فریم
$scrolling_items = array_merge($texts, $texts);
?>
<script type="text/javascript">
(function() {
// ساخت بدنه نوار اعلان
var topBar = document.createElement('div');
topBar.id = 'miladalizadeh-top-bar';
topBar.className = 'premium-top-bar';
var container = document.createElement('div');
container.className = 'top-bar-container';
var tickerWrap = document.createElement('div');
tickerWrap.className = 'ticker-wrap';
var tickerMove = document.createElement('div');
tickerMove.className = 'ticker-move';
<?php foreach ($scrolling_items as $text) : ?>
var item = document.createElement('div');
item.className = 'ticker-item';
item.textContent = <?php echo json_encode($text); ?>;
tickerMove.appendChild(item);
<?php endforeach; ?>
tickerWrap.appendChild(tickerMove);
container.appendChild(tickerWrap);
topBar.appendChild(container);
// دکمه بستن
var closeBtn = document.createElement('button');
closeBtn.className = 'top-bar-close';
closeBtn.setAttribute('aria-label', 'بستن');
closeBtn.innerHTML = '<svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>';
closeBtn.onclick = function() {
topBar.style.display = 'none';
};
topBar.appendChild(closeBtn);
// قرار دادن نوار اعلان در بالاترین بخش تگ body به عنوان اولین فرزند
if (document.body) {
document.body.insertBefore(topBar, document.body.firstChild);
}
})();
</script>
<style>
:root {
--tb-bg-color-1: <?php echo esc_html($bg_color_1); ?>;
--tb-bg-color-2: <?php echo esc_html($bg_color_2); ?>;
--tb-text-color: <?php echo esc_html($text_color); ?>;
--tb-highlight-color: <?php echo esc_html($highlight_color); ?>;
--tb-duration: <?php echo esc_html($duration); ?>s;
--tb-font-size: 13.5px;
--tb-padding: 10px 0;
}
.premium-top-bar {
background: linear-gradient(135deg, var(--tb-bg-color-1) 0%, var(--tb-bg-color-2) 100%) !important;
color: var(--tb-text-color) !important;
direction: rtl !important;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important;
font-size: var(--tb-font-size) !important;
font-weight: 500 !important;
position: relative !important;
z-index: 9999999 !important; /* اعمال بالاترین اولویت لایهها */
width: 100% !important;
padding: var(--tb-padding) !important;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15) !important;
overflow: hidden !important;
display: flex !important;
align-items: center !important;
border-bottom: 1px solid rgba(255, 255, 255, 0.08) !important;
box-sizing: border-box !important;
}
.top-bar-container {
width: 95% !important;
margin: 0 auto !important;
overflow: hidden !important;
padding-left: 40px !important;
box-sizing: border-box !important;
}
.ticker-wrap {
width: 100% !important;
overflow: hidden !important;
}
.ticker-move {
display: inline-flex !important;
white-space: nowrap !important;
animation: tickerScroll var(--tb-duration) linear infinite !important;
}
.ticker-move:hover {
animation-play-state: paused !important;
cursor: pointer;
}
.ticker-item {
display: inline-block !important;
padding: 0 45px !important;
position: relative !important;
box-sizing: border-box !important;
}
.ticker-item::after {
content: "•" !important;
position: absolute !important;
left: 0 !important;
color: var(--tb-highlight-color) !important;
font-weight: bold !important;
font-size: 16px !important;
top: 50% !important;
transform: translateY(-50%) !important;
}
.ticker-item:last-child::after {
display: none !important;
}
.top-bar-close {
position: absolute !important;
left: 15px !important;
top: 50% !important;
transform: translateY(-50%) !important;
background: rgba(255, 255, 255, 0.15) !important;
border: none !important;
color: var(--tb-text-color) !important;
cursor: pointer !important;
width: 26px !important;
height: 26px !important;
border-radius: 50% !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
transition: all 0.3s ease !important;
padding: 0 !important;
z-index: 10000000 !important;
}
.top-bar-close:hover {
background: rgba(239, 68, 68, 0.9) !important;
color: #fff !important;
transform: translateY(-50%) rotate(90deg) !important;
}
@keyframes tickerScroll {
0% {
transform: translate3d(0, 0, 0);
}
100% {
transform: translate3d(50%, 0, 0);
}
}
/* بهینهسازی ریسپانسیو فوقالعاده برای موبایل تحت هر شرایطی */
@media screen and (max-width: 768px) {
:root {
--tb-font-size: 12px !important;
--tb-padding: 8px 0 !important;
}
.ticker-item {
padding: 0 25px !important;
}
.premium-top-bar {
display: flex !important;
visibility: visible !important;
opacity: 1 !important;
}
}
</style>
<?php
}
راهنمای گامبهگام: چگونه این کد را به سایت وردپرسی خود اضافه کنیم؟
برای اضافه کردن این کد به وردپرس، چندین روش وجود دارد. در ادامه ایمنترین و استانداردترین روشها را با هم بررسی میکنیم:
روش اول: ویرایش از طریق مدیریت فایل هاست (روش حرفهای)
گاهی اوقات ممکن است دسترسی به ویرایشگر وردپرس (Theme File Editor) به دلایل امنیتی توسط توسعهدهنده قالب بسته شده باشد، یا شاید ترجیح میدهید به جای محیط وردپرس، مستقیماً با فایلهای سرور کار کنید. در این صورت، استفاده از File Manager هاست بهترین راهکار است.
گامهای اجرای کار در هاست (cPanel یا DirectAdmin):
- ورود به هاست: ابتدا وارد پنل مدیریت هاست خود (cPanel یا DirectAdmin) شوید.
- باز کردن فایل منیجر: روی گزینه File Manager کلیک کنید.
- مسیریابی: به پوشه ریشه سایت خود (معمولاً
public_html) بروید. سپس مسیر زیر را دنبال کنید:wp-content>themes>your-theme-name(نکته: بهجایyour-theme-nameنام پوسته فعال سایت خود را انتخاب کنید. اگر از Child Theme استفاده میکنید، حتماً وارد پوشه فرزند شوید). - ویرایش فایل: فایل
functions.phpرا پیدا کنید. روی آن راستکلیک کرده و گزینه Edit را انتخاب کنید. - جایگذاری کد: کد مورد نظر خود را به انتهای فایل اضافه کنید.
- ذخیره: دکمه Save Changes را در بالای صفحه ویرایشگر بزنید.
روش دوم : اضافه کردن کد به فایل functions.php (روش سریع)
فایل functions.php قلب تپنده قالب شماست و کدهای شخصیسازی در آن قرار میگیرند.
- وارد پیشخوان وردپرس شوید: از منوی سمت راست به مسیر نمایش > ویرایشگر پرونده پوسته (Theme File Editor) بروید.
- فایل مناسب را انتخاب کنید: از ستون سمت چپ (بخش پروندههای پوسته)، فایل توابع پوسته (functions.php) را پیدا کرده و روی آن کلیک کنید.
- قرار دادن کد: به انتهای فایل بروید، یک خط جدید ایجاد کنید و کدهای بالا را دقیقاً در انتهای فایل پیست (Paste) کنید.
- ذخیره تغییرات: روی دکمه بهروزرسانی پرونده کلیک کنید.
⚠️ یک هشدار امنیتی بسیار مهم:
پیش از ویرایش فایلهای قالب، حتماً یک نسخه پشتیبان (Backup) از فایل تهیه کنید. همچنین اگر قالب خود را آپدیت کنید، تغییراتی که در فایل
functions.phpقالب اصلی اعمال کردهاید پاک خواهند شد. برای جلوگیری از این مشکل، پیشنهاد میکنیم از پوسته فرزند (Child Theme) استفاده کنید یا به سراغ روش دوم بروید.
روش سوم: استفاده از افزونههای مدیریت کدهای سفارشی (روش ایمن و بدون خطر)
اگر نمیخواهید فایلهای قالب را به صورت دستی ویرایش کنید و نگران به هم ریختن سایت یا پاک شدن کدها در آپدیتهای بعدی قالب هستید، این روش بهترین گزینه است.
- افزونه رایگان WPcode (Insert Headers and Footers) یا Code Snippets را از مخزن وردپرس نصب و فعال کنید.
- از منوی جدیدی که در پیشخوان اضافه شده، روی Add Snippet (افزودن کد جدید) کلیک کنید.
- یک عنوان دلخواه برای آن انتخاب کنید (مثلاً: نوار اعلان بالای هدر).
- نوع کد (Code Type) را روی حالت PHP Snippet قرار دهید.
- کدهای بالا را در باکس مربوطه کپی کنید.
- وضعیت را روی Active (فعال) قرار داده و دکمه Save را بزنید.
چگونه از نوار اعلان ساخته شده استفاده کنیم؟
پس از ذخیره کد به یکی از روشهای بالا، مراحل زیر را طی کنید تا نوار شما آماده به کار شود:
- به پیشخوان وردپرس خود بروید. اکنون خواهید دید که منوی جدیدی به نام «نوار بالای هدر» با آیکون بلندگو در منوی اصلی ظاهر شده است.
- روی آن کلیک کنید تا وارد صفحه تنظیمات اختصاصی پلاگین خودتان شوید.
- رنگهای دلخواه، سرعت حرکت متون و جملات تبلیغاتی یا اعلانهای خود را وارد کرده و دکمه ذخیره تنظیمات را بزنید.
- وارد صفحه اصلی سایت شوید؛ نوار اعلان شیک و متحرک شما آماده جذب کاربران است!
توسعه اصولی وردپرس به سبک حرفهایها
توسعه قالب و پلاگین در وردپرس نیازمند رعایت استانداردهای کدنویسی تمیز (Clean Code) است. اگر علاقهمند به کار در این حوزه هستید، تحلیل بخشهای اصلی این کد به شما نشان میدهد که در پروژههای واقعی کارفرماها چگونه باید کدنویسی کرد.
۱. پیادهسازی مکانیزم امنیتی کامل
در متد مربوط به ذخیره تنظیمات، از دو ساختار امنیتی بسیار مهم استفاده شده است:
check_admin_refererبرای بررسی صحت درخواستها و جلوگیری از حملات جعل درخواست فروسایت (CSRF).- توابع پاکسازی نظیر
sanitize_hex_colorبرای فیلتر کردن کدهای رنگی ورودی وsanitize_text_fieldبرای متنها. این کار از ورود کدهای مخرب تزریقی (XSS) به دیتابیس جلوگیری میکند.
۲. تزریق پویا با جاوااسکریپت و اولویت در DOM
یکی از چالشهای رایج نوار اعلانها، عدم نمایش درست در برخی از قالبها به علت ویژگیهای CSS هدر یا تداخل در ساختار HTML قالب است. در این بخش، کد با استفاده از اکشن wp_footer لود شده و سپس با متد insertBefore در جاوااسکریپت، به عنوان اولین تگ داخل تگ <body> قرار میگیرد. این روش تضمین میکند که نوار اعلان در تمام قالبها و سناریوهای مختلف به شکل صحیح و در بالاترین نقطه رندر شود.
۳. بهینهسازی انیمیشن متحرک با CSS (بدون افت فریم)
بسیاری از اسکریپتهای نوار متحرک از توابع سنگین جیکوئری استفاده میکنند که باعث لرزش متن (Stuttering) در موبایل میشود. در این کد، انیمیشن تماماً با استفاده از translate3d در CSS هندل شده است که مستقیماً از شتابدهنده گرافیکی سختافزار (GPU Rendering) استفاده میکند و حرکتی فوقالعاده نرم و ۶۰ فریم بر ثانیه را به نمایش میگذارد.
درباره میلاد علیزاده وکیلی
میلاد علیزاده هستم مدرس دوره های آموزش برنامه نویسی در شهر تبریز که فعالیت خودم رو از سال 95 در زمینه ی طراحی و میزبانی وبسایت شروع کردم. هدف من از راه اندازی این وبسایت ارائه ی آموزشی متفاوت همچنین اشتغال محور و پروژه محور هستش که هنرجو بعد از آموزش بتواند با دانش و تجربه ای کافی مستقیما وارد بازار کار شده و در زمینه ی برنامه نویسی کسب درامد کند.
نوشتههای بیشتر از میلاد علیزاده وکیلی

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