Содержимое и результаты поиска по модулю / повторному использованию

Мой клиент хочет создать небольшие блоки контента (называть их «контейнеры») и (повторно) использовать их на разных страницах сайта. Пока это достигается путем создания настраиваемого типа сообщений (рис. 1] и вызывающие страницы, сгенерированные в нем с помощью короткого кода [рис. 2] на страницу «контейнер» [рис. 3].

Проблема в том, что поиск только возвращает хиты внутри этих «контейнеров», а не в «контейнерную» страницу. Это имеет смысл, поскольку контент не построен на странице «контейнер», но я бы предпочел, чтобы поиск показывал результаты только для «контейнерной» страницы. Я искал решения, думающие, что моя проблема не может быть новой, но безрезультатно. Возможно ли это, или я лаяю неправильное дерево?

Инжир. 1 – Пользовательский тип сообщения

function create_content_pod_post_type() { register_post_type( 'content_pod', array( 'labels' => array( 'name' => __( 'Content Pods' ), 'singular_name' => __( 'Content Pod' ), 'menu_name' => __( 'Content Pods' ), 'name_admin_bar' => __( 'Pod' ), ), 'public' => true, 'publicly_queryable' => true, 'exclude_from_search' => true, 'has_archive' => true, 'menu_position' => 20, 'capability_type' => 'page' ) ); } add_action( 'init', 'create_content_pod_post_type' ); 

Инжир. 2 – Функция Shortcode для отображения содержимого «pod»

 function get_pod_content( $atts ) { $pod_id = $atts[ 'id' ]; $args = array( 'page_id' => $pod_id, 'post_type' => 'content_pod' ); $custom_query = new WP_Query( $args ); if($custom_query->have_posts()) { while( $custom_query->have_posts() ) { $custom_query->the_post(); echo '<div class="content-pod">' . get_the_content() . '</div>'; } } wp_reset_postdata(); } add_shortcode( 'pod', 'get_pod_content' ); 

Инжир. 3 – Пример макроса короткого кода на странице «контейнер»

 [pod id="135"] 

Solutions Collecting From Web of "Содержимое и результаты поиска по модулю / повторному использованию"

В базе данных должностей есть небольшое недооцененное поле, называемое post_content_filtered . Он не используется ядром (насколько я помню), и иногда плагины используют его для хранения альтернативного представления содержимого (что более или менее то, для чего оно предназначено).

Поэтому для вашего случая использования моя идея состояла бы в том, чтобы хранить контент с помощью коротких кодов, отображаемых в этом поле, и корректировать поиск SQL, чтобы использовать его для ваших «контейнеров» вместо основного содержимого.

Но на самом деле есть несколько способов приблизиться к этому, просто первое, что попало мне в голову, отнюдь не простой способ сделать это.

Я хотел проследить и упомянуть, что между предложением Rarst (WP теперь сохраняет post_content_filtered в любое время, когда создается или обновляется страница «контейнер»), и способность Relevanssi включать столбцы wp_posts в результаты поиска, я смог достичь желаемых результатов. Большое вам спасибо, Rarst!

Редактировать: В точку кайзера мой ответ не помогает никому в подобной ситуации. Итак, чтобы добавить ясность, вот как это было разрешено.

Во-первых, чтобы помочь проиллюстрировать, как страница будет собраться вместе в этом сценарии, вот небольшая наглядная помощь (см. Ниже). Следует отметить, что на сайте также есть плагин, который позволяет перетаскивать страницу. Задача, которую это представляет, вступает в игру позже.

http://img.wordpressask.com/search/PodContainerFlow.png

Следующий фильтр был добавлен в функции.php и запускается, когда страница создается или обновляется. Сначала он проверяет, является ли страница страницей «контейнера» наличием короткого кода «pod» *, затем захватывает содержимое страницы и выдает короткие коды, созданные плагином макета страницы. Затем он создает список коротких кодов «pod», извлекает контент из каждого и добавляет его в контент для конкретной страницы. Наконец, он делает последний проход для удаления любого HTML-кода, а затем записывает весь текст в поле post_content_filtered .

 function write_content_pod_content ( $data, $postarr ) { // If this is not an update or a pod container page, there's nothing to do if ( ! isset($postarr[ 'ID' ] ) || ! $postarr[ 'ID' ] || ! has_shortcodes( 'pod' ) ) { return $data; } else { $post_content = $postarr[ 'post_content' ]; // Get the container page's content $search_data = preg_replace("~(?:\[/?)[^/\]]+/?\]~s", '', $post_content); // Strip shortcodes, keep shortcode content $pod_id_array = has_shortcodes( 'pod', true ); // Get a list of the pod content page IDs foreach( $pod_id_array as $pod_id ) { $search_data .= do_shortcode( '[pod id=' . $pod_id . ']' ); } // Write pod content to post_content_filtered field $clean_data = wp_filter_nohtml_kses( $search_data ); // Remove all of the HTML, leaving only raw text $data[ 'post_content_filtered' ] = $clean_data; return $data; } } add_filter('wp_insert_post_data', 'write_content_pod_content', 999, 2); 

Наконец, чтобы сделать это полезным, столбец базы данных post_content_filtered должен быть включен в поиск. Оказывается, это был наименее трудный шаг в этом процессе благодаря Релеванси. На странице настроек плагина есть поле для определения дополнительных столбцов базы данных для индексации. Например (примечание: эта функциональность доступна только в версии Premium для плагина):

http://img.wordpressask.com/search/RelevanssiSetting.png

* Поскольку короткие коды добавляются на страницу с помощью интерфейса перетаскивания, я счел необходимым создать функцию для поиска коротких кодов на странице и / или их идентификатора. Я уверен, что есть лучшие способы сделать это, поэтому, пожалуйста, извините за отсутствие оптимизации и т. Д.

 function has_shortcodes( $shortcode = '', $return_ids = false ) { $post_to_check = get_post( get_the_ID() ); //False because we have to search through the post content first $found = false; //If no short code was provided, return false if ( ! $shortcode ) { return $found; } //Check the post content for the short code $haystack = $post_to_check->post_content; $needle = '[' . $shortcode; $lastPos = 0; $positions = array(); if ( stripos( $haystack, $needle ) !== false ) { //Return an array containing the shortcode IDs if ( $return_ids ) { $pattern = '/\[\b' . $shortcode. '\b(.*?)\]/'; preg_match_all( $pattern, $haystack, $all_codes, PREG_PATTERN_ORDER ); $found = array(); for( $i = 0; $i < count( $all_codes[1]); $i++ ) { $id_string_pattern = '/id\=\"(.*?)\"/'; preg_match( $id_string_pattern, $all_codes[1][$i], $id_string_matches, PREG_OFFSET_CAPTURE ); $found[] = $id_string_matches[1][0]; } //Return true when nothing more than confirmation of finding shortcodes is needed } else { $found = true; } } //Return our final results return $found; } 

Надеюсь, это поможет!