在管理员列表帖子屏幕中扩展搜索上下文

时间:2011-03-11 作者:Stefano

我已经创建了一个自定义帖子类型,并附加了一些自定义字段。现在,我希望作者可以在自定义帖子列表屏幕(在管理后端)上执行的搜索也可以在元字段上执行,而不仅仅像往常一样查看标题和内容。

我可以挂接到哪里,我必须使用什么代码?

Example imageenter image description here

斯特凡诺

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

我通过在Posteta表中添加连接并更改where子句来解决过滤查询的问题。筛选WHERE子句(通常需要正则表达式搜索和替换)的提示如下here on codex:

add_filter( \'posts_join\', \'segnalazioni_search_join\' );
function segnalazioni_search_join ( $join ) {
    global $pagenow, $wpdb;

    // I want the filter only when performing a search on edit page of Custom Post Type named "segnalazioni".
    if ( is_admin() && \'edit.php\' === $pagenow && \'segnalazioni\' === $_GET[\'post_type\'] && ! empty( $_GET[\'s\'] ) ) {    
        $join .= \'LEFT JOIN \' . $wpdb->postmeta . \' ON \' . $wpdb->posts . \'.ID = \' . $wpdb->postmeta . \'.post_id \';
    }
    return $join;
}

add_filter( \'posts_where\', \'segnalazioni_search_where\' );
function segnalazioni_search_where( $where ) {
    global $pagenow, $wpdb;

    // I want the filter only when performing a search on edit page of Custom Post Type named "segnalazioni".
    if ( is_admin() && \'edit.php\' === $pagenow && \'segnalazioni\' === $_GET[\'post_type\'] && ! empty( $_GET[\'s\'] ) ) {
        $where = preg_replace(
            "/\\(\\s*" . $wpdb->posts . ".post_title\\s+LIKE\\s*(\\\'[^\\\']+\\\')\\s*\\)/",
            "(" . $wpdb->posts . ".post_title LIKE $1) OR (" . $wpdb->postmeta . ".meta_value LIKE $1)", $where );
        $where.= " GROUP BY {$wpdb->posts}.id"; // Solves duplicated results
    }
    return $where;
}

SO网友:Calara Ionut

Stefano的回答很好,但缺少一个明确的条款:

function segnalazioni_search_distinct( $where ){
    global $pagenow, $wpdb;

    if ( is_admin() && $pagenow==\'edit.php\' && $_GET[\'post_type\']==\'segnalazioni\' && $_GET[\'s\'] != \'\') {
    return "DISTINCT";

    }
    return $where;
}
add_filter( \'posts_distinct\', \'segnalazioni_search_distinct\' );
添加上面的代码更新它,它将不会重复工作。

SO网友:Vin_fugen

This will work,

function custom_search_query( $query ) {
    $custom_fields = array(
        // put all the meta fields you want to search for here
        "rg_first_name",
        "rg_1job_designation"
    );
    $searchterm = $query->query_vars[\'s\'];

    // we have to remove the "s" parameter from the query, because it will prevent the posts from being found
    $query->query_vars[\'s\'] = "";

    if ($searchterm != "") {
        $meta_query = array(\'relation\' => \'OR\');
        foreach($custom_fields as $cf) {
            array_push($meta_query, array(
                \'key\' => $cf,
                \'value\' => $searchterm,
                \'compare\' => \'LIKE\'
            ));
        }
        $query->set("meta_query", $meta_query);
    };
}
add_filter( "pre_get_posts", "custom_search_query");
SO网友:dev

Answer 1:在函数文件中添加此代码,并更改和添加更多在自定义帖子类型中使用的列名称

function extend_admin_search( $query ) {

    // use your post type
    $post_type = \'document\';
    // Use your Custom fields/column name to search for
    $custom_fields = array(
        "_file_name",
    );

    if( ! is_admin() )
        return;

    if ( $query->query[\'post_type\'] != $post_type )
        return;

    $search_term = $query->query_vars[\'s\'];

    // Set to empty, otherwise it won\'t find anything
    $query->query_vars[\'s\'] = \'\';

    if ( $search_term != \'\' ) {
        $meta_query = array( \'relation\' => \'OR\' );

        foreach( $custom_fields as $custom_field ) {
            array_push( $meta_query, array(
                \'key\' => $custom_field,
                \'value\' => $search_term,
                \'compare\' => \'LIKE\'
            ));
        }

        $query->set( \'meta_query\', $meta_query );
    };
}

add_action( \'pre_get_posts\', \'extend_admin_search\' );
Answer 2: Recommended在函数文件中使用此代码,无需任何更改

function cf_search_join( $join ) {
    global $wpdb;

    if ( is_search() ) {    
        $join .=\' LEFT JOIN \'.$wpdb->postmeta. \' ON \'. $wpdb->posts . \'.ID = \' . $wpdb->postmeta . \'.post_id \';
    }

    return $join;
}
add_filter(\'posts_join\', \'cf_search_join\' );
function cf_search_where( $where ) {
    global $pagenow, $wpdb;

    if ( is_search() ) {
        $where = preg_replace(
            "/\\(\\s*".$wpdb->posts.".post_title\\s+LIKE\\s*(\\\'[^\\\']+\\\')\\s*\\)/",
            "(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where );
    }

    return $where;
}
add_filter( \'posts_where\', \'cf_search_where\' );

function cf_search_distinct( $where ) {
    global $wpdb;

    if ( is_search() ) {
        return "DISTINCT";
    }

    return $where;
}
add_filter( \'posts_distinct\', \'cf_search_distinct\' );

SO网友:Seyed Abbas Seyedi

使用此代码,您可以search 在WordPress管理面板的帖子列表中custom post meta 值以及title 和其他默认字段。

请在函数中添加以下代码。php文件:

if (!function_exists(\'extend_admin_search\')) {
    add_action(\'admin_init\', \'extend_admin_search\');

    /**
     * hook the posts search if we\'re on the admin page for our type
     */
    function extend_admin_search() {
        global $typenow;

        if ($typenow === \'your_custom_post_type\') {
            add_filter(\'posts_search\', \'posts_search_custom_post_type\', 10, 2);
        }
    }

    /**
     * add query condition for custom meta
     * @param string $search the search string so far
     * @param WP_Query $query
     * @return string
     */
    function posts_search_custom_post_type($search, $query) {
        global $wpdb;

        if ($query->is_main_query() && !empty($query->query[\'s\'])) {
            $sql    = "
            or exists (
                select * from {$wpdb->postmeta} where post_id={$wpdb->posts}.ID
                and meta_key in (\'custom_field1\',\'custom_field2\')
                and meta_value like %s
            )
        ";
            $like   = \'%\' . $wpdb->esc_like($query->query[\'s\']) . \'%\';
            $search = preg_replace("#\\({$wpdb->posts}.post_title LIKE [^)]+\\)\\K#",
                $wpdb->prepare($sql, $like), $search);
        }

        return $search;
    }
}

SO网友:Marcin

它不是一个搜索,而是通过不同的值进行“选择”。

在文件中functions-iworks-posts-filter.zip 您有一个如何通过一些meta\\u键为常规帖子添加过滤器的示例。我认为它很容易转换。

SO网友:jwinn

在pre\\u get\\u posts中修改搜索WP\\u查询的meta\\u查询参数的两个答案中的代码版本不再搜索post\\u标题。如果不修改SQL,就无法在WP\\U查询中直接添加搜索帖子标题或元数据的功能,很遗憾,正如此问题所阐述的:Using meta query ('meta_query') with a search query ('s')

我在这里结合了一些技术,得到了一个可以避免preg\\u替换和太多SQL修改的工作版本(我希望可以完全避免)。唯一的缺点是,在搜索之后,页面顶部的字幕文本会显示“搜索结果”。我刚刚用CSS为插件的自定义帖子类型隐藏了它。

/**
 * Extend custom post type search to also search meta fields
 * @param  WP_Query $query
 */
function extend_cpt_admin_search( $query ) {
  // Make sure we\'re in the admin area and that this is our custom post type
  if ( !is_admin() || $query->query[\'post_type\'] != \'your_custom_post_type\' ){
    return;
  }

  // Put all the meta fields you want to search for here
  $custom_fields = array(
    "your_custom_meta_field",
    "your_custom_meta_field2",
    "your_custom_meta_field3"
  );
  // The string submitted via the search form
  $searchterm = $query->query_vars[\'s\'];

  // Set to empty, otherwise no results will be returned.
  // The one downside is that the displayed search text is empty at the top of the page.
  $query->query_vars[\'s\'] = \'\';

  if ($searchterm != ""){
    // Add additional meta_query parameter to the WP_Query object.
    // Reference: https://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters
    $meta_query = array();
    foreach($custom_fields as $cf) {
      array_push($meta_query, array(
        \'key\' => $cf,
        \'value\' => $searchterm,
        \'compare\' => \'LIKE\'
      ));
    }
    // Use an \'OR\' comparison for each additional custom meta field.
    if (count($meta_query) > 1){
      $meta_query[\'relation\'] = \'OR\';
    }
    // Set the meta_query parameter
    $query->set(\'meta_query\', $meta_query);


    // To allow the search to also return "OR" results on the post_title
    $query->set(\'_meta_or_title\', $searchterm);
  }
}
add_action(\'pre_get_posts\', \'extend_cpt_admin_search\');



/**
 * WP_Query parameter _meta_or_title to allow searching post_title when also
 * checking searching custom meta values
 * https://wordpress.stackexchange.com/questions/78649/using-meta-query-meta-query-with-a-search-query-s
 * https://wordpress.stackexchange.com/a/178492
 * This looks a little scary, but basically it\'s modifying the WHERE clause in the 
 * SQL to say "[like the post_title] OR [the existing WHERE clause]"
 * @param  WP_Query $q
 */
function meta_or_title_search( $q ){
  if( $title = $q->get( \'_meta_or_title\' ) ){
    add_filter( \'get_meta_sql\', function( $sql ) use ( $title ){
      global $wpdb;

      // Only run once:
      static $nr = 0;
      if( 0 != $nr++ ) return $sql;

      // Modified WHERE
      $sql[\'where\'] = sprintf(
          " AND ( (%s) OR (%s) ) ",
          $wpdb->prepare( "{$wpdb->posts}.post_title LIKE \'%%%s%%\'", $title),
          mb_substr( $sql[\'where\'], 5, mb_strlen( $sql[\'where\'] ) )
      );

      return $sql;
    });
  }
}
add_action(\'pre_get_posts\', \'meta_or_title_search\');

结束

相关推荐

Search result permalink

如何使permalink可用于搜索结果页/?s=一+二+确定到/搜索/一-二确定/感谢