“模块化/可重复使用”的内容和搜索结果

时间:2014-10-28 作者:Gabe

我的一个客户希望能够创建小块内容(称之为“pods”),并在整个网站的各个页面中(重新)使用它们。到目前为止,这是通过创建自定义帖子类型[图1]并将其中生成的页面通过快捷码[图2]调用到“容器”页面[图3]中来实现的。

问题是,搜索只会返回那些“pod”中的点击,而不会返回“container”页面。考虑到内容不是在“容器”页面中构建的,这是有道理的,但我更喜欢只在“容器”页面中显示搜索结果。我一直在寻找解决方案,认为我的问题不可能是新的,但没有用。这是可能的还是我找错了方向?

图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-显示“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-“container”页面中的shortcode宏示例

[pod id="135"]

2 个回复
最合适的回答,由SO网友:Rarst 整理而成

posts数据库中有一个鲜为人知的字段,名为post_content_filtered. core没有使用它(据我所知),有时插件使用它来存储内容的替代表示(这或多或少是它的目的)。

因此,对于您的用例,我的想法是使用呈现到该字段中的短代码存储内容,并调整搜索SQL以将其用于“容器”,而不是主内容字段。

但实际上有多种方法来实现这一点,只是我脑海中浮现的第一件事,绝不是简单的方法。

SO网友:Gabe

我想跟进并提到,在Rarst的建议(WP现在可以在任何时候创建或更新新的“容器”页面时保存到post\\u content\\u filtered)和Relevansi在搜索结果中包含WP\\u posts列的能力之间,我能够获得所需的结果。非常感谢你,拉斯特!

Edit:就凯撒而言,我的回答对处于类似情况的任何人都没有帮助。因此,为了澄清问题,下面是如何解决的。

首先,为了帮助说明在这个场景中页面是如何组合在一起的,这里有一个小的视觉帮助(下面)。我应该注意到,该网站还使用了一个插件,支持拖放页面布局。这一挑战将在稍后发挥作用。

已将以下筛选器添加到functions.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 搜索中必须包含数据库列。事实证明,多亏了Relevansi,这是整个过程中难度最小的一步。在插件的设置页面上,有一个字段用于定义要索引的其他数据库列。例如(注意:此功能仅在插件的高级版本中可用):

*由于短代码是使用拖放界面添加到页面中的,我发现有必要创建一个函数来查找页面中的短代码和/或其ID。我确信有更好的方法可以做到这一点,因此请原谅缺乏优化等。

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;
}
希望有帮助!

结束

相关推荐

有没有办法阻止WP编辑删除<gcse:earchbox-only></gcse:search box>

我想将我的谷歌自定义网站搜索代码粘贴到编辑器中,以显示在我的一个页面上。当粘贴到“文本”侧时,它会起作用,但如果我切换到“视觉”,get会变成一个NBSP有没有办法让我<gcse:searchbox-only></gcse:searchbox-only> 编辑是否得体?