Skip to content

Instantly share code, notes, and snippets.

@soderlind
Last active July 24, 2025 08:04
Show Gist options
  • Save soderlind/cc7283db9290031455c5a79d40e3119b to your computer and use it in GitHub Desktop.
Save soderlind/cc7283db9290031455c5a79d40e3119b to your computer and use it in GitHub Desktop.

Revisions

  1. soderlind revised this gist Jul 24, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@

    > This is not a complete plugin, but a how-to. Want more, take a look at my [WP Loop plugin](https://github.com/soderlind/wp-loupe). Search is in [class-wp-loupe-search.php](https://github.com/soderlind/wp-loupe/blob/main/includes/class-wp-loupe-search.php)
    Sample below:
    Code below:
    - expects that you've created your own `search()` function, which returns an array with post id. (eg.: Eg.: `[ [ 'id' => 1 ], [ 'id' => 2 ] ]`)
    - includes pagination
    - tested (using [WP Loop plugin](https://github.com/soderlind/wp-loupe)) with [Twenty Twenty-Four](https://wordpress.org/themes/twentytwentyfour/) and [Twenty Twenty-Five](https://wordpress.org/themes/twentytwentyfive/)
  2. soderlind revised this gist Jan 31, 2025. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -23,10 +23,10 @@ add_filter( 'posts_pre_query', 'my_posts_pre_query', 10, 2 );
    */
    function my_posts_pre_query( $posts, \WP_Query $query ) {
    /**
    * Check if we are on the main query and on the search page. If not, return the original posts.
    * Check if we are on the main query and on the search page. If not, return to the original posts.
    */
    if ( ! ( ! is_admin() && $query->is_main_query() && $query->is_search() && ! $query->is_admin ) ) {
    return $posts;
    return null; // To allow WP to run its normal queries.
    }

    $query->set( 'post_type', ['post','page'] ); // add cpt if needed
  3. soderlind revised this gist Jan 30, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -18,7 +18,7 @@ add_filter( 'posts_pre_query', 'my_posts_pre_query', 10, 2 );
    * and replace the results with our own. Also, we calculate the pagination parameters.
    *
    * @param array $posts Array of posts.
    * @param \WP_Query $query WP_Query object.(passed by reference)
    * @param \WP_Query $query WP_Query object (passed by reference).
    * @return array
    */
    function my_posts_pre_query( $posts, \WP_Query $query ) {
  4. soderlind revised this gist Jan 30, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -18,7 +18,7 @@ add_filter( 'posts_pre_query', 'my_posts_pre_query', 10, 2 );
    * and replace the results with our own. Also, we calculate the pagination parameters.
    *
    * @param array $posts Array of posts.
    * @param \WP_Query $query WP_Query object.
    * @param \WP_Query $query WP_Query object.(passed by reference)
    * @return array
    */
    function my_posts_pre_query( $posts, \WP_Query $query ) {
  5. soderlind revised this gist Jan 30, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    # Create a WordPress custom search

    > This not a complete plugin, but a how-to. Want more, take a look at my [WP Loop plugin](https://github.com/soderlind/wp-loupe). Search is in [class-wp-loupe-search.php](https://github.com/soderlind/wp-loupe/blob/main/includes/class-wp-loupe-search.php)
    > This is not a complete plugin, but a how-to. Want more, take a look at my [WP Loop plugin](https://github.com/soderlind/wp-loupe). Search is in [class-wp-loupe-search.php](https://github.com/soderlind/wp-loupe/blob/main/includes/class-wp-loupe-search.php)
    Sample below:
    - expects that you've created your own `search()` function, which returns an array with post id. (eg.: Eg.: `[ [ 'id' => 1 ], [ 'id' => 2 ] ]`)
  6. soderlind revised this gist Jan 30, 2025. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -14,8 +14,8 @@ Sample below:
    add_filter( 'posts_pre_query', 'my_posts_pre_query', 10, 2 );

    /**
    * Filter posts before the main query is executed. This is where we intercept the query and replace the results with
    * our own. Also, we calculate the pagination parameters.
    * Filter posts before the main query is executed. This is where we intercept the query
    * and replace the results with our own. Also, we calculate the pagination parameters.
    *
    * @param array $posts Array of posts.
    * @param \WP_Query $query WP_Query object.
  7. soderlind revised this gist Jan 30, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@
    Sample below:
    - expects that you've created your own `search()` function, which returns an array with post id. (eg.: Eg.: `[ [ 'id' => 1 ], [ 'id' => 2 ] ]`)
    - include pagination
    - includes pagination
    - tested (using [WP Loop plugin](https://github.com/soderlind/wp-loupe)) with [Twenty Twenty-Four](https://wordpress.org/themes/twentytwentyfour/) and [Twenty Twenty-Five](https://wordpress.org/themes/twentytwentyfive/)


  8. soderlind revised this gist Jan 30, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    # Create a WordPress custom search

    > This not a complete plugin, but an how-to. Want more, take a look at my [WP Loop plugin](https://github.com/soderlind/wp-loupe). Search is in [class-wp-loupe-search.php](https://github.com/soderlind/wp-loupe/blob/main/includes/class-wp-loupe-search.php)
    > This not a complete plugin, but a how-to. Want more, take a look at my [WP Loop plugin](https://github.com/soderlind/wp-loupe). Search is in [class-wp-loupe-search.php](https://github.com/soderlind/wp-loupe/blob/main/includes/class-wp-loupe-search.php)
    Sample below:
    - expects that you've created your own `search()` function, which returns an array with post id. (eg.: Eg.: `[ [ 'id' => 1 ], [ 'id' => 2 ] ]`)
  9. soderlind revised this gist Jan 30, 2025. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,9 +1,9 @@
    # Create a WordPress custom search

    > This not a complete plugin, but an how-to. Want more, take a look at my [WP Loop plugin](https://github.com/soderlind/wp-loupe)
    > This not a complete plugin, but an how-to. Want more, take a look at my [WP Loop plugin](https://github.com/soderlind/wp-loupe). Search is in [class-wp-loupe-search.php](https://github.com/soderlind/wp-loupe/blob/main/includes/class-wp-loupe-search.php)
    Sample below:
    - expects that you've created your search, which returns an array with post id.
    - expects that you've created your own `search()` function, which returns an array with post id. (eg.: Eg.: `[ [ 'id' => 1 ], [ 'id' => 2 ] ]`)
    - include pagination
    - tested (using [WP Loop plugin](https://github.com/soderlind/wp-loupe)) with [Twenty Twenty-Four](https://wordpress.org/themes/twentytwentyfour/) and [Twenty Twenty-Five](https://wordpress.org/themes/twentytwentyfive/)

    @@ -36,10 +36,10 @@ function my_posts_pre_query( $posts, \WP_Query $query ) {
    * - id: The post ID
    * Eg.: [ [ 'id' => 1 ], [ 'id' => 2 ] ]
    */
    $hits = search( $query->query_vars[ 'search_terms' ] ); // Your search function
    $hits = search( $query->query_vars[ 'search_terms' ] ); // Your search function

    // Get all search results first
    $all_posts = create_post_objects( $hits );
    $all_posts = create_post_objects( $hits ); // see below
    $total_found_posts = count( $all_posts );

    // Get pagination parameters
  10. soderlind created this gist Jan 30, 2025.
    86 changes: 86 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,86 @@
    # Create a WordPress custom search

    > This not a complete plugin, but an how-to. Want more, take a look at my [WP Loop plugin](https://github.com/soderlind/wp-loupe)
    Sample below:
    - expects that you've created your search, which returns an array with post id.
    - include pagination
    - tested (using [WP Loop plugin](https://github.com/soderlind/wp-loupe)) with [Twenty Twenty-Four](https://wordpress.org/themes/twentytwentyfour/) and [Twenty Twenty-Five](https://wordpress.org/themes/twentytwentyfive/)


    ```php


    add_filter( 'posts_pre_query', 'my_posts_pre_query', 10, 2 );

    /**
    * Filter posts before the main query is executed. This is where we intercept the query and replace the results with
    * our own. Also, we calculate the pagination parameters.
    *
    * @param array $posts Array of posts.
    * @param \WP_Query $query WP_Query object.
    * @return array
    */
    function my_posts_pre_query( $posts, \WP_Query $query ) {
    /**
    * Check if we are on the main query and on the search page. If not, return the original posts.
    */
    if ( ! ( ! is_admin() && $query->is_main_query() && $query->is_search() && ! $query->is_admin ) ) {
    return $posts;
    }

    $query->set( 'post_type', ['post','page'] ); // add cpt if needed

    /**
    * Hits is an array of search results. Each hit is an array with the following key:
    * - id: The post ID
    * Eg.: [ [ 'id' => 1 ], [ 'id' => 2 ] ]
    */
    $hits = search( $query->query_vars[ 'search_terms' ] ); // Your search function

    // Get all search results first
    $all_posts = create_post_objects( $hits );
    $total_found_posts = count( $all_posts );

    // Get pagination parameters
    $posts_per_page = get_option( 'posts_per_page' );
    $paged = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
    $offset = ( $paged - 1 ) * $posts_per_page;

    // Calculate max pages
    $max_num_pages = ceil( $total_found_posts / $posts_per_page );

    // Slice the results for current page
    $paged_posts = array_slice( $all_posts, $offset, $posts_per_page );

    // Update the main query object with pagination info
    $query->found_posts = $total_found_posts;
    $query->max_num_pages = $max_num_pages;

    // Set query pagination properties
    $query->is_paged = $paged > 1;

    return $paged_posts;

    }

    /**
    * Create array with post objects
    *
    * @param array $hits Array of hits.
    * @return array
    */
    function create_post_objects( $hits ) {
    $posts = [];

    foreach ( $hits as $hit ) {
    $post = new \stdClass();
    $post->ID = $hit[ 'id' ];

    $post = new \WP_Post( $post );
    $posts[] = $post;
    }
    return $posts;
    }

    ```