Какой лучший способ обрезать содержимое из WYSIWYG-редактора?

Вопрос или проблема

Я слишком много искал в Google и пока не нашел именно то, что мне нужно.

Клиент использует редактор (WYSIWYG) для создания постов. Она добавляет фотографии, ссылки на внешние фотографии, видео, вставляет внешние видео и все остальное форматирование. Но она не использует тег и поле для отрывков.

Когда я использую wp_trim_words(), результаты получаются смешанные.

  • В постах с локальными видео на странице появляется лишняя разметка
  • Некоторые посты состоят только из изображений, так что контента там вообще нет
  • Посты с большим количеством форматирования выглядят очень странно

У кого-нибудь есть идеи о том, как обрезать контент или найти лучшие способы использования wp_trim_words()?

РЕДАКТИРОВАНО: Чтобы прояснить, в основном я хочу получить обрезанную версию полного поста, которая по-прежнему содержит все форматирование, изображения, видео, ссылки, вставки, что бы еще она ни добавила в редактор. Очевидно, я не хочу, чтобы на странице появлялась лишняя разметка.

wp_strip_all_tags() удалит все теги.

Однако в постах, где есть только изображения и нет контента, нет решения для этого, отрывок или место, где вы пытаетесь его использовать, будет пустым, так как он не может “волшебным образом” создать контент для поста, если контента вообще нет.

Для получения дополнительной информации > https://codex.wordpress.org/Function_Reference/wp_strip_all_tags

Это будет довольно сложно сделать. Вы могли бы написать собственную функцию для попытки обрезки контента и затем закрыть любые не закрытые теги в конце. Пример:

/**
 * Вспомогательная функция для отображения пользовательских кратких отрывков с HTML.
 */
function custom_excerpt_with_html( $word_count = 40 ) {
    $text = get_the_content( null, false ); // Примечание: возможно, вам нужно будет пропустить это через do_blocks()

    if ( ! $text ) {
        return;
    }

    if ( strlen( strip_tags( $text ) ) <= $word_count ) {
        return $text; // текст короче длины.
    }

    $last_space = $word_count + 1; // добавление +1, потому что массивы начинаются с 0
    $words = explode( ' ', $text, $last_space );
    array_pop( $words ); // Укорочение массива на 1, так как последний элемент будет суммой всех слов после last_space.
    $excerpt = implode( ' ', $words ); // создание строки отрывка снова из слов

    echo close_open_html_tags( $excerpt );
}

/**
 * Вспомогательная функция для закрытия всех открытых HTML-тегов в строке.
 */
function close_open_html_tags( $html ) {
    preg_match_all('#<([a-zA-Z0-9]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result );

    if ( empty( $result[1] ) ) {
        return $html; // нет тегов.
    }

    $opened_tags = $result[1];
    preg_match_all('#</([a-zA-Z0-9]+)>#iU', $html, $result );

    $closed_tags = $result[1];
    $opend_tags_length = count( $opened_tags );

    if ( count( $closed_tags ) === $opend_tags_length ) {
        return $html;
    }

    $opened_tags = array_reverse($opened_tags);

    for ( $i=0; $i < $opend_tags_length; $i++ ) {
        if ( ! in_array( $opened_tags[ $i ], $closed_tags ) ) {
            $html .= '</'.$opened_tags[ $i ].'>';
        } else {
            unset( $closed_tags[ array_search( $opened_tags[ $i ], $closed_tags ) ] );
        }
    }

    return $html;
}

Я взял этот код из собственного проекта, который я выполнял несколько месяцев назад. Но у клиента было всего несколько html-тегов, которые они хотели сохранить, такие как жирный текст, и это работало хорошо там, не уверен, подойдет ли это для изображений и ссылок — но, возможно, код можно изменить так, чтобы лучше соответствовать вашим нуждам.

Если клиент хочет отображать HTML в отрывках, я бы настоятельно рекомендовал научить их использовать тег “more” (или блок, если они используют Gutenberg).

Любая созданная вами функция автоматической обрезки не будет очень хороша. Единственный способ правильно разделить HTML — это вставить в пост что-то вроде маркера (например, тег more), по которому вы сможете разделить контент.

Если пользователь хотя бы захочет, скажем, разделить контент после первого изображения или абзаца, это, возможно, будет более целесообразно.

Возможно, вы захотите взглянуть на этот ответ: https://stackoverflow.com/a/24160854/7607379

Ответ или решение

В сегодняшнем мире веб-разработки и контент-менеджмента многие клиенты и пользователи предпочитают использовать WYSIWYG-редакторы для создания и редактирования текстов. Они предоставляют возможность видеть итоговый результат буквально "на лету", включая все текстовые стили, изображения и медиа-контент. Тем не менее, при попытке обрезать текст для генерации коротких отрывков или резюме, может возникнуть ряд сложностей, особенно если отсутствует использование специальных тегов или полей, таких как тег "more" или поле для краткого содержания. В этой ситуации, возникает вопрос: как обрезать содержимое из WYSIWYG-редактора так, чтобы сохранить исходное форматирование и не нарушить структуру страницы?

Теория

Прежде всего, стоит понять, что функция wp_trim_words(), часто используемая в WordPress для обрезания текста, просто удаляет часть текста, основываясь на количестве слов. Она не заботится о форматировании или других HTML-тегах, что может привести к появлению "некрасивого" содержимого, включая незакрытые теги и другие подобные проблемы. В результате мы можем получить рассинхронизацию логической структуры и визуального представления текста.

Пример

Как упоминалось в описании проблемы, функция wp_trim_words() может вызывать проблемы, такие как:

  1. "Утечка" разметки: когда обрабатываются локальные видео или сложные элементы, незакрытые HTML-теги могут нарушить структуру страницы.
  2. Посты, состоящие только из изображений: если текст отсутствует, обрезка приведет к пустому полю.
  3. Неоптимальное отображение форматированного текста: стили и форматирование могут потеряться или смешаться, искажающие задуманное восприятие.

Применение

Для решения данной проблемы потребуется более гибкий подход, нежели просто сокращение текста. Ниже предложены шаги и подходы для преодоления данной ситуации:

  1. Кастомизация обрезания текста: создание пользовательской функции обрезания, которая учитывает структуру HTML. Включение таких функций, как close_open_html_tags, поможет в корректном закрытии всех открытых тегов после удаления лишних слов. Это позволит избежать ошибок разметки на конечной странице.

  2. Использование маркеров разбиения: настоятельно рекомендуется применять встроенные возможности WYSIWYG-редакторов, такие как тег "more" или специальные блоки в редакторе Gutenberg для явного обозначения точек обрезания текста. Если возможно, обучите клиента использовать эти инструменты для достижения наилучших результатов.

  3. Настройка политики формирования краткого содержания: если посты часто состоят лишь из изображений, обсудите с клиентом возможность добавления хотя бы минимального текстового описания или использования атрибутов изображений в качестве исходного материала для обрезания.

  4. Создание более умной функции обрезки: такая функция может анализировать первое изображение или параграф, после чего использовать их для создания отрывка. Это особенно актуально для постов без значительного объема текста.

  5. Проведение регулярного аудита: настройте систему на автоматизированное выявление и исправление ошибок обрезания путем регулярных проверок.

Вот пример кода для кастомного обрезания текста с учетом HTML (основанный на предложенном контексте):

function custom_excerpt_with_html($word_count = 40) {
    $text = get_the_content(null, false);

    if (!$text) { return; }

    if (strlen(strip_tags($text)) <= $word_count) {
        return $text;
    }

    $words = explode(' ', $text, $word_count + 1);
    array_pop($words);
    $excerpt = implode(' ', $words);

    echo close_open_html_tags($excerpt);
}

function close_open_html_tags($html) {
    preg_match_all('#<([a-zA-Z0-9]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result);

    if (empty($result[1])) { return $html; }

    $opened_tags = $result[1];
    preg_match_all('#</([a-zA-Z0-9]+)>#iU', $html, $result);

    $closed_tags = $result[1];
    $opend_tags_length = count($opened_tags);

    if (count($closed_tags) === $opend_tags_length) {
        return $html;
    }

    $opened_tags = array_reverse($opened_tags);

    for ($i = 0; $i < $opend_tags_length; $i++) {
        if (!in_array($opened_tags[$i], $closed_tags)) {
            $html .= '</' . $opened_tags[$i] . '>';
        } else {
            unset($closed_tags[array_search($opened_tags[$i], $closed_tags)]);
        }
    }

    return $html;
}

Заключение

В контексте работы с WYSIWYG-редакторами и CMS, такими как WordPress, ключевым является интеграция решений, которые не только удовлетворяют краткосрочным задачам, но и поддерживают долгосрочную стабильность и качество отображения контента. Создание продуманных функций для обрезания контента, усиление обучающих аспектов для пользователей и постоянный мониторинг — всё это способствует более успешной и устойчивой работе редакционных систем.

Оцените материал
Добавить комментарий

Капча загружается...