I want to add some custom conditions and do some other things on a search WordPress results page. So, I’m checking the value of is_search() to make sure I’m only applying the condition at the right time. So in my child theme's functions.php I put:
if (is_search()) {
...
}
But this always returns false, even with a url like http://mysite/?s=something and my theme's search.php template is being used! Is this not valid to call from functions.php, or am I misunderstanding this function's purpose?
For that matter, looking at a template hierarchy like presented at https://wphierarchy.com, how does WP even know it’s a search results page? How does it know to proceed down the "search results" path? I’ve spent some time perusing the source code but haven’t been able to find the right spot yet.
I tried calling is_search() from search.php, and it works! From some more source code perusal, I discovered that you can't call is_search() from functions.php because functions.php is called too early in the process. Apparently functions.php is considered part of the "WordPress library" and is loaded in wp-blog-header.php line 13, while the template is called in line 19.
In between the two is the wp() function, which sets up the query. That query is actually set up in user.php line lines 1198-1212:
$args = array(
'post_type' => $this->post_type,
'post_name__in' => array( $this->request_type ),
'posts_per_page' => $posts_per_page,
'offset' => isset( $_REQUEST['paged'] ) ? max( 0, absint( $_REQUEST['paged'] ) - 1 ) * $posts_per_page : 0,
'post_status' => 'any',
's' => isset( $_REQUEST['s'] ) ? sanitize_text_field( $_REQUEST['s'] ) : '',
);
...
$requests_query = new WP_Query( $args );
To answer my second question (how does WordPress know it's a search), it’s as simple as having the "s=" query string parameter. Not sure what to do if you want a search result that does not have a search string (say a custom search based solely on pulldowns or something). If you need that, I would recommend looking thru the source file WP-query.php and seeing exactly what you need to pass. Don’t be scared of looking at the source code; It’s very educational!
Related
I have the next WP_Query in footer.php in my wordpress:
wp_reset_postdata();
$argsLast = array(
'post_type' => 'post',
'posts_per_page' => 3,
'orderby' => 'date',
'order' => 'DESC',
'category__not_in' => array(193,189,192,195,207,190,213),
);
$ultimosposts = new WP_Query( $argsLast );
And it works fine in all pages of my wordpress except the category pages.
I have done several tests and the paremeter which doesn't work are 'order' or 'orderby'.
I would be grateful if someone could explain what is going on.
SOLVED: The problem was caused by a plugin: Sort Categories By Title
I deactivated the plugin and I'm sorting the posts in category using the next code in functions.php of my theme (a lot of thanks to #PieterGoosen, now I understand much better the queries in Wordpress):
add_action( 'pre_get_posts', 'orden_posts_categoria');
function orden_posts_categoria($q){
if (!is_admin()
&& $q->is_main_query()
&& $q->is_category()
) {
$q->set( 'orderby', 'title' );
$q->set( 'order', 'ASC' );
}
}
Note: this code is from #PieterGoosen
In this way, I modify the main query of wordpress. So it is very important setting the correct conditions in the selective structure.
Glad you have deactivated the plugin as in my opinion, the plugin is a pile off crap due to the fact that it breaks page functionalities. I can only speculate, but it either uses pre_get_posts wrongly or it uses query_posts which you should never ever use.
To solve your issue, you need to go back to the dafault loop which should look like this
if ( have_posts() ) { // Sometimes category pages don't have this, not really necessary
while ( have_posts() ) {
the_post();
// Your markup and template tags
}
}
You again should see posts on your category page ordered by date as per default.
Now, to solve the issue of sorting your posts by title on category pages, we will use pre_get_posts to alter the main query variables before the main query run. This is the recommended method, you should never replace the main query with a custom one to solve these kind of issues. It leads to other issues, specially wrong posts and wrong pagination
In your functions.php or your own custom plugin, add the following
add_action( 'pre_get_posts', function ($q )
{
if ( !is_admin() // Check that we are on the front end and not back end
&& $q->is_main_query() // Make sure we only alter the main query
&& $q->is_category() // Only target category pages
) {
$q->set( 'orderby', 'title' );
$q->set( 'order', 'ASC' );
}
});
The check I have done is very very important. pre_get_posts alters all instances of WP_Query, not only the main query, and this happens back end and front end and on all pages. Always make sure that you use these checks when using pre_get_posts
You should now have your category pages sorted by post title, and your custom query 8n the footer should also now correctly on category pages.
Just one last tip, to avoid custom filters altering your custom WP_Query instances, use 'suppress_filters' => true in your query arguments. get_posts does the same to avoid custom filters altering the output
EDIT
Just on the issue of queries, you should take your time and read this post I have done on the subject of the main query and custom queries
I'm looking for some help, for some reason this code isn't working when trying to display total image attachments on the main index.php page.
// Get all the attachments
$attachments = get_posts ( array(
'numberposts' => -1,
'post_type' => 'attachment',
'post_mime_type' => 'image',
'post_parent' => get_the_ID(),
'post_status' => 'inherit',
) );
// Count all the attachments
$total = count( $attachments );
The problem is, the loop is in the main index.php page, but it's calling a post.php template so I have placed this code there instead (I'm assuming that's still in the loop?) I am then calling $total just below it where I want to show "View all # images".
Any ideas why this is just displaying the number as 0 even though I have added an image gallery to the post using the basic Wordpress gallery media library?
Thanks
The attachment count only increases if it's attached to a post. You can force the count by adding this:
$wp_taxonomies['category']->update_count_callback = '_update_generic_term_count';
in a function in your functions.php something like this:
function change_category_arg() {
global $wp_taxonomies;
if ( ! taxonomy_exists('category') )
return false;
$wp_taxonomies['category']->update_count_callback = '_update_generic_term_count';
}
add_action( 'init', 'change_category_arg' );
Explanation:
This is significant in the case of attachments. Because an attachment
is a type of post, the default _update_post_term_count() will be used.
However, this may be undesirable, because this will only count
attachments that are actually attached to another post (like when you
insert an image into a post). This means that attachments that you
simply upload to WordPress using the Media Library, but do not
actually attach to another post will not be counted. If your intention
behind associating a taxonomy with attachments was to leverage the
Media Library as a sort of Document Management solution, you are
probably more interested in the counts of unattached Media items, than
in those attached to posts. In this case, you should force the use of
_update_generic_term_count() by setting '_update_generic_term_count' as the value for update_count_callback.
from Wordpress Codex on register_taxonomy
I have looked at this thread and tried to implement the given code sample there;
//code snippet to mass update all posts
add_action('init','mass_update_posts');
function mass_update_posts(){
$all_posts = get_posts('numberposts=');
$my_posts = get_posts( array('post_type' => 'post', 'numberposts' => $all_posts ) );
foreach ( $my_posts as $my_post ):
wp_update_post( $my_post );
endforeach;
}
I put the code in my footer.php but it doesn't seem to do anything? What am I missing? Initially I used;
$my_posts = get_posts( array('post_type' => 'post', 'numberposts' => -1 ) );
But that didn't help either...
Let me see if I understand what you are trying to do with this code...
First every time someone loads the page the footer.php will fire so you want to mass update all of your posts with a loop of the post itself?
There about a million things wrong with what you are trying to do with this code.
Never add actions in a footer file they belong in the function.php file of a theme.
Your $all_posts variable is probably empty because you are sending a function expecting an array of arguments a string (please read the get_post() function documentation)
$all_posts is not an integer as you are using it the next line (the get_post() function returns a list of WP_Post objects.
Your loop goes through all your posts and updates them with the same post, changing nothing and effectively accomplishing nothing.
So I guess the real question is what exactly are you trying to accomplish?
Good Day,
I am fairly new to WordPress and WooCommerce.
But I am fairly versed in PHP and MySQL.
So my question is, how do I go about making a specific query for WooCommerce where I can point it to specific meta. For example, if I wanted to make a query to call all the different categories within WooCommerce>
I would normally call it like this;
$args = array(
'number' => 'null',
'orderby' => 'name',
'order' => 'ASC',
'columns' => '4',
'hide_empty' => '1',
'parent' => '',
'ids' => ''
)
Ok so that would be my query, now what I am so struggling with is what do I do with it it now? Cause that part there is what everyone shows, no one tells you or shows you how to actually use the query or where to start.
I have used the basic WP query function, but then the only categories I receive back come from WP and WC.
So how do I point it directly to WC?
Furthermore, these hooks annoy me so. So how do I go about doing it the normal way, bypassing WC and WP functions and build my own query;
$query = "SELECT * FROM wc_categories";
$result = mysql_query($query);
$temp_array = mysqli_fetch_array($result);
That is how I would love to do it, cause no one explains hooks and how to use it, or edit it, everyone assumes that you are pro-leet when it come to familial of WP workings.
So if anyone can point me in the right direction, I would really appreciate it.
And I would love you long time if you could explain to me how to go about my 2nd code block cause that is my preferred way.
Kind Regards,
DK
Creating query using standard wp/wc function is easy. For example if you want to get customer details for specific orders. Required codes might look like this (notice the global function):
global $post, $woocommerce, $the_order;
if ( empty( $the_order ) || $the_order->id != $post->ID )
$the_order = new WC_Order( $post->ID );
$user_info = get_userdata( $the_order->user_id );
$biling_email = $the_order->billing_email;
$phone_no = $the_order->billing_phone;
If you want to query a custom order meta field, you may use a code something like below. You need to know the custom field name in database:
$custom_field = get_post_meta( $post->ID, 'custom_field', true );
For custom query you need to initialize global wpdb function first by adding global $wpdb function before your query. Even this will work with a WP page only, it'll not work with a page created outside WP. Below is an example:
global $wpdb
$table = $wpdb->prefix . 'postmeta'; //Good practice
$orderno = $wpdb->get_results( "SELECT * FROM $table");
I'm trying to print out a number of posts from multiple post types. However, I can't seem to implement the pagination - once I go to .../category.../page/2 I get a page not found error. It seems like it doesn't even try to read what's inside of my archive.php file.
I'm 100% sure that there's no problem with permalinks, since I've tried resetting them and etc.
I suppose it has something to do with the fact that in admin settings the number of posts per page is set to 10, but i really need to be able to edit this number dynamically.
I've tried a variaty of fixes from here, but non of them seem to work: http://wordpress.org/support/topic/pagination-with-custom-post-type-getting-a-404?replies=1#post-1616810
I'm sorry if it's highly repetitive question - none of other fixes I found worked for me.
Thanks a lot!
You can do something like this (not tested):
$posts_per_page = 10;
$post_type = 'YOUR_POST_TYPE'
$args = array( 'post_type'=> $post_type, 'posts_per_page' => $posts_per_page, 'paged' => get_query_var('paged') );
query_posts( $args );
// here loop