My website is build with alot of parents and childs.
I am currently using the follow function: https://gist.github.com/mprahweb/3c94d9c65b32ec9e3b2908305efd77d5
However it doesnt achieve what i want. I can only use it under the parent.
I want to be able to use a shortcode to list a child-pages for a specfic parent on any page (mainly the homepage)
The dream would be that i could have a shortcode like this:
[wpb_childpages_xxx] where xxx equals the parent page
is this possible?
Here is the modified code:
function wpb_list_child_pages( $atts = array() ) {
$atts = shortcode_atts( array(
'id' => 0,
'slug' => '',
), $atts );
if ( $atts['slug'] ) {
global $wpdb;
$q = $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_name = %s", $atts['slug'] );
$post_id = $wpdb->get_var( $q );
if ( ! $post_id ) {
return '';
}
} else {
$post_id = absint( $atts['id'] );
}
$post = get_post( $post_id ); // WP_Post on success.
$childpages = '';
if ( $post && is_post_type_hierarchical( $post->post_type ) ) {
$childpages = wp_list_pages( array(
'child_of' => $post->ID,
'title_li' => '',
'echo' => 0,
) );
}
if ( $childpages ) {
$childpages = '<ul>' . $childpages . '</ul>';
}
return $childpages;
}
add_shortcode( 'wpb_childpages', 'wpb_list_child_pages' );
Using the Shortcode β use either id or slug, but if you specify a slug, the id will be ignored:
To show child pages of the current page:
[wpb_childpages /]
To show child pages of any pages:
With the post ID: [wpb_childpages id="{POST_ID} /]
E.g. [wpb_childpages id="123" /]
With the post slug: [wpb_childpages slug="{SLUG} /]
E.g. [wpb_childpages slug="home" /]
Related
when you are a new designer and start working with several content editors in wordpress, the first thing you realize is that it is not easy to find the functions you want exactly.
plugin editors can't think of everything.. and especially extract information to display them everywhere in the desired and consistent manner.
that's why wordpress shortcodes exist. but you have to master them.. first! (which is precisely my handicap currently)
Grab your cup of coffee β and admire the detailed visual of today's issue
It will be very short and precise,
before starting look at what taxonomies we have in our post..
my current code allows me to do figure 1, as you can see it quickly becomes limited when you try to be .. more creative
add_shortcode( 'parent-child', 'taxonomy_hierarchy' );
function taxonomy_hierarchy( $atts ){
// Don't extract, rather parse shortcode params with defaults.
$atts = shortcode_atts( array(
'link' => 'true',
'taxonomy' => 'property_city'
), $atts, 'parent-child' );
// Check the $atts parameters and their typecasting.
//var_dump( $atts );
global $post;
$terms = wp_get_post_terms( $post->ID, $atts['taxonomy'] );
/* You can pass conditions here to override
* $link based on certain conditions. If it's
* a single post, current user is editor, etc.
*/
ob_start();
foreach( $terms as $term ){
if( $term->parent != 0 ){
$parent_term = get_term( $term->parent, $taxonomy );
if ($atts['link'] !== 'false') {
printf( '%s, ', esc_url( get_term_link($parent_term) ), $parent_term->name );
} else {
echo $parent_term->name . ', ';
}
}
if ($atts['link'] !== 'false') {
printf( '%s', esc_url( get_term_link($term) ), $term->name );
} else {
echo $term->name;
}
}
return ob_get_clean();
}
in this figure 1 we don't need to display "residential" and "rental" it doesn't make sense it's confusing. we don't have control over this.
but..What if I want to test and accomplish figure 2, figure 3 and figure 4
You : but there are already shortcodes what is it???
yes, don't worry, I took care to simulate a logic of things inside shortcodes, maybe that's not exactly how it's going to be. or how things work ..
I prefer to remain cautious and wait for your opinion or solution.
if logic allows, we need to separate the parent and childs values ββand paste them back as we want
like a puzzle
Something Like π
β[taxonomy-parent = "name_of_my_taxonomy"]
β[taxonomy-child = "name_of_my_taxonomy"]
or simply reverse in some cases
β[child-parent] (manhattan, new york)
β[parend-child] (new york, manhattan)
note that I used [acf field "name field here"] to invoke a price value, if it is possible to fit it inside our combination or leave it like that?
final word: you can tell I spent some time working out and thinking about this, if only coding was that easy for me I would have done even better. for now that's all I need more flexibility to display information in different ways.
You could consider using an array() instead to store the $parent if it exists, and then the $child which should exist. This would give you the benefit of being able to use array_reverse() to flip the order of the terms based on a parameter saying whether you want the parent or the child first. This gives you the added benefit of being able to convert the array to a string with the implode() function, which you can pass a $glue argument to, to determine whether you want them separated by a space, comma + space, hyphen, slash, etc.
add_shortcode( 'parent-child', 'taxonomy_hierarchy' );
function taxonomy_hierarchy( $atts ){
// Don't extract, rather parse shortcode params with defaults.
$atts = shortcode_atts( array(
'link' => 'true',
'glue' => ', ',
'taxonomy' => 'property_city',
'first' => 'parent',
), $atts, 'parent-child' );
// Check the $atts parameters and their typecasting.
//var_dump( $atts );
global $post;
$terms = wp_get_post_terms( $post->ID, $atts['taxonomy'] );
/* You can pass conditions here to override
* $link based on certain conditions. If it's
* a single post, current user is editor, etc.
*/
$array = array();
foreach( $terms as $term ){
if( $term->parent != 0 ){
$parent_term = get_term( $term->parent, $taxonomy );
if ($atts['link'] !== 'false') {
$array[] = sprintf( '%s', esc_url( get_term_link($parent_term) ), $parent_term->name );
} else {
$array[] = $parent_term->name;
}
}
if( $atts['link'] !== 'false' ){
$array = sprintf( '%s', esc_url( get_term_link($term) ), $term->name );
} else {
$array = $term->name;
}
}
if( $atts['first'] != 'parent' ){
$array = array_reverse( $array );
}
return implode($glue, $array);
}
Doing this should give you the ability to put out shortcodes like:
[parent-child first="child" glue=" - "] // Child - Parent
[parent-child glue="/"] // Parent/Child
Documentation & Function Reference
Function
Linked Description
array_reverse()
Return an array with elements in reverse order
implode()
Join array elements with a string
I think I found a solution but in this case it is no longer a shortcode with parameters.
it's become a bunch of shortcodes with a parameters, at least we have more flexibility now.
I simply cut the code into 3 parts
if you are not afraid to see π° very long complicated shortcodes. it's a solution that will help.
but I'm not sure if this is the best practice.
output taxonomy parent, child
/*output taxonomy parent, child*/
add_shortcode( 'parent-child', 'taxonomy_hierarchy' );
function taxonomy_hierarchy( $atts ){
$atts = shortcode_atts( array(
'link' => 'true',
'taxonomy' => 'property_city' // my default taxonomy
), $atts, 'parent-child' );
global $post;
$terms = wp_get_post_terms( $post->ID, $atts['taxonomy'] );
ob_start();
foreach( $terms as $term ){
if( $term->parent != 0 ){
$parent_term = get_term( $term->parent, $taxonomy );
if ($atts['link'] !== 'false') {
printf( '%s, ', esc_url( get_term_link($parent_term) ), $parent_term->name );
} else {
echo $parent_term->name . ', ';
}
}
if ($atts['link'] !== 'false') {
printf( '%s', esc_url( get_term_link($term) ), $term->name );
} else {
echo $term->name;
}
}
return ob_get_clean();
}
output only taxonomy parent
/*output only taxonomy parent*/
add_shortcode( 'parent', 'taxonomy_parent' );
function taxonomy_parent( $atts ){
$atts = shortcode_atts( array(
'link' => 'true',
'taxonomy' => 'property_city' // my default taxonomy
), $atts, 'parent' );
global $post;
$terms = wp_get_post_terms( $post->ID, $atts['taxonomy'] );
ob_start();
foreach( $terms as $term ){
if( $term->parent != 0 ){
$parent_term = get_term( $term->parent, $taxonomy );
if ($atts['link'] !== 'false') {
printf( '%s', esc_url( get_term_link($parent_term) ), $parent_term->name );
} else {
echo $parent_term->name;
}
}
}
return ob_get_clean();
}
output only taxonomy child
/*output only taxonomy child*/
add_shortcode( 'child', 'taxonomy_child' );
function taxonomy_child( $atts ){
$atts = shortcode_atts( array(
'link' => 'true',
'taxonomy' => 'property_city' // my default taxonomy
), $atts, 'child' );
global $post;
$terms = wp_get_post_terms( $post->ID, $atts['taxonomy'] );
ob_start();
foreach( $terms as $term ){
if ($atts['link'] !== 'false') {
printf( '%s', esc_url( get_term_link($term) ), $term->name );
} else {
echo $term->name;
}
}
return ob_get_clean();
}
I'm writing some details of each prodcuts (short/long description) on woocommerce.
i'd like to insert a SHORTCODE inside the description that shows the current PRICE (sale / regular).
it should look something like that on the backend:
"Buy it now, for only [wc_price] $"
is there any shortcode i can use for that?
This is one the most simple snippet that does what you want without the need of inputting the id manually:
function my_shortcode_product_price() {
$html = '';
global $product;
$price = wc_get_price_to_display( $product, array( 'price' => $product->get_price() ) );
$args = array(
'ex_tax_label' => false,
'currency' => 'USD',
'decimal_separator' => '.',
'thousand_separator' => ' ',
'decimals' => 2,
'price_format' => '%2$s %1$s',
);
$html = "<span>" . wc_price( $price, $args ) . "</span>";
return $html;
}
add_shortcode( 'product_price', 'my_shortcode_product_price' );
The above code goes in the functions.php file of your active theme. After that you can use the shortcode like this:
[product_price]
Here You Go: add this code in your function.php
function short_code_woo_comm_desc( $atts ) {
$atts = shortcode_atts( array(
'id' => null
), $atts, 'tag_for_short_code_price' );
if ( empty( $atts[ 'id' ] ) ) {
return '';
}
$product = wc_get_product( $atts['id'] );
if ( ! $product ) {
return '';
}
return $product->get_price_html();
}
add_shortcode( 'tag_for_short_code_price', 'short_code_woo_comm_desc' );
Use:
[tag_for_short_code_price id="101"]
I have a custom post type named location and I'm trying to set posts of this type as children of existing pages, to achieve a permalink structure like this:
example.com/alabama <-- Page with generic content
example.com/alabama/locations <-- Another page, child of a state page
example.com/alabama/locations/location-name <- Custom type, child of alabama/locations seen above and titled `Location Name`
The closest I've got to create hierarchical relationships between two distinct post types was through a meta box where I can assign a post ID as the post_parent of my custom type posts when saving them. However despite the page ID being indeed saved to the CPT post_parent field, it has no effect on the permalinks. They are coming as defined in the rewrite CPT option. But I don't know how to make the ['rewrite']['slug'] option dynamic, or if it's even possible.
This is how my post type is being defined:
add_action( 'init', function() {
register_post_type( 'location', [
'label' => 'Location',
'menu_icon' => 'dashicons-location-alt',
'supports' => [ 'title', 'editor', 'custom-fields' ],
'public' => true,
'hierarchical' => false,
'has_archive' => false,
'rewrite' => false,
] );
} );
How can I configure the rewrite rules for locations to get the permalinks I need?
I'm assuming that all the location posts will have a permalink structure that looks like this:
example.com/{STATE NAME}/locations/{CPT SLUG}
Sample URL addresses:
http://example.com/alabama/locations/location-1
http://example.com/alabama/locations/location-2
http://example.com/new-york/locations/location-3
So if that is correct, then:
β’ Use the add_rewrite_rule() function to add a custom rewrite rule for those permalinks.
β’ You don't need the /locations/ Page.
add_action( 'init', function(){
// Handles requests to `your-site-domain.com/{STATE NAME}/locations/{CPT SLUG}`
add_rewrite_rule(
'([^/]+)/locations/([^/]+)(?:/([0-9]+))?/?$',
'index.php?location=$matches[2]&page=$matches[3]&state_name=$matches[1]',
'top'
);
// Allows you to retrieve the `state_name`; for example using `get_query_var()`.
add_rewrite_tag( '%state_name%', '([\w\-]+)' );
} );
(You can change state_name to another name; it's up to you. And don't forget to flush the rewrite rules β go to the Permalink Settings page and click on the Save Changes button without having to make any changes.)
Next, when you create or edit a location post, set the value of the post_parent custom field to the ID of the 'state Page' β e.g. the /alabama/ Page.
And this code will filter the get_permalink() output, and returns the appropriate permalink for a location post:
add_filter( 'post_type_link', 'so51217355_post_type_link', 10, 2 );
function so51217355_post_type_link( $permalink, $post ) {
if ( 'location' === $post->post_type ) {
$page_id = get_post_meta( $post->ID, 'post_parent', true );
$state_name = ( is_numeric( $page_id ) && $page_id ) ?
get_post_field( 'post_name', $page_id ) : null;
// Make sure the post is associated to a valid 'state Page'.
if ( $state_name ) {
$permalink = $state_name . '/locations/' . $post->post_name;
$permalink = home_url( user_trailingslashit( $permalink ) );
}
}
return $permalink;
}
So for example, get_permalink( 123 ) would return http://example.com/alabama/locations/location-1, if the location post's slug is location-1, and its 'state Page' is /alabama/.
UPDATE
When the permalink is requested (i.e. users visit example.com/{STATE NAME}/locations/{CPT SLUG}), and you want to make sure the 'state Page' and location post both exist, and that the 'state Page' was indeed associated to the location post, then this code can help you:
// Validates the `state_name` of the current page/URL.
add_action( 'parse_request', 'so51217355_parse_request' );
function so51217355_parse_request( $wp ) {
if ( ! empty( $wp->query_vars['state_name'] ) &&
! empty( $wp->query_vars['location'] ) ) {
global $wpdb;
$page_id = $wpdb->get_var( $wpdb->prepare(
"SELECT ID FROM {$wpdb->posts} WHERE post_name = %s",
$wp->query_vars['state_name']
) );
if ( ! is_numeric( $page_id ) || ! $page_id ) {
$wp->query_vars['error'] = '404';
// Don't let WordPress finds a post with nearest match.
remove_action( 'template_redirect', 'redirect_canonical' );
return;
}
$post_id = $wpdb->get_var( $wpdb->prepare(
"SELECT ID FROM {$wpdb->posts} WHERE post_name = %s",
$wp->query_vars['location']
) );
$page_id2 = get_post_meta( $post_id, 'post_parent', true );
if ( (int) $page_id2 !== (int) $page_id ) {
$wp->query_vars['error'] = '404';
// Don't let WordPress finds a post with nearest match.
remove_action( 'template_redirect', 'redirect_canonical' );
}
}
}
UPDATE #2
Refer to the // Comment in the code below this image β see the _so51217355_admin_ajax_js() function.
add_action( 'wp_ajax_so51217355_admin_ajax', '_so51217355_admin_ajax_php' );
function _so51217355_admin_ajax_php() {
$post_id = filter_input( INPUT_POST, 'post_id' );
echo get_sample_permalink_html( $post_id );
wp_die();
}
add_action( 'admin_print_footer_scripts', '_so51217355_admin_ajax_js', 11 );
function _so51217355_admin_ajax_js() {
$screen = get_current_screen();
if ( 'location' === $screen->id ) :
?>
<script>
// This script will sync the Permalink under the big/main post title box on
// the Edit Post page; but only if and when editing or deleting the custom
// field as in `meta_key` below. Make sure to change it, if necessary.
jQuery( function( $ ){
var meta_key = 'post_parent';
function ajax() {
$.post( ajaxurl, {
action: 'so51217355_admin_ajax',
post_id: $( '#post_ID' ).val()
}, function( s ){
$( '#edit-slug-box' ).html( s );
} );
}
function _go( e, a ) {
var $input = $( a.target ),
mid, mkey;
if ( /^meta\-(\d+)\-submit$/.test( $input.attr( 'name' ) ) ||
/^deletemeta\[(\d+)\]$/.test( $input.attr( 'name' ) ) ) {
mid = RegExp.$1;
mkey = $( 'input[name="meta[' + mid + '][key]"]' ).val();
if ( meta_key === mkey ) {
ajax();
}
}
}
$( '#the-list' )
.on( 'wpListAddEnd', _go )
.on( 'wpListDelEnd', _go );
} );
</script>
<?php
endif;
}
So i make custom form-tag in contact form 7! It is a drop down with list of my courses and now I want to make it required because that is the main thing in whole form.
So can someone give me a tip how to do that?
When I do the [myCustomField* course-name class:custom-field]
It does not working with *
So if someone can help it will be great!
I have been working on this myself this afternoon and I do not think Mahmoud has added everything that is needed to get the validation working well and the messages showing up.
using what I have learnt from the posts on contact form 7 here:
https://contactform7.com/2015/01/10/adding-a-custom-form-tag
https://contactform7.com/2015/02/27/using-values-from-a-form-tag/
and looking at this file in the plugin: contact-form-7/modules/select.php which helped a lot.
I think this will work better and needs to be added to your functions.php file in your child-theme.
add_action( 'wpcf7_init', 'custom_add_form_tag_myCustomField' );
function custom_add_form_tag_myCustomField() {
wpcf7_add_form_tag( array( 'myCustomField', 'myCustomField*' ),
'custom_myCustomField_form_tag_handler', true );
}
function custom_myCustomField_form_tag_handler( $tag ) {
$tag = new WPCF7_FormTag( $tag );
if ( empty( $tag->name ) ) {
return '';
}
$validation_error = wpcf7_get_validation_error( $tag->name );
$class = wpcf7_form_controls_class( $tag->type );
if ( $validation_error ) {
$class .= ' wpcf7-not-valid';
}
$atts = array();
$atts['class'] = $tag->get_class_option( $class );
$atts['id'] = $tag->get_id_option();
if ( $tag->is_required() ) {
$atts['aria-required'] = 'true';
}
$atts['aria-invalid'] = $validation_error ? 'true' : 'false';
$atts['name'] = $tag->name;
$atts = wpcf7_format_atts( $atts );
$myCustomField = '';
$query = new WP_Query(array(
'post_type' => 'CUSTOM POST TYPE HERE',
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
));
while ($query->have_posts()) {
$query->the_post();
$post_title = get_the_title();
$myCustomField .= sprintf( '<option value="%1$s">%1$s</option>',
esc_html( $post_title ) );
}
wp_reset_query();
$myCustomField = sprintf(
'<span class="wpcf7-form-control-wrap %1$s"><select %2$s>%3$s</select>%4$s</span>',
sanitize_html_class( $tag->name ),
$atts,
$myCustomField,
$validation_error
);
return $myCustomField;
}
That is how we create the custom tag. The important differences here are the addition of the $validation_error variables as wells the aria-required and aria-invalid data. It is also important to include the $validation_error in the final output so that we can see the validation messages being created.
Then to finish it off we need to add some validation via filters.
There is no documentation on this yet, but I used the functions from the select.php and altered them to what I needed.
/* Validation filter */
add_filter( 'wpcf7_validate_myCustomField', 'wpcf7_myCustomField_validation_filter', 10, 2 );
add_filter( 'wpcf7_validate_myCustomField*', 'wpcf7_myCustomField_validation_filter', 10, 2 );
function wpcf7_myCustomField_validation_filter( $result, $tag ) {
$tag = new WPCF7_FormTag( $tag );
$name = $tag->name;
if ( isset( $_POST[$name] ) && is_array( $_POST[$name] ) ) {
foreach ( $_POST[$name] as $key => $value ) {
if ( '' === $value ) {
unset( $_POST[$name][$key] );
}
}
}
$empty = ! isset( $_POST[$name] ) || empty( $_POST[$name] ) && '0' !== $_POST[$name];
if ( $tag->is_required() && $empty ) {
$result->invalidate( $tag, wpcf7_get_message( 'invalid_required' ) );
}
return $result;
}
This code should also go in your functions.php file just under the code for the custom CF7 tag.
Here the filter's first string $tag should match with the class that is being generated in the custom CF7 tag so if your custom tag->type = 'myCustomField' then the $tag of the filter must include the name, like so wpcf7_validate_myCustomField as well as the required version of it, wpcf7_validate_myCustomField*.
I hope that helps anyone else looking for this.
If you want even more of the options available from the backend of Contact Form 7 check the select.php file as it lays it out quite nicely on how to get each option and include it.
You can use [select*] to output a required drop-down menu.
[select* course-name include_blank "English" "Math"]
Check https://contactform7.com/checkboxes-radio-buttons-and-menus/
EDIT:
So you have your own shortcode [myCustomField]. To make two versions of your shortcode as [myCustomField] and [myCustomField*] you have to pass both shortcodes to your function as the following:
add_action( 'wpcf7_init', 'wpcf7_add_form_tag_mycustomfield' );
function wpcf7_add_form_tag_mycustomfield() {
wpcf7_add_form_tag( array( 'myCustomField', 'myCustomField*'),
'wpcf7_mycustomfield_form_tag_handler', array( 'name-attr' => true ) );
}
function wpcf7_mycustomfield_form_tag_handler( $tag ) {
$tag = new WPCF7_FormTag( $tag );
if ( empty( $tag->name ) ) {
return '';
}
$atts = array();
$class = wpcf7_form_controls_class( $tag->type );
$atts['class'] = $tag->get_class_option( $class );
$atts['id'] = $tag->get_id_option();
$atts['name'] = $tag->name;
$atts = wpcf7_format_atts( $atts );
$html = sprintf( '<your-tag %s></your-tag>', $atts );
return $html;
}
Then, you can use it:
[myCustomField course-name class:custom-field]
or
[myCustomField* course-name class:custom-field]
References:
https://contactform7.com/2015/01/10/adding-a-custom-form-tag
https://contactform7.com/2015/02/27/using-values-from-a-form-tag/
I've got a function added in functions.php to improve the search functionality in my directory section: http://www.highwaysindustry.com/?post_type=directory_listings&s=king
However, with the following enabled, it overrides the search for the rest of the website also: http://www.highwaysindustry.com
This particular function I would prefer it to be targeted for the directory search only.
Function in functions.php
function __search_by_title_only( $search, $wp_query )
{
global $wpdb;
if ( empty( $search ) )
return $search; // skip processing - no search term in query
$q = $wp_query->query_vars;
$n = ! empty( $q['exact'] ) ? '' : '%';
$search =
$searchand = '';
foreach ( (array) $q['search_terms'] as $term ) {
$term = esc_sql( like_escape( $term ) );
$search .= "{$searchand}($wpdb->posts.post_title REGEXP '[[:<:]]{$term}[[:>:]]')";
$searchand = ' AND ';
}
if ( ! empty( $search ) ) {
$search = " AND ({$search}) ";
if ( ! is_user_logged_in() )
$search .= " AND ($wpdb->posts.post_password = '') ";
}
return $search;
}
add_filter( 'posts_search', '__search_by_title_only', 1000, 2 );
Snippet of my directory-search.php which the form on /Directory uses:
<?php
$args = array(
'post_type'=> 'directory_listings',
's' => $s,
'paged' => $paged,
'meta_query' => array(
array(
'key' => 'membership_type',
'orderby' => 'meta_value',
'order' => "DESC"
,
),
),
);
?>
<div class="row">
<div class="small-12 columns">
<div class="directory-banner">
<img src="<?php echo site_url(); ?>/wp-content/themes/highways/images/directory-banner.jpg" alt="" title="" />
<h1><?php echo $s; ?></h1>
</div>
</div>
</div>
**I currently have the function defined above commented out, when enabled it's a lot more specific, for example, searching "King" would only provide back 2 results. Right now the generic search provides too many unspecific results.
The other 2 answers are also worth investigating. However I'll stick to your solution.
To search only directory_listings post type, tweak the function as shown below
function __search_by_title_only( $search, $wp_query )
{
global $wpdb;
if ( empty( $search ) )
return $search; // skip processing - no search term in query
$q = $wp_query->query_vars;
// post_type query var has other posts types as well, return default search
if( ! 'directory_listings' == $q['post_type'] )
return $search
// We are here, it means post_type var contains only directory_listings
// continue with the rest of the code
........
Answering your 2nd query
There is a company called blakedale, if you search just blake you won't get the result. Any method to increase the method of the returned result(s).
The regexp being used in the code below searches for full words hence "blake" doesn't return any results
$search .= "{$searchand}($wpdb->posts.post_title REGEXP '[[:<:]]{$term}[[:>:]]')";
You need to either change the regexp or use SQL LIKE
$search .= "{$searchand}($wpdb->posts.post_title LIKE '%{$term}%')";
P.S: I haven't tested the line of code above, so it may need polishing.
did you try using pre_get_posts ?
function search_filter($query) {
if ( !is_admin() && $query->is_main_query() ) {
if ($query->is_search && $_GET['post_type'] == 'directory_listings') {
// add custom meta / tax queries
}
}
}
add_action('pre_get_posts','search_filter');
You can try this .
$query_args = array( 'post_type' => 'directory_listings', 'tax_query' => array() );
if ( !empty( $search_terms ) ) {
$query_args['s'] = $search_terms;
}
if ( !empty( $search_terms ) ) {
$query_args['tax_query'][] = array(
array(
'taxonomy' => 'directory_listings',
'field' => 'slug',
'terms' => $news_category
)
);
}
$my_posts = new WP_Query( $query_args );
if ( $my_posts->have_posts() ) { // etc
}