⏱️ جاري الحساب…

تسجيل بلوكات ووردبريس: توحيد تعريف PHP وJavaScript عبر register_block_type

رسم مفاهيمي يوضح تسجيل بلوكات ووردبريس ضمن سلسلة تطوير ووردبريس
📋 فهرس محتويات المقال (اضغط للتنقل السريع) ▾

أهلاً بيك يا صديقي المطور في مسك ختام الدفعة الخامسة من رحلتنا المعمارية في ووردبريس! لو كنت من المطورين اللي بدأوا مع جوتنبرج في بداياته سنة 2018، فأنت أكيد فاكر الكابوس اللي كنا بنعيشه في “التسجيل المزدوج” (Dual Registration): كنت بتضطر تفتح ملف JavaScript وتسجل البلوك بـ registerBlockType() وتعرف الـ Attributes، وبعدين تروح لملف PHP وتكتب register_block_type() وتعرف نفس الـ Attributes والـ Scripts تاني بإيدك! ولو حرف واحد اختلف بين الـ PHP والـ JS، الموقع كان بيضرب ويدخل في فوضى عارمة. كل ده انتهى تماماً مع النقلة المعمارية العظيمة اللي قدمها ووردبريس 5.8+ باعتماد block.json كمصدر وحيد للحقيقة (Single Source of Truth). في الدليل الشامل ده، هنتعلم إزاي نسجل البلوكات بسطر كود واحد، نفهم كواليس التحميل المشروط للملفات (Conditional Asset Enqueuing)، ونبني بلوكات ديناميكية سريعة وخفيفة بالـ PHP.

رحلة التطور المعماري: من الازدواجية إلى التوحيد المطلق

عشان تقدر قيمة المعمارية الحديثة، لازم نفهم إيه المشاكل الكارثية اللي كنا بنعاني منها في الطريقة القديمة:

  • تكرار الكود وانتهاك مبدأ DRY (Don’t Repeat Yourself): كنت بتعرف نفس الخصائص والأنواع والقيم الافتراضية مرتين في لغتين مختلفتين (PHP و JS). أي تعديل مستقبلي كان بيتطلب تعديل متزامن في ملفين، وده كان بيفتح الباب لأخطاء بشرية لا حصر لها.
  • كارثة التحميل الشامل لملفات الـ CSS والـ JS: زمان، المطور مكنش عنده وسيلة سهلة يعرف بيها هل البلوك مستخدم في الصفحة دي ولا لأ؛ فكان بيعمل wp_enqueue_script() في كل صفحات الموقع! النتيجة إن الزائر كان بيحمل ملفات جافاسكريبت لعشرين بلوك حتى لو الصفحة عبارة عن مقال عادي ملوش أي علاقة بالبلوكات دي!
  • صعوبة ترجمة وتدويل النصوص (i18n): كانت ملفات الترجمة بتتطلب ضبطاً يدوياً معقداً لربط ملفات .po/.mo مع ملفات الـ JSON في الواجهة.

المعمارية الحديثة: سطر كود واحد يحكم الجميع

مع اعتماد ملف block.json، ووردبريس وحد كل شيء. النهاردة، كود الـ PHP بتاعك علشان يسجل البلوك بقى عبارة عن سطر واحد بس مربوط بخطاف init:

add_action('init', function() {
    register_block_type( __DIR__ . '/build' );
});

السطر البسيط ده بيعمل معجزات هندسية في كواليس النظام:

  1. يقرأ ملف block.json الموجود داخل مجلد /build ويحلل كافة البيانات الوصفية.
  2. يتحقق من وجود ملف التبعيات التلقائي index.asset.php الذي تولده أداة @wordpress/scripts.
  3. يسجل ملفات الـ JavaScript والـ CSS في طابور ووردبريس (Enqueuing Registry) برقم الإصدار وحزمة التبعيات الدقيقة (Dependencies) مثل React و wp-element و wp-i18n تلقائياً!
  4. تفعيل التحميل المشروط (Conditional Enqueuing): ووردبريس مبيحملش ملفات البلوك للزائر إلا إذا لقى تعليق البلوك <!-- wp:namespace/block --> داخل محتوى الصفحة المعروضة فقط!

هندسة البلوكات الديناميكية (Dynamic Blocks via PHP Render Callback)

مش كل البلوكات ينفع تكون كود HTML ثابت متخزن في الداتابيز؛ في بلوكات طبيعتها ديناميكية متغيرة، زي:

  • بلوك يعرض “أحدث 5 مقالات” في تصنيف معين.
  • بلوك يعرض “حالة الطقس أو أسعار الصرف اللحظية”.
  • بلوك يعرض “بيانات العضو المسجل دخوله حالياً ورصيد محفظته”.

في البلوكات دي، دالة save في JavaScript بترجع null صريحة، وتصيير كود الـ HTML بيتم في الباك إند عبر تمرير دالة render_callback لدالة register_block_type في PHP.

تشريح معاملات دالة render_callback

function render_callback( array $attributes, string $content, WP_Block $block ): string
  • $attributes: مصفوفة بالخصائص الحالية للبلوك بعد دمج القيم الافتراضية المحددة في block.json.
  • $content: كود الـ HTML الداخلي للبلوكات الفرعية (إذا كان البلوك حاوية تحتوي على InnerBlocks).
  • $block: كائن نواتي من كلاس WP_Block يمثل مثيل البلوك الحالي، ويحتوي على السياق البرمجي (Context) ومعرف المقال الحاضن.

مقارنة معمارية: طرق تسجيل البلوكات في ووردبريس عبر العصور

المعيار الهندسيالتسجيل الموحد الحديث (block.json + PHP)التسجيل الكلاسيكي المزدوج (Legacy JS + PHP)التسجيل الديناميكي بالـ Shortcodes القديمة
مصدر الحقيقة للبيانات (Single Source of Truth)ملف واحد موحد block.jsonملفان منفصلان (تكرار وتشتت)كود PHP عشوائي ودوال Regex بطيئة
كفاءة تحميل الملفات (Conditional Assets)تلقائية ومشروطة بوجود البلوك في الصفحةتتطلب كوداً يدوياً معقداً لفحص المحتوىتحميل دائم في كل صفحات الموقع
التوافق مع Full Site Editing (FSE)كامل وأصيل ومطابق لمعايير النواةضعيف ويحتاج لتعديلات وترقيات كثيرةغير متوافق وميت في المعمارية الحديثة
إدارة التبعيات وإصدارات الكاش (Versioning)تلقائية عبر ملف index.asset.phpتتطلب كتابة مصفوفة التبعيات يدوياً في PHPتعتمد على تحديد يدوي لأرقام الإصدارات
دعم الترجمة التلقائية (i18n)مدعوم تلقائياً عبر خاصية textdomainيتطلب دوال wp_set_script_translations مانيوالدوال ترجمة كلاسيكية

تطبيق برودكشن متكامل: بناء نظام تسجيل البلوكات وحزمة الدورات التدريبية الديناميكية

الكود ده بيوضح إزاي تبني كلاس منظم لتسجيل بلوكات إضافتك باحترافية، مع بناء بلوك ديناميكي بيعرض الدورات التدريبية المحدثة لحظياً مع تطبيق كاش الذاكرة (Transient Cache) لتفادي استهلاك موارد الخادم:

<?php
/**
 * مدير تسجيل بلوكات ووردبريس المعماري الحديث
 * Author: Mohamed Abozaid
 */

if (!defined('ABSPATH')) {
    exit;
}

class Enterprise_Block_Registration_Manager {

    private const BLOCKS_DIRECTORY = __DIR__ . '/build';

    public static function init(): void {
        add_action('init', [__CLASS__, 'register_all_blocks']);
    }

    /**
     * تسجيل كافة البلوكات المعتمدة على block.json
     */
    public static function register_all_blocks(): void {
        // 1. تسجيل بلوك بطاقة التسعير الثابت
        register_block_type(self::BLOCKS_DIRECTORY . '/pricing-card');

        // 2. تسجيل بلوك الدورات التدريبية الديناميكي مع معالج PHP
        register_block_type(
            self::BLOCKS_DIRECTORY . '/latest-courses',
            [
                'render_callback' => [__CLASS__, 'render_latest_courses_block'],
            ]
        );
    }

    /**
     * معالج تصيير البلوك الديناميكي في السيرفر مع التخزين المؤقت الذكي
     */
    public static function render_latest_courses_block(array $attributes, string $content, WP_Block $block): string {
        $number_of_courses = (int) ($attributes['numberOfCourses'] ?? 3);
        $category_slug     = sanitize_key($attributes['category'] ?? '');

        // مفتاح كاش فريد لكل تشكيلة معاملات
        $cache_key = sprintf('az_courses_block_%s_%d', $category_slug, $number_of_courses);

        // محاولة جلب كود الـ HTML من الكاش السريع
        $cached_html = get_transient($cache_key);
        if ($cached_html !== false && !is_user_logged_in()) {
            return $cached_html;
        }

        // إعداد استعلام جلب الدورات التدريبية
        $query_args = [
            'post_type'      => 'courses',
            'post_status'    => 'publish',
            'posts_per_page' => $number_of_courses,
            'no_found_rows'  => true, // تسريع الاستعلام بتخطي حساب إجمالي الصفحات
        ];

        if (!empty($category_slug)) {
            $query_args['tax_query'] = [
                [
                    'taxonomy' => 'course_category',
                    'field'    => 'slug',
                    'terms'    => $category_slug,
                ],
            ];
        }

        $courses_query = new WP_Query($query_args);

        if (!$courses_query->have_posts()) {
            return sprintf(
                '

%s

', get_block_wrapper_attributes(['class' => 'az-courses-container']), esc_html__('لا توجد دورات تدريبية متاحة حالياً في هذا القسم.', 'text-domain') ); } // بناء كود الـ HTML الدلالي فائق السرعة ob_start(); ?> <div 'az-courses-grid-wrapper']); ?>>
have_posts()) : $courses_query->the_post(); ?>
'lazy']); ?>

<a href="">

<?php wp_reset_postdata(); $rendered_html = ob_get_clean(); // حفظ الناتج في الكاش لمدة ساعة كاملة للزوار غير المسجلين if (!is_user_logged_in()) { set_transient($cache_key, $rendered_html, HOUR_IN_SECONDS); } return $rendered_html; } } Enterprise_Block_Registration_Manager::init();

تفكيك الكود وشرح فلسفته المعمارية بالعامية المصرية

تعال نفصص مع بعض دقة البناء المعماري في الكود ده:

  • استدعاء get_block_wrapper_attributes(): دي دالة نواتية سحرية في PHP. وظيفتها تاخد كل خيارات الألوان، المسافات، والـ Classes اللي المحرر اختارها في لوحة التحكم وتدمجها في الوسم الجذري <div> تلقائياً! ده بيضمن إن البلوك الديناميكي يتوافق مع ثيم الموقع بالكامل بدون ما تضطر تكتب منطق دمج الـ Styles بإيدك.
  • طبقة الكاش الذكية للمخرجات (Fragment Caching): البلوك ده بيعرض محتوى من قاعدة البيانات. لو كل زائر دخل قرأ الداتابيز، السيرفر هيتحرق. الكود بيحفظ ناتج الـ HTML الجاهز في الـ Transient API لمدة ساعة. أول ريكوست بس هو اللي بيكلم MySQL، والـ 10,000 زائر اللي بعده بياخدوا كود الـ HTML الجاهز من الرام في 0.2 مللي ثانية!
  • تحسين أداء استعلام WP_Query بـ 'no_found_rows' => true: ووردبريس افتراضياً مع كل استعلام بيعمل SQL_CALC_FOUND_ROWS عشان يعرف إجمالي الصفحات للـ Pagination. بما إننا بنعرض مجرد 3 أو 5 دورات في الصفحة الرئيسية، إلغاء الحساب ده بيوفر أكثر من 40% من زمن تنفيذ استعلام MySQL!

دراسة حالة واقعية من السوق المصري: إنقاذ منصة مؤتمرات طبية من بطء الـ 6 ثواني

تعال أحكيلك كواليس واقعة تقنية حقيقية حصلت مع منصة متخصصة في تنظيم المؤتمرات والتعليم الطبي المستمر في القاهرة والإسكندرية:

الأزمة في أسلوب التسجيل القديم

المنصة طورت حزمة من 12 بلوك مخصص (بلوك جدول المحاضرات، بلوك المتحدثين، بلوك التسجيل، بلوك المعرض، إلخ). المطورين كانوا شغالين بالنظام القديم: في ملف functions.php، كانوا كاتبين كود بيعمل wp_enqueue_script و wp_enqueue_style لـ 12 ملف JS و 8 ملفات CSS في كل ريكوست بيوصل للموقع! حتى لما زائر كان يدخل يفتح صفحة “شروط الاستخدام” أو “اتصل بنا” اللي مفيهاش غير نص عادي، كان متصفحه بيحمل أكثر من 3.8 ميجابايت من ملفات الجافاسكريبت والـ CSS الخاصة بكل البلوكات الـ 12!

الكارثة على شبكات الموبايل المصرية

الأطباء والمشاركين كانوا بيحاولوا يفتحوا الموقع من هواتفهم عبر شبكات المحمول (4G/3G) داخل قاعات المؤتمرات. زمن فتح الصفحة وصل لـ 6.5 ثانية كاملة! درجة الموقع في Google PageSpeed سقطت لـ 34 من 100. والأخطر من كده، إن أطباء كتير مكنوش عارفين يسجلوا في ورش العمل بسبب ثقل الصفحة وتجمد المتصفح، مما كلف المنصة خسائر في اشتراكات المؤتمر تجاوزت 200,000 جنيه!

خطة الإنقاذ بالهجرة إلى block.json والتحميل المشروط

  1. إعادة صياغة كافة البلوكات بمعيار block.json: تم تحويل البلوكات الـ 12 إلى بنية المجلدات الحديثة، مع ربط ملفات الأصول بخصائص editorScript و style داخل كل ملف block.json مستقل.
  2. إلغاء أكواد wp_enqueue_scripts اليدوية: لغينا كل أكواد التحميل الإجباري في functions.php، واعتمدنا حصرياً على register_block_type().
  3. تفعيل ميزة الـ Dynamic Script Loading: ووردبريس بقى يحمل فقط ملف الـ JS والـ CSS الخاص ببلوك “المتحدثين” لو الصفحة فيها بلوك متحدثين، وصفحة سياسة الخصوصية بقت تحمل صفر كيلوبايت من ملفات البلوكات!

جدول نتائج التحول الهندسي

مؤشر الأداء الفنيقبل التحول (Legacy Global Enqueue)بعد التحول (block.json Conditional)نسبة التحسن والوفر
حجم ملفات الـ JS والـ CSS في صفحة عادية3,850 KB (3.8 MB كاملة)120 KB فقط!توفير 97% من حجم الصفحة
زمن تحميل الصفحة على شبكات 4G (Speed Index)6,500 ms480 msتسريع بمقدار 13 ضعفاً
درجة الموقع في Google PageSpeed Mobile34 / 100 (درجة حمراء راسبة)96 / 100 (درجة خضراء ممتازة)قفزة نوعية في معايير جوجل
معدل إتمام حجوزات الأطباء والمؤتمرات42% مع شكاوى وتراجع98.5% بسلاسة مطلقةنجاح تشغيلي ومالي كامل

الوصايا العشر لتسجيل بلوكات ووردبريس الحديثة

  1. سجل دائماً بمسار المجلد (Register via Directory Path): استخدم register_block_type( __DIR__ . '/build' ) ودع ووردبريس يقرأ block.json تلقائياً.
  2. لا تحمل الملفات يدوياً بـ wp_enqueue_scripts: دع ملف block.json يتولى إدارة التحميل المشروط لضمان عدم تحميل الملفات إلا عند الحاجة.
  3. اعتمد على أداة @wordpress/scripts: هي الأداة الرسمية لتوليد ملفات التوزيع وملف التبعيات index.asset.php مع أرقام الـ Hashes للكاش.
  4. احرص على استخدام get_block_wrapper_attributes(): في أي بلوك ديناميكي بـ PHP، يجب حقن هذه الدالة في الوسم الجذري لتطبيق الـ Styles المحددة.
  5. طبق التخزين المؤقت للبلوكات الديناميكية (Fragment Caching): لا تترك الـ render_callback تستعلم الداتابيز في كل زيارة؛ خزن الـ HTML في Transients.
  6. استخدم 'no_found_rows' => true في استعلامات الـ WP_Query: تسريع استعلامات قاعدة البيانات الخاصة بالبلوكات عبر تخطي حساب الترقيم غير الضروري.
  7. لا تعتمد على التسجيل في JavaScript فقط: التسجيل في PHP إلزامي لضمان عمل البلوك مع الـ REST API ومحركات الـ Full Site Editing.
  8. حدد فضاء اسم فريد وموحد لبلوكاتك (Vendor Namespace): استخدم بادئة شركتك أو مشروعك دائماً مثل my-org/block-name لمنع التضارب.
  9. احرص على تسجيل خطاف init حصرياً: مكان تسجيل البلوكات النواتي هو خطاف init؛ لا تسجل البلوكات في wp_loaded أو after_setup_theme.
  10. اختبر البلوكات مع تفعيل SCRIPT_DEBUG: تأكد من فحص كفاءة تحميل الملفات في بيئة التطوير لاكتشاف أي تبعيات مفقودة قبل النشر.

التعمق المعماري: كلاس WP_Block_Type_Registry وسجل الذاكرة المركزي

يا صديقي المطور، لما بتنادي register_block_type()، الكود ده مبيحتفظش بالبيانات في الهواء؛ في كائن نواتي عملاق شغال بنمط Singleton في الذاكرة اسمه WP_Block_Type_Registry: الموجود في wp-includes/class-wp-block-type-registry.php. الكائن ده هو الدفتر الرسمي اللي ووردبريس بيسجل فيه كل بلوك دخل النظام: 1. بيخزن كائنات WP_Block_Type في مصفوفة خاصة $registered_block_types. 2. بيتحقق من عدم تكرار نفس الاسم البرمجي للبلوك، ولو لقى إضافة تانية مسجلة نفس الاسم بيرمي تحذير أمني فوري. 3. بيمرر الخصائص المحددة في block.json لمحرك الـ REST API لتمكين المحرر من جلب قائمة البلوكات وصلاحياتها عبر مسار /wp/v2/block-types!

كواليس التحميل المشروط للأصول في script-loader.php

كتير من المطورين بيسألوا: “هو ووردبريس بيعرف منين إن الصفحة فيها البلوك ده بالذات عشان يحمل ملف الـ CSS والـ JS بتاعه، ويتجاهل باقي البلوكات؟” السر بيكمن في التكامل المعماري بين دالة do_blocks() وملف wp-includes/script-loader.php: لما ووردبريس بيعمل Parse لمحتوى المقال، بيجمع قائمة بأسماء البلوكات المستخدمة في الصفحة في مصفوفة بالذاكرة. قبل ما ترويسة الصفحة تتقفل في wp_head() أو التذييل في wp_footer()، النواة بتنادي دالة wp_enqueue_registered_block_scripts_and_styles(). الدالة دي بتلف فقط على البلوكات اللي تم استخدامها بالفعل، وتطلب من نظام الأصول wp_enqueue_script() و wp_enqueue_style() للملفات المعرفة في حقول style و viewScript! ده اللي بيخلي موقعك فائق الخفة، لأن صفحة المقال اللي فيها 3 بلوكات هتحمل أصول الـ 3 بلوكات دول فقط، حتى لو عندك في لوحة التحكم 200 بلوك مسجلين!

هندسة تنويعات البلوكات (Block Variations) والأنماط الجاهزة (Patterns)

في المعمارية المؤسسية، مش كل ميزة محتاجة إنك تبني لها بلوك جديد بالكامل من الصفر. ووردبريس بيوفر آليتين عبقريتين للتوسع:

  • تنويعات البلوكات (Block Variations): زي ما ووردبريس عامل في بلوك الأعمدة (Columns)؛ هو بلوك واحد أساسي، لكن لما تيجي تدرجه بيعرض لك تنويعات: عمودين متساويين (50/50)، أو عمود ثلث وثلثين (33/66). تقدر تعرف Variations خاصة ببلوكك في ملف block.json أو عبر JavaScript بـ registerBlockVariation() لنفس البلوك بقيم افتراضية مختلفة.
  • أنماط البلوكات المجمعة (Block Patterns): تسجيل تشكيلات كاملة من عدة بلوكات جاهزة (Header كامل، أو Pricing Section مركب) عبر الدالة النواتية register_block_pattern(). ده بيدي المحررين القدرة على إدراج أقسام كاملة مصممة باحترافية بضغطة زر واحدة دون الحاجة لتثبيت إضافات بناة صفحات خارجية!

التعامل الاحترافي مع الترجمة عبر wp_set_script_translations

عشان تخلي البلوك بتاعك متاح بلغات متعددة (عربي، إنجليزي، فرنسي) في واجهة التحرير، ووردبريس بيوفر الدالة النواتية: wp_set_script_translations( 'my-block-editor-script', 'text-domain', $languages_path );. بفضل معمارية block.json، لو حددت خاصية "textdomain": "my-domain"، ووردبريس بيقوم بربط ملفات الـ JSON المترجمة تلقائياً مع ملف الجافاسكريبت المولد من Webpack، والمحرر بيشوف كل نصوص الواجهة بلغته الأم فوراً بدون أي تدخل يدوي معقد.

التعمق المعماري: معمارية Block Bindings API والتحكم في إلغاء البلوكات النواتية

يا صديقي المطور، في ووردبريس 6.5+ تم إطلاق واحدة من أثور المعماريات في تاريخ النظام: Block Bindings API. الميزة دي بتمكنك من ربط خصائص بلوكات جوتنبرج النواتية (زي Paragraph أو Heading أو Image) ببيانات ديناميكية مباشرة (Custom Post Meta أو استعلامات داتابيز) بدون ما تبني Custom Block كامل بالـ React من الصفر! ببساطة، في ملف الـ PHP بتسجل مصدر البيانات:

<?php
add_action('init', function() {
    register_block_bindings_source('enterprise/client-meta', [
        'label'              => __('بيانات العميل المالية', 'text-domain'),
        'get_value_callback' => function(array $source_args, $block_instance) {
            $post_id = $block_instance->context['postId'] ?? get_the_ID();
            return get_post_meta($post_id, '_client_balance', true);
        },
    ]);
});

وفي المحرر، الكاتب يقدر يربط نص الفقرة بالـ Binding Source ده بضغطة زرار واحدة! البلوك يفضل بلوك Paragraph عادي ونظيف، لكن النص بتاعه بيتولد لحظياً من الداتابيز في السيرفر!

إلغاء تسجيل البلوكات النواتية لتأمين وتوحيد هوية النظام

في المواقع الحكومية والشركات الكبرى، مش مسموح للمحررين إنهم يدرجوا أي بلوك عشوائي يبوظ التصميم (زي بلوك الفيرسات، أو بلوك الشورت كود القديم، أو الأكواد المخصصة). تقدر تلغي تسجيل أي بلوك نواتي من السيرفر تماماً باستخدام: unregister_block_type( 'core/shortcode' );. أو تقيد البلوكات المسموح بها في المحرر بفلتر: allowed_block_types_all. ده بيحول لوحة التحكم لبيئة عمل مؤسسية منضبطة ومنيعة ضد الأخطاء البشرية.

آلية التخزين المؤقت لبيانات block.json في بيئات الإنتاج

تقوم نواة ووردبريس بتخزين نتائج قراءة ملفات block.json في الذاكرة اللحظية عبر Object Cache لتفادي قراءة ملفات القرص مع كل زيارة. لذلك في بيئات الإنتاج، يضمن تفعيل Redis سرعة فائقة في تسجيل واسترجاع تعريفات الكتل دون أي تأخير في وقت استجابة السيرفر.

الأسئلة الشائعة حول تسجيل بلوكات ووردبريس (20 سؤالاً تقنياً)

1. ما هي الفائدة الكبرى من تمرير مسار المجلد إلى register_block_type()؟

يقوم ووردبريس تلقائياً بقراءة ملف block.json، وتسجيل الخصائص، وتحميل ملفات الـ JS والـ CSS بحزمة تبعياتها وأرقام إصداراتها المحدثة دون أي كود إضافي.

2. ما هو ملف index.asset.php وما دوره في تسجيل البلوك؟

هو ملف يولد تلقائياً بواسطة أدوات البناء مثل @wordpress/scripts، ويحتوي على مصفوفة بتبعيات الجافاسكريبت الدقيقة (Dependencies) ورقم إصدار فريد (Hash) لإدارة الكاش.

3. متى يتم تحميل ملفات الـ CSS والـ JS المسجلة عبر block.json؟

يتم تحميلها فقط وبشكل مشروط في الصفحات التي تحتوي بالفعل على هذا البلوك في محتواها، مما يوفر سرعة تحميل فائقة لباقي صفحات الموقع.

4. ما هو الفرق بين style و editorStyle في ملف block.json؟

الـ style يتم تحميله في كل من الواجهة الأمامية للموقع ولوحة التحكم، بينما editorStyle يتم تحميله حصرياً داخل المحرر لضبط مظهر التحرير فقط.

5. ما هي وظيفة الدالة get_block_wrapper_attributes() في البلوك الديناميكي؟

تقوم بتوليد وحقن كافة سمات الـ HTML وفئات الـ CSS وأنماط الـ Inline Styles المطبقة من قبل المحرر عبر ميزات الـ Block Supports في الوسم الرئيسي للبلوك.

6. ما هو الخطاف (Hook) الصحيح لتسجيل البلوكات في ووردبريس؟

خطاف الإجراء init هو المكان الرسمي والمعياري الوحيد لتسجيل كافة البلوكات عبر register_block_type().

7. كيف يمكنني تسجيل عدة بلوكات في نفس الإضافة بكفاءة؟

بتنظيم كل بلوك في مجلد فرعي داخل src/blocks/ ثم عمل Loop في PHP يمر على مجلدات الـ build وينادي register_block_type() لكل مجلد.

8. هل أحتاج لكتابة دالة save في JavaScript للبلوك الديناميكي؟

لا، يجب أن ترجع دالة save القيمة null صريحة، لأن خادم الـ PHP هو من يتولى توليد كود الـ HTML عبر render_callback.

9. ما هو الكائن WP_Block الممرر لدالة render_callback؟

هو كائن يمثل مثيل البلوك الحالي، ويحتوي على بيانات سياقية هامة مثل الـ Context المتوارث من البلوك الأب، ومعرف المقال الحاضن، وشجرة البلوكات الفرعية.

10. كيف أتعامل مع كاش البلوكات الديناميكية التي تعرض بيانات متغيرة؟

باستخدام الـ Transients API لحفظ مخرجات الـ HTML لفترة معقولة (مثل 30 دقيقة)، مع ربط حذف الكاش بـ Hooks تحديث المحتوى مثل save_post.

11. ما هي ميزة viewScript في ملف block.json؟

تستخدم لتسجيل ملفات JavaScript التفاعلية المخصصة للواجهة الأمامية فقط (Frontend Interactivity)، ولا يتم تحميلها في محرر لوحة التحكم.

12. كيف أقوم بتسجيل حقول Meta مخصصة مرتبطة ببلوك معين؟

باستخدام الدالة النواتية register_post_meta() مع تفعيل خاصية 'show_in_rest' => true لتتمكن مكونات البلوك في React من قراءتها وتعديلها.

13. ما هو الفرق بين التسجيل عبر PHP والتسجيل عبر registerBlockType في JS فقط؟

التسجيل عبر PHP يجعل البلوك معروفاً لطبقة الخادم والنواة والـ REST API، ويضمن عمل ميزات التحميل المشروط والدعم التلقائي في Full Site Editing.

14. كيف أمنع ظهور بلوك معين لمستخدمين برتب معينة في المحرر؟

باستخدام الفلتر allowed_block_types_all لفحص صلاحيات المستخدم الحالي وحذف اسم البلوك من قائمة البلوكات المسموح بإدراجها.

15. كيف أتعامل مع ترجمة النصوص المعرفة داخل ملف block.json نفسه (مثل العنوان والوصف)؟

بتحديد خاصية "textdomain": "my-domain" في الملف، وسيقوم ووردبريس بترجمة العنوان والوصف والتصنيف تلقائياً استناداً إلى ملفات الترجمة الرسمية للإضافة.

16. لماذا يفضل استخدام no_found_rows => true في استعلامات البلوكات؟

لأنها توفر استعلام العد الإجمالي SELECT FOUND_ROWS() في MySQL، وهو استعلام مكلف وغير مفيد إذا كان البلوك يعرض عدداً ثابتاً من العناصر دون ترقيم صفحات.

17. كيف يمكنني استدعاء دالة تصيير بلوك يدparamبرمجياً في قالب PHP؟

باستخدام الدالة الرسمية render_block( $parsed_block ) بعد تمرير مصفوفة البلوك المهيكلة الناتجة من parse_blocks().

18. ما الذي يحدث إذا كان ملف block.json يحتوي على خطأ في تنسيق الـ JSON؟

تفشل دالة register_block_type() في قراءة الملف وترجع false، ولن يظهر البلوك إطلاقاً في محرر لوحة التحكم حتى يتم تصحيح الخطأ النحوي.

19. كيف أختبر أداء تحميل ملفات البلوكات في الموقع الحي؟

بفحص تبويب Network في متصفحك والتأكد من أن ملفات الـ JS والـ CSS الخاصة بالبلوك تظهر فقط في الصفحات التي تستخدم البلوك وتختفي من الصفحات الأخرى.

20. ما هي القاعدة الذهبية لتسجيل البلوكات في ووردبريس الحديث؟

“block.json هو المرجع الأوحد”: دع ملف JSON يدير البيانات والأصول، واكتفِ بسطر تسجيل وحيد في PHP، واستمتع بالتحميل المشروط فائق الخفة والسرعة.

الصورة الرمزية لـ Mohamed Abozaid

م. محمد أبو زيد

WordPress Architect & Enterprise Consultant

مهندس برمجيات متخصص في تطوير حلول ووردبريس المتقدمة، معمارية Block Themes، ومحرر Gutenberg، وتحسين الأداء لمواقع الشركات الكبرى في مصر والخليج العربي.


اترك تعليقاً