Як закінчити уривок реченням, а не словом?


15

Ось уривок допису на моїй домашній сторінці. Я хочу закінчити уривок реченням. У цьому випадку це 'можливості. '. Я знаю, як змінити довжину, але це не буде робити те, що я хочу.

введіть тут опис зображення

Ось уривок з іншого веб-сайту. Тут ви бачите уривок, що закінчується належним реченням на відміну від вищевказаного, який закінчується першим словом наступного речення "Проактивно".

введіть тут опис зображення

Після впровадження рішення GM :

введіть тут опис зображення


Будь ласка, поясніть свою проблему краще, ніж це. З відповідей та коментарів до них важко зрозуміти, чого ти хочеш досягти.
кайзер

@kaiser Я оновив деталі.
Мохіт

@Mohit ти спробував мій код?
gmazzap

Так, уривок закінчується реченням, але "Читати далі" вже немає.
Мохіт

@GM Добре, я повинен додати прочитане ще у відповідь.
Мохіт

Відповіді:


13

Для цього потрібно PHP 5.3+ (WP вимагає PHP 5.2.4+)

add_filter('get_the_excerpt', 'end_with_sentence');

function end_with_sentence($excerpt) {
  $allowed_end = array('.', '!', '?', '...');
  $exc = explode( ' ', $excerpt );
  $found = false;
  $last = '';
  while ( ! $found && ! empty($exc) ) { 
    $last = array_pop($exc);
    $end = strrev( $last );
    $found = in_array( $end{0}, $allowed_end );
  }
  return (! empty($exc)) ? $excerpt : rtrim(implode(' ', $exc) . ' ' .$last);
}

Редагувати

Після коментаря @kaiser я намагаюся запустити це на збереження / оновлення, щоб запобігти сповільненню сторінки на показ багатьох публікацій. Це слід перевірити

add_filter('wp_insert_post_data', 'end_with_sentence_on_save', 20, 2);

function end_with_sentence_on_save($data, $postarr) {
  if ( ! empty( $data['post_content'] ) && $data['post_status'] != 'inherit' && $data['post_status'] != 'trash' ) {
    $text = strip_shortcodes( $data['post_content'] );
    $text = apply_filters('the_content', $text );
    $text = str_replace(']]>', ']]>', $text );
    $excerpt_length = apply_filters('excerpt_length', 55);
    $data['post_excerpt'] = wp_trim_words($text, $excerpt_length, '');
  } else {
    return $data;
  }
  $allowed_end = array('.', '!', '?', '...');
  $exc = explode(' ', $data['post_excerpt']);
  $found = false;
  $last = '';
  while ( ! $found && ! empty($exc) ) { 
    $last = array_pop($exc);
    $end = strrev( $last );
    $found = in_array( $end{0}, $allowed_end );
  }
  if (! empty($exc)) $data['post_excerpt'] = rtrim(implode(' ', $exc) . ' ' .$last);
  return $data; 
}

1
упевнений , що: $end{0}? До речі, ви могли просто повернутися або breakколи щось знайдете. Додаткова примітка. Це може бути краще для збереження публікації, тому воно не відновлюється під час виконання, що може вийти досить повільним, якщо ви показуєте багато публікацій.
кайзер

@kaiser цитуйте: до тих же цілей можна отримати доступ, використовуючи дужки, як у $ str {42}. php.net docs Щоб знайти щось, мені довелося знайти останній знак останнього рядка. Використовуючи, $foundя перериваю цикл і перевіряю останній рядок, тому не потрібно break.
gmazzap

Повністю пропустив, що це whileперевірка false. +1
кайзер

@kaiser +1 для другої частини вашого коментаря, тепер я редагую код, щоб працювати на збереженні
gmazzap

1
Звичайно, @jessica був поганим редагуванням (у оригінальній версії це було нормально). Спасибі, виправлено.
gmazzap

2

Ось моя версія, зберігаючи всі теги HTML, а також обрізаючи вміст після останнього слова у реченні

if ( ! function_exists( 'pietergoosen_custom_wp_trim_excerpt' ) ) : 

    function pietergoosen_custom_wp_trim_excerpt($pietergoosen_excerpt) {
    global $post;
    $raw_excerpt = $pietergoosen_excerpt;
        if ( '' == $pietergoosen_excerpt ) {

            $pietergoosen_excerpt = get_the_content('');
            $pietergoosen_excerpt = strip_shortcodes( $pietergoosen_excerpt );
            $pietergoosen_excerpt = apply_filters('the_content', $pietergoosen_excerpt);
            $pietergoosen_excerpt = str_replace(']]>', ']]>', $pietergoosen_excerpt);

            //Set the excerpt word count and only break after sentence is complete.
                $excerpt_word_count = 75;
                $excerpt_length = apply_filters('excerpt_length', $excerpt_word_count); 
                $tokens = array();
                $excerptOutput = '';
                $count = 0;

                // Divide the string into tokens; HTML tags, or words, followed by any whitespace
                preg_match_all('/(<[^>]+>|[^<>\s]+)\s*/u', $pietergoosen_excerpt, $tokens);

                foreach ($tokens[0] as $token) { 

                    if ($count >= $excerpt_word_count && preg_match('/[\?\.\!]\s*$/uS', $token)) { 
                    // Limit reached, continue until  ? . or ! occur at the end
                        $excerptOutput .= trim($token);
                        break;
                    }

                    // Add words to complete sentence
                    $count++;

                    // Append what's left of the token
                    $excerptOutput .= $token;
                }

            $pietergoosen_excerpt = trim(force_balance_tags($excerptOutput));

                $excerpt_end = ' <a href="'. esc_url( get_permalink() ) . '">' . '&nbsp;&raquo;&nbsp;' . sprintf(__( 'Read more about: %s &nbsp;&raquo;', 'pietergoosen' ), get_the_title()) . '</a>'; 
                $excerpt_more = apply_filters('excerpt_more', ' ' . $excerpt_end); 

                //$pos = strrpos($pietergoosen_excerpt, '</');
                //if ($pos !== false)
                // Inside last HTML tag
                //$pietergoosen_excerpt = substr_replace($pietergoosen_excerpt, $excerpt_end, $pos, 0);
                //else
                // After the content
                $pietergoosen_excerpt .= $excerpt_end;

            return $pietergoosen_excerpt;   

        }
        return apply_filters('pietergoosen_custom_wp_trim_excerpt', $pietergoosen_excerpt, $raw_excerpt);
    }

endif; 

remove_filter('get_the_excerpt', 'wp_trim_excerpt');
add_filter('get_the_excerpt', 'pietergoosen_custom_wp_trim_excerpt'); 

0

Про всяк випадок, якщо хтось використовує відповідь, слово поради: Це зруйнує розширені спеціальні поля. ACF також викликає wp_insert_post_dataпід час створення або оновлення поля, але $dataзмінна не є однаковою, і це призведе до того, що ім'я поля ACF стане деяким нечитабельним помилкою, що призводить до неможливості використання поля.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.