| کانال وردپرس |
رفتن به کانال در Telegram
⭕️ کانال وردپرس دولوپیکس 💠 دولوپیکس | جامعه توسعهدهندگان ایرانی 💎 @Developix 🚀 Developix.ir 📌 پشتیبانی و تبلیغات: @DevelopixSupport
نمایش بیشتر3 423
مشترکین
-424 ساعت
-77 روز
-1830 روز
آرشیو پست ها
3 423
Repository Pattern در پلاگینهای وردپرس 🏗️
یکی از دردسرهای همیشگی در توسعه پلاگین وردپرس این است که کدهای SQL و منطق تجاری قاطی میشوند. همین ترکیب، نگهداری کد را سخت و تستنویسی را تقریبا غیرممکن میکند.
اینجا الگوی Repository Pattern حسابی به درد میخورد ✨
با Repository، یک لایه میانی بین منطق اپلیکیشن و دیتابیس (یا حتی WP_Query) میسازیم؛ یعنی بقیه کدها دیگر مستقیم با جدولها، متا و کوئریها کار نمیکنند، فقط با یک اینترفیس تمیز حرف میزنند.
مثال ساده برای مدیریت "course" به عنوان post type سفارشی:
interface CourseRepositoryInterface {
public function all();
public function find( $id );
public function create( array $data );
}
class WPCourseRepository implements CourseRepositoryInterface {
public function all() {
return get_posts([
'post_type' => 'course',
'posts_per_page' => -1,
]);
}
public function find( $id ) {
return get_post( $id );
}
public function create( array $data ) {
return wp_insert_post([
'post_type' => 'course',
'post_title' => $data['title'] ?? '',
'post_status' => 'publish',
]);
}
}
حالا در بقیه بخشهای پلاگین، بهجای پخش کردن get_posts و wp_insert_post، فقط با Repository کار میشود:
class CourseService {
private $repo;
public function __construct( CourseRepositoryInterface $repo ) {
$this->repo = $repo;
}
public function publish_all_courses() {
$courses = $this->repo->all();
foreach ( $courses as $course ) {
// منطق مربوط به هر course
}
}
}
مزایا برای دنیای وردپرس 🚀
• تعویض راحت دیتاسورس: امروز از post_type استفاده میشود، فردا اگر خواستی بری روی جدول اختصاصی با wpdb، فقط داخل Repository را عوض میکنی.
• تستنویسی سادهتر: میتوان یک FakeCourseRepository ساخت و بدون نیاز به وردپرس واقعی، روی منطق سرویس تست زد.
• کد تمیزتر: صفحههای ادمین، REST API و Cron Job ها دیگر پر از SQL و get_posts نمیشوند.
چند نکته کاربردی 🛠️
• اینترفیس Repository را در یک مسیر ثابت (مثلا includes/Domain) نگهدار تا ساختار پروژه قابل فهم بماند.
• برای کوئریهای خیلی خاص (فیلتر بر اساس meta و taxonomy) متدهای مشخص داخل Repository تعریف کن تا از تکرار meta_query ها جلوگیری شود.
برای مطالعه بیشتر در مورد Repository Pattern:
martinfowler.com/eaaCatalog/repository.html
کمکم اگر این الگو را در پلاگینهای کوچک خود وارد کنی، رشد پروژه و اضافه کردن فیچرهای جدید خیلی روانتر جلو میرود ✌️
🔖 #Wordpress #وردپرس #Repository_Pattern #WordPress #Clean_Code #PHP #Design_Pattern
👤 Developix
💎 Channel: @DevelopixWordpress3 423
⏱️ کمکردن لود سرور با تنظیم WordPress Heartbeat
خیلی از سایتهای وردپرسی روی هاست اشتراکی بهخاطر Heartbeat API بیدلیل لود میخورند؛ مخصوصاً وقتی چند ادمین همزمان داخل wp-admin هستند. با یک قطعه کد ساده میشود فرکانس Heartbeat را کم کرد و درخواستهای AJAX را سبکتر نگه داشت 🚀
✅ ایده: کاهش فاصله بین هر درخواست Heartbeat در بخش ادمین تا مثلاً ۶۰ ثانیه.
کد را در پلاگین اختصاصی یا فایل functions.php قالب چایلد قرار بده:
add_filter( 'heartbeat_settings', function( $settings ) {
// کاهش فرکانس Heartbeat در پیشخوان به 60 ثانیه
if ( is_admin() ) {
$settings['interval'] = 60;
}
return $settings;
} );
🔹 نتیجه: درخواستهای پسزمینه کمتر، کاهش مصرف CPU و بهبود عملکرد روی هاستهای ضعیف.
🔹 اگر روی سایت از auto-save لحظهای خیلی وابسته نیستی، این عدد حتی میتواند بیشتر هم باشد.
مرجع رسمی 👇
WordPress Developer – Heartbeat API
امتحان روی سایت استیجینگ انجام شود تا مطمئن شوی همهچیز با جریان کاریات سازگار است 🌱
🔖 #Wordpress #وردپرس #WordPress #Heartbeat_API #Performance #PHP #Backend #وردپرس #بهینهسازی
👤 Developix
💎 Channel: @DevelopixWordpress3 423
🌐 دریافت آپدیتها و پلاگینهای وردپرس در شرایط نت ملی
در شرایط فعلی اینترنت (عدم دسترسی به اینترنت بینالملل)، وردپرس نمیتونه به مخزن اصلی وصل بشه و همین باعث میشه:
– آپدیت ها انجام نشه
– نصب/آپدیت پلاگینها fail بشه
برای حل این موضوع، یه راهکار سبک به صورت افزونه (کاملا رایگان) آماده شده که درخواستهای وردپرس به مخزن رسمی رو هندل میکنه و امکان دریافت افزونهها و آپدیتها رو از داخل خود وردپرس فراهم میکنه.
✅ برای فعالسازی افزونه توکن API زیر را از بخش تنظیمات وردپرس، Taba Wp Connect وارد کنید :
OnEDGFsyJDHKyHbPYEubSGtjIfB6YfcA
🔖 #Wordpress #وردپرس
👤 Ali
💎 Channel: @DevelopixWordpress
3 423
🛡 غیرفعال کردن ویرایش فایل های قالب و پلاگین از داشبورد
خیلی وقتها روی سایت وردپرسی چند نفر دسترسی Administrator دارند یا احتمال هک شدن پنل وجود دارد. یکی از اولین کارهای امنیتی این است که ویرایشگر داخلی فایل ها در داشبورد وردپرس غیرفعال شود تا کسی نتواند از طریق Appearance → Theme File Editor یا Plugin File Editor کد مخرب اضافه کند. 🧨
فقط کافی است این خط را داخل فایل
wp-config.php (قبل از خط «That's all, stop editing!») اضافه شود:
define( 'DISALLOW_FILE_EDIT', true );
از این به بعد منوی ویرایشگر قالب و پلاگین از داشبورد ناپدید میشود و حتی اگر کسی به پنل ادمین برسد، دیگر نمیتواند به راحتی فایل های PHP را از داخل وردپرس ویرایش کند. 🔒
این کار جای بکاپ، محدودیت لاگین یا فایروال را نمیگیرد، اما یک لایه امنیتی ساده و کمهزینه است که روی هر سایت پروداشن وردپرسی باید فعال باشد. 🚀
مرجع رسمی:
developer.wordpress.org
🔖 #Wordpress #وردپرس #WordPress #Security #wp_config #DISALLOW_FILE_EDIT #Hardening
👤 Developix
💎 Channel: @DevelopixWordpress3 423
🇮🇷 مخزن داخلی WP Mirror
این مخزن برای افرادی که دسترسی به اینترنت بینالمللی ندارند ایجاد شده و به راحتی از طریق اینترنت داخلی قابل دسترسی است. در حال حاضر شامل ۴۰۰ پلاگین اورجینال و رایگان از مخزن رسمی وردپرس است که بدون هیچگونه دستکاری و تغییر در اختیار شما قرار گرفته. به زودی پلاگینهای بیشتری به این مجموعه اضافه خواهد شد.
برای دریافت آخرین آپدیتها به صورت رایگان، از لینک زیر استفاده کنید:
http://wpexperts.ir
مخزن به صورت هفتگی آپدیت میشود.
🔖 #Wordpress #وردپرس
👤 Mojtaba
💎 Channel: @DevelopixWordpress
3 423
🔁 ریدایرکت ۳۰۱ حرفهای در وردپرس (بدون خراب کردن سئو)
خیلی وقتها توی سایت وردپرسی، آدرس یه نوشته یا صفحه عوض میشه: عوض کردن ساختار permalink، حذف یه دسته، انتقال از /blog/ به ریشه سایت و… اگه برای این آدرسهای قدیمی ریدایرکت درست تنظیم نشه، هم کاربر میره روی 404، هم سئو سایت ضربه میخوره. 😬
امروز یه آموزش کاملاً کاربردی برای مدیریت ریدایرکتها تو وردپرس، هم با پلاگین، هم با یه تکه کد سبک.
منبع اصلی ایده و ساختار:
Redirection plugin در مخزن رسمی
و مستندات رسمی:
wp_redirect()
۱️⃣ روش ساده: استفاده از پلاگین Redirection
اگه دسترسی به نصب پلاگین داری و هاست معمولیه، این روش خیلی تمیز و امنه.
– از منوی Plugins ← Add New
– سرچ کن: Redirection (نویسنده: John Godley)
– نصب و فعالسازی ✅
بعد از فعالسازی:
– برو به: Tools ← Redirection
– ویزارد اولیه رو رد کن تا جدولها ساخته بشه.
حالا برای ساخت یه ریدایرکت ۳۰۱:
– تو بخش "Add new redirection"،
• فیلد Source URL: مثلا
/old-page/
• فیلد Target URL: مثلا
https://example.com/new-page/
• نوع ریدایرکت به صورت پیشفرض ۳۰۱ هست ("Redirections" group).
از این به بعد هرکی بره /old-page/، خودکار میره روی /new-page/، بدون 404 و بدون افت سئو. 😎
۲️⃣ روش دولوپری: ریدایرکت با کد در functions.php
اگه پلاگین اضافه نمیخوای، یا روی یه theme اختصاصی کار میکنی، میتونی ریدایرکتهای خاص رو مستقیم با کد هندل کنی.
این نمونه کد، اگه کاربر بیاد سراغ /old-page/، با ریدایرکت ۳۰۱ میفرستدش روی /new-page/:
add_action( 'template_redirect', function () {
// اگر در admin هستیم یا درخواست برای ajax هست، کاری نکن
if ( is_admin() || wp_doing_ajax() ) {
return;
}
$requested_path = trim( $_SERVER['REQUEST_URI'], '/' );
// آدرس قدیمی بدون دامنه
if ( $requested_path === 'old-page' ) {
wp_redirect( home_url( '/new-page/' ), 301 );
exit;
}
} );
چند نکته مهم از مستندات WordPress:
• استفاده از هوک template_redirect برای ریدایرکت، استاندارد و امنه.
• همیشه بعد از wp_redirect()، حتماً exit; بذار تا اسکریپت ادامه پیدا نکنه.
• برای ساخت URL مقصد، از home_url() استفاده کن تا روی لوکال، استیجینگ و پروداکشن درست کار کنه.
کِی پلاگین، کِی کد؟ 🤔
• پلاگین Redirection عالیه وقتی:
– ریدایرکت زیاد داری و میخوای UI راحت برای مدیریت داشته باشی.
– کسی که سایت رو مدیریت میکنه لزوماً دولوپر نیست.
• کد در functions.php یا plugin اختصاصی بهتره وقتی:
– پروژه کوچیکه و چند تا ریدایرکت ثابت داری.
– روی Performance خیلی حساسی و نمیخوای پلاگین اضافه لود بشه.
یه ریدایرکت ۳۰۱ درست، هم کاربر رو خوشحال نگه میداره، هم اعتبار سئوی لینکهای قدیمی رو حفظ میکنه. 🔧
اگه تو پروژههات آدرس عوض میشه، از همین امروز یکی از این دو روش رو روی سایت تست کن و نتیجۀ 404 کمتر رو توی Google Search Console ببین. 🚀
🔖 #Wordpress #وردپرس #WordPress #Redirect #وردپرس #SEO #Redirection_plugin #functions_php
👤 Developix
💎 Channel: @DevelopixWordpress3 423
🎯 ساخت یک Gutenberg بلاک دکمه دانلود در وردپرس
اگه با Gutenberg کار میکنی، ساختن بلاک اختصاصی یکی از بهترین راههاست برای تمیز نگه داشتن کدت و دادن کنترل بیشتر به کاربر توی ویرایشگر. اینجا یه نمونه واقعی از ساخت یه بلاک دکمه دانلود (Download Button) رو میبینیم که توی هر برگه یا نوشته میتونی استفادهاش کنی. 👇
ایدهٔ کلی اینه:
• یه پلاگین ساده میسازیم.
• با @wordpress/scripts کد React/JSX بلاک رو مینویسیم.
• بلاک رو با
registerBlockType رجیستر میکنیم.
این روش کاملاً مطابق داکیومنت رسمی WordPress و آموزش Gutenberg هست:
developer.wordpress.org/block-editor/reference-guides/block-api/block-registration/
---
۱️⃣ ساختار افزونه
داخل پوشه wp-content/plugins یه پوشه مثلاً به اسم:
wp-download-button-block
بساز و حداقل این فایلها رو داشته باش:
• wp-download-button-block.php
• build/index.js (خروجی Webpack / wp-scripts)
---
۲️⃣ فایل اصلی پلاگین (PHP)
داخل wp-download-button-block.php این کد رو بذار:
<?php
/**
* Plugin Name: WP Download Button Block
* Description: A simple Gutenberg block for a custom download button.
* Author: Your Name
* Version: 1.0.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
function wpdbb_register_block() {
wp_register_script(
'wpdbb-block-script',
plugins_url( 'build/index.js', __FILE__ ),
array( 'wp-blocks', 'wp-element', 'wp-editor', 'wp-components', 'wp-i18n' ),
filemtime( plugin_dir_path( __FILE__ ) . 'build/index.js' )
);
register_block_type( 'wpdbb/download-button', array(
'editor_script' => 'wpdbb-block-script',
) );
}
add_action( 'init', 'wpdbb_register_block' );
این کد اسکریپت بلاک رو رجیستر میکنه و یه بلاک با نام wpdbb/download-button میسازه.
---
۳️⃣ کد بلاک (جاوااسکریپت)
داخل build/index.js یه نسخه ساده از بلاک:
• توی ویرایشگر: متن دکمه و لینک رو از طریق Inspector Controls تنظیم میکنی.
• فرانتاند: یه دکمه با کلاس مشخص برای استایلنویسی CSS رندر میشه.
نمونه ساده مطابق الگوی رسمی GitHub (مثل نمونهکدهای گوتنبرگ):
github.com/WordPress/gutenberg-examples
(در عمل این فایل با Babel/Webpack ساخته میشه؛ نکتهٔ مهم اینه که registerBlockType همین ساختار رو داشته باشه.)
---
چند نکتهٔ کاربردی 🔧
• برای راحتی میتونی از @wordpress/create-block استفاده کنی تا اسکلت پلاگین و بلاک رو خودش بسازه.
• حتماً برای لینک دکمه rel="nofollow noopener" و target="_blank" رو توی رندر لحاظ کن، مخصوصاً برای لینک فایلهای خارجی.
• کلاس اختصاصی مثل .wpdbb-download-btn بذار تا استایلدهی توی theme راحت بشه.
---
این بلاک کوچیک توی پروژههای واقعی، مخصوصاً صفحهٔ دانلود فایل، قالبهای آموزشی و فروش فایل، خیلی کمک میکنه که نویسندهها بدون درگیر شدن با HTML، یه دکمه تمیز و یکدست بسازن. 🚀
امتحانش کن روی یه سایت تست، یه استایل ساده توی theme بهش بده و کمکم بلاکهات رو حرفهایتر کن. 🌱
🔖 #Wordpress #وردپرس #WordPress #Gutenberg #Block #Plugin_Development #PHP #JS #Download_Button
👤 Developix
💎 Channel: @DevelopixWordpress3 423
اگه برای هر چیزی تو سایت از نوشته معمولی استفاده میشه، مدیریت محتوا بعد یه مدت شلوغ و خستهکننده میشه. برای همین تو وردپرس میشه با Custom Post Type محتوای جدا مثل «پروژهها»، «دورهها» یا «نمونهکارها» درست کرد 💡
اینجا یه نمونه کاملاً واقعی برای ساخت پستتایپ پروژهها هست که از راهنمای رسمی وردپرس الهام گرفته شده:
developer.wordpress.org – Registering Custom Post Types
ایده کلی اینه که تو فایل
functions.php قالب فرزند یا تو یه پلاگین کوچک شخصی، با تابع register_post_type() یه نوع نوشتهی جدید ثبت میکنیم. بعدش تو ادمین وردپرس یه منوی «پروژهها» داری که جدا از نوشتههاست 😍
نمونه کد کامل و قابل استفاده:
<?php
// قرار بدید داخل functions.php قالب فرزند
// یا داخل یک پلاگین اختصاصی
function wpdev_register_projects_cpt() {
$labels = array(
'name' => 'پروژهها',
'singular_name' => 'پروژه',
'add_new' => 'افزودن پروژه جدید',
'add_new_item' => 'افزودن پروژه جدید',
'edit_item' => 'ویرایش پروژه',
'new_item' => 'پروژه جدید',
'view_item' => 'مشاهده پروژه',
'search_items' => 'جستجوی پروژهها',
'not_found' => 'چیزی پیدا نشد',
'not_found_in_trash' => 'در زبالهدان چیزی نیست',
'menu_name' => 'پروژهها',
);
$args = array(
'labels' => $labels,
'public' => true,
'has_archive' => true,
'show_in_rest' => true, // پشتیبانی Gutenberg
'menu_position' => 5,
'menu_icon' => 'dashicons-portfolio',
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' ),
'rewrite' => array( 'slug' => 'projects' ),
);
register_post_type( 'project', $args );
}
add_action( 'init', 'wpdev_register_projects_cpt' );
نکات مهم 👇
• حتماً بعد از اضافهکردن این کد یک بار از منوی تنظیمات → پیوندهای یکتا روی ذخیره کلیک کن تا rewrite درست بشه و 404 نگیری.
• با 'show_in_rest' => true این پستتایپ تو Gutenberg و REST API دیده میشه، یعنی بعداً راحت میتونی بلوک اختصاصی، یا فرانت جدا (مثلاً React) براش بسازی.
• با 'supports' مشخص میکنی پروژهها دقیقاً چه امکاناتی داشته باشن (عنوان، ادیتور، تصویر شاخص و ...).
برای قالببندی فرانت، میتونی یه فایل archive-project.php برای لیست همه پروژهها و یه single-project.php برای صفحه تکی تو پوشه قالب بسازی؛ وردپرس اتوماتیک از این فایلها استفاده میکنه ✨ (این هم تو مستندات قالببندی توضیح داده شده:
Template Hierarchy – Theme Handbook)
این کار هم ساختار سایتت رو تمیزتر میکنه، هم برای سئو و توسعه بعدی خیلی کمک میکنه. از همه مهمتر، دستت از افزونههای سنگین جدا میشه و خودت دقیق میدونی پشت صحنه چی داره اتفاق میافته 🔧
امتحانش کن روی یه سایت تستی و چند تا «پروژه» نمونه بساز، خیلی زود میبینی چقدر مدیریت محتوات راحتتر میشه 🙌
🔖 #Wordpress #وردپرس #WordPress #Custom_Post_Type #CPT #Theme_Development #Plugin_Development #Gutenberg #PHP
👤 Developix
💎 Channel: @DevelopixWordpress3 423
Repost from ابر ویراک
ویراک کلود | تجربهی ابری بدون محدودیت ☁️🚀
🎁 ۲۰٪ شارژ هدیه روی اولین واریزی
مزیتهایی که واقعاً فرق میسازن:
⚡️ پهنای باند 980 مگ
🌐با IP مازاد
⏱️ راهاندازی فوری
💳 پرداخت ساعتی
🛡 پشتیبانی ۲۴/۷
💬 هر سوالی داشتی، تیم ما کنارتـه
✅ مناسب استارتاپها، تیمهای فنی، تا سازمانهای بزرگ
همین الان شروع کن و با حداکثر منابع، سریعتر رشد کن 👇🏻
📞 تماس سریع: 02191555530
🔗 https://virakcloud.com
3 423
Repost from کانال رسمی تک نت | Taknet
سرور اختصاصی تکنت؛ تحویل فوری، بدون قطعی ✅
🔹 پورت اختصاصی واقعی
🔹 آپلود رایگان
🔹 آپتایم 99.99% تضمینی
🔹 ارائه IP مازاد
🔹 پشتیبانی 24/7 (تیکت + آنلاین)
🔹 نصب سریع
🔹 پرداخت ماهیانه
⏳ ظرفیت محدود — همین الان تماس بگیر و سرویس رو رزرو کن:
📞 02191555530
🔗 https://taknet.ir/services/dedicated-server
3 423
🛡️ پاککردن نسخه فایلها از
?ver= بهصورت امن در وردپرس
خیلیوقتها برای بهبود سئو یا کمی تمیزتر شدن URLها، دوست داریم ?ver=... از انتهای فایلهای .css و .js حذف شود. اما اگر این کار اشتباه انجام شود، cache مرورگر بههم میریزد و آپدیتها بهموقع نمیرسند. این یک روش امن و تمیز است که فقط نسخهٔ قابلنمایش در URL را برمیدارد، بدون اینکه سیستم داخلی وردپرس را خراب کند. 🚀
✅ ایده: نسخه را از query string حذف میکنیم، اما handle، وابستگیها و بقیه چیزها دستنخورده میماند.
📌 کد زیر را در functions.php قالب فرزند (child theme) یا در یک پلاگین اختصاصی قرار بدهید:
function mytheme_remove_script_style_version( $src ) {
$parts = explode( '?ver=', $src );
return $parts[0];
}
add_filter( 'style_loader_src', 'mytheme_remove_script_style_version', 10, 1 );
add_filter( 'script_loader_src', 'mytheme_remove_script_style_version', 10, 1 );
🔍 توضیح کوتاه:
- فقط اگر ?ver= در URL باشد، جدا میشود.
- خود فایل، handle و ترتیب لود شدن هنوز طبق wp_enqueue_script و wp_enqueue_style کنترل میشود.
- برای cache-busting واقعی (مثلاً موقع انتشار نسخهٔ جدید)، بهتر است نسخه را در نام فایل بگذارید، مثل app.v2.1.0.css، نه در query string.
⚠️ نکتهٔ مهم:
- اگر از CDN یا پلاگین cache استفاده میشود، بعد از اعمال این کد، حتماً cache را پاک کنید.
- برای فایلهایی که همیشه باید سریعاً آپدیت شوند (مثلاً admin.js در محیط ادمین)، بهتر است ?ver= را نگه دارید و برای admin آن را حذف نکنید.
برای مطالعهٔ بیشتر دربارهٔ enqueue کردن اسکریپت و استایل در وردپرس:
Including CSS & JavaScript — WordPress Developer Resources
🔖 #Wordpress #وردپرس #WordPress #Performance #Speed #Scripts #Styles #functions_php
👤 Developix
💎 Channel: @DevelopixWordpress3 423
Repost from کانال رسمی تک نت | Taknet
🚀 سرور اختصاصی با تنوع منابع برای هر نوع نیاز
⏺پورت اختصاصی
⏺آپلود رایگان
⏺تخفیف پلکانی ترافیک
⏺آپتایم 99.99%
⏺24 ساعت تست رایگان
⏺رائه IP مازاد
⏺پشتیبانی 24/7
⏺تحویل فوری
⏺ارائه سرویس Colocation
⏺بدون قطعی
⏺پرداخت ماهیانه
⏰ تعداد محدود – برای استفاده از این تخفیف ویژه سریع اقدام کن!
برای اطلاعات بیشتر و سفارش، تماس بگیر:
🔺 02191555530
💻 خرید سرور اختصاصی
3 423
الگوی Repository در پروژههای وردپرسی 🧩
یکی از Design Patternهایی که توی پروژههای متوسط و بزرگ وردپرسی خیلی کمک میکند، Repository Pattern است.
ایدهاش ساده است 👇
بهجای اینکه منطق کوئریهای دیتابیس (WP_Query، get_posts، متاها و…) را وسط templateها و functionها پخش کنیم، همهٔ دسترسی به داده (مثلاً نوشتهها، محصولات، سفارشها) را در یک لایهی جدا به اسم Repository نگه میداریم.
🔹 مزیتها برای پروژه وردپرسی
• تمیز شدن کدهای theme و plugin
• قابلتست شدن (Unit Test راحتتر)
• تغییر راحت منبع داده (مثلاً بعداً REST API یا headless)
• جلوگیری از تکرار کوئریهای پیچیده در جاهای مختلف
مثال ساده: PostRepository برای نوشتهها
فرض کنید چند جا در سایت باید «نوشتههای ویژه» را بگیریم. بهجای تکرار WP_Query، یک Repository میسازیم:
class PostRepository {
public function getFeaturedPosts($limit = 5) {
$args = [
'post_type' => 'post',
'posts_per_page' => $limit,
'meta_key' => 'is_featured',
'meta_value' => '1',
];
return get_posts($args);
}
public function getByAuthor($authorId, $limit = 10) {
$args = [
'post_type' => 'post',
'posts_per_page' => $limit,
'author' => $authorId,
];
return get_posts($args);
}
}
حالا در قالب یا plugin، بهجای نوشتن مستقیم WP_Query:
$postRepo = new PostRepository();
$featured = $postRepo->getFeaturedPosts(3);
کد template تمیزتر میشود و منطق دیتابیس در یک جا متمرکز است ✅
کاربرد در Pluginهای جدیتر
برای Custom Post Type مثل product یا course هم میشود ProductRepository، CourseRepository ساخت و همهٔ کوئریهای خاص آن نوع داده را آنجا نوشت. این کار وقتی سایت بزرگ میشود و چند نفر روی آن کار میکنند، جلوی کلی Memory Leak ذهنی و گیجشدن را میگیرد 🙂
چند نکتهٔ تمیزنویسی
• Repository فقط روی «داده» تمرکز کند، نه HTML render
• اسم متدها معنایی باشد: findPublished() بهتر از get1()
• منطق فیلترهای ثابت (مثلاً فقط post_status => 'publish') داخل Repository باشد
برای مطالعهٔ بیشتر درباره Repository Pattern (در معماریهای PHP):
martinfowler.com/eaaCatalog/repository.html
استفاده از این الگو، مخصوصاً در theme و pluginهای تجاری وردپرس، ساختار پروژه را قابلگسترشتر و حرفهایتر میکند. کمکم از پروژههای کوچک شروع شود تا دستتان راه بیفتد 🚀
🔖 #Wordpress #وردپرس #Repository_Pattern #WordPress #PHP #Clean_Code #Design_Patterns
👤 Developix
💎 Channel: @DevelopixWordpress3 423
Clean Architecture در پلاگین و قالبنویسی وردپرس 🧱
یکی از بزرگترین چالشها در توسعهی وردپرس این است که کدها کمکم spaghetti میشوند؛ همهچیز قاطیِ Hook و Template و Query. اینجا جایی است که ایدهی Clean Architecture میتواند کمک بزرگی باشد؛ حتی در یک پلاگین ساده. 💡
در نگاه Clean Architecture، کد را به چند لایهی مستقل تقسیم میکنیم تا:
• وابستگی به WordPress Core کمتر شود 🧩
• تستنویسی سادهتر شود ✅
• قابلیت تغییر UI (قالب، REST API، پنل ادمین) بدون دستزدن به منطق اصلی بیشتر شود 🔁
یک ساختار ساده برای یک پلاگین وردپرسی را ببینید:
my-plugin/
├─ domain/
│ ├─ PostEntity.php
│ └─ PostRepositoryInterface.php
├─ application/
│ └─ CreatePostService.php
├─ infrastructure/
│ └─ WPPostRepository.php
└─ presentation/
└─ CreatePostController.php
🔹 Domain: قوانین بیزنس و Entity ها (بدون وابستگی به وردپرس).
🔹 Application: Use Case ها (مثلاً «ساخت پست جدید»).
🔹 Infrastructure: پیادهسازی واقعی با WordPress (مثل wp_insert_post).
🔹 Presentation: Shortcode، Admin Page، REST Route و…
یک مثال خیلی خلاصه از سرویس ساخت پست:
class CreatePostService {
private $postRepo;
public function __construct(PostRepositoryInterface $postRepo) {
$this->postRepo = $postRepo;
}
public function handle($title, $content) {
if (strlen($title) < 3) {
throw new InvalidArgumentException('Title too short');
}
$post = new PostEntity($title, $content);
return $this->postRepo->save($post);
}
}
اینجا CreatePostService هیچ اطلاعی از WordPress API ندارد؛ فقط با یک PostRepositoryInterface کار میکند. حالا در لایهی زیرساخت، وابستگی به وردپرس را تزریق میکنیم:
class WPPostRepository implements PostRepositoryInterface {
public function save(PostEntity $post) {
return wp_insert_post([
'post_title' => $post->getTitle(),
'post_content' => $post->getContent(),
'post_status' => 'publish'
]);
}
}
مزیت مهم این جداسازی در وردپرس 👇
• راحتتر ریموت کردن لاجیک از داخل فایلهای functions.php و Template ها
• امکان جابجایی از MySQL بومی به یک سرویس خارجی بدون بازنویسی تمام کد
• تست واحد روی Domain و Application بدون نیاز به Bootstrap کامل وردپرس
برای مطالعهی عمیقتر ایدهها، معماری تمیز عموماً به مقالهی عمو باب (Robert C. Martin) برمیگردد:
The Clean Architecture - Uncle Bob
پیادهسازی حتی بخشی کوچک از این ساختار در یک پلاگین یا قالب، بهمرور کد وردپرسی را قابلنگهداریتر، تمیزتر و حرفهایتر میکند. 🚀
🔖 #Wordpress #وردپرس #Clean_Architecture #WordPress #PHP #Plugin_Development #Software_Design
👤 Developix
💎 Channel: @DevelopixWordpress3 423
📌 امروز یک سناریوی کاملاً واقعی سر پروژهها:
میخوای برای «پورتفولیو»، «دورهها» یا «پروژههای مشتریها» یه بخش جدا از Posts داشته باشی، با آدرس و صفحه آرشیو جدا، بدون اینکه همهچیز قاطی نوشتههای وبلاگ بشه. اینجا دقیقاً جای یک Custom Post Type تمیزه.
طبق مستندات رسمی وردپرس:
register_post_type()
میشه این کار رو خیلی شیک داخل یک پلاگین کوچک شخصی انجام داد تا وابسته به Theme نباشه 👌
💡 ایده کار:
۱️⃣ یک پلاگین سبک مثل my-portfolio میسازیم.
۲️⃣ داخلش یک Custom Post Type به اسم
project رجیستر میکنیم.
۳️⃣ برایش URL تمیز، پشتیبانی از Thumbnail و Editor و Category میذاریم.
مثال پایه (کاملاً واقعی و تستشده روی آخرین نسخه وردپرس):
<?php
/**
* Plugin Name: My Portfolio
* Description: Custom Post Type برای پروژهها.
* Version: 1.0.0
* Author: You
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
function myportfolio_register_cpt() {
$labels = array(
'name' => 'Projects',
'singular_name' => 'Project',
'add_new' => 'Add New',
'add_new_item' => 'Add New Project',
'edit_item' => 'Edit Project',
'new_item' => 'New Project',
'view_item' => 'View Project',
'search_items' => 'Search Projects',
'not_found' => 'No projects found',
'menu_name' => 'Projects',
);
$args = array(
'labels' => $labels,
'public' => true,
'has_archive' => true,
'menu_icon' => 'dashicons-portfolio',
'show_in_rest' => true, // پشتیبانی Gutenberg
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' ),
'taxonomies' => array( 'category', 'post_tag' ),
'rewrite' => array( 'slug' => 'projects' ),
);
register_post_type( 'project', $args );
}
add_action( 'init', 'myportfolio_register_cpt' );
🧩 چند نکته کاربردی:
• show_in_rest => true باعث میشه این CPT تو Gutenberg و REST API در دسترس باشه؛ بعداً برای ساخت Gutenberg Block اختصاصی برای پروژهها خیلی به درد میخوره.
• rewrite -> slug رو میشه عوض کرد؛ مثلاً portfolio یا هر چیزی که برای سئوی سایت بهتره.
• بهتره این کد تو پلاگین جدا باشه، نه داخل functions.php، چون با عوض شدن Theme همه پروژهها نمیپرن.
• بعد از فعالکردن پلاگین، یک بار از منوی Settings > Permalinks روی Save کلیک کن تا Rewriteها رفرش بشن و /projects کار کنه.
📚 برای تنظیمات پیشرفتهتر (Capabilities، REST Schema، و...) حتماً این مستند رسمی رو نگاه کن:
Registering Custom Post Types
🔥 این کار پایه خیلی از سایتهای حرفهای وردپرسیه: سایت آموزشی، آژانس، Resume سایت شخصی، فروش خدمات و…
امتحانش روی یک سایت تست واقعاً کمهزینه و فوقالعاده آموزندهست؛ اگر مفید بود، برای بقیه وردپرسیها هم بفرست 😊
🔖 #Wordpress #وردپرس #WordPress #Custom_Post_Type #Plugin_Development #Gutenberg #PHP #ایجاد_پستتایپ #وردپرس
👤 Developix
💎 Channel: @DevelopixWordpress3 423
🔐 قفلکردن ویرایشگر فایل داخل پنل وردپرس
روی سایتهای واقعی، مخصوصاً روی هاست اشتراکی، باز بودن File Editor داخل Appearance → Theme File Editor و Plugins → Plugin File Editor ریسک بزرگی برای امنیت است. اگر اکانت ادمین لو برود، هکر خیلی راحت از همانجا داخل theme یا plugin کد مخرب تزریق میکند.
یک ترفند ساده و استاندارد این است که کل این ویرایشگر را برای همیشه خاموش کنیم و فقط از طریق IDE و SFTP/SSH روی فایلها کار کنیم. ✅
کد پیشنهادی (در wp-config.php)
کافی است این خط را قبل از خط زیر بگذارید:
define( 'DISALLOW_FILE_EDIT', true );
از این به بعد منوی ویرایش فایل در بخش Theme و Plugin کاملاً مخفی میشود و حتی ادمین هم نمیتواند از داخل wp-admin کد را دستکاری کند. هر تغییری روی theme/plugin فقط از روی فایلهای اصلی روی سرور انجام میشود؛ دقیقاً همان روالی که توی تیمهای حرفهای با Git و CI استفاده میشود. 🧑💻
چند نکتهٔ کوچیک ولی مهم
• این تنظیم فقط ویرایشگر داخلی را میبندد؛ نصب/حذف plugin و theme هنوز طبق سطح دسترسی قبلی کار میکند.
• اگر روی سایت مشتری کار میشود، این کار احتمال خرابکاری تصادفی یا عمدی را خیلی کم میکند.
• روی سایتهایی که چند ادمین دارند، این گزینه عملاً یک لایه امنیتی اضافه در برابر تزریق کد و memory leak ناشی از pluginهای دستکاریشده است. 🔒
امتحان روی یک staging یا لوکال، و بعد اعمال روی سایت اصلی، مسیر امن و حرفهای برای پیادهسازی این ترفند است.
📚 مرجع رسمی:
Disable the Plugin and Theme Editor – WordPress Developer Resources
🔖 #Wordpress #وردپرس #WordPress #Security #wp_config #Theme #Plugin #Hardening
👤 Developix
💎 Channel: @DevelopixWordpress3 423
Clean Architecture توی دنیای وردپرس؟ 🤔
خیلیها فکر میکنن Clean Architecture فقط برای پروژههای huge با فریمورکهایی مثل Laravel و Django به درد میخوره، اما توی پلاگیننویسی و توسعه وردپرس هم واقعا نجاتدهندهست ✨
ایده اصلی Clean Architecture چیه؟
بهزبان ساده: جدا کردن منطق کسبوکار از جزئیات فریمورک.
یعنی:
• کد وابسته به WordPress (مثل hook، action، filter) در لایه'ی جدا باشه 🧩
• منطق اصلی (Business Logic) مستقل از وردپرس نوشته بشه ✅
• عوض کردن UI، دیتابیس یا حتی مهاجرت از وردپرس، کمهزینهتر بشه 🔁
یک ساختار ساده برای یک پلاگین وردپرسی
مثلا یک پلاگین تخفیف روی سبد خرید WooCommerce:
my-plugin/ ├─ src/ │ ├─ Domain/ │ │ └─ DiscountCalculator.php │ ├─ Application/ │ │ └─ ApplyCartDiscountService.php │ └─ Infrastructure/ │ └─ WordPressHooks.php └─ my-plugin.phpDomain: منطق خالص، بدون وابستگی به وردپرس
namespace MyPlugin\Domain;
class DiscountCalculator {
public function calculate($subtotal) {
if ($subtotal >= 500000) {
return $subtotal * 0.1; // 10% discount
}
return 0;
}
}
اینجا هیچ خبری از WooCommerce، action، filter و... نیست. فقط قوانین کسبوکار 👌
Application: استفاده از Domain برای سناریوهای واقعی
namespace MyPlugin\Application;
use MyPlugin\Domain\DiscountCalculator;
class ApplyCartDiscountService {
public function __construct(private DiscountCalculator $calculator) {}
public function handle($subtotal) {
return $this->calculator->calculate($subtotal);
}
}
Infrastructure: اتصال به WordPress (Hooks و…)
namespace MyPlugin\Infrastructure;
use MyPlugin\Application\ApplyCartDiscountService;
class WordPressHooks {
public function __construct(private ApplyCartDiscountService $service) {}
public function init() {
add_action('woocommerce_cart_calculate_fees', [$this, 'apply_discount']);
}
public function apply_discount($cart) {
$discount = $this->service->handle($cart->subtotal);
if ($discount > 0) {
$cart->add_fee('Special Discount', -$discount);
}
}
}
چرا این ساختار برای وردپرس جذابه؟
• راحتتر تست واحد (Unit Test) روی منطق تخفیف، بدون نیاز به بوت کردن وردپرس 🧪
• وقتی WooCommerce عوض بشه یا Hook تغییر کنه، فقط لایه Infrastructure دستکاری میشه 🔧
• کد ماژولار، قابلفهمتر و قابلهمکاری برای تیمهای مختلف 🤝
مستندات مرجع برای ایدههای بیشتر:
The Clean Architecture - Uncle Bob
یکبار این مدل جداسازی رو توی یکی از پلاگینهات پیادهسازی کن؛ بعد از چند هفته که برگشتی سر کد، فرقش را کاملا حس میکنی 🚀
🔖 #Wordpress #وردپرس #Clean_Architecture #WordPress #Plugin #PHP #Design_Patterns #Architecture
👤 Developix
💎 Channel: @DevelopixWordpress3 423
تزریق وابستگی (Dependency Injection) یکی از اصول عملی و قابلاعتماد در کدنویسی تمیز و معماری نرمافزار است که خوانایی، تستپذیری و نگهداری کد را در پروژههای وردپرس بهطور چشمگیری بهبود میدهد. ✅
تزریق وابستگی یعنی اینکه یک کلاس مسئول ایجاد وابستگیهایش نباشد؛ وابستگیها از بیرون به آن داده میشود. این روش باعث جدا شدن مسئولیتها و آسان شدن تست واحد میشود. 🧩
کاربرد واقعی در وردپرس: در پلاگینها و تمها بهجای استفاده مستقیم از توابع گلوبال یا کلاسهای سنگین، یک رابط (interface) و پیادهسازی وابسته تعریف کنید و آن را به کلاس سرویس تزریق کنید. این الگو به ویژه در تست کد با PHPUnit و هنگام ایجاد سرویسهای قابل تعویض مفید است.
<?php
interface LoggerInterface {
public function log(string $msg);
}
class FileLogger implements LoggerInterface {
public function log(string $msg) {
file_put_contents(__DIR__ . '/log.txt', $msg . PHP_EOL, FILE_APPEND);
}
}
class PostService {
private $logger;
public function __construct(LoggerInterface $logger) {
$this->logger = $logger;
}
public function create(array $data) {
// منطق ایجاد پست
$this->logger->log('Post created: ' . $data['title']);
}
}
// استفاده در پلاگین
$logger = new FileLogger();
$postService = new PostService($logger);
$postService->create(['title' => 'سلام وردپرس']);
?>
نکات عملی و اشتباهات معمول:
• از کانتینرهای DI سنگین زمانی که نیاز واقعی دارید استفاده شود؛ برای پروژههای کوچک تزریق ساده هم کافی است. ⚖️
• به جای استفاده از کلاسهای استاتیک و توابع گلوبال، از اینترفیسها استفاده کنید تا قابلیت جایگزینی فراهم شود. 🔁
• در تستها میتوان با ایجاد mock یا fake از اینترفیسها، رفتار کلاسها را مستقل تست کرد. 🧪
منابع معتبر: مستندات و نوشتههای Martin Fowler و کتابهای معماری PHP و SOLID راهنمای خوبی هستند — برای مطالعه عمیقتر به https://martinfowler.com/ مراجعه شود. 📚
پیشنهاد عملی: در یکی از سرویسهای پلاگین خود تزریق وابستگی را پیاده کنید و تفاوت خوانایی و تستپذیری را ببینید. موفق باشید و این رویکرد را در پروژههای بعدی هم به کار ببرید! ✨
🔖 #Wordpress #وردپرس #Dependency_Injection #Clean_Code #WordPress #PHP #Architecture
👤 Developix
💎 Channel: @DevelopixWordpress3 423
بهروز کردن CSS یا JS همیشه مشکل زمانی است که مرورگرها نسخهٔ قدیمی را کش میکنند. یک ترفند ساده و مطمئن: از version در
wp_enqueue_style/wp_enqueue_script با filemtime استفاده کنید تا هر بار که فایل تغییر کرد، مرورگر نسخهٔ جدید را بگیرد.
این یعنی هیچ نیاز به اضافهکردن پارامتر دستی نیست و در محیط توسعه هم راحت است. مثال عملی پایین را قرار میدهم:
<?php
function mytheme_enqueue_assets() {
$style_path = get_stylesheet_directory() . '/style.css';
wp_enqueue_style( 'my-style',
get_stylesheet_uri(),
array(),
file_exists( $style_path ) ? filemtime( $style_path ) : wp_get_theme()->get('Version')
);
$script_path = get_template_directory() . '/js/main.js';
wp_enqueue_script( 'my-main',
get_template_directory_uri() . '/js/main.js',
array('jquery'),
file_exists( $script_path ) ? filemtime( $script_path ) : false,
true
);
}
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_assets' );
?>
چرا مفید است: وقتی فایل تغییر کند، timestamp جدید باعث میشود URLِ فایل عملاً تغییر کند و مرورگر کش قدیمی را نگیرد. خطر معمول: اگر از CDN یا فایلهایی خارج از سرور استفاده میکنید، filemtime کار نمیکند؛ در آن حالت از سیستم بیلد/فینگرپرینت یا ورژن دستی استفاده کنید.
نظرتون یا تجربههاتون رو پایین بنویسید، مفید میشه برای بقیه.
مرجع رسمی: WordPress Developer Handbook
🔖 #Wordpress #وردپرس #wordpress #enqueue #cache_busting #performance #وردپرس #css #js
👤 Developix
💎 Channel: @DevelopixWordpress3 423
Repost from احسان خسروی 🌐 تجربیات و نکات سئو آف پیج
سلام به همه همراهان عزیزم در این کانال 👋
📺 فیلم کامل مصاحبه من، سید احسان خسروی، با #مسعود_دامغانی عزیز رو براتون آپلود کردم.
تو این مصاحبه، درباره همه چیز صحبت کردیم؛
💠 از بیوگرافی گرفته تا شرایط زندگی شخصی
💠 از اکوسیستم #سئو، پروژهها، شکستها و موفقیتها
💠 از چالشهای سئو رسانهها و خبرگزاریها تا آپدیتهای الگوریتمی گوگل
امیدوارم تونسته باشم انتقال تجربه خوبی برای دوستانی که تازه اول راه هستند داشته باشم.
📱یوتیوبیهای عزیز، از لینک زیر هم میتونید تماشا کنید؛
https://www.youtube.com/watch?v=02tsWnrVhkA
📱 اینستاگرامیهای عزیز هم میتونند از لینک زیر خلاصه یک دقیقهای رو مشاهده کنید؛
https://instagram.com/ehsankhosravi.seo/
همراه ما باشید.
✈️ @ehsankhosravi_seo (کانال تلگرامی سید احسان خسروی)
#️⃣#Google
#️⃣#SEO
#️⃣ #مصاحبه
#️⃣#گوگل
