مستندات رسمی ساخت افزونه‌های وبلین

نسخه ۲.۴۰۵ · به‌روزرسانی ۱۴۰۵
راهنمای کامل توسعه‌دهندگان برای ساخت افزونه‌های قدرتمند وبلینی
۱. افزونه وبلینی چیست؟

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

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

افزونه‌های وبلینی برخلاف بسیاری از سیستم‌های دیگر، نیاز به کامپایل یا بیلد ندارند. شما کد را می‌نویسید، کاربر آن را در مرکز افزونه‌ها بارگذاری می‌کند، و پس از تنظیمات، یک کد نهایی دریافت می‌کند که در سایت خود قرار می‌دهد.

هشدار مهم: افزونه‌های وبلینی در محیط مرورگر کاربر اجرا می‌شوند. بنابراین همیشه باید به امنیت کد توجه کنید. از eval و innerHTML با داده‌های ورودی کاربر خودداری کنید و همیشه ورودی‌ها را اعتبارسنجی کنید.

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

 
۲. دو نوع کد در افزونه‌های وبلین

در سیستم افزونه‌های وبلین، دو نوع کد وجود دارد که نباید با هم اشتباه شوند:

۲-۱. کد اصلی افزونه (کد بارگذاری)

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

{ id: 'my_plugin', name: 'نام افزونه', icon: 'fa-cube', desc: 'توضیحات', category: 'خدماتی', version: '1.0.0', author: 'نویسنده', renderConfigPanel: function(existing) { ... }, collectConfigData: function() { ... }, generateCode: function(config) { ... } }
۲-۲. کد فرعی افزونه (کد تولیدی برای نصب در سایت)

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

خلاصه:
کد اصلی → توسط توسعه‌دهنده نوشته می‌شود → در مرکز افزونه‌ها بارگذاری می‌شود.
کد فرعی → توسط سیستم تولید می‌شود → کاربر در سایت خود نصب می‌کند.
 
۳. ساختار کامل یک افزونه وبلینی

هر افزونه وبلینی از ۵ بخش اصلی تشکیل شده است که در ادامه با جزئیات کامل توضیح داده می‌شود.

۳-۱. بخش اطلاعات (ضروری)
فیلد نوع توضیح مثال
id string شناسه یکتا (فقط حروف انگلیسی، اعداد و خط تیره) 'carpet_calculator'
name string نام نمایشی افزونه 'ماشین حساب قیمت فرش'
icon string کلاس آیکون از Font Awesome 4.7 'fa-calculator'
desc string توضیح کوتاه (حداکثر ۱ خط) 'دکمه شناور با ماشین حساب'
category string دسته‌بندی افزونه 'خدماتی' یا 'فروشگاهی'
version string شماره نسخه (اختیاری) '1.0.0'
author string نام نویسنده (اختیاری) 'توسعه‌دهنده وبلین'
۳-۲. پنل تنظیمات renderConfigPanel(existing)

این تابع یک رشته HTML برمی‌گرداند که در مودال تنظیمات به کاربر نمایش داده می‌شود. کاربر از طریق این پنل، مقادیر مورد نیاز افزونه را وارد می‌کند.

renderConfigPanel: function(existing) { return '
'; }
۳-۳. جمع‌آوری داده collectConfigData()

این تابع داده‌های وارد شده توسط کاربر را از پنل تنظیمات جمع‌آوری کرده و به‌صورت یک شیء برمی‌گرداند.

collectConfigData: function() { return { min_price: document.getElementById('min_price').value, main_color: document.getElementById('main_color').value }; }
۳-۴. تولید کد نهایی generateCode(config)

این تابع کد نهایی را تولید می‌کند که کاربر در سایت خود نصب می‌کند. ورودی این تابع، داده‌های جمع‌آوری‌شده از collectConfigData است.

generateCode: function(config) { var minPrice = config.min_price || 1000; var color = config.main_color || '#ff6b00'; return ' '; }
۳-۵. هوک‌های اختیاری

می‌توانید هوک‌های onBeforeBuild و onAfterBuild را برای کنترل بیشتر اضافه کنید.

onBeforeBuild: function(config) { config.min_price = parseInt(config.min_price) || 0; return config; }, onAfterBuild: function(code) { console.log('ساخته شد، طول کد:', code.length); }
 
۴. ساختار صفحات در وبلین

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

نکته کلیدی: با استفاده از window.location.pathname می‌توانید آدرس صفحه را شناسایی کرده و بر اساس آن، کدهای متفاوتی اجرا کنید. این روش به شما اجازه می‌دهد تا برای هر صفحه، تغییرات خاص خود را اعمال کنید.
۴-۱. صفحات پیش‌فرض وبلین
صفحه آدرس توضیح کاربرد در افزونه
حساب کاربری /userarea.php صفحه مدیریت حساب کاربری شامل سفارشات، تغییر رمز و خروج تغییر ظاهر دکمه‌ها، افزودن آیتم‌های جدید به منوی کاربری، تغییر پیام خوش‌آمدگویی
آرشیو کلی /archive/ نمایش لیست تمام مطالب (اخبار و مقالات) تغییر چیدمان کارت‌ها، افزودن فیلترهای جدید، تغییر استایل صفحه‌بندی
آرشیو اخبار /archiven.php نمایش لیست اخبار تغییر نحوه نمایش اخبار، افزودن برچسب‌های دسته‌بندی
آرشیو مقالات /archivem.php نمایش لیست مقالات تغییر استایل کارت‌های مقالات، افزودن تاریخ‌های شمسی
فروشگاه /shop.php صفحه اصلی فروشگاه با لیست محصولات تغییر چیدمان محصولات، افزودن فیلترهای قیمتی، تغییر دکمه خرید
دسته‌بندی فروشگاه /shop/دسته-بندی صفحه محصولات یک دسته خاص تغییر بنر دسته، افزودن توضیحات سفارشی، تغییر ترتیب محصولات
صفحه محصول /p/شناسه-محصول صفحه نمایش جزئیات یک محصول تغییر جایگاه قیمت، افزودن دکمه‌های اشتراک‌گذاری، تغییر گالری تصاویر
سبد خرید /cart.php صفحه سبد خرید کاربر تغییر استایل جدول، افزودن توضیحات اضافی، تغییر دکمه تسویه
تسویه حساب /checkout.php صفحه تکمیل خرید و پرداخت تغییر فرم‌ها، افزودن گزینه‌های ارسال، تغییر ظاهر دکمه پرداخت
جستجو /search.php یا /?s= نتایج جستجوی کاربر تغییر نحوه نمایش نتایج، افزودن فیلترهای جانبی
۴-۲. شناسایی صفحه با شرط‌گذاری

برای اعمال تغییرات در صفحات خاص، از کد زیر استفاده کنید:

var path = window.location.pathname; if (path.indexOf('/userarea.php') !== -1) { console.log('صفحه حساب کاربری'); } else if (path.indexOf('/archive/') !== -1 || path.indexOf('/archiven.php') !== -1 || path.indexOf('/archivem.php') !== -1) { console.log('صفحه آرشیو'); } else if (path.indexOf('/shop.php') !== -1 || path.indexOf('/shop/') !== -1) { console.log('صفحه فروشگاه'); } else if (path.indexOf('/cart.php') !== -1) { console.log('صفحه سبد خرید'); } else if (path.indexOf('/p/') !== -1) { console.log('صفحه محصول'); } else { console.log('سایر صفحات'); }
۴-۳. شخصی‌سازی پنل کاربری

با استفاده از سلکتورهای مشترک و شرط‌گذاری روی /userarea.php، می‌توانید تغییرات زیر را اعمال کنید:

if (window.location.pathname.indexOf('/userarea.php') !== -1) { var title = document.querySelector('h2:contains("خوش آمدی")'); if (title) { title.textContent = 'سلام کاربر عزیز! به پنل خود خوش آمدید'; title.style.color = '#ff6b00'; title.style.fontSize = '28px'; } var btns = document.querySelectorAll('.unav'); btns.forEach(function(btn) { btn.style.background = 'linear-gradient(135deg, #ff6b00, #ff8c42)'; btn.style.color = '#fff'; btn.style.borderRadius = '12px'; btn.style.padding = '14px 24px'; btn.style.boxShadow = '0 4px 15px rgba(255,107,0,0.2)'; }); var newBtn = document.createElement('a'); newBtn.className = 'unav'; newBtn.href = '/userarea.php?action=editprofile'; newBtn.innerHTML = '
ویرایش پروفایل'; newBtn.style.cssText = 'padding:10px;display:inline-block;text-decoration:none;color:#1e293b;'; var container = document.querySelector('.container.internalpage, .website-wrapper.container, main.not-index .single-page'); if (container) { var menuDiv = container.querySelector('div[style*="padding-top:20px"]'); if (menuDiv) { menuDiv.appendChild(newBtn); } } }
۴-۴. شخصی‌سازی آرشیو

برای تغییر ظاهر صفحات آرشیو، از سلکتورهای زیر استفاده کنید:

if (window.location.pathname.indexOf('/archive/') !== -1 || window.location.pathname.indexOf('/archiven.php') !== -1 || window.location.pathname.indexOf('/archivem.php') !== -1) { var cards = document.querySelectorAll('.scard'); cards.forEach(function(card, index) { card.style.background = '#ffffff'; card.style.borderRadius = '16px'; card.style.boxShadow = '0 4px 20px rgba(0,0,0,0.06)'; card.style.transition = 'all 0.3s ease'; card.style.border = '1px solid #eef2f6'; card.style.marginBottom = '20px'; card.addEventListener('mouseenter', function() { this.style.transform = 'translateY(-4px)'; this.style.boxShadow = '0 12px 40px rgba(0,0,0,0.1)'; this.style.borderColor = '#ff6b00'; }); card.addEventListener('mouseleave', function() { this.style.transform = 'translateY(0)'; this.style.boxShadow = '0 4px 20px rgba(0,0,0,0.06)'; this.style.borderColor = '#eef2f6'; }); var img = card.querySelector('.scardimg img'); if (img) { img.style.borderRadius = '12px 12px 0 0'; img.style.width = '100%'; img.style.height = '200px'; img.style.objectFit = 'cover'; } var title = card.querySelector('.scardtitle a, .scardtitle strong'); if (title) { title.style.color = '#1e293b'; title.style.fontSize = '18px'; title.style.fontWeight = '700'; title.style.textDecoration = 'none'; title.addEventListener('mouseenter', function() { this.style.color = '#ff6b00'; }); title.addEventListener('mouseleave', function() { this.style.color = '#1e293b'; }); } var date = card.querySelector('.scardfooter .ssmall, .scardfooter .slblgray'); if (date) { date.style.color = '#94a3b8'; date.style.fontSize = '12px'; date.style.background = '#f1f5f9'; date.style.padding = '2px 12px'; date.style.borderRadius = '20px'; } var readMore = card.querySelector('.scardfooter .sbtn, .scardfooter a'); if (readMore) { readMore.style.background = 'linear-gradient(135deg, #ff6b00, #ff8c42)'; readMore.style.color = '#fff'; readMore.style.padding = '8px 20px'; readMore.style.borderRadius = '30px'; readMore.style.textDecoration = 'none'; readMore.style.fontWeight = '600'; readMore.style.transition = 'all 0.3s ease'; readMore.textContent = 'مطالعه بیشتر'; readMore.addEventListener('mouseenter', function() { this.style.transform = 'scale(1.05)'; this.style.boxShadow = '0 4px 20px rgba(255,107,0,0.3)'; }); readMore.addEventListener('mouseleave', function() { this.style.transform = 'scale(1)'; this.style.boxShadow = 'none'; }); } }); var pagination = document.querySelector('.sfooterbar'); if (pagination) { pagination.style.direction = 'rtl'; pagination.style.textAlign = 'center'; pagination.style.padding = '20px 0'; pagination.style.marginTop = '30px'; pagination.style.borderTop = '2px solid #eef2f6'; var pageLinks = pagination.querySelectorAll('.sbtn'); pageLinks.forEach(function(link) { link.style.display = 'inline-block'; link.style.padding = '8px 16px'; link.style.margin = '0 4px'; link.style.borderRadius = '8px'; link.style.background = '#f1f5f9'; link.style.color = '#1e293b'; link.style.textDecoration = 'none'; link.style.transition = 'all 0.3s ease'; link.style.fontWeight = '600'; link.addEventListener('mouseenter', function() { this.style.background = '#ff6b00'; this.style.color = '#fff'; this.style.transform = 'scale(1.05)'; }); link.addEventListener('mouseleave', function() { this.style.background = '#f1f5f9'; this.style.color = '#1e293b'; this.style.transform = 'scale(1)'; }); }); } }
۴-۵. شخصی‌سازی فروشگاه

برای تغییر ظاهر صفحات فروشگاه، از سلکتورهای زیر استفاده کنید:

if (window.location.pathname.indexOf('/shop.php') !== -1 || window.location.pathname.indexOf('/shop/') !== -1) { var products = document.querySelectorAll('.product, .product-item, .product-grid-item'); products.forEach(function(product) { product.style.background = '#ffffff'; product.style.borderRadius = '16px'; product.style.boxShadow = '0 4px 20px rgba(0,0,0,0.06)'; product.style.transition = 'all 0.3s ease'; product.style.border = '1px solid #eef2f6'; product.style.padding = '16px'; product.style.marginBottom = '20px'; product.addEventListener('mouseenter', function() { this.style.transform = 'translateY(-4px)'; this.style.boxShadow = '0 12px 40px rgba(0,0,0,0.1)'; this.style.borderColor = '#ff6b00'; }); product.addEventListener('mouseleave', function() { this.style.transform = 'translateY(0)'; this.style.boxShadow = '0 4px 20px rgba(0,0,0,0.06)'; this.style.borderColor = '#eef2f6'; }); var price = product.querySelector('.price, .woocommerce-Price-amount, .product-price'); if (price) { price.style.color = '#ff6b00'; price.style.fontSize = '20px'; price.style.fontWeight = '700'; } var addBtn = product.querySelector('.add-to-cart, .add_to_cart_button, .add-to-cart-btn'); if (addBtn) { addBtn.style.background = 'linear-gradient(135deg, #ff6b00, #ff8c42)'; addBtn.style.color = '#fff'; addBtn.style.border = 'none'; addBtn.style.borderRadius = '30px'; addBtn.style.padding = '8px 20px'; addBtn.style.cursor = 'pointer'; addBtn.style.transition = 'all 0.3s ease'; addBtn.addEventListener('mouseenter', function() { this.style.transform = 'scale(1.05)'; this.style.boxShadow = '0 4px 20px rgba(255,107,0,0.3)'; }); addBtn.addEventListener('mouseleave', function() { this.style.transform = 'scale(1)'; this.style.boxShadow = 'none'; }); } }); }
هشدار مهم: ساختار صفحات و سلکتورها ممکن است در قالب‌های مختلف تغییر کند. همیشه قبل از نوشتن افزونه، سورس کد قالب را در بخش «قالب‌های وبلین» در پنل مدیریت بررسی کنید و سلکتورهای دقیق را از روی کد واقعی استخراج نمایید. با کاوش در سورس صفحات، می‌توانید دموی آنها را به‌طور کامل تغییر دهید.
 
۵. سلکتورهای مشترک در قالب‌های وبلین

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

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

سلکتورهای زیر یک الگوی مشترک هستند و ممکن است در همه قالب‌ها دقیقاً یکسان نباشند. شاید کد قالب‌های ثابت تغییر کند، باید حتما خودتان کد قالب‌های وبلینی را کاوش کنید که از صفحه قالب‌ها در وبلین در دسترس هستند.
۵-۱. صفحه حساب کاربری (userarea.php)
بخش سلکتور(های) پیشنهادی توضیح
عنوان خوش‌آمدگویی h2:contains("خوش آمدی") عنوان بالای صفحه
دکمه سفارشات .unav:has(.fa-shopping-cart) لینک مشاهده سفارشات
دکمه تغییر رمز .unav:has(.fa-lock) لینک تغییر رمز عبور
دکمه خروج .unav:has(.fa-power-off) لینک خروج از حساب
همه دکمه‌ها .unav تمام دکمه‌های کاربری
کانتینر اصلی .container.internalpage, .website-wrapper.container, main.not-index محفظه اصلی صفحه
۵-۲. صفحه آرشیو (archive / archiven.php / archivem.php)
بخش سلکتور(های) پیشنهادی توضیح
عنوان صفحه .sheaderbar .scol-md-6, h2:contains("آرشیو") عنوان اصلی آرشیو
فرم جستجو form[action*="archiven.php"] فرم جستجوی آرشیو
فیلد جستجو input[name="search"], .sinput ورودی جستجو
دکمه جستجو button[type="submit"], .sbtn دکمه ارسال
کارت‌های مطالب .scard هر آیتم در آرشیو
تصویر شاخص .scardimg img تصویر هر مطلب
عنوان مطلب .scardtitle a, .scardtitle strong لینک عنوان
خلاصه مطلب .scardbody (بدون .scardtitle) متن خلاصه
تاریخ انتشار .scardfooter .ssmall, .scardfooter .slblgray تاریخ
دکمه ادامه مطلب .scardfooter .sbtn, .scardfooter a لینک ادامه
صفحه‌بندی .sfooterbar, .sfooterbar .sbtn لینک‌های صفحات
۵-۳. صفحه محصول (product.php / p/)
بخش سلکتور(های) پیشنهادی توضیح
عنوان محصول .product-title, h1.product-title, .product-name نام محصول
قیمت محصول .price, .woocommerce-Price-amount, .product-price قیمت نمایشی
موجودی محصول .product-stock, [data-stock], .stock-info تعداد موجودی
تعداد سفارش .product-quantity, input[name="qty"], .quantity-input فیلد تعداد
دکمه خرید .add-to-cart, .add-to-cart-btn, .add_to_cart_button دکمه افزودن به سبد
توضیحات محصول .product-description, .woocommerce-product-details__short-description توضیحات کوتاه
گالری تصاویر .product-images, .woocommerce-product-gallery گالری تصاویر محصول
۵-۴. صفحه سبد خرید (cart.php)
بخش سلکتور(های) پیشنهادی توضیح
آیتم‌های سبد .cart-item, [data-cart-item], .cart-row هر ردیف محصول
تعداد محصول .item-quantity input, [data-qty], .product-quantity input فیلد تعداد
قیمت هر آیتم .item-price, .product-subtotal قیمت هر ردیف
جمع کل سبد .cart-total, .total-price, .order-total جمع کل قیمت‌ها
مبلغ قابل پرداخت .carttotal, .mustpay مبلغ نهایی
دکمه تسویه .checkout-btn, .proceed-to-checkout, .view-cart دکمه تکمیل خرید
۵-۵. صفحه فروشگاه (shop.php / shop/)
بخش سلکتور(های) پیشنهادی توضیح
لیست محصولات .products, .product-grid, .product-list کانتینر محصولات
هر محصول .product, .product-item, .product-grid-item کارت هر محصول
تصویر محصول .product-image img, .woocommerce-LoopProduct-link img تصویر شاخص
عنوان محصول .product-title, .woocommerce-loop-product__title نام محصول
قیمت محصول .price, .woocommerce-Price-amount قیمت محصول
دکمه خرید .add-to-cart, .add_to_cart_button, .ajax_add_to_cart دکمه افزودن به سبد
فیلترها .woocommerce-widget-layered-nav, .price_slider فیلترهای جانبی
صفحه‌بندی .woocommerce-pagination, .page-numbers صفحه‌بندی محصولات
۵-۶. توابع کمکی برای سلکتورها

این توابع را در افزونه خود استفاده کنید تا کار با سلکتورها آسان‌تر شود:

function findElement(selectorsList) { for (var i = 0; i < selectorsList.length; i++) { var el = document.querySelector(selectorsList[i]); if (el) return el; } return null; } function findAllElements(selectorsList) { var all = []; for (var i = 0; i < selectorsList.length; i++) { var els = document.querySelectorAll(selectorsList[i]); if (els.length) { for (var j = 0; j < els.length; j++) { all.push(els[j]); } } } return all; } function extractPrice(text) { if (!text) return 0; var num = text.replace(/[^0-9]/g, ''); return parseInt(num) || 0; } function findParent(el, selector) { while (el && el.parentNode) { el = el.parentNode; if (el.matches && el.matches(selector)) { return el; } } return null; } function waitForElement(selector, callback, timeout) { var maxAttempts = timeout || 50; var attempts = 0; function check() { attempts++; var el = document.querySelector(selector); if (el) { callback(el); return; } if (attempts < maxAttempts) { setTimeout(check, 100); } } check(); } function getPageType() { var path = window.location.pathname; if (path.indexOf('/userarea.php') !== -1) return 'userarea'; if (path.indexOf('/archiven.php') !== -1) return 'archiven'; if (path.indexOf('/archivem.php') !== -1) return 'archivem'; if (path.indexOf('/archive/') !== -1) return 'archive'; if (path.indexOf('/shop.php') !== -1 || path.indexOf('/shop/') !== -1) return 'shop'; if (path.indexOf('/cart.php') !== -1) return 'cart'; if (path.indexOf('/p/') !== -1) return 'product'; if (path.indexOf('/checkout.php') !== -1) return 'checkout'; if (path.indexOf('/search.php') !== -1 || path.indexOf('?s=') !== -1) return 'search'; return 'other'; }
 
۶. رویکردهای توسعه افزونه‌های وبلین

افزونه‌های وبلین عمدتاً بر اساس دستکاری DOM و سلکتورها کار می‌کنند، اما می‌توانند عملکردهای دیگری نیز داشته باشند. در ادامه مهم‌ترین رویکردها را بررسی می‌کنیم:

۶-۱. رویکرد سلکتورمحور (Selector-Based)

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

var prices = document.querySelectorAll('.price, .woocommerce-Price-amount'); prices.forEach(function(price) { price.style.color = '#ff6b00'; price.style.fontWeight = 'bold'; });
۶-۲. رویکرد افزودن المان (Element Injection)

در این روش، شما المان‌های جدید به صفحه اضافه می‌کنید؛ مانند دکمه‌های شناور، بنرها، مودال‌ها و ...

var btn = document.createElement('a'); btn.href = 'https://wa.me/989123456789'; btn.target = '_blank'; btn.textContent = 'چت واتساپ'; btn.style.cssText = 'position:fixed;bottom:20px;right:20px;background:#25D366;color:#fff;padding:10px 20px;border-radius:40px;z-index:99999;'; document.body.appendChild(btn);
۶-۳. رویکرد رویدادمحور (Event-Driven)

افزونه‌ها می‌توانند به رویدادهای مختلف مانند کلیک، اسکرول، تغییرات DOM و ... گوش دهند و واکنش نشان دهند.

window.addEventListener('scroll', function() { if (window.scrollY > 500) { console.log('کاربر به پایین صفحه اسکرول کرد'); } });
۶-۴. رویکرد تعامل با API و داده‌ها

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

fetch('https://api.example.com/data') .then(response => response.json()) .then(data => { var container = document.createElement('div'); container.textContent = 'داده دریافت شد: ' + data.message; document.body.appendChild(container); });
۶-۵. رویکرد تغییر ساختار صفحه (Layout Manipulation)

در این روش، شما چیدمان کلی صفحه را تغییر می‌دهید؛ مانند جابجایی المان‌ها، تغییر ترتیب آنها، یا تغییر استایل‌های کلی.

var cart = document.querySelector('.woodmart-shopping-cart'); var header = document.querySelector('.whb-general-header'); if (cart && header) { header.prepend(cart); }
۶-۶. رویکرد شرطی بر اساس نوع صفحه

با تشخیص نوع صفحه، می‌توانید کدهای متفاوتی برای هر صفحه اجرا کنید.

var pageType = getPageType(); switch(pageType) { case 'userarea': console.log('صفحه حساب کاربری'); break; case 'archive': case 'archiven': case 'archivem': console.log('صفحه آرشیو'); break; case 'shop': console.log('صفحه فروشگاه'); break; case 'cart': console.log('صفحه سبد خرید'); break; case 'product': console.log('صفحه محصول'); break; default: console.log('سایر صفحات'); }
 
۷. ساخت دمو و تغییر ظاهر کلی قالب
ساخت دموی افزونه:
شما می‌توانید با استفاده از سلکتورها و دستکاری DOM، بر روی قالب‌های ثابت وبلین تغییرات اساسی اعمال کنید و ظاهر کلی قالب را از اول طراحی کنید.

درست مثل وردپرس که روی یک بیس (Base) کار می‌کند، شما نیز می‌توانید با افزونه خود، تم کامل سایت را تغییر دهید، المان‌های جدید اضافه کنید، و یا حتی المان‌های موجود را حذف یا جابجا کنید.
۷-۱. تغییر کامل هدر سایت
(function() { var header = document.querySelector('.whb-general-header, .site-header, header'); if (!header) return; header.style.display = 'none'; var newHeader = document.createElement('header'); newHeader.style.cssText = 'background:linear-gradient(135deg,#1e293b,#0f172a);padding:15px 30px;display:flex;justify-content:space-between;align-items:center;color:#fff;font-family:Tahoma,sans-serif;position:sticky;top:0;z-index:9999;box-shadow:0 2px 20px rgba(0,0,0,0.3);'; newHeader.innerHTML = '
سایت من
'; document.body.prepend(newHeader); })();
۷-۲. تغییر کامل فوتر
(function() { var footer = document.querySelector('.footer-container, footer, .copyrights-wrapper'); if (!footer) return; footer.style.display = 'none'; var newFooter = document.createElement('footer'); newFooter.style.cssText = 'background:#0f172a;color:#94a3b8;padding:30px 20px;text-align:center;border-top:2px solid #1e293b;font-size:14px;'; newFooter.innerHTML = '

© ۱۴۰۴ تمامی حقوق محفوظ است.

طراحی شده با وبلین

'; document.body.appendChild(newFooter); })();
۷-۳. تغییر کامل استایل‌های صفحه
(function() { document.body.style.background = '#f0f4f8'; var style = document.createElement('style'); style.textContent = 'body,*{font-family:"Tahoma",sans-serif !important;}.container{max-width:1200px !important;padding:0 20px !important;}h1,h2,h3{color:#1e293b !important;}a{color:#ff6b00 !important;transition:color 0.3s !important;}a:hover{color:#e05e00 !important;}.btn,button,.sbtn{border-radius:30px !important;padding:10px 30px !important;background:linear-gradient(135deg,#ff6b00,#ff8c42) !important;color:#fff !important;border:none !important;cursor:pointer !important;transition:all 0.3s !important;}.btn:hover,button:hover,.sbtn:hover{transform:scale(1.05) !important;box-shadow:0 4px 20px rgba(255,107,0,0.3) !important;}'; document.head.appendChild(style); })();
۷-۴. تغییر کامل صفحه فروشگاه
if (window.location.pathname.indexOf('/shop.php') !== -1 || window.location.pathname.indexOf('/shop/') !== -1) { var container = document.querySelector('.products, .product-grid, .product-list'); if (container) { container.style.display = 'grid'; container.style.gridTemplateColumns = 'repeat(auto-fill, minmax(250px, 1fr))'; container.style.gap = '20px'; container.style.padding = '20px 0'; } var products = document.querySelectorAll('.product, .product-item, .product-grid-item'); products.forEach(function(product) { product.style.background = '#fff'; product.style.borderRadius = '16px'; product.style.boxShadow = '0 4px 20px rgba(0,0,0,0.06)'; product.style.transition = 'all 0.3s ease'; product.style.padding = '16px'; product.style.textAlign = 'center'; product.style.border = '1px solid #eef2f6'; var img = product.querySelector('img'); if (img) { img.style.borderRadius = '12px'; img.style.width = '100%'; img.style.height = '200px'; img.style.objectFit = 'cover'; } var title = product.querySelector('.product-title, .woocommerce-loop-product__title'); if (title) { title.style.fontSize = '16px'; title.style.fontWeight = '700'; title.style.margin = '10px 0'; title.style.color = '#1e293b'; } var price = product.querySelector('.price, .woocommerce-Price-amount'); if (price) { price.style.color = '#ff6b00'; price.style.fontSize = '20px'; price.style.fontWeight = '700'; } var btn = product.querySelector('.add-to-cart, .add_to_cart_button'); if (btn) { btn.style.background = 'linear-gradient(135deg, #ff6b00, #ff8c42)'; btn.style.color = '#fff'; btn.style.border = 'none'; btn.style.borderRadius = '30px'; btn.style.padding = '8px 20px'; btn.style.cursor = 'pointer'; btn.style.transition = 'all 0.3s ease'; } }); }
نکته: برای ساخت دموی حرفه‌ای، می‌توانید از CSS سفارشی و جاوااسکریپت پیشرفته استفاده کنید و تم کامل سایت را مطابق با برند خود تغییر دهید. کاربران وبلین می‌توانند با افزونه شما، سایت خود را کاملاً شخصی‌سازی کنند.
 
۸. توابع کمکی و ابزارهای پیشنهادی

در ادامه چند تابع کمکی مفید برای استفاده در افزونه‌ها آورده شده است:

function waitForElement(selector, callback, timeout) { var maxAttempts = timeout || 50; var attempts = 0; function check() { attempts++; var el = document.querySelector(selector); if (el) { callback(el); return; } if (attempts < maxAttempts) { setTimeout(check, 100); } else { console.warn('المان پیدا نشد:', selector); } } check(); } function safeSetText(element, newText) { if (!element) return; var children = element.childNodes; var textNodeFound = false; for (var i = 0; i < children.length; i++) { if (children[i].nodeType === 3) { children[i].textContent = newText; textNodeFound = true; break; } } if (!textNodeFound) { element.textContent = newText; } } function createElement(tag, attributes, children) { var el = document.createElement(tag); if (attributes) { for (var key in attributes) { if (key === 'style' && typeof attributes[key] === 'object') { for (var prop in attributes[key]) { el.style[prop] = attributes[key][prop]; } } else if (key === 'text') { el.textContent = attributes[key]; } else if (key === 'html') { el.innerHTML = attributes[key]; } else { el.setAttribute(key, attributes[key]); } } } if (children) { if (Array.isArray(children)) { children.forEach(function(child) { if (typeof child === 'string') { el.appendChild(document.createTextNode(child)); } else { el.appendChild(child); } }); } else if (typeof children === 'string') { el.innerHTML = children; } } return el; } function setStorage(key, value) { try { localStorage.setItem('wbl_' + key, JSON.stringify(value)); } catch (e) { console.warn('خطا در ذخیره‌سازی:', e); } } function getStorage(key, defaultValue) { try { var data = localStorage.getItem('wbl_' + key); return data ? JSON.parse(data) : defaultValue; } catch (e) { return defaultValue; } } function showToast(message, type) { var existing = document.querySelector('.wbl-toast'); if (existing) existing.remove(); var toast = document.createElement('div'); toast.className = 'wbl-toast'; toast.textContent = message; var colors = { success: '#238636', error: '#f85149', warning: '#d29922', info: '#58a6ff' }; toast.style.cssText = 'position:fixed;bottom:30px;left:50%;transform:translateX(-50%);background:' + (colors[type] || '#238636') + ';color:#fff;padding:10px 30px;border-radius:40px;font-size:14px;font-weight:500;z-index:999999;box-shadow:0 4px 20px rgba(0,0,0,0.3);animation:slideUp 0.3s ease;font-family:Tahoma,sans-serif;'; document.body.appendChild(toast); setTimeout(function() { if (toast.parentNode) toast.remove(); }, 3000); } function getPageType() { var path = window.location.pathname; if (path.indexOf('/userarea.php') !== -1) return 'userarea'; if (path.indexOf('/archiven.php') !== -1) return 'archiven'; if (path.indexOf('/archivem.php') !== -1) return 'archivem'; if (path.indexOf('/archive/') !== -1) return 'archive'; if (path.indexOf('/shop.php') !== -1 || path.indexOf('/shop/') !== -1) return 'shop'; if (path.indexOf('/cart.php') !== -1) return 'cart'; if (path.indexOf('/p/') !== -1) return 'product'; if (path.indexOf('/checkout.php') !== -1) return 'checkout'; if (path.indexOf('/search.php') !== -1 || path.indexOf('?s=') !== -1) return 'search'; return 'other'; } function isUserLoggedIn() { var userEl = document.querySelector('.user-name, [data-user-name], .my-account-with-username'); return userEl !== null; } function getUserName() { var nameEl = document.querySelector('.user-name, [data-user-name], .my-account-with-username'); if (nameEl) { return nameEl.textContent.trim(); } return null; } function getCartTotal() { var totalEl = document.querySelector('.carttotal, .mustpay, .total-price, .cart-total'); if (totalEl) { return extractPrice(totalEl.textContent); } return 0; } function getProductPrice() { var priceEl = document.querySelector('.price, .woocommerce-Price-amount, .product-price'); if (priceEl) { return extractPrice(priceEl.textContent); } return 0; } function getProductStock() { var stockEl = document.querySelector('.product-stock, [data-stock], .stock-info'); if (stockEl) { return extractPrice(stockEl.textContent); } return 0; }
 
۹. نکات امنیتی
امنیت در افزونه‌های وبلین:
افزونه‌های وبلین در محیط مرورگر کاربر اجرا می‌شوند. بنابراین همیشه باید به امنیت کد توجه کنید.
  • از eval و new Function با داده‌های ورودی کاربر خودداری کنید. اگر نیاز به پردازش داده دارید، از روش‌های امن مانند JSON.parse استفاده کنید.
  • ورودی‌های کاربر را اعتبارسنجی کنید. قبل از استفاده از داده‌های وارد شده توسط کاربر، آنها را بررسی و پاک‌سازی کنید.
  • از innerHTML با احتیاط استفاده کنید. اگر محتوای دریافتی از کاربر را با innerHTML قرار می‌دهید، حتماً آن را با DOMPurify یا روش‌های مشابه پاک‌سازی کنید.
  • از localStorage برای داده‌های حساس استفاده نکنید. اطلاعاتی مانند رمز عبور، کلیدهای API و ... را در localStorage ذخیره نکنید.
  • همیشه کد خود را در یک IIFE قرار دهید. این کار از تداخل متغیرهای شما با متغیرهای دیگر جلوگیری می‌کند.
  • از XSS (Cross-Site Scripting) جلوگیری کنید. هرگز داده‌های ورودی کاربر را مستقیماً در صفحه قرار ندهید. از textContent به جای innerHTML استفاده کنید.
  • از CSRF (Cross-Site Request Forgery) جلوگیری کنید. اگر افزونه شما با سرور ارتباط برقرار می‌کند، از توکن‌های CSRF استفاده کنید.
  • از اطلاعات حساس کاربر محافظت کنید. هرگز اطلاعاتی مانند شماره کارت، رمز عبور یا اطلاعات شخصی کاربران را در کد خود ذخیره نکنید.
  • از HTTPS استفاده کنید. اگر افزونه شما با سرور ارتباط برقرار می‌کند، حتماً از HTTPS استفاده کنید.
  • کد خود را به‌روز نگه دارید. با تغییرات وبلین و قالب‌ها، افزونه خود را به‌روز نگه دارید تا از آسیب‌پذیری‌های امنیتی جلوگیری کنید.
(function() { var userInput = document.getElementById('user_input'); if (userInput) { var value = userInput.value; var sanitized = value.replace(/[<>]/g, ''); var safeElement = document.createElement('div'); safeElement.textContent = sanitized; document.body.appendChild(safeElement); } })();
 
۱۰. عیب‌یابی
۱۰-۱. افزونه فعال نمی‌شود
  • بررسی کنید که کد فرعی در تنظیمات پیشرفته سایت قرار داده شده است.
  • بررسی کنید که کد در تگ‌های script صحیح قرار گرفته است.
  • از کنسول مرورگر (F12) برای مشاهده خطاها استفاده کنید.
  • بررسی کنید که کد اصلی افزونه به درستی در مرکز افزونه‌ها بارگذاری شده است.
  • بررسی کنید که نام افزونه و شناسه به درستی وارد شده باشند.
۱۰-۲. سلکتورها کار نمی‌کنند
  • بررسی کنید که ساختار قالب تغییر نکرده باشد.
  • از کنسول مرورگر برای تست سلکتورها استفاده کنید: document.querySelector('.your-selector')
  • از توابع کمکی مانند findElement با چند سلکتور جایگزین استفاده کنید.
  • صفحه مورد نظر را کاوش کنید و سورس کد واقعی را بررسی کنید.
  • بررسی کنید که صفحه مورد نظر در حال بارگذاری است و DOM آن آماده است.
  • از waitForElement برای منتظر ماندن برای بارگذاری المان استفاده کنید.
۱۰-۳. خطاهای جاوااسکریپت
  • از کنسول مرورگر برای مشاهده پیام‌های خطا استفاده کنید.
  • بررسی کنید که همه متغیرها تعریف شده باشند.
  • از try-catch برای مدیریت خطاها استفاده کنید.
  • کد را در IIFE قرار دهید تا از تداخل با سایر کدها جلوگیری شود.
  • بررسی کنید که نوع داده‌ها صحیح است (مثلاً عدد به جای رشته).
۱۰-۴. افزونه با سایر افزونه‌ها تداخل دارد
  • از اسامی یکتا برای متغیرها و توابع خود استفاده کنید.
  • کد خود را در IIFE قرار دهید.
  • از setTimeout برای تاخیر در اجرا استفاده کنید تا سایر افزونه‌ها بارگذاری شوند.
  • از فضای نام (Namespace) برای توابع خود استفاده کنید.
  • بررسی کنید که سلکتورهای شما با سلکتورهای سایر افزونه‌ها تداخل نداشته باشند.
۱۰-۵. مشکلات عملکرد (Performance)
  • از حلقه‌های سنگین روی المان‌های زیاد خودداری کنید.
  • از Event Delegation برای رویدادهای متعدد استفاده کنید.
  • از requestAnimationFrame برای انیمیشن‌ها استفاده کنید.
  • از debounce و throttle برای رویدادهای پرتکرار مانند اسکرول استفاده کنید.
  • از تغییرات زیاد DOM در یک زمان خودداری کنید.
try { var element = document.querySelector('.my-selector'); if (element) { element.style.color = '#ff6b00'; } else { console.warn('المان پیدا نشد، شاید ساختار قالب تغییر کرده است.'); } } catch (e) { console.error('خطا در اجرای افزونه:', e.message); }
 
۱۱. جمع‌بندی و نکات نهایی
جمع‌بندی:
افزونه‌های وبلین ابزاری قدرتمند برای توسعه و شخصی‌سازی سایت‌های وبلینی هستند. با استفاده از سلکتورها، دستکاری DOM و رویکردهای مختلف، می‌توانید قابلیت‌های بی‌نهایتی به سایت‌های کاربران اضافه کنید.

نکات نهایی برای توسعه‌دهندگان:

  • همیشه کد خود را تست کنید. افزونه خود را در چند قالب مختلف وبلین تست کنید تا از سازگاری آن اطمینان حاصل کنید.
  • مستندات بنویسید. برای کاربران خود راهنمای نصب و استفاده بنویسید تا بتوانند به راحتی از افزونه شما استفاده کنند.
  • به‌روزرسانی کنید. با تغییرات وبلین و قالب‌ها، افزونه خود را به‌روز نگه دارید.
  • از بازخورد کاربران استفاده کنید. نظرات کاربران می‌تواند به بهبود افزونه شما کمک کند.
  • سورس کد قالب‌ها را کاوش کنید. بهترین راه برای پیدا کردن سلکتورهای دقیق، بررسی مستقیم سورس کد قالب‌های وبلین است.
  • از دام (DOM) و روش‌های دیگر استفاده کنید. می‌توانید با استفاده از دام و روش‌های دیگر، بر روی قالب‌های ثابت تغییراتی را اعمال کنید که قالب به طور کلی ظاهر آن عوض شود و کل المان‌های قالب را از اول بچینید. درست مثل وردپرس که روی یک بیس کار می‌کند.
  • از نسخه‌های جدید وبلین مطلع باشید. با هر نسخه جدید، ممکن است تغییراتی در ساختار قالب‌ها ایجاد شود که بر روی افزونه شما تأثیر بگذارد. حتما کد منبع قالب های وبلینی را در این لینک «قالب های وبلینی » با فشردن طولانی پیش‌نمایش هرکدام را ببینید و کد منبع آنهارا هم ببینید
  • از ابزارهای توسعه‌دهنده مرورگر استفاده کنید. ابزارهایی مانند Chrome DevTools به شما کمک می‌کنند تا سلکتورها را پیدا کرده و کد خود را دیباگ کنید.
  • کد خود را بهینه کنید. از کدهای تکراری خودداری کنید و توابع خود را کوچک و متمرکز نگه دارید.
  • از کتابخانه‌های کوچک و سبک استفاده کنید. اگر به کتابخانه‌هایی مانند jQuery نیاز دارید، از نسخه‌های کوچک و به‌روز استفاده کنید.
سخن پایانی:
افزونه‌نویسی در وبلین آسان و لذت‌بخش است. با کمی خلاقیت و دانش جاوااسکریپت، می‌توانید افزونه‌های فوق‌العاده‌ای بسازید که تجربه کاربری را متحول کند.

موفق باشید!