I have a problem when trying to get the search to work for both the default WordPress blog search and WooCommerce product search and I can't seem to find the solution anywhere. What I have in functions.php right now is:
function wp_search_filter($query) {
if ( $query->is_search ) {
$query->set( 'post_type', 'post' );
}
if ( function_exists( 'is_woocommerce' ) ) :
if ( $query->is_search && is_woocommerce() ) {
$query->set( 'post_type', 'product' );
}
endif;
return $query;
}
add_filter('pre_get_posts','wp_search_filter');
But my product search does not work. Any ideas?
To answer my own question, in case anyone needs a solution, I just came up with something that works. The problem here was that the is_woocommerce() condition is not firing on search results template. To get around that I used this code:
function wp_search_filter($query) {
$url = 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
if ( (strpos($url,'post_type=product') !== false) && is_search() ) {
$query->set('post_type', 'product');
}
return $query;
}
add_filter('pre_get_posts','wp_search_filter');
Related
I'm a wordpress newbie. I will try to describe my problem in the clearest way possible.
I'm trying to do two things here:
Remove CPT from a permalink.
Add a custom taxonomy type where it used to be the CPT in the permalink.
Permalinks on site used to be like this:
http://example.com/custom-post-type/post-name
I managed to remove the CPT from the permalink based on this:
how to remove custom post type from wordpress url?
Then I modify my code to add the custom taxonomy type to the permalink to be like this:
http://example.com/post-category/post-name
This is my code:
function remove_cpt_slug( $post_link, $post ) {
if ( 'custom-post-type-name' === $post->post_type && 'publish' === $post->post_status ) {
$post_tags = get_the_terms($post->ID, 'custom-post-type-name-category');
$post_link = str_replace( '/' . $post->post_type . '/', '/' . $post_tags[0]->slug . '/', $post_link );
}
return $post_link;
}
add_filter( 'post_type_link', 'remove_cpt_slug', 10, 2 );
function add_cpt_post_names_to_main_query( $query ) {
// Return if this is not the main query.
if ( ! $query->is_main_query() ) {
return;
}
// Return if this query doesn't match our very specific rewrite rule.
if ( ! isset( $query->query['page'] ) || 2 !== count( $query->query ) ) {
return;
}
// Return if we're not querying based on the post name.
if ( empty( $query->query['name'] ) ) {
return;
}
// Add CPT to the list of post types WP will include when it queries based on the post name.
$query->set( 'post_type', array( 'post', 'page', 'custom-post-type-name' ) );
}
add_action( 'pre_get_posts', 'add_cpt_post_names_to_main_query' );
This worked but now every post from my CPT gives a 404. How can I solve this?
I have the following function in my functions.php, that changes the number of posts displayed per page in the custom post type archive page. How can I also target the corresponding taxonomy page(taxonomy-case.php)? Is there something similar to "is_post_type_taxonomy"?
// Post number limits
function my_cptui_change_posts_per_page( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( is_post_type_archive( 'case' ) ) {
$query->set( 'posts_per_page', 8 );
}
}
add_filter( 'pre_get_posts', 'my_cptui_change_posts_per_page' );
Add below code inside your function and check if it's working. Don't forget to replace your category with your taxonomy name.
if (is_tax( 'your-category' ) ) {
$query->set( 'posts_per_page', 8 );
}
The is_tax() function should accomplish what you're looking to do.
// Post number limits
function my_cptui_change_posts_per_page( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( is_post_type_archive( 'case' || is_tax( 'case' ) ) ) { // Or whatever your taxonomy name is
$query->set( 'posts_per_page', 8 );
}
}
add_filter( 'pre_get_posts', 'my_cptui_change_posts_per_page' );
I just want to customize the theme of WooCommerce in my theme. But the problem is when I add the folder of WooCommerce template to override the WooCommerce theme and after adding this function:
function add_woocommerce_support() {
add_theme_support( 'woocommerce' );
}
add_action( 'after_setup_theme', 'add_woocommerce_support' );
The shop page is not displaying the list of products. Instead the archive post is displaying. But when I comment the add_action of woocommerce theme setup, everything is working fine. See this picture:
I also have this function to display my custom post type all post in archive page:
function add_cpt_program_in_archive( $query ) {
if ( !is_admin() && $query->is_archive() && $query->is_main_query() ) {
$query->set( 'post_type', array('post', 'program' ) );
}
}
add_action( 'pre_get_posts', 'add_cpt_program_in_archive' );
I also try to add !is_shop() in the condition of my add_cpt_program_in_archive function. So its look like this:
function add_cpt_program_in_archive( $query ) {
if ( !is_admin() && $query->is_archive() && $query->is_main_query() && !is_shop() ) {
$query->set( 'post_type', array('post', 'program' ) );
}
}
add_action( 'pre_get_posts', 'add_cpt_program_in_archive' );
The shop page is now displaying the list of products. But the problem is when I visit the category page of product. Example the uncategorized category. It's not displaying the list of product that was in the uncategorized category. See this picture:
I found the solution. I add this code !$query->query_vars['product_cat']) in the condition of my add_cpt_program_in_archive function. So its look like this
function add_cpt_program_in_archive( $query ) {
if ( !is_admin() && $query->is_archive() && $query->is_main_query() && !is_shop() && !$query->query_vars['product_cat']) {
$query->set( 'post_type', array('post', 'program' ) );
}
}
add_action( 'pre_get_posts', 'add_cpt_program_in_archive' );
But I dont know if this is correct format or maybe you guys have a better suggestion answer rather than to my solution.
I have a custom post type(product) with taxonomy product-type. One of my url like this:
http://www.naturesbioscience.com/product-type/immune-support-supplements/
I want this like:
http://www.naturesbioscience.com/immune-support-supplements/
I have used "rewrite" => array('slug' => '/ ', 'with_front' => false in register_taxonomy function and I got the url like:
http://www.naturesbioscience.com/immune-support-supplements/
But I got 404 not found in other pages.
Anyone can help me?
I think you forgot to rewrite custom taxonomy post slug.
Write this in your register_post_type methord.
'rewrite' => array('slug' => 'product-type')
Now you have to remove product-type slug from your custom products
/**
* Remove the slug from published post permalinks.
*/
function custom_remove_cpt_slug($post_link, $post, $leavename)
{
if ('product-type' != $post->post_type || 'publish' != $post->post_status)
{
return $post_link;
}
$post_link = str_replace('/' . $post->post_type . '/', '/', $post_link);
return $post_link;
}
add_filter('post_type_link', 'custom_remove_cpt_slug', 10, 3);
Now as you have removed the custom post type slug so WordPress will try to match it with page or post so you have tell WP to check the URL in you custom post type also. So use this for that:
function custom_parse_request_tricksy($query)
{
// Only noop the main query
if (!$query->is_main_query())
return;
// Only noop our very specific rewrite rule match
if (2 != count($query->query) || !isset($query->query['page']))
{
return;
}
// 'name' will be set if post permalinks are just post_name, otherwise the page rule will match
if (!empty($query->query['name']))
{
$query->set('post_type', array('post', 'product-type', 'page'));
}
}
add_action('pre_get_posts', 'custom_parse_request_tricksy');
Reference: Remove The Slugs from Custom Post Type URL
Hope this helps!
add_filter( 'post_type_link', 'change_product_request', 10, 3 );
function change_product_request( $post_link, $post, $leavename ) {
if ( 'product' != $post->post_type || 'publish' != $post->post_status ) {
return $post_link;
}
$post_link = str_replace( "/{$post->post_type}/" , '/', $post_link );
return $post_link;
}
Now, you'll get a 404 page because WordPress only allow posts and pages to behave in this way. You'll also have to add the following:
add_action( 'pre_get_posts', 'product_permalink' );
function product_permalink( $query ) {
if ( ! $query->is_main_query() ) {
return;
}
if ( 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
return;
}
if ( ! empty( $query->query['pagename'] ) ) { // name has been updated to pagename so $query->query['pagename']
global $wpdb;
$pt = $wpdb->get_var(
"SELECT post_type FROM `{$wpdb->posts}` " .
"WHERE post_name = '{$query->query['pagename']}'"
);
$query->set( 'post_type', $pt );
}
return $query;
}
I had similar issue. The question is quite old, but anyone looking for apt answer can see this.
Do not pass "/" for rewrite slug, since it causes more problem than it solves, as in this case, causing 404 error in other pages.
First, we need to remove the slug from the URL for the published post. Paste the code in functions.php
/**
* Remove the slug from published post permalinks. Only affect our CPT though.
*/
function sh_remove_cpt_slug( $post_link, $post, $leavename ) {
if ( in_array( $post->post_type, array( 'product-type' ) )
|| 'publish' == $post->post_status )
$post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
return $post_link;
}
add_filter( 'post_type_link', 'sh_remove_cpt_slug', 10, 3 );
This will still cause error since it specifies that only 'post' and 'page' post types can have url without post-type slug.
Now to teach WP that out CPT will also have URL without slug, we need to get this in our functions.php
function sh_parse_request_tricksy( $query ) {
// Only loop the main query
if ( ! $query->is_main_query() ) {
return;
}
// Only loop our very specific rewrite rule match
if ( 2 != count( $query->query )
|| ! isset( $query->query['page'] ) )
return;
// 'name' will be set if post permalinks are just post_name, otherwise the page rule will match
if ( ! empty( $query->query['name'] ) ) {
$query->set( 'post_type', array( 'product-type' ) );
}
}
add_action( 'pre_get_posts', 'sh_parse_request_tricksy' );
This is it. Ref: https://wordpress.stackexchange.com/a/320711/98322
I have a website with some custom post type created with Ultimate CMS plugin.
In admin area, when I make a new search, the result is ok, but after that, when I'm try to make a second search, It give me an error "Invalid post type".
I also realize that the url it's not ok:
In the first search, the url is something like this:
http://www.site.com/wp-admin/edit.php?s=SearchTerm1&post_status=all&post_type=post&action=-1&m=0&cat=0&paged=1&mode=list&action2=-1
In the second search, the url is something like:
http://www.site.com/wp-admin/edit.php?s=SearchTerm2&post_status=all&post_type=Array&_wpnonce=4d88f268e4&_wp_http_referer=%2Fwp-admin%2Fedit.php%3Fs%3DSearchTerm1%26post_status%3Dall%26post_type%3Dpost%26action%3D-1%26m%3D0%26cat%3D0%26paged%3D1%26mode%3Dlist%26action2%3D-1&action=-1&m=0&cat=0&paged=1&mode=list&action2=-1
And the error message: "Invalid post type".
I deactived all of my plugins, I upgraded wordpress to the latest version 3.5.1, I reset permalinks to default, but this error still remain.
Any help would be much appreciated!
Thank you
I also came across this issue and found that it was a result of one of my functions in my functions.php file that was modifying the global wordpress query parameters.
It sounds like you edited the global $query object. If you used a hook such as 'pre_get_posts' and manipulated the $query object and you do not exclude the admin area, then any changes you make to the query parameters will also apply to the admin panel and it will display that error when trying to add in parameters that don't fit your search.
For example:
Let's say you have a search feature on your site, and when the user enters a search and goes to the search results page, you only want to display posts of a custom post type called $searchable_posts, then you would add a hook to your functions.php file like this:
function searchfilter($query) {
if ($query->is_search && $query->is_main_query() ) {
$query->set('post_type', $searchable_posts);
}
return $query;
}
add_filter('pre_get_posts', 'searchfilter');
This will make it so that any global default $query will only search for results that have a matching post type of $searchable_posts. However, the way it is written above means this will also apply to any global $query in the admin panel also.
The way around this is to structure your query like this:
function searchfilter($query) {
if ($query->is_search && $query->is_main_query() && !is_admin() ) {
$query->set('post_type', $searchable_posts);
}
return $query;
}
add_filter('pre_get_posts', 'searchfilter');
Adding in that !is_admin() means that your function will exclude anything in the backend administration panel (see is_admin ).
Alternatively, a safer way if you can, instead of using the global default $query is to create your own new WP_Query and searching using that instead - the codex has good examples of how to set that up.
I am also get the issue same as you and finally I got the solution.
We have to add $query->is_main_query() in IF CONDITION.
Below is the full code.
function acf_meta_value_filter() {
global $typenow;
global $wp_query;
if ( $typenow == 'your_custom_post_type_name' ) { // Your custom post type meta_key_name
$plugins = array( 'value1', 'value2', 'value3' ); // Options for the filter select field
$current_plugin = '';
if( isset( $_GET['meta_key_name'] ) ) {
$current_plugin = $_GET['meta_key_name']; // Check if option has been selected
} ?>
<select name="meta_key_name" id="meta_key_name">
<option value="all" <?php selected( 'all', $current_plugin ); ?>><?php _e( 'All', '' ); ?></option>
<?php foreach( $plugins as $key=>$value ) { ?>
<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $value, $current_plugin ); ?>><?php echo esc_attr( $value ); ?></option>
<?php } ?>
</select>
<?php }
}
add_action( 'restrict_manage_posts', 'acf_meta_value_filter' );
function acf_meta_value_filter_by_slug( $query ) {
global $pagenow;
// Get the post type
$post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : '';
if ( is_admin() && $pagenow=='edit.php' && $post_type == 'your_custom_post_type_name' && isset( $_GET['meta_key_name'] ) && $_GET['meta_key_name'] !='all' && $query->is_main_query()) {
$query->query_vars['meta_key'] = 'meta_key_name';
$query->query_vars['meta_value'] = $_GET['meta_key_name'];
$query->query_vars['meta_compare'] = '=';
}
}
add_filter( 'parse_query', 'acf_meta_value_filter_by_slug' );
I had a similar problem with a site a took over from other dev.
function anty_search_form( $query ) {
if ( $query->is_search ) {
$query->set( 'post_type', array('post', 'product') );
}
return $query;
}
add_filter( 'pre_get_posts', 'anty_search_form' );
Someone forgot to exclude this function from wp-admin page. So changing to this helped Invalid post type.
function anty_search_form( $query ) {
if (!is_admin()){
if ( $query->is_search ) {
$query->set( 'post_type', array('post', 'product') );
}
return $query;
}
}
add_filter( 'pre_get_posts', 'anty_search_form' );
At wp-admin when submitted the second search for a custom post type, I was getting the same error, "Invalid post type." The URL seemed long and incorrect. Anyway, the following code worked perfectly:
add_filter( 'pre_get_posts', 'tgm_io_cpt_search' );
function tgm_io_cpt_search( $query ) {
if ( $query->is_search ) {
$query->set( 'post_type', 'your_custom_post_type' );
}
return $query;
}