Вопрос или проблема
У меня есть следующий код:
function auto_link_post_titles( $content, $post_id, $field ) {
$excluded_ids = array(); // Укажите здесь идентификаторы страниц, которые хотите исключить
$excluded_field_names = array(); // Укажите здесь названия полей, которые хотите исключить
if ( isset( $_GET['ntb'] ) || did_action( 'ninja_tables_loaded' ) ) {
return $content;
}
if(!in_array($post_id, $excluded_ids) && !in_array($field['name'], $excluded_field_names)) {
// Устанавливаем тип(ы) постов, которые мы будем извлекать.
$desired_post_types = array( 'my_post_type', 'my_other_post_type' );
// Это для получения всех опубликованных постов из всех типов постов.
$args = array(
'post_type' => $desired_post_types,
'post_status' => 'publish',
'posts_per_page' => -1, // это для получения всех постов
);
$posts = get_posts( $args );
// Здесь мы проходим по каждому посту и заменяем заголовок в содержимом на ссылку.
foreach ( $posts as $post ) {
$post_title = esc_html( $post->post_title ); // Здесь мы получаем заголовок поста.
$post_link = esc_url( get_permalink( $post->ID ) ); // Здесь мы получаем ссылку на пост.
// Создаем элемент ссылки
$link = '<a href="' . $post_link . '" target="_blank">' . $post_title . '</a>';
// Здесь мы заменяем заголовок в виде обычного текста на ссылку.
$content = str_replace( $post_title, $link, $content );
}
}
return $content;
}
// Мы применили функцию к содержимому постов.
// Обратите внимание, что количество параметров установлено на 3
add_filter( 'acf/load_value', 'auto_link_post_titles', 10, 3 );
Код автоматически обнаруживает заголовки постов на основе введенных данных.
Моя проблема в том, что в нем нет логики.
У меня есть три поста. Их имена:
1. CATA
2. CATA(1)
3. CATA(2)
Код не учитывает полный заголовок, только первые несколько букв – и как только он готов, он начинает автоматическую привязку.
Таким образом, поскольку у меня есть пост с названием “CATA”, во всех трех случаях только пост с названием “CATA” связан, что неправильно для CATA(2) и CATA(3).
Итак, мой вопрос:
Есть ли способ расширить код или изменить его, чтобы он распознавал полный заголовок? И если да, то как?
Ответ или решение
Ваша проблема заключается в том, что код на данный момент заменяет только часть заголовка поста в контенте, и это приводит к некорректному связыванию заголовков, особенно когда у них есть схожие начальные части. Чтобы исправить эту ситуацию и убедиться, что полные заголовки постов правильно заменяются на ссылки в контенте, вам необходимо модифицировать код так, чтобы он сначала проходил по всем заголовкам постов в обратном порядке, заменяя их на ссылки. Это предотвратит ситуацию, когда замена одного заголовка влияет на другой.
Вот обновлённая версия кода:
function auto_link_post_titles( $content, $post_id, $field ) {
$excluded_ids = array(); // Укажите здесь ID страниц, которые хотите исключить
$excluded_field_names = array(); // Укажите здесь имена полей, которые хотите исключить
if ( isset( $_GET['ntb'] ) || did_action( 'ninja_tables_loaded' ) ) {
return $content;
}
if (!in_array($post_id, $excluded_ids) && !in_array($field['name'], $excluded_field_names)) {
// Указываем типы постов, которые мы хотим получить.
$desired_post_types = array( 'my_post_type', 'my_other_post_type' );
// Получаем все опубликованные посты из указанных типов.
$args = array(
'post_type' => $desired_post_types,
'post_status' => 'publish',
'posts_per_page' => -1, // чтобы получить все посты
);
$posts = get_posts( $args );
// Сначала подготовим массив заголовков постов.
$post_titles = array();
foreach ( $posts as $post ) {
$post_titles[$post->ID] = esc_html( $post->post_title ); // Получаем заголовок поста
}
// Сортируем заголовки по длине в убывающем порядке, чтобы длинные заголовки заменялись раньше
usort($post_titles, function($a, $b) {
return strlen($b) - strlen($a);
});
// Заменяем заголовки в контенте
foreach ( $post_titles as $post_id => $post_title ) {
$post_link = esc_url( get_permalink( $post_id ) ); // Получаем ссылку на пост
// Создаем элемент ссылки
$link = '<a href="' . $post_link . '" target="_blank">' . $post_title . '</a>';
// Заменяем заголовок на ссылку в контенте
$content = str_replace($post_title, $link, $content);
}
}
return $content;
}
// Применяем функцию к контенту постов.
// Обратите внимание, что количество параметров установлено на 3
add_filter( 'acf/load_value', 'auto_link_post_titles', 10, 3 );
Объяснение изменений:
- Сохранение заголовков: Вместо прямой замены заголовков, мы сохраняем их в массив, чтобы избежать конфликта замены.
- Сортировка: Мы сортируем заголовки по длине в убывающем порядке с помощью функции
usort
. Это гарантирует, что более длинные заголовки будут заменены первыми, что минимизирует вероятность неправильной замены. - Замена в контенте: Мы проходим по отсортированным заголовкам и заменяем каждый заголовок на ссылку в контенте.
Эти изменения должны решить проблему некорректного связывания заголовков постов и обеспечить, что каждый заголовок будет правильно распознан и заменён на соответствующую ссылку.