Search ACF items with CS Forms

Hi Team,

I’ve got another problem with the Search Field when used with ACF CPT items. In my current project I’ve got different archives for Blog Posts (News), Events (ACF CPT) and Documents (ACF CPT). All of them are using CS Forms for filtering and searching.

It seemed to me that search worked before with both WP blog posts and ACF CPT records. But now it only works with the blog posts. If I change the Search Text Input field’s names from 'search' to 's' for Events and Documents archives, the filters stop working. The search also doesn’t work. If I change them back to 'search', the filters are working but the search itself doesn’t.

I doubt when the issue started to appear. Before I utilized the Query Builder Looper Provider for the ‘Events’ Custom Post Type (CPT). But when added a pagination it didn’t work so I had to switch to native WP query. It seemed to me that the Search still worked after that change but I am not sure 100%. I named the Serch Field as ‘search’ inside custom JSON for Events Query Builder before. I also retained WordPress 6.9 for a while at my installation. Recently I updated to 7.1 as CS and PRO also got some fixes for WP 7. My issue might be related to it, or it might not be. I will provide the links for your review inside Secure Note.

Hey John,

Why it worked before (with the Query Builder Looper)

When you were using the Query Builder Looper Provider, you likely had a custom JSON query where you explicitly mapped the WordPress search parameter 's' to the URL parameter search (using something like {{dc:url:param key="search"}}).

  • Because the input field was named search, the URL became ?search=keyword.
  • WordPress’s main query parser ignored search because it is not a native query parameter, keeping the main query on your archive page stable.
  • Your Looper then manually fetched the search value and ran the query. However, as you noted, custom Loopers do not integrate with native WP archive pagination out of the box.

Why it behaves this way now (with the Native WP Query)

Now that you have switched to the Native WP Query (to support native pagination on the archive pages), WordPress handles the query parsing before the page and cornerstone elements render. This causes two different issues depending on the input name:

1. When the field is named s:

  • Submitting the search form sends ?s=keyword to the URL.
  • When WordPress detects the native search query parameter s on an archive page, it automatically assumes a global site search and defaults the search post type to 'post' (standard blog posts), unless told otherwise.
  • This strips away the Custom Post Type context (events or documents), causing the archive template to load blog posts instead of your CPT items, which breaks your CPT filters.

2. When the field is named search:

  • Submitting the search form sends ?search=keyword to the URL.
  • Because search is not a native WordPress query parameter, WordPress ignores it, meaning the archive query stays on the correct CPT (events or documents) and your filters continue to work.
  • However, because WordPress ignores it, the query is never actually filtered by that keyword (which is why the search itself does not work).

Recommended Solutions

You can solve this using one of two approaches:

Option A: Keep s and add a hidden post_type field (No Code Needed)

If you want to keep the search input named s, you must tell WordPress to restrict the search to that specific post type.

  1. In your Cornerstone Form for the Events archive, add a Hidden Input element.
  2. Set its Name to post_type.
  3. Set its Value to events.
  4. Do the same for the Documents archive, setting the hidden input value to documents.

When submitted, the URL will contain ?s=keyword&post_type=events, forcing WordPress to run the search specifically on your CPT.

Option B: Keep search and map it via pre_get_posts (Recommended but requires custom coding)

Please note that the following suggestion involves custom coding. We cannot support any issues that might arise from the use of the code nor can we improve the code. For this, you can subscribe to our One service.

If you prefer to keep the search field named search (which avoids WordPress default query side-effects entirely), you can add a small PHP snippet to your child theme’s functions.php file. This hook intercepts the native WordPress query before it runs and applies the search keyword:

add_action('pre_get_posts', function($query) {
  // Apply only on the front-end main archive queries
  if (!is_admin() && $query->is_main_query() && (is_post_type_archive('events') || is_post_type_archive('documents'))) {
    if (!empty($_GET['search'])) {
      $query->set('s', sanitize_text_field($_GET['search']));
    }
  }
});

Thanks @christian for keeping your way of precise and detailed explanations as always.

Unfortunately, Option B solution doesn’t work (I didn’t test Option A). I’ve spent a few hours with AI trying to figure out what the issue is and what could be a fix. And it looks like I am ready to provide AI’s report on the subject.

Cornerstone Forms + Native WP Query looper: search field cannot work, and the recommended pre_get_posts workaround fails due to the form’s AJAX re-render

Following up on my ticket about search fields on CPT archives (post types events , documents , built with ACF; archives use Layouts with a Native WP Query looper and a Cornerstone Form for filtering).

Environment: WordPress [7.0.1], Pro [6.8.12], cornerstone-forms.js ver 1.0.10.

Summary of the problem:

  1. A search text input named s breaks the CPT archive: WordPress flips to a global search context, losing the post type and the assigned archive layout.
  2. A search input named search does not work either — and I can now demonstrate exactly why.

Diagnosis (verified with query-var and SQL logging):

  • The Native WP Query looper does consume the main query, and the pre_get_posts mapping works correctly on a normal page load. Opening the full results URL directly in a new tab — e.g. /events/?search=test&event-level=&cs-form-id=events-filter&event-season=2026&paged=1 — returns correctly filtered and searched results.
  • However, when the user actually submits the form , cornerstone-forms.js intercepts the submission: it updates the URL via history state and re-renders the looper through an AJAX request instead of a page load. In that AJAX context, standard pre_get_posts snippets (including the hook you provided) never apply, because is_admin() is true for admin-ajax and is_main_query() / is_post_type_archive() / is_home() don’t match. Result: filters work, search is silently ignored — in 100% of real user interactions.
  • Reproduction of the contrast: submit the form → search ignored; press browser reload on the identical resulting URL → search works.

Working workaround (PHP snippet update):

add_action( 'pre_get_posts', function ( $query ) {
    	if ( is_admin() && ! wp_doing_ajax() ) {
    		return;
    	}
    	if ( empty( $_REQUEST['search'] ) ) {
    		return;
    	}
    	$post_types = array_filter( (array) $query->get( 'post_type' ) );
    	if (
    		( $query->is_main_query() && $query->is_home() ) || array_intersect( $post_types, array( 'post', 'events', 'documents' ) )
    	) {
    		$query->set( 's', sanitize_text_field( wp_unslash( $_REQUEST['search'] ) ) );
    	}
    }, 9999 );

Requests:

  1. Please treat this as a product gap: Cornerstone Forms currently offers no supported way to connect a search text input to the s parameter of a Native WP Query looper — naming the field s breaks the archive, naming it anything else means the keyword is never applied, and the AJAX re-render defeats the standard WordPress with the hook you recommend.
  2. Ideally, add a field option like “map to WP search ( s )” that restricts the search to the looper’s post type without triggering the global search context — handled consistently in both full page loads and the form’s AJAX re-render.
  3. At minimum, please correct the guidance you provide, since a main-query-only pre_get_posts snippet cannot work with the form’s AJAX submission path.

P.S. With this snippet version, use of ‘search’ for the Search Field Name inside a blog posts archive is also possible for consistancy. This way all URL parameres will look the same no matter if it’s ACF CPT or native WP blog posts. I hope that will help to improve CF Forms in the following updates.

Hey John,

Thank you for your feedback and sharing your working workaround. I’ve forwarded this to our development team as a feature or improvement request.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.