SN.
همه مقالات
وردپرس۱۶ مرداد ۱۴۰۵۹ دقیقه

WordPress و Elementor قابل‌ویرایش، بدون اینکه پروژه سنگین و شکننده شود

مرزی که بین Elementor، کد سفارشی، افزونه‌ها و WooCommerce می‌گذارم تا سایت برای مدیر محتوا ساده بماند و برای توسعه‌دهنده قابل نگهداری.

میز کار WordPress با لپ‌تاپ و محیط ویرایش سایت

در پروژه WordPress، مسئله من این نیست که ثابت کنم Elementor خوب است یا بد. سؤال کاربردی‌تر این است: کدام بخش باید برای مدیر سایت قابل ویرایش بماند و کدام بخش بهتر است به کد قابل کنترل سپرده شود؟

اگر این مرز از ابتدا مشخص نباشد، پروژه معمولاً به یکی از دو سمت می‌رود: یا هر رفتار کوچکی با چند Widget و افزونه ساخته می‌شود، یا آن‌قدر Custom Code وارد Theme می‌شود که ویرایش یک صفحه ساده برای مشتری به توسعه‌دهنده وابسته می‌ماند.

هدف من بین این دو حالت است؛ محتوای روزمره باید داخل WordPress قابل مدیریت باشد، اما منطق، CSS و Scriptهایی که روی پایداری سایت اثر دارند باید مرز مشخص داشته باشند.

قبل از ساخت صفحه، وضعیت واقعی پروژه را Audit می‌کنم

قبل از اینکه Section جدیدی در Elementor بسازم، چند چیز را بررسی می‌کنم: Theme و Child Theme، افزونه‌های فعال، Templateهای Elementor، Global Styleها، کدهای سفارشی، Scriptهای Third-party و مسیرهای اصلی WooCommerce اگر فروشگاه باشد.

این Audit جلوی یک اشتباه رایج را می‌گیرد: اضافه کردن راه‌حل جدید برای مسئله‌ای که پروژه از قبل یک راه‌حل دیگر برای آن دارد.

مثلاً اگر دو افزونه هم‌زمان برای Popup، Form یا Optimization کار مشابهی انجام دهند، مسئله فقط چند فایل CSS اضافه نیست. ممکن است Hookها، Ajax Requestها، Event Listenerها و تنظیمات Cache نیز روی هم اثر بگذارند.

برای من قبل از توسعه این سؤال‌ها مهم‌اند:

  • چه چیزی همین حالا Global است و چه چیزی فقط در یک صفحه مصرف می‌شود؟
  • کدام Templateها توسط مدیر سایت ویرایش می‌شوند؟
  • کدام رفتارها به WooCommerce Hook یا داده واقعی محصول وابسته‌اند؟
  • چه Assetهایی در تمام صفحات Load می‌شوند، در حالی که فقط یک Feature به آن‌ها نیاز دارد؟
  • آیا تغییر بعدی Theme یا Plugin Update می‌تواند کد سفارشی را بشکند؟

این اطلاعات مشخص می‌کند راه‌حل باید داخل Elementor بماند، در Child Theme قرار بگیرد یا به یک Plugin کوچک و مستقل منتقل شود.

Elementor را برای جایی نگه می‌دارم که ویرایش بصری واقعاً ارزش دارد

Hero، بخش‌های محتوایی، تصاویر، FAQ، CTA و Composition صفحه معمولاً جاهایی هستند که Visual Editing برای مدیر سایت ارزش مستقیم دارد. اگر قرار است تیم محتوا عنوان، تصویر یا ترتیب یک بخش را تغییر دهد، پنهان کردن آن داخل PHP کمکی به پروژه نمی‌کند.

اما رفتارهای تکراری و حساس را ترجیح می‌دهم با مرز فنی روشن‌تری بسازم. نمونه‌ها:

  • منطق خاص سبد خرید یا Checkout؛
  • رفتار وابسته به Variationهای محصول؛
  • درخواست Ajax و وضعیت Loading/Error؛
  • Integration با REST API؛
  • Component تعاملی که در چند صفحه تکرار می‌شود؛
  • Validation یا Business Rule که نباید به ساختار اتفاقی DOM وابسته باشد.

در چنین مواردی یک Widget سفارشی یا Component کوچک با CSS و JavaScript مشخص، معمولاً قابل پیش‌بینی‌تر از زنجیره‌ای از Widgetها، Custom HTML و افزونه‌های کمکی است.

یک قانون ساده برای مرزبندی

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

CSS سفارشی باید Scope داشته باشد

بخش زیادی از بدهی فنی سایت‌های Elementor از خود Builder نمی‌آید؛ از CSSهایی می‌آید که بدون مرز نوشته شده‌اند.

Selectorهایی مثل .elementor-button یا .woocommerce a.button ممکن است امروز مشکل یک صفحه را حل کنند و ماه بعد روی Popup، Cart یا Template جدید اثر ناخواسته بگذارند. به‌جای Override سراسری، Feature را با یک Wrapper مشخص محدود می‌کنم.

.rabino-checkout .woocommerce-checkout-payment {
  border: 1px solid var(--checkout-border);
}

.rabino-checkout .place-order .button {
  min-height: 48px;
}

هدف این Code Example زیبایی CSS نیست؛ موضوع محدوده اثر است. وقتی Feature کلاس ریشه مشخص دارد، حذف، تست و تغییر آن ساده‌تر می‌شود و نیاز به زنجیره !important کمتر است.

همین منطق را برای CSS Variableها هم استفاده می‌کنم. اگر چند بخش یک Design Token مشترک دارند، Token باید منبع واحد داشته باشد؛ نه اینکه همان Hex یا Radius در ده Selector تکرار شود.

Script را فقط جایی Load می‌کنم که واقعاً مصرف می‌شود

یک Feature کوچک نباید هزینه تمام سایت شود. اگر JavaScript فقط در Checkout لازم است، دلیلی ندارد در Blog و صفحه About هم Load شود.

در WordPress ترجیح می‌دهم Assetها بر اساس Page، Shortcode، Block یا شرایط واقعی Feature Enqueue شوند. برای Scriptهای سفارشی نیز Dependency و زمان اجرا را واضح نگه می‌دارم و از Event Listenerهای تکراری بعد از Ajax Update جلوگیری می‌کنم.

این موضوع در Elementor مهم‌تر می‌شود چون صفحه ممکن است هم Assetهای Builder و هم Assetهای Pluginهای جانبی را داشته باشد. حذف یک کتابخانه بزرگ همیشه تصمیم درستی نیست؛ اما باید بدانم چرا Load می‌شود و چه چیزی واقعاً به آن وابسته است.

WooCommerce را مثل یک صفحه عادی Elementor نمی‌بینم

فروشگاه بخش‌هایی دارد که DOM آن‌ها در طول تعامل کاربر عوض می‌شود. Variation، Cart، Mini Cart، Coupon، Checkout و Payment Methodها ممکن است با Ajax دوباره Render شوند.

اگر یک تغییر فقط با querySelector روی Markup فعلی کار کند ولی بعد از Update سبد خرید از بین برود، UI ظاهراً درست است اما پیاده‌سازی پایدار نیست.

برای WooCommerce این موارد را جداگانه بررسی می‌کنم:

  • Hookهای PHP و ترتیب Render شدن بخش‌ها؛
  • Ajax Eventها و DOM Updateها؛
  • Cart Fragment یا بخش‌هایی که دوباره ساخته می‌شوند؛
  • صفحه‌های Checkout و Cart که نباید مثل محتوای ثابت Cache شوند؛
  • رفتار Variation و موجودی؛
  • Gatewayهای پرداخت و Scriptهای وابسته به آن‌ها؛
  • Noticeها، Validation و مسیر Error State.

هرچه منطق فروشگاه مهم‌تر باشد، وابستگی آن به یک Selector شکننده باید کمتر شود.

افزونه جدید را با «یک قابلیت بیشتر» توجیه نمی‌کنم

Plugin سریع‌ترین راه برای اضافه کردن Feature است، اما هر Plugin یک Dependency جدید هم هست. قبل از نصب، بررسی می‌کنم آیا همان قابلیت در Stack فعلی وجود دارد، Plugin چه Assetهایی Load می‌کند، آیا با WooCommerce/Elementor نسخه‌های فعلی سازگار است و در صورت حذف آن چه داده‌ای باقی می‌ماند.

برای Featureهای کوچک و پروژه‌محور، گاهی یک Plugin اختصاصی محدود از نصب یک Suite بزرگ منطقی‌تر است. برعکس، برای قابلیت استاندارد و پیچیده‌ای مثل Payment Gateway یا SEO، بازنویسی چیزی که یک Plugin معتبر و نگهداری‌شده درست انجام می‌دهد معمولاً تصمیم خوبی نیست.

معیار من تعداد کمتر Plugin نیست؛ تعداد کمتر مسئولیت مبهم است.

Responsive QA را بعد از Desktop انجام نمی‌دهم

در Elementor خیلی راحت می‌شود یک صفحه را در Desktop تمیز کرد و بعد با چند Override برای Tablet و Mobile آن را «جمع کرد». این روش معمولاً فاصله‌ها و Typography را ناپایدار می‌کند.

من Layout را در طول توسعه در عرض‌های مختلف می‌بینم، نه فقط در پایان. مواردی که بیشتر بررسی می‌کنم:

  • Headingهای بلند و متن فارسی/انگلیسی؛
  • Gridهایی که در 1024px فضای مرزی دارند؛
  • Button و Form در عرض 320 تا 430px؛
  • تصاویر با نسبت‌های مختلف و object-fit؛
  • Sticky Elementها و Modalها؛
  • RTL/LTR، مخصوصاً Icon، Padding و Physical Direction؛
  • Hoverهایی که روی Touch Device نباید تنها راه دسترسی به اطلاعات باشند.

این QA فقط ظاهر نیست؛ بخشی از تعریف Done است.

Core Web Vitals را با حذف تصادفی Assetها دنبال نمی‌کنم

اگر صفحه کند است، ابتدا دلیل را پیدا می‌کنم. LCP می‌تواند از Hero Image، Font یا Server Response اثر بگیرد. CLS ممکن است از Image Dimension، Font Swap یا Widgetی که بعداً ارتفاع می‌گیرد ایجاد شود. Interaction ضعیف هم ممکن است از Main Thread شلوغ یا Script Third-party بیاید.

به‌جای اینکه چند فایل را Disable کنم و امیدوار باشم چیزی نشکند، مسیر Render را بررسی می‌کنم و تغییر را اندازه‌پذیر و محدود نگه می‌دارم.

کارهای معمول من بسته به پروژه می‌تواند شامل این‌ها باشد:

  • Local و Optimized کردن Assetهای دائمی؛
  • تعریف Dimension یا Aspect Ratio برای تصاویر؛
  • کاهش Font Variantهای غیرضروری؛
  • Conditional Loading برای Featureها؛
  • حذف Duplicate Library یا Integration قدیمی؛
  • کم کردن DOM و Widgetهای بی‌دلیل؛
  • بررسی Third-party Scriptهایی که در Critical Path قرار گرفته‌اند.

بدون داده واقعی، عدد Performance ساختگی معنی ندارد. هدف این است که بدانم هر تغییر چه مشکلی را حل می‌کند.

Update Safety بخشی از معماری است

سایتی که امروز درست کار می‌کند ولی با Update بعدی Theme یا WooCommerce می‌شکند، تحویل کامل نیست.

کد پروژه را تا جای ممکن از فایل‌های Core یا Parent Theme جدا نگه می‌دارم. منطق مستقل در Plugin یا Child Theme قرار می‌گیرد، Hookهای رسمی ترجیح داده می‌شوند و تغییرات حساس قبل از Update در Staging بررسی می‌شوند.

در سمت مشتری هم سعی می‌کنم ناحیه قابل ویرایش روشن باشد. مدیر سایت نباید برای تغییر عکس Banner وارد بخشی شود که Business Logic Checkout در آن قرار دارد.

Checklist من قبل از تحویل یک سایت Elementor

  • Content مهم بدون ویرایش کد قابل مدیریت است.
  • CSS سفارشی Scope مشخص دارد و Override سراسری ناخواسته ندارد.
  • Scriptهای Featureمحور فقط جایی Load می‌شوند که لازم‌اند.
  • WooCommerce بعد از Ajax Update و تغییر Variation تست شده است.
  • Desktop، Tablet و Mobile جداگانه QA شده‌اند.
  • RTL/LTR و متن‌های طولانی بررسی شده‌اند.
  • Imageها Dimension مشخص و Assetهای دائمی مسیر قابل اتکا دارند.
  • Pluginهای Third-party نقش مشخص دارند و قابلیت تکراری ایجاد نکرده‌اند.
  • مسیر Update و محل نگهداری Custom Code برای توسعه‌دهنده بعدی قابل فهم است.
  • مدیر سایت می‌داند کدام بخش‌ها را می‌تواند بدون ریسک ویرایش کند.

جمع‌بندی

من Elementor را جایگزین Architecture نمی‌بینم. آن را یک لایه ویرایش محتوا می‌دانم که باید در مرز درست قرار بگیرد.

وقتی Content Editing، Custom Code، WooCommerce Logic و Asset Loading مسئولیت مشخص داشته باشند، می‌توان سایتی ساخت که هم برای مشتری قابل ویرایش باشد و هم بعد از چند ماه توسعه به مجموعه‌ای از Overrideها و Pluginهای وابسته تبدیل نشود. برای من کیفیت یک پروژه WordPress دقیقاً در همین تعادل دیده می‌شود.