Filter wordpress query by checkboxes - wordpress

I have a situation where I have a query with two different post types and I have to checkboxes on top with the names of post type. I wont by default those checkboxes to be checked and if one of theme is unchecked to remove that post type and the post affiliated to that post type from the query.

This part is circumstancial, but you get the idea. Give the values to the ones that are/aren't checked.
if($checkboxone == '1') {
$types = array( 'typeone' )
}
if($checkboxtwo == '1') {
$types = array( 'typetwo' )
}
if($checkboxtwo == '1' && $checkboxone == '1'){
$types = array( 'typeone', 'typetwo' )
}
then plug that value into your WP_Query by some means like this. the documentation for it is here
// The Query
$the_query = new WP_Query( array( 'post_type' => $types );
// The Loop
while ( $the_query->have_posts() ) : $the_query->the_post();
//DO STUFF
endwhile;
// Reset Post Data
wp_reset_postdata();

Related

Get the value of a field in gravity forms and use that value as a php parameter?

I am trying to dynamically populate two dropdown fields in a Gravity Forms form. The first field dynamically populates with the terms available in a custom post type. I want the second dynamically populated field to contain the list of all post titles within the custom post type AND have those titles filtered by the term selected in the previous dropdown. Is it possible to get the value of a dropdown within Gravity Forms and pass that value as a parameter in $args to use the get_posts($args) function?
I started using the following tutorial as a guide. https://docs.gravityforms.com/dynamically-populating-drop-down-fields/
add_filter( 'gform_pre_render_3', 'populate_procedures' );
add_filter( 'gform_pre_validation_3', 'populate_procedures' );
add_filter( 'gform_pre_submission_filter_3', 'populate_procedures' );
add_filter( 'gform_admin_pre_render_3', 'populate_procedures' );
function populate_procedures( $form ) {
// Procedure Category Dropdown
foreach ( $form['fields'] as &$field ) {
The first field. The following code populates a dropdown field containing a list of all of the terms within a custom post type (procedure):
if ( $field->type != 'select' || strpos( $field->cssClass, 'populate_procedure_categories' ) === false ) {
continue;
}
$terms = get_terms( array(
'taxonomy' => 'procedure_category',
'orderby' => 'name',
'order' => 'ASC',
) );
// you can add additional parameters here to alter the posts that are retrieved
// more info: http://codex.wordpress.org/Template_Tags/get_posts
//$posts = get_posts( 'post_type=procedure&numberposts=-1&post_status=publish' );
$choices = array();
foreach ( $terms as $term ) {
$choices[] = array( 'text' => $term->name, 'value' => $term->name );
}
// update 'Select a Post' to whatever you'd like the instructive option to be
$field->placeholder = 'Select Procedure Category';
$field->choices = $choices;
The second field. The following code dynamically populates the field with all of the the post titles of the custom post type (procedure). I want to filter these results based upon the value selected above.
if ( $field->type != 'select' || strpos( $field->cssClass, 'populate_procedures' ) === false ) {
continue;
}
$args = array(
'post_status' => 'publish',
'post_type' => 'procedure',
'procedure_category' => 'cardiovascular',
);
$posts = get_posts( $args );
$choices = array();
foreach ( $posts as $post ) {
$choices[] = array( 'text' => $post->post_title, 'value' => $post->post_title );
}
// update 'Select a Post' to whatever you'd like the instructive option to be
$field->placeholder = 'Select Procedure';
$field->choices = $choices;
}
return $form;
}
The second dynamically populated field successfully pulls in the filtered list of post titles based on the $args if I explicitly listed the term (in the example above I used 'cardiovascular'). What I am wondering is if there is a way to grab the value of the previous field and use that to filter the results of the second field (without having to reload the page). Any ideas? Does Gravity Forms have a functionality like this built in?
Using this method, you would need to use multiple pages and add the second Drop Down field to the second page on the form. Then, when the user submits the first page, you can access the value of the first Drop Down from the $_POST. Gravity Forms has a helper method for doing this called rgpost(). Here's what your $args might look like:
$args = array(
'post_status' => 'publish',
'post_type' => 'procedure',
'procedure_category' => rgpost( 'input_FIELDID' ),
);
Replace FIELDID with the field ID of your first Drop Down.
With that said, if you want to accomplish this without having to touch any code, try Gravity Forms Populate Anything.
https://gravitywiz.com/documentation/gravity-forms-populate-anything/

$wp_query and WP_QUERY - same arguments, different results

I spend this whole day trying to figure out a problem with a combination of a custom query and custom post types. This is my last resort...
The setting
I wrote a plugin that introduces some custom post types to my WordPress. To display them in the main query I hooked them into the query like this:
function add_cpt_to_query( $query ) {
*some code...*
// add custom post types to query
if ( !( is_admin() || is_post_type_archive() || is_page() ) && $query->is_main_query() ) {
$query->set('post_type', array_merge( array('post'), $cpt ) );
}
}
add_action('pre_get_posts','add_cpt_to_query');
In my theme on the other hand I setup ajax pagination like this:
function setup_pagination() {
global $wp_query;
$max_pages = $wp_query->max_num_pages;
$current_page = ( $wp_query->paged > 1 ) ? $wp_query->paged : 1;
$ajaxurl = admin_url( 'admin-ajax.php' );
wp_register_script( 'ajax-pagination', get_template_directory_uri() .'/js/dummy.js', array('jquery'), '', true);
wp_localize_script( 'ajax-pagination', 'ajaxpagination', array(
'max_pages' => $max_pages,
'current_page' => $current_page,
'ajaxurl' => $ajaxurl,
'query_vars' => $wp_query->query_vars
));
wp_enqueue_script( 'ajax-pagination' );
}
add_action( 'wp_enqueue_scripts', 'setup_pagination' );
function pagination() {
$query = $_POST['query_vars'];
$query['paged'] = $_POST['next_page'];
/*
$query = array(
'paged' => 2,
'post_type' => array('post', 'custom_post_type_1', 'custom_post_type_2' )
);
*/
$posts = new WP_Query( $query );
$GLOBALS['wp_query'] = $posts;
// Start the loop.
while ( have_posts() ) : the_post();
?>
*some code...*
<?php endwhile;
die();
}
add_action( 'wp_ajax_nopriv_ajax_pagination', 'pagination' );
add_action( 'wp_ajax_ajax_pagination', 'pagination' );
and the script part:
$.ajax({
url: ajaxpagination.ajaxurl,
type: 'post',
data: {
action: 'ajax_pagination',
query_vars: ajaxpagination.query_vars,
next_page: parseInt(ajaxpagination.current_page) + 1
}
});
The problem
If I pass the query_vars array I get from $wp_query with the altered 'paged' value back to WP_QUERY, it returns the wrong set of posts. It looks like, that WP_QUERY does not account for the cpts in the loop. Though these cpts are mentioned in the 'post_type' of the query_vars array and thereby passed along to the new WP_QUERY.
When I manually set 'post_type' and only pass this argument, it works as intended. The aspect that blows my mind is, that the resulting query_vars used in the ajax call to WP_QUERY are exactly the same, but only when I manually set 'post_type' the pagination works as it should.
I dont know if this was a somewhat understandable explanation, but I'm thankful for every idea that could help me out. Big THX!
Ok... I got it now.
I made a mistake in wp_localize_script(). The query_vars should be a json-string, I on the other hand just passed the array itself. My code above has to be altered in two lines:
function mk_setup_pagination() {
...
wp_localize_script( 'ajax-pagination', 'ajaxpagination', array(
...
'query_vars' => json_encode($wp_query->query_vars) <- convert to json-string
));
...
}
function mk_pagination() {
$query = json_decode( stripslashes( $_POST['query_vars'] ) , true); <- convert json-string to array
...
Works like a charm now. :)
btw: the code is based on a tutorial by wpmudev.org: Loading WordPress Posts Dynamically With AJAX

wordpress $query->set by meta key value

I am trying to modify all queries of a post type "products" to only show if the product/post has a certain meta_key of "wholesale_price" which the meta_value needs to be greater than 0.
Here is what i have:
add_action( 'pre_get_posts', 'rc_modify_query_get_design_projects' );
function rc_modify_query_get_design_projects( $query ) {
if($query->is_main_query() && $query->query_vars['post_type'] == 'product' ) {
$query->set('meta_key', 'wholesale_price');
$query->set('meta_compare', '>');
$query->set('meta_value', '0');
}
}
For some reason this still returns everything. Is this the right way of doing things?
The problem is the method by which you are setting your meta_query. You should read up on the WP_Query functionality, because meta queries are unfortunately not that simple.
You need to do something more like so:
add_action( 'pre_get_posts', 'rc_modify_query_get_design_projects' );
function rc_modify_query_get_design_projects( $query ) {
// Do not add meta arguments in admin pages
if (is_admin()) {
return;
}
if($query->is_main_query() && $query->query_vars['post_type'] == 'product' ) {
//Get original meta query
$meta_query = (array)$query->get('meta_query');
// Add your criteria
$meta_query[] = array(
'key' => 'wholesale_price',
'value' => 0,
'compare' => '>',
);
// Set the meta query to the complete, altered query
$query->set('meta_query',$meta_query);
}
And no need to return anything in this function.

Wordpress: Custom post type segregation on Category page

I've got two custom post types, for example 'Cars' and 'Bikes'. I've used Wordpress's default category to categorise the posts from the two post types. Let's say for example the categories are 'Red', 'Blue' and 'Black'.
What I'm trying to achieve here is that when I go to the category page for 'Red', I want to see the 'Cars' and the 'Bikes' that are categorised under 'Red'. I'm using the category.php and this is the query that I'm trying to run:
$car_args = array(
'posts_per_page' => -1,
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'cars',
'post_status' => 'publish',
'cat' => $cat
);
// The Query
$car_query = new WP_Query( $car_args );
// The Loop
if ( $car_query ->have_posts() ) {
echo "<h3>Cars</h3>";
while ( $car_query->have_posts() ) {
$car_query->the_post();
echo get_post_type() . '' . get_the_title() . '<br />';
}
} else {
// no posts found
}
$bikes_args = array(
'posts_per_page' => -1,
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'bikes',
'post_status' => 'publish',
'cat' => $cat
);
// The Query
$bikes_query = new WP_Query( $bikes_args );
// The Loop
if ( $bikes_query ->have_posts() ) {
echo "<h3>Bikes</h3>";
while ( $bikes_query->have_posts() ) {
$bikes_query->the_post();
echo get_post_type() . '' . get_the_title() . '<br />';
}
} else {
// no posts found
}
/* Restore original Post Data */
wp_reset_postdata();
The $cat in the query gets the category id of 'Red' category. Both these queries are correctly restricting the posts by the 'Red' category but posts from both the 'Cars' post type and 'Bikes' post type are showing up even though I've tried to restrict by post type. I've read in a few articles that Wordpress ignores the post type args on the category page. Is this true and if it is, is there a workaround for this?
What you are trying to do is possible with one query only, and only with the main query without any custom queries.
First of all, lets first add your custom post types to your category page. By default, custom pist types are excluded from category pages. So we need to add this manually to the main query arguments via pre_get_posts. Add the following to your functions.php: (CAVEAT: Untested and also requires PHP 5.3+)
add_action( 'pre_get_posts', function ( $q )
{
if ( !is_admin() && $q->is_main_query() && $q->is_category() ) {
$q->set( 'post_type', array( 'post', 'cars', 'bikes' ) ); // Change this according to your post types
$q->set( 'nopaging', true ); // This will get all posts, same as posts_per_page=-1
}
});
You should now have all posts from a clicked category is your set post types on your category pages.
Next, wee need to sort out your loops. Delete all your custom queries in category.php and replace it with the default loop. As you would want two block ordered by post type, we will use rewind_posts() so we can run the loop twice
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
if ( $post->post_type == 'cars' ) { //Change accordingly to only show cars in this loop
// Your loop
}
}
rewind_posts();
while ( have_posts() ) {
the_post();
if ( $post->post_type == 'bikes' ) { // Change accordingly to only show bikes
// Your loop
}
}
}
This should now display your posts in two block sorted by post type

How to refresh pagination links after submit new query?

I modified WordPress main loop for blog posts, made it query and loop through different types of posts according to what filter is submitted.
At the beginning of the HTML, there is a form with several buttons as option, it's similar to the SA site menu: Questions Tags Users Badges Unanswered.
When visitor click one of the menu button, a new WP_Query is submitted.
Below the options, is the loop of posts, depends on what filter is submitted.
The php codes is basically a standard wordpress loop with customized functions:
$args= !empty($_POST['filter']) ? $_POST['filter']:null;
get_option_nav();
if( my_loop_have_posts(array('filter'=>$args))):
while my_loop_posts(): the_my_loop_post();
get_template_part('contents');
endwhile;
endif;
Things are working fine except that only the default filter get the correct pagination links. After submit a new filter, when click the pagination links, it goes to the default filter's pages. How to modify wordpress pagination links to get it work for the other filters?
Here's the code that I use for query args:
function get_args($args){
$defaults= array(
'order' => 'DESC',
'orderby' => 'modified',
'max_num_pages' =>5,
'paged' => get_paged (),
'post_status' => 'any',
'post_type' => array ('post', 'docs','topics'),
'posts_per_page' => 5,
)
$args = wp_parse_args ( $args, $defaults );
extract ( $args );
if(!empty($args['filter'])){
switch ($args['filter']){
case 'top_voted':
$args['post_type'] = 'docs';
$args['meta_key'] = '_vote_total';
$args['order'] = 'DESC';
$args['orderby']='meta_value_num';
break;
case 'unanswered_questions':
$args['post_type] = 'topics';
$args['blabla'] = 'blabla';
break;
default:
blabla;
break;
}
return $args;
}
and the code for the paged:
function get_paged() {
global $wp_query;
if ( get_query_var( 'paged' ) ) {
$paged = get_query_var( 'paged' );
} elseif ( ! empty( $wp_query->query['paged'] ) ) {
$paged = $wp_query->query['paged'];
}
if ( ! empty( $paged ) )
return (int) $paged;
return 1;
}
When you make a custom query, you need to explicitly call every parameter of the query. Thus, standard ones disappear, as is the pagination case.
Depending on how you are making this new query you could try:
To concatenate at the beginning $query_string, for example
$query = new WP_Query( $query_string . 'order=DESC' ) As it is explained in the Codex:
If you want to preserve the original query parameter information that
was used to generate the current query, and then add or over-ride some
parameters, you can use the $query_string global variable in the call
to query_posts().
To get the pagination from the default query and use it in your custom query
$paged = get_query_var('paged'); $query = new WP_Query( array( 'paged' => $paged ) );
In your case there is something wrong with your get_paged() function. I have tested it and it does not work, but I have not found the bug. Instead, I tried what I usually use, and it works for me:
function get_paged() {
if ( get_query_var('paged') ) {
$paged = get_query_var('paged');
} elseif ( get_query_var('page') ) { $paged = get_query_var('page');
} else { $paged = 1; }
return $paged;
}
Something seems to fail in you else if statement. Let me know if this solves your issue.

Resources