اذهب إلى المحتوى

كيفية إنشاء مقتطف من منشور وضبطه بعدد الأحرف في ووردبريس


Ali Alrohia

هناك نوعان من النصوص المرتبطة بمنشورات ووردبريس، حيث يتضمن النوع الأول مقتطفًا والثاني لا يتضمن، ويُضاف المُقتطف ضمن حقلٍ خاصٍ به أو يُولده ووردبريس باستخدام الجزء الأول من المحتوى.

سيُركز هذا المقال على المنشورات التي لا تمتلك مقتطفًا وكيفية التحكم بطول هذا المُقتطف، حيث يُفضل ملء المُقتطف بكلماتك الخاصة دائمًا للتحكم به كليًا، وهذا مُمكن باستخدام حقل المقتطف ضمن محرّر ووردبريس التقليدي.

الحاجة إلى مقتطف بطول ثابت من المحارف

تعرض العديد من الصفحات الرئيسية للمواقع الإلكترونية قائمةً بالمنشورات، حيث يظهر لكل منشورٍ العنوان والمقتطف الخاص به، وغالبًا تكون هذه القائمة على شكل شبكة، بحيث يُشكّل كل منشور جزءًا من صف، وهنا تكون مساحة كل منشورٍ مُحددةً بعرض وارتفاع معين، ولذلك يجب أن يكون طول المقتطف واحدًا لجميع المنشورات لتكون متحاذيةً أفقيًا وعموديًا.

يمتلك ووردبريس دالةً مفيدةً هي the_excerpt()‎ تعرض مُقتطفًا للمنشور، حيث تعمل هذه الدالة بذكاء، فهي تتأكد أولًا مما إذا كان المنشور يتضمن مقتطفًا لعرضه، وفي حال عدم تضمنه فستستخرجُ أول بضع كلماتٍ من محتوى المنشور لتحل محل المُقتطف، والطول الافتراضي للمُقتطف هو 55 كلمة، ويُمكن تغيير هذا الطول باستخدام مُرشح excerpt_length.

يمكن من الناحية النظرية استخدام الدالة the_excerpt()‎ لتحديد طول المٌقتطف، ولكن تبين بعد التجربة أنها غير كافية لأنّ الكلمات وحدة قياسٍ غير دقيقة، فهي تتفاوت بالطول ولا بد من دقةٍ أكبر في تحديد الطول، ولذلك يجب استخدام المحارف كما تُدعى في لغة البرمجة أو الحروف في لغتنا العربية لتعيين طول المقتطف.

يشرح هذا المقال دالةً تستخدم محتوى المنشور (وليس المُقتطف) من أجل استخراج العدد المرغوب من المحارف، حيث سيتناول جميع أجزاء هذه الدالة بما فيها من مكونات، مع الانتباه إلى أنّ عملية استخراج المحارف ليست عملية تعدادٍ للمحارف فقط، إذ يُمكن أن يتضمن محتوى المنشور عناصر أخرى ضمنه مثل وسوم HTML أو صورًا أو أكوادًا قصيرة، ويجب الأخذ بالحسبان عند عدّ المحارف تلك المحارف المكتوبة بشيفرة مغايرة لشيفرة ASCII مثل ترميز UTF-8.

إزالة الوسوم والأكواد القصيرة الأسطر والفراغات

يجب إزالة جميع وسوم HTML بالخطوة الأولى، وهذا سوف يؤدي إلى إزالة وسم img ووسم التعليق، لذلك سوف تكون التعليمة الأولى في الدالة هي:

$content = strip_tags($content);

أصبح المحتوى الآن خاليًا من وسوم HTML، ولكن ما تزال هناك الكثير من العناصر التي لا نحتاجها ضمن المُقتطف، مثل الأكواد القصيرة لأن وظيفة المٌقتطف هي عرض نص فقط ولا حاجة للأكواد القصيرة ضمنه حتى لو كان مضمونها نصًا، حيث لن يكون لها معنًى إلا عند تحليلها والأفضل التخلص منها. لن نحتاج إلى كتابة دالةٍ جديدة لفعل ذلك لأن ووردبريس يمتلك دالة strip_shortcodes()‎ وظيفتها إزالة الأكواد القصيرة.

أيضًا أصبح لدينا الآن محتوىً بدون وسومٍ أو أكوادٍ قصيرة، لكن يُحتمل ظهور فراغاتٍ وأسطر لا حاجة لها، حيث نريد أن يظهر المُقتطف على أنه مقطعٌ واحدٌ مستمر، ولذلك سنستخدم تعبيرًا نمطيًا للبحث عن الفراغات والأسطر وغيرها واستبدالها بفراغٍ واحد.

عد المحارف والحفاظ على كلمة كاملة

لقد حصلنا الآن على نصٍ بدون أي عناصر أخرى، وبقي علينا أمران هما استخراج عدد المحارف المطلوب والانتباه إلى أنّ الكلمة الأخيرة من المقتطف غير مقسومة. يمكن عدّ المحارف باستخدام إحدى الدالتين strpos()‎ أوsubstr()‎، لكن عند تجربتهما على موقعٍ لا يستخدم ترميز ASCII، فقد حصل شيئان، وأولهما عدم الحصول على نفس عدد المحارف الممرر للدالة، والثاني ظهور أحرفٍ غريبةٍ بعض المرات في نهاية المُقتطف. وبعد البحث اكتشفنا وجود دالةٍ متعددة البايت مكافئةٍ لكل دالة str في PHP وتُستخدم لمعالجة جميع محارف UTF-8، حيث أن طول محارف UTF-8 أكبر من 1 بايت، لذلك كانت دالة strpos()‎ تَعُد المحارف بالاعتماد على الطول وهو 1 بايت، ونتج عن ذلك أخطاء عند عَدّ محارف بترميز UTF-8 ليظهر عددٌ أقل من المطلوب، وكان هذا أيضًا السبب وراء ظهور محارفٍ غير معروفة في نهاية المقتطف.

تعتمد substr()‎ على طول المحارف لعدّها، والطول المعتمد لديها هو 1 بايت أيضًا، وعند وصولها بالعد لمنتصف محرفٍ معين (طول المحرف 2 بايت في ترميز UTF-8)، فسوف تعرض محرفًا غير معروف، ولذلك يجب استخدام mb_strpos()‎ بدلًا من strpos()‎، وmb_substr()‎ بدلًا من substr()‎.

تتمثل الخطوة الآن في ترتيب المقتطف بصورةٍ أنيقة بحيث لا تُقتطع أية كلمة من المنتصف، حيث لن يكون عدد المحارف الذي يُمرر مثل معاملٍ في أغلب الأحيان دقيقًا، لكننا نريد أن نبقى قريبين منه قدر الإمكان، لذا سنتحقق أي الحالتين أقرب، وهما القطع قبل أو بعد الكلمة الأخيرة التي نحن في منتصفها. سنستخدم mb_strrpos لإيجاد الفراغ الأخير قبل نهاية المحرف وmb_strpos لإيجاد الفراغ التالي بعد نهاية المحرف، ثم نقيس المسافة بين هذين الفراغين من نهاية المحرف ونعيد المقتطف إلى أقرب فراغ.

الدالة الكاملة

تسمح الشيفرة البرمجية التالية بالحفاظ على آخر كلمة من المقتطف دون اقتطاعها مهما كان عدد المحارف المطلوب استخراجه من المحتوى.

/**
* Get a limited part of the content - sans html tags and shortcodes - 
* according to the amount written in $limit. Make sure words aren't cut in the middle
* @param int $limit - number of characters
* @return string - the shortened content
*/
function wpshout_the_short_content($limit) {
   $content = get_the_content();
  /* sometimes there are <p> tags that separate the words, and when the tags are removed, 
   * words from adjoining paragraphs stick together.
   * so replace the end <p> tags with space, to ensure unstickinees of words */
   $content = strip_tags($content);
   $content = strip_shortcodes($content);
   $content = trim(preg_replace('/\s+/', ' ', $content));
   $ret = $content; /* if the limit is more than the length, this will be returned */
   if (mb_strlen($content) >= $limit) {
      $ret = mb_substr($content, 0, $limit);
     // make sure not to cut the words in the middle:
     // 1. first check if the substring already ends with a space
      if (mb_substr($ret, -1) !== ' ') {
        // 2. If it doesn't, find the last space before the end of the string
         $space_pos_in_substr = mb_strrpos($ret, ' ');
        // 3. then find the next space after the end of the string(using the original string)
         $space_pos_in_content = mb_strpos($content, ' ', $limit);
        // 4. now compare the distance of each space position from the limit
         if ($space_pos_in_content != false && $space_pos_in_content - $limit <= $limit - $space_pos_in_substr) {
           /* if the closest space is in the original string, take the substring from there*/
            $ret = mb_substr($content, 0, $space_pos_in_content);
         } else {
           // else take the substring from the original string, but with the earlier (space) position
            $ret = mb_substr($content, 0, $space_pos_in_substr);
         }
      }
   }
   return $ret . '...';
}

تحديث المنشور بالمقتطف المولد

يمكن تحديث مُقتطف المنشور ضمن قاعدة البيانات إذا كنا لا تريد للشيفرة البرمجية أن تُولّد المُقتطف في كل مرةٍ يُعرض فيها المنشور، وبالتالي فعندما تعمل الدالة has_excerpt()‎ على منشورٍ معين، فسوف تُعيد نتيجةً إيجابيةً وتأخذ المُقتطف مباشرةً من قاعدة البيانات دون المرور بكل ما سبق. ويجب هنا أن يحدث استدعاء للدالّة wp_update_post()‎ في نهاية الدالة wpshout_the_short_content()‎، وذلك من أجل تحديث المنشور والتي تحتاج لمُعرّف المنشور ID والمُقتطف.

function wpshout_update_post_excerpt($new_excerpt){
    $post = array( 
        'ID' => get_the_ID(),
        'post_excerpt' => $new_excerpt,
    );
    wp_update_post($post);
}

أفضل طريقةٍ لاستدعاء هذه الدالة هي من خلال ربطها مع مُرشح wp_trim_excerpt يولِّد مُقتطفًا من محتوى منشور ووردبريس عن طريق اختصاره إلى 55 كلمة وإضافة "[…]"، وقبل الإنتهاء نستدعي مرشح wp_trim_excerpt للسماح بترشيح النتائج وتوليد سلوك مقتطفٍ خاصٍ بنا.

function wpshout_excerpt( $text ) {
    if( is_admin() ) {
        return $text;
    }
    if (! has_excerpt() ) {
        $text = wpshout_the_short_content(200);
    }
    wpshout_update_post_excerpt($text);
    return $text;
}

add_filter( 'wp_trim_excerpt', 'wpshout_excerpt' );

الخلاصة

شرح هذا المقال كيفية توليد مُقتطف لمنشور برمجيًا وتحديد طول هذا المُقتطف باستخدام عدد المحارف دون قطع الكلمة الأخيرة إلى قسمين.

ترجمة -وبتصرّف- للمقال How to Create an Excerpt From a Post Without an Excerpt and Limit It by Character Count لصاحبه Lea Cohen.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...