آموزش طراحی سایت سئو در وبینیو
74 subscribers
21 photos
2 videos
42 files
39 links
کانال وبینیو | طراحی سایت، سئو، دیجیتال مارکتینگ|
👇👇 گروه جهت پرسش و پاسخ و تبادل اطلاعات 👇👇
گروه : @webinew
کانال بله
https://ble.ir/webinew
Download Telegram
آموزش طراحی سایت سئو در وبینیو
Photo
تبدیل «تومان» به گلیف اختصاصی با فونت IRANYekanX در ووکامرس — بدون افزونه!
تو این آموزش نشون می‌دم چطور واحد پول «تومان» رو به گلیف مخصوص فونت تبدیل کنیم تا دقیقاً مثل پیش‌نمایش‌های ایران‌یکان X دیده بشه.

خلاصه مراحل

فونت IRANYekanX (نسخه کامل وب) رو روی سایت لود کنید.

این اسنیپت رو داخل functions.php چایلد تم بذارید و تعداد حالت‌ها رو با عدد مشخص کنید:
define('WEBINEW_TOMAN_HAMZA_COUNT', 2); // ← فقط این عدد را عوض کن
function webinew_toman_hamzas(){
$n = max(1, (int) WEBINEW_TOMAN_HAMZA_COUNT);
return str_repeat('ء', $n);
}

// نماد «تومان» با تریگر گلیف (ءء...)
add_filter('woocommerce_currency_symbol', function($symbol, $currency){
$hamzas = webinew_toman_hamzas(); // "ءء"
if (strpos($symbol, 'تومان') !== false) {
// هر تعداد "ء" قبلی را به دقیقا n تا تبدیل کن
$symbol = preg_replace('/تومانء*/u', 'تومان' . $hamzas, $symbol);
}
if (in_array($currency, ['IRT','TOMAN'], true)) {
$symbol = 'تومان' . $hamzas;
}
return $symbol;
}, 10, 2);

// فرمت قیمت: «عدد + واحد»
add_filter('woocommerce_price_format', function($format, $currency_pos){
return '%1$s %2$s';
}, 10, 2);

// پوشش خروجی‌های متنی قیمت (اگر جایی "تومان" را مستقیم چاپ کند)
add_filter('woocommerce_get_price_html', function($html){
return preg_replace('/تومان(ء*)/u', 'تومان' . webinew_toman_hamzas(), $html);
}, 10, 1);


(اختیاری) روی نماد ارز، letter-spacing:0 و فیچرهای OpenType رو فعال کنید.

نتیجه
«تومان» به‌صورت خودکار با یک/دو/سه ء به گلیف‌های خوش‌فرم ایران‌یکان X تبدیل می‌شود


اگر می‌خوای همین استایل رو برای فروشگاهت پیاده‌سازی کنم یا یک سایت سریع، سبک و سئو-محور می‌خوای، پیام بده تا صفر تا صد طراحی، توسعه و بهینه‌سازی رو برات انجام بدم.

#طراحی_سایت #ووکامرس #وردپرس #IRANYekanX #ایرانیکانX #فونت_فارسی #تومان #گلیف #OpenType #Woodmart #سئو #وبینیو #طراحی_سایت_مشهد #مشاور_کسب_و_کار #توسعه_وب
معمولا wordcount در اسکیمایی که توسط یاست سئو ایجاد میشه اشتباه هست.
حتما یکبار اسکیما ها رو چک کنید از طریق لینک زیر
https://validator.schema.org/

اگر wordcount مقدارش با تعداد کلمات بلاگ تون کمتر بود با استفاده از کد زیر اصلاح ش کنید.

add_filter('wpseo_schema_article', function( $data, $context ){
$post = get_post( $context->id );
if ( ! $post ) return $data;

$text = wp_strip_all_tags( $post->post_content );
// شمارش ساده بر اساس فاصله برای فارسی
$text = preg_replace('/\s+/u', ' ', trim($text));
$words = $text === '' ? 0 : count( preg_split('/\s/u', $text) );

// اگر کمتر از 50 شد (علامت خطر)، بهتره حذفش کنیم تا ناسازگاری ایجاد نشه
if ( $words >= 50 ) {
$data['wordCount'] = $words;
} else {
unset($data['wordCount']);
}
return $data;
}, 15, 2 );
wp-cerber-9.6.9.zip
2.2 MB
WP Cerber Security, Anti-spam, and Malware Scan 9.6.9
افزونه امنیتی جایگزین مناسب برای وردفنس
wordfence


مزایا
تعداد کوئری کمتر روی صفحات مشابه با سایتی که افزونه وردفنس رو داره.
در ووکامرس اگر بخوایم فقط محصولات تخفیف دار رو در یک لینک نشون بدیم کد زیر راه حل کار هست :

function filter_shop_products_on_sale( $query ) {
if ( ! is_admin() && $query->is_main_query() && is_post_type_archive( 'product' ) && isset( $_GET['onsale'] ) ) {
global $wpdb;

// دریافت محصولات متغیر با تخفیف
$on_sale_variable_ids = $wpdb->get_col( "
SELECT DISTINCT post_parent
FROM {$wpdb->posts} AS p
INNER JOIN {$wpdb->postmeta} AS pm ON p.ID = pm.post_id
WHERE pm.meta_key = '_sale_price'
AND pm.meta_value > 0
AND p.post_type = 'product_variation'
AND p.post_status = 'publish'
" );

// دریافت محصولات ساده با تخفیف
$on_sale_simple_ids = $wpdb->get_col( "
SELECT ID
FROM {$wpdb->posts} AS p
INNER JOIN {$wpdb->postmeta} AS pm ON p.ID = pm.post_id
WHERE pm.meta_key = '_sale_price'
AND pm.meta_value > 0
AND p.post_type = 'product'
AND p.post_status = 'publish'
" );

$on_sale_ids = array_merge( $on_sale_simple_ids, $on_sale_variable_ids );

if ( ! empty( $on_sale_ids ) ) {
$query->set( 'post__in', $on_sale_ids );
} else {
$query->set( 'post__in', array( 0 ) );
}
}
}
add_action( 'pre_get_posts', 'filter_shop_products_on_sale' );


برای فراخونبی محصولات تخفیف خورده کافیه لینک زیر رو بزنی :
https://yoursite.com/shop/?onsale=1

@webinewcom
اگر قصد دارید لوگو برند محصولات رو در کارت محصولات به صورت المنتور نمایش بدید شورتکد زیر چاره کار هست :
/**
* ===================================================================
* Dynamic Tag المنتور برای نمایش لوگو برند
* ===================================================================
*/

/**
* ثبت Dynamic Tag سفارشی برای نمایش لوگو برند محصولات
*
* این Dynamic Tag به شما امکان نمایش لوگوی برند محصولات در المنتور را می‌دهد
*
* نحوه استفاده در المنتور:
* 1. ویجت Image را اضافه کنید
* 2. Image Source > Dynamic را انتخاب کنید
* 3. Brand Logo را از لیست انتخاب کنید
*
* پیش‌نیازها:
* - المنتور Pro نصب باشد
* - برند در تنظیمات وودمارت فعال باشد
* - محصولات دارای برند باشند
*/
add_action('elementor/dynamic_tags/register', function($dynamic_tags_manager) {

/**
* کلاس Dynamic Tag برای نمایش لوگو برند
*/
class Brand_Logo_Dynamic_Tag extends \Elementor\Core\DynamicTags\Data_Tag {

/**
* نام یکتای تگ
*/
public function get_name() {
return 'woodmart-brand-logo';
}

/**
* عنوان نمایشی تگ در المنتور
*/
public function get_title() {
return 'Brand Logo';
}

/**
* گروه تگ (media برای تصاویر)
*/
public function get_group() {
return 'media';
}

/**
* دسته‌بندی تگ (image برای تصاویر)
*/
public function get_categories() {
return [ 'image' ];
}

/**
* ثبت کنترل‌های تگ (در اینجا نیازی نیست)
*/
protected function register_controls() {
// هیچ کنترلی نیاز نیست
}

/**
* دریافت مقدار تگ (لوگوی برند)
*
* @param array $options تنظیمات اضافی
* @return array|string آرایه‌ای شامل id و url تصویر یا رشته خالی
*/
public function get_value(array $options = []) {
global $product;

// دریافت محصول جاری
if (!$product) {
$product = wc_get_product(get_the_ID());
}

if (!$product) {
return '';
}

// استفاده از منطق وودمارت برای دریافت تنظیمات برند
$attr = woodmart_get_opt( 'brands_attribute' );

// بررسی وجود تنظیمات برند
if ( ! $attr && ! taxonomy_exists( 'product_brand' ) ) {
return '';
}

// تعیین نام taxonomy برند
if ( $attr ) {
$attributes = $product->get_attributes();
if ( empty( $attributes[ $attr ] ) ) {
return '';
}
} else {
$attr = 'product_brand';
}

// دریافت برندهای محصول
$brands = wc_get_product_terms( $product->get_id(), $attr, array( 'fields' => 'all' ) );

if ( empty( $brands ) ) {
return '';
}


$brand = $brands[0]; // انتخاب اولین برند

// دریافت تصویر برند مطابق کد وودمارت
$image = get_term_meta( $brand->term_id, 'image', true );

// بررسی thumbnail_id در صورت عدم وجود image
if ( ! $image ) {
$thumbnail_id = get_term_meta( $brand->term_id, 'thumbnail_id', true );
if ( $thumbnail_id ) {
return array(
'id' => $thumbnail_id,
'url' => wp_get_attachment_url( $thumbnail_id )
);
}
}

// بازگرداندن تصویر به فرمت مناسب المنتور
if ( is_array( $image ) && ! empty( $image['id'] ) ) {
return array(
'id' => $image['id'],
'url' => wp_get_attachment_url( $image['id'] )
);
} elseif ( ! is_array( $image ) && $image ) {
return array(
'id' => 0,
'url' => $image
);
}

return '';
}
}

// ثبت تگ در المنتور
$dynamic_tags_manager->register_tag(new Brand_Logo_Dynamic_Tag());
});

/**
* ===================================================================
* شورتکد نمایش لوگو برند
* ===================================================================
*/

/**
* شورتکد برای نمایش لوگوی برند محصولات
*
* این شورتکد لوگوی برند محصول جاری را نمایش می‌دهد
*
* نحوه استفاده:
* [woodmart_brand_logo]
* [woodmart_brand_logo width="100px" height="auto" class="my-brand-logo"]
*
* پارامترهای قابل استفاده:
* - width: عرض تصویر (پیش‌فرض: 80px)
* - height: ارتفاع تصویر (پیش‌فرض: auto)
* - class: کلاس CSS اضافی (پیش‌فرض: brand-logo)
*
* مثال‌های استفاده:
* - در ویجت Shortcode المنتور
* - در محتوای صفحات و نوشته‌ها
* - در فایل‌های قالب با do_shortcode('[woodmart_brand_logo]')
*/
add_shortcode('woodmart_brand_logo', 'woodmart_brand_logo_shortcode');
function woodmart_brand_logo_shortcode($atts) {
global $product;

// دریافت محصول جاری
if (!$product) {
$product = wc_get_product(get_the_ID());
}

if (!$product) {
return '';
}

// تنظیمات پیش‌فرض شورتکد
$atts = shortcode_atts(array(
'width' => '80px', // عرض تصویر
'height' => 'auto', // ارتفاع تصویر
'class' => 'brand-logo' // کلاس CSS
), $atts);

// استفاده از منطق وودمارت برای دریافت برند
$attr = woodmart_get_opt( 'brands_attribute' );

if ( ! $attr && ! taxonomy_exists( 'product_brand' ) ) {
return '';
}

if ( $attr ) {
$attributes = $product->get_attributes();
if ( empty( $attributes[ $attr ] ) ) {
return '';
}
} else {
$attr = 'product_brand';
}

$brands = wc_get_product_terms( $product->get_id(), $attr, array( 'fields' => 'all' ) );

if ( empty( $brands ) ) {
return '';
}

$brand = $brands[0];
$image = get_term_meta( $brand->term_id, 'image', true );
$attrs = '';

// دریافت ابعاد تصویر در صورت وجود image_id
if ( get_term_meta( $brand->term_id, 'image_id', true ) ) {
$data = wp_get_attachment_image_src( get_term_meta( $brand->term_id, 'image_id', true ) );
if ($data) {
$attrs = ' width="' . $data[1] . '" height="' . $data[2] . '"';
}
}

// بررسی thumbnail_id در صورت عدم وجود image
if ( ! $image ) {
$thumbnail_id = get_term_meta( $brand->term_id, 'thumbnail_id', true );
if ( $thumbnail_id ) {
$image = array(
'id' => $thumbnail_id,
);
}
}


$content = '';

// ایجاد HTML تصویر بر اساس نوع داده
if ( is_array( $image ) && ! empty( $image['id'] ) ) {
// استفاده از wp_get_attachment_image برای تصاویر با ID
$content = wp_get_attachment_image(
$image['id'],
'full',
false,
array(
'title' => $brand->name,
'alt' => $brand->name,
'style' => 'width: ' . esc_attr($atts['width']) . '; height: ' . esc_attr($atts['height']) . ';',
'class' => esc_attr($atts['class'])
)
);
} elseif ( ! is_array( $image ) && $image ) {
// ایجاد تگ img برای URL مستقیم
$content = '<img src="' . esc_url( $image ) . '" title="' . esc_attr( $brand->name ) . '" alt="' . esc_attr( $brand->name ) . '" class="' . esc_attr($atts['class']) . '" style="width: ' . esc_attr($atts['width']) . '; height: ' . esc_attr($atts['height']) . ';" ' . $attrs . '>';
}

return $content;
}
دوستانی که اکانت gemini pro رو تو طرح دانشجویی گرفتند میتونن با این ترفند تمدید ش کنن و تا یکسال از این اشتراک استفاده کنند.
https://youtu.be/Awsk-1qfXz4?si=tEWWrX5cq-lFdF1v
یک مطالب مفید از شهرام رهبری عزیز :
کرال باجت؛ جایی که خیلی‌ها اشتباه می‌کنن

▫️بارها توی مشاوره‌هام به پروژه‌هایی برخوردم که کارفرما یا حتی متخصص سئو به بُن‌بست می‌رسن.
چرا؟ چون می‌بینن کلمات اصلی سایت افت کرده ولی در آمار کلی، تغییر محسوسی وجود نداره.

▫️اینجا گوگل میاد یه‌سری از کلمات اصلی رو می‌ندازه پایین و در عوض یه‌سری کلمات جدید (که ورودی کمتری دارن) رو بالا میاره.
چرا؟ چون صفحه‌های اصلی معمولاً ورودی یکتای بالایی دارن و وقتی کرال باجت به حد نصاب می‌رسه، گوگل اون‌ها رو پایین میاره و جاش رو به صفحه‌هایی میده که ورودی کمتری دارن.

▫️این نشونه می‌تونه بگه: حد نصاب کرال باجت سایت پر شده و گوگل نمی‌تونه بیشتر از اون براتون ورودی ایجاد کنه.

▫️ اینجاست که خیلی‌ها اشتباه می‌کنن:
سایت رو می‌دن دست یکی برای مشاوره، هزار تا ایراد می‌گیره، بعد شروع می‌کنن به تغییر تایتل، کم‌وزیاد کردن محتوا، یا دستکاری صفحه‌های اصلی.

🚫 نتیجه؟ هیچ رتبه‌ای برنمی‌گرده!

▫️حتی اگر در مسیر درست باشید و مشکل رو کرال باجت تشخیص بدید، باز هم چندین ماه طول می‌کشه تا دوباره کلمات اصلی به جایگاه قبلی برسن.

▫️ وقتی بحث کرال باجت و بهینه‌سازی نرخ کرال باشه، سه نکته‌ی حیاتی وجود داره:
1. بهینه‌سازی درخواست‌ها به سرور
2. جلوگیری از کرال‌های پرتکرار بی‌فایده، مثلاً صفحاتی که اهمیت ندارن یا عکس‌هایی که گوگل چندبار در روز بی‌دلیل می‌خزه
3. کمپین‌های اصولی در شبکه‌های اجتماعی؛ مقالات رو یک‌دفعه منفجر نکنید، بلکه حداقل یک ماه به‌صورت پیوسته منتشر و بازنشر کنید

🛠 راه‌حل‌ها
▫️رپورتاژ: امن‌ترین و اصولی‌ترین روش هست. دیرتر جواب می‌ده، اما می‌دونید که در نهایت مؤثر خواهد بود.
▫️لینک سایدبار: خیلی زودبازدهه، ولی ریسک بالای جریمه داره و من توصیه نمی‌کنم مگر دقیقاً بدونید دارید چیکار می‌کنید.

⚠️ توصیه مهم
▫️اگر متخصص با تجربه نیستید، تنها چیزی که واقعاً می‌تونم توصیه کنم رپورتاژ هست.
چون بقیه راه‌ها اگر درست اجرا نشن می‌تونن ضربه سنگینی به سایت بزنن و حتی کل دامنه رو در خطر بندازن.

▫️و در نهایت اگر تصمیم گرفتید مشاوره بگیرید، سراغ کسی برید که سایت‌های پر‌بازدید واقعی توی رزومه‌ش داشته باشه، نه صرفاً تئوری.

▫️ تجربه‌ی من میگه: خیلی وقت‌ها مشکل از محتوای شما یا تایتل و دیسکریپشن نیست، بلکه از Crawl Budget هست که مثل نفس کشیدن گوگل برای سایت شماست

Channel: @ShahramRahbari

حالا چجوری این دو مورد رو چک کنید در ادامه کامل میکنم در تکمیل فرمایشات ایشون :
دو عامل اصلی که گوگل میگه روی کرال باجت تأثیر دارن:

Crawl Rate Limit → محدودیت ظرفیت سرور (گوگل نمی‌خواد سرور شما از کار بیفته).

Crawl Demand → میزان ارزش محتوای شما برای ایندکس شدن (میزان محبوبیت و تازگی محتوا).


حالا چجوری تست کنیم ؟
image_2025-09-20_17-01-40.png
94.1 KB
در تصویر میبینید که اون زمان که نمودار نارنجی بالا رفته هاست من نتونسته جواب بده و روی کروال بادجتم تاثیر منفی میذاره


روش بررسی:

Google Search Console → Crawl Stats

مسیر: GSC > Settings > Crawl Stats Report

اونجا می‌تونی ببینی گوگل چه تعداد درخواست در روز/هفته می‌زنه.

سه تا نمودار مهم داره:

Total Crawl Requests (تعداد درخواست‌ها)

Average Response Time (زمان پاسخ سرور)

Host Status (مشکلات سرور)

اگر نمودار Response Time بالا باشه یا Spike (اوج) بزنه → یعنی سرور داره کند جواب می‌ده و کرال باجت محدود میشه.

لاگ سرور (Access Log)

با دسترسی هاست یا cPanel می‌تونی فایل لاگ رو دانلود کنی.

درخواست‌های Googlebot رو فیلتر کن (User-Agent: Googlebot).

اگر می‌بینی توی ساعت‌های خاص حجم زیادی درخواست میاد و Response Code ها 5xx یا 429 هستن → نشونه محدودیت ظرفیت سروره.
copy_zip.php
641 B
برای انتقال یک فایل زیپ از یک سرور به سرور دیگه کافیه کد زیر رو داخل سرور مقصد بذارید و در مرورگر اجراش کنید.

@webinewcom

ادرس مبدا و ادرس مقصد رو در کد قرار بدید.
اگر ادرس ها رو نمیدونید فایل test_path رو در محل مورد نظر اجرا کنید.

#انتقال #فایل #زیپ #ZIP #بکاپ #هاست
1
ما در یک پروژه نیاز داشتیم برای کاربران ای دی کارت صادر کنیم.
با arform ثبت نام کاربران رو انجام دادیم ولی عکس ها در خروجی arform نمایش داده نمیشد که با کد زیر که در فانکشن گذاشتیم و در رپیتور یک باکس متنی خالی قرار دادیم برای ورود url مشکل برطرف شد.

// arform
/**
* ARForms 5.98 – Fill PhotoURL (field 152) with the real file URL per repeater row
* Runs VERY EARLY so ARForms sees the values when saving.
*/

define('ARF_FORM_ID', 102);
define('ARF_REPEAT_PARENT', 144);
define('ARF_FILE_FIELD', 151); // stores attachment IDs
define('ARF_PHOTOURL_FIELD', 152); // your Text/Hidden field inside repeater

function _arf_fill_photourls_early() {
// فقط وقتی همین فرم ارسال شده
if (empty($_POST['is_submit_form_'.ARF_FORM_ID])) {
return;
}

// آرایه آیدی های پیوست در هر ردیف ریپیتر (همون hidden که ARForms می‌سازه)
$files_by_row = isset($_POST['item_meta'][ARF_REPEAT_PARENT][ARF_FILE_FIELD])
? (array) $_POST['item_meta'][ARF_REPEAT_PARENT][ARF_FILE_FIELD] : [];

if (!$files_by_row) {
return;
}

foreach ($files_by_row as $i => $attach_id) {
$attach_id = intval($attach_id);
if ($attach_id <= 0) { continue; }

// URL فایل از روی attachment ID
$url = wp_get_attachment_url($attach_id);
if (!$url) { continue; }

// مقدار را قبل از ذخیره در POST تزریق می‌کنیم تا ARForms همان را ذخیره کند
$_POST['item_meta'][ARF_REPEAT_PARENT][ARF_PHOTOURL_FIELD][$i] = esc_url_raw($url);
}
}

/* خیلی زود اجرا شود تا قبل از پردازش ARForms باشد */
add_action('plugins_loaded', '_arf_fill_photourls_early', 1);
/* پشتیبان در صورت لود ترتیب متفاوت */
add_action('wp', '_arf_fill_photourls_early', 1);
1
اگر در سایت تون از اسکیما ی رنک مث استفاده میکنید و قیمت محصولات به تومان هست میتونید از مشکل عدم نمایش صحیح قیمت در سرپ با کد زیر جلوگیری نمایید.
کد خطا : Invalid ISO 4217 currency code (optional)
#schema #rankmath
#snippet

/* --- جلوگیری از نمایش تومان در اسنیپت گوگل --- */
add_filter( 'woocommerce_get_price_html', function( $price_html ) {
// فقط تومانِ نمایشی را از اسنیپت گوگل پنهان می‌کنیم
$price_html = str_replace(
'<span class="woocommerce-Price-currencySymbol">',
'<span class="woocommerce-Price-currencySymbol" data-nosnippet>',
$price_html
);
return $price_html;
});
یکی از مشکلات دیجیتس اینه که کاربر وقتی لاگین میکنه با موبایل برنمیگرده همون صفحه ای که در اون لاگین کرده . با کد زیر این مشکل برطرف میشه :
#digits #login #my-account #redirect
// برگشت به صفحه ای که بوده در دیجیتس
/**
* Return user to the same page after Digits/WC login by webinew
* Priority: cookie(last page) > request redirect_to (if not my-account) > fallback - Ehsan Ghasimi
*/

/* Save last seen page for guests (avoid login/account pages) */
add_action('init', function () {
if (is_user_logged_in() || is_admin()) return;

$scheme = is_ssl() ? 'https' : 'http';
$url = $scheme . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

if (strpos($url, 'wp-login.php') !== false || preg_match('#/my-account/?($|\?)#', $url)) return;

setcookie('dg_return_to', $url, time() + 1800, '/', '', is_ssl(), false);
}, 5);

/* Helper: pick the correct return url */
function _dg_pick_return_url($current = '') {
$fallback = function_exists('wc_get_page_permalink') ? wc_get_page_permalink('myaccount') : home_url('/');

// 1) If request redirect_to exists and is NOT my-account, honor it
if (!empty($_REQUEST['redirect_to'])) {
$req = esc_url_raw($_REQUEST['redirect_to']);
$path = wp_parse_url($req, PHP_URL_PATH);
if ($path && strpos($path, '/my-account') === false && strpos($path, 'wp-login.php') === false) {
return wp_validate_redirect($req, $fallback);
}
}

// 2) If cookie exists, use it
if (!empty($_COOKIE['dg_return_to'])) {
$ret = esc_url_raw($_COOKIE['dg_return_to']);
if ($ret && strpos($ret, '/my-account') === false && strpos($ret, 'wp-login.php') === false) {
return wp_validate_redirect($ret, $fallback);
}
}

// 3) Else, if current candidate is valid, use it
if ($current && strpos($current, '/my-account') === false && strpos($current, 'wp-login.php') === false) {
return wp_validate_redirect($current, $fallback);
}

return $fallback;
}

/* Fix early when theme/plugin sends ?login=true&redirect_to=/my-account/ */
add_action('init', function () {
if (!is_user_logged_in()
&& isset($_GET['login'])
&& isset($_GET['redirect_to'])
&& preg_match('#/my-account/?$#', (string) $_GET['redirect_to'])
) {
$ref = !empty($_COOKIE['dg_return_to']) ? $_COOKIE['dg_return_to'] : wp_get_raw_referer();
if ($ref && strpos($ref, '/my-account') === false && strpos($ref, 'wp-login.php') === false) {
$_GET['redirect_to'] = $ref;
$_REQUEST['redirect_to'] = $ref;
}
}
}, 6);

/* Enforce destination in Digits hooks */
add_filter('digits_login_redirect', function ($url) {
return _dg_pick_return_url($url);
}, 999);

add_filter('digits_login_user_redirect', function ($url, $user_id) {
return _dg_pick_return_url($url);
}, 999, 2);

/* Enforce destination in WooCommerce login too */
add_filter('woocommerce_login_redirect', function ($redirect, $user) {
return _dg_pick_return_url($redirect);
}, 9999, 2);

/* Neutralize Digits' own WC redirect (if present) */
add_action('init', function () {
if (has_filter('woocommerce_login_redirect', 'digits_wc_login_redirect')) {
remove_filter('woocommerce_login_redirect', 'digits_wc_login_redirect', 10);
}
}, 20);


/* After login, if we land on /?redirect_to=/my-account/, jump to cookie page (your current end-state) */
add_action('template_redirect', function () {
if (is_user_logged_in()
&& isset($_GET['redirect_to'])
&& preg_match('#/my-account/?$#', (string) $_GET['redirect_to'])
&& !empty($_COOKIE['dg_return_to'])
) {
$ret = esc_url_raw($_COOKIE['dg_return_to']);
if ($ret && strpos($ret, '/my-account') === false && strpos($ret, 'wp-login.php') === false) {
// clear cookie to avoid loops, then redirect
setcookie('dg_return_to', '', time() - 3600, '/', '', is_ssl(), false);
wp_safe_redirect( wp_validate_redirect($ret, home_url('/')) );
exit;
}
}
}, 1);
// بازنویسی لینک‌های /my-account تا قبل از کلیک، مقصد را "همین صفحه" کند
add_action('wp_footer', function () {
if (is_user_logged_in() || is_admin()) return; ?>
<script>
(function(){
var here = location.href.split('#')[0];
// لینک‌های رایج به صفحه ورود/اکانت (منو، دکمه، …)
var sels = 'a[href$="/my-account"],a[href$="/my-account/"],a[href*="/my-account?"],a[href*="/my-account/?"]';
document.querySelectorAll(sels).forEach(function(a){
try{
var u = new URL(a.getAttribute('href'), location.origin);
u.searchParams.set('login','true'); // برای باز شدن فرم لاگین
u.searchParams.set('redirect_to', here); // مقصد: همین صفحه
a.setAttribute('href', u.toString());
}catch(e){}
});
})();
</script>
<?php }, 99);
image_2025-10-12_14-15-43.png
95.1 KB
اگر در بخش کروال استیت سرچ کنسول زمان های بالای 1 ثانیه دارید باید یک فکری به حالش بکنید چون کراول بادجت شما رو محدود میکنه. برای این کار کافیه کد زیر رو در مسیر اعلام شده قرار بدید و لاگ ها رو چک کنید ببینید روی کدوم صفحات و چه درخواست هایی سرعت مشکل دارد.
#speed #crawl #seo