wordpress pagination not working? - php

My code is
I have written this code for pagination before my loop
$arrangement = get_cat_ID('arrangement');
$antiquarianism = get_cat_ID('antiquarianism');
$paged = (get_query_var('page')) ? get_query_var('page') : 1;
print_r($paged);
$query = query_posts(array(
'page' => intval($paged),
'category__not_in' => array($arrangement, $antiquarianism ) ));
every time its printing 1.

Have you tried a var_dump of $paged? Or resetting the get_query_var('page') as suggested here : worpress support

I have had a similar issue before. Unfortunately it could be a number of things.
One possibility is the treatment of the page query in relation to the Wordpress 'loop'. I was just reading through the documentation for query_posts and spotted this:
Preserving the Original Query (Pagination etc.)
By default running query_posts will completely overwrite all existing query variables on the current page. Pagination, categories dates etc. will be lost and only the variables you pass into query_posts will be used.
If you want to preserve the original query you can merge the original query array into your parameter array:
global $wp_query;
query_posts(
array_merge(
array( 'cat' => 1 ),
$wp_query->query
)
);
http://codex.wordpress.org/Function_Reference/query_posts
I'm not sure if this affects you, but it's worth shot.
EDIT: you could also try running a seperate get_post loop after 'the loop' has closed (i.e. after the main endwhile). This has solved issues for me in the past
<?php
// custom pagination improvements
//http://codex.wordpress.org/Template_Tags/get_posts
$lastposts = get_posts('numberposts=50&order=DESC&orderby=ID');
setup_postdata($lastposts);
$valid_posts = array ();
$lastposts = (array) $lastposts;
foreach ($lastposts as $post) {
$post = (array) $post;
// Sort through arrays here - get the next valid post
switch (true) {
case ($post['post_status'] == 'publish' && $post['ID'] < $curr_pid[0]):
array_push($valid_posts, $post);
break;
default:
break;
}
}
$nextArray = $valid_posts[0];
?>
<ul class="pagination">
<li class="next"><?php echo ($nextArray['post_title']); ?></li>
</ul>
This is some code I wrote for the front page so it would just show "next", and then link to the next post according to my filter (rather than what Wordpress thought should go next). You could of course echo out multiple links with numbers using a foreach loop. This will complicate thing a little, but it gives you very granular control over what is happening in the pagination.
Does that help you?

Related

Exclude Woocommerce products from search loop

I am trying to create a custom search results page where Woocommerce product results are displayed separately to blog / general posts.
My aim is to display them as separate blocks with different styling.
[Block 1] - Woocommerce results
[Block 2] - Blog / Post results
I have managed to display the products in one loop, but I am struggling to exclude products from the post loop.
I have tried creating a custom loop, however this just displays all the posts within those terms, rather than the posts returned in the search.
The loop I usually use is:
<?php $loop = new WP_Query( array( 'post_type' => 'post' ?>
<p>Something here</p>
<?php endwhile; wp_reset_query(); ?>
However I believe this just isn't compatible and suitable for my needs.
If there's a better solution to separating these I would absolutely love to hear more.
The problem you are having is that you have one main query, where you actually want to do two queries. You could of course modify the main query to contain both post types, but you would end up with a random number of both post types where you actually want to fill both columns.
If you modify the main query to only return one of the columns, you end up with a situation where it is awful to run the other query to get the rest of the posts. I think you should be able to use the posts_join and posts_where filters if you need them, but I am unsure about posts_search. You can use either WP_Query or get_posts to finally do the two queries you need.
<?php
// Since we are searching, we probably should get the search keyword
$search = get_query_var('s');
// Since we want to be able to navigate, we probably should figure out on which page we are
$paged = get_query_var('paged');
// Anything else we want to do in search queries we should be able to do in
// a posts_join or posts_where filter by checking if is_search() is true
// With that out of the way, we can construct our queries
$query_posts_page = new WP_Query([
's' => $search,
'paged' => $paged,
'post_type' => ['post', 'page']
]);
$query_woocommerce = new WP_Query([
's' => $search,
'paged' => $paged,
'post_type' => 'product'
]);
?>
<div class="col">
<?php
if ( $query_posts_page->have_posts() ) {
while ( $the_query->have_posts() ) {
$query_posts_page->the_post();
echo get_the_title();
}
/* Restore original Post Data */
wp_reset_postdata();
} else {
echo 'Nope, no more data';
}
?>
</div>
<div class="col">
<?php
if ( $query_woocommerce->have_posts() ) {
while ( $query_woocommerce->have_posts() ) {
$query_posts_page->the_post();
echo get_the_title();
}
/* Restore original Post Data */
wp_reset_postdata();
} else {
echo 'Nope, no more data';
}
?>
</div>
There is however still another problem. we can't automatically generate pagination, considering we are running two custom queries instead of the main query. Furthermore, we are unlikely to have an equal number of normal page/posts and products.
We can figure out what the maximum number of pages is for each of the loops by using max_num_pages. You can generate something yourself using that.
<?php
$maximum_page = max($query_posts_page->max_num_pages, $query_woocommerce->max_num_pages);
for( $i = 1; $i < $maximum_page; $i++) {
echo "{$i} ";
}

A complicated query combining a WP Courseware function, ACF repeater fields and a meta_query looking for a particular template file

I have a pretty complicated query that I have not been able to get to work the way I need it to.
I have a Wordpress install using the plugins WP Courseware and ACF. I need to display a page of courses associated with the current user. I want the links to lead the user to the course "home" pages that the user should hit prior to starting the course. I have created course "home" pages, but the problem is WP Courseware has no way to associate a page with a course. So I had to use an ACF options repeater that associates the course ID with whatever course pages are necessary. The only way I know that one of those associated pages is the course "home" page is by the template I use for course home pages.
So the loops within loops need to first determine what courses the current user has access to, get those course IDs, loop the ACF options repeater to find the pages associated with those course IDs, then of those pages loop to find out which one (there is only one per course) uses the course home page template. This last loop I discovered needs to be a WP_Query loop as that's the only way to query for a Wordpress template.
I am lost in loops and I'm having the hardest time. I thought it might be simpler and most direct to use the WP_Query to query an array meta_queries of both the Wordpress template and the ACF repeater (to determine is the ACF repeater course ID matches the course ID the user has access to) but my attempts at querying ACF repeater sub fields is not working.
Here's my code:
$user = wp_get_current_user();
$user_id = $user->ID;
$user_course_list = WPCW_users_getUserCourseList($user_id);
$course_association_arr = get_field('course_association', 'option');
// Loop through user's courses
foreach ( $user_course_list as $user_course ) :
$course_id = $user_course->course_id;
$course_title = $user_course->course_title;
// Loop through the ACF course ID/page associations
foreach ( $course_association_arr as $course_association ) :
$assoc_course_id = $course_association['wp_courseware_id'];
if ( $course_id == $assoc_course_id ) :
// Loop through the ACF associated pages
foreach ( $course_association['associated_pages'] as $associated_page ) :
$page_id = $associated_page->ID;
$page_url = $associated_page->guid;
echo '<li>'. $course_title . '</li>';
endforeach;
endif;
endforeach;
endforeach;
This displays all pages associated with a user's courses, not just the ones using the course home template. I somehow have to incorporate a WP_Query with these args in there and nothing I have done has worked:
$args = array(
'post_type' => 'page',
'meta_query' => array(
array(
'key' => '_wp_page_template',
'value' => 'page-course-home.php',
),
)
);
If I could somehow turn the WP query into an if statement (if template = page-course-home.php) I could have that inside the associated pages query to only show course home pages. Or there maybe another more brilliant way to do what I need to do. I appreciate all feedback.
Ok I got something to work! I think spending so much time framing the question here helped me see one way I could do it:
$user = wp_get_current_user();
$user_id = $user->ID;
$user_course_list = WPCW_users_getUserCourseList($user_id);
$course_association_arr = get_field('course_association', 'option');
// Loop through user's courses
foreach ( $user_course_list as $user_course ) :
$course_id = $user_course->course_id;
$course_title = $user_course->course_title;
// Loop through the ACF course ID/page associations
foreach ( $course_association_arr as $course_association ) :
$assoc_course_id = $course_association['wp_courseware_id'];
if ( $course_id == $assoc_course_id ) :
// Loop through the ACF associated pages
foreach ( $course_association['associated_pages'] as $associated_page ) :
$page_id = $associated_page->ID;
$page_url = $associated_page->guid;
$args = array(
'post_type' => 'page',
'page_id' => $page_id,
'meta_query' => array(
array(
'key' => '_wp_page_template',
'value' => 'page-course-home.php',
),
)
);
$course_assoc_pages = new WP_Query( $args );
if( $course_assoc_pages->have_posts() ) :
while ( $course_assoc_pages->have_posts() ) : $course_assoc_pages->the_post();
echo '<li>'. $course_title . '</li>';
endwhile;
endif;
wp_reset_query();
endforeach;
endif;
endforeach;
endforeach;
This seems a bit cumbersome, but it works. I'm not sure if it would be better but it seems more elegant to incorporate the ACF subfield query into the meta query, so could eliminate two of the loops. If anyone has any thoughts on this I would love to hear them.

Wordpress shortcode display incorrect number of posts

I'm using this code to show recent posts with a shortcode that I found at smashingmagazine site. It's not working the correct way, I mean when I specify the number of posts to show, it just shows one post with every number I specify.
Here's the code:
function recent_posts_function() {
query_posts(array('orderby' => 'date', 'order' => 'DESC' , 'showposts' => 1));
if (have_posts()) :
while (have_posts()) : the_post();
$return_string = ''.get_the_title().'';
endwhile;
endif;
wp_reset_query();
return $return_string;
}
function register_shortcodes(){
add_shortcode('recent-posts', 'recent_posts_function');
}
add_action( 'init', 'register_shortcodes');
I've changed the showposts number, but nothing happens. What's wrong?
Any suggestions?
Just before I start, never use query_posts to construct or modify any type of query. It outright fails in many scenarios, specially pagination, and breaks the main query, which you should never do.
If you need to construct custom queries, rather use WP_Query
Also, showposts have been deprerciated long time ago and have been replaced with posts_per_page
You should read the Shortcode API, this should give you an overview of what is happening and how shortcodes should be used and created. One important thing to remember here, shortcode content should be returned, not echo'ed. Here is also a tutorial that help me a lot.
Just a quick tip here, shortcodes should always go into a plugin. If you haven't yet created one, go and read MU-Plugin (must-use-plugin)
The correct way of constructing your shortcode would be as follows: (Your shortcode will be [my-shortcode]) This is untested though
add_shortcode( 'my-shortcode', 'my_custom_query_shortcode' );
function my_custom_query_shortcode( $atts ) {
ob_start();
$query = new WP_Query(array('orderby' => 'date', 'order' => 'DESC' , 'posts_per_page' => 1));
if ( $query->have_posts() ) :
while($query->have_posts()) : $query->the_post();
//YOUR LOOP ELEMENTS
<?php
endwhile;
$myvariable = ob_get_clean();
return $myvariable;
endif;
}
Just replace your code with mine, and make sure that you add your loop elements.
Just one more thing, remember, if you run any custom query on a page, and you have not reset that query, it will influence any other query on that page, even this shortcode, so always make sure that you reset all custom queries once you've done

Dynamically call content of page in another page in wordpress

I am trying to do something very characteristic and i am not that kinda good with PHP.
I am making some site for soccer team. And i want to have one main page called RESULTS. I will have for example 10 rounds(every round have separate page) in full season. I already make fixtures and everything depending on date.
My problem is how to call specific page, for example today is 29.10.2013 and my 3rd round has just over and i fill out all my result on my "3rd round page", and i want that this content be shown on page "RESULTS" also.
Than next week 04.11.2013 its coming my 4th round and i will also fill out everything on my "4th round page", but i just want now that all this be on "RESULTS" page because this is active round now not 3rd round.
I am guessing that i need to make template for my "RESULTS" page but i just need code, function how to call specific ID page depending on date. (29.10.2013 call page id 54; 04.11.2013 call page id 55).
I hope i explained well and hope someone is good in this.
Thanks in advance!
This is probably not the most elegant answer but should work
<?php
switch(date('d.m.Y'))
{
case '29.10.2013':
$THE_PAGE_ID = 1;
break;
case '29.10.2013':
$THE_PAGE_ID = 2;
break;
case '29.10.2013':
$THE_PAGE_ID = 3;
break;
default:
$THE_PAGE_ID = 4; // page if the date does not match
}
$args = array( 'posts_per_page' => -1,
'post_type' => 'page',
'include'=> $THE_PAGE_ID
);
$myposts = get_posts( $args );
foreach ( $myposts as $post ) :
setup_postdata( $post );
?>
<h1><?php the_title(); ?></h1>
<div id="page-content">
<?php the_content(); ?>
</div>
<?php
endforeach;
wp_reset_postdata();
?>
If you want to get the data of a specific page you can use "get_posts"
http://codex.wordpress.org/Template_Tags/get_posts
Inside your page template add something like this
<ul>
<?php
$args = array( 'posts_per_page' => -1,
'post_type' => 'page',
'include'=> $THE_PAGE_ID
);
$myposts = get_posts( $args );
foreach ( $myposts as $post ) :
setup_postdata( $post );
?>
<li>
<?php the_title(); ?>
</li>
<?php
endforeach;
wp_reset_postdata();
?>
</ul>
Or use "get_post":
http://codex.wordpress.org/Function_Reference/get_post
<?php
$thepost = get_post($THE_PAGE_ID, ARRAY_A);
$title = $thepost['post_title'];
echo $title;
?>
Hope that's what you where after.
Thanks a lot for reply, i see that you very good with this. I did like you tell me and with this i got link to page on my "RESULTS" page.
So is it possible to little bit change code that will be checking date. For example:
check date,
if date is 29.10.2013->call content(not link)of page ID=2
if date is 30.10.2013->call content of page ID=3
if date is 31.10.2013->call content of page ID=4
I would do it myself but i am not even close good with this like you. So sorry for being boring but i really need to learn this stuff.

Query all wordpress post titles

I am using Wordpress auto suggests using this snippet of code
and currently it is searching all tags, I want it to search only post titles. Any help is appreciated.
This is sql query calling all the tags which needs to be modified for all posts.
<?php global $wpdb;
$search_tags = $wpdb->get_results("SELECT name from wp_terms WHERE name LIKE '$search%'");
foreach ($search_tags as $mytag)
{
echo $mytag->name. " ";
}
?>
These days i had to do some request in a wordpress theme.
In your case ( getting title can be done easier than getting tags, as in your example link ) the stuff can be done easier (i guess).
Firstly you have to make a php page to get posts. As you maybe know you won't be able to use wp stuff in standalone php files, so your file ( let call it get_posts.php ) will look like
<?php
// Include the file above for being able to use php stuff
// In my case this file was in a folder inside my theme ( my_theme/custom_stuff/get_posts.php ).
// According to this file position you can modify below path to achieve wp-blog-header.php from wp root folder
include( '../../../../wp-blog-header.php' );
// Get all published posts.
$list_posts = get_posts( array( 'numberposts' => -1 ) );
// Get "q" parameter from plugin
$typing = strtolower( $_GET["q"] );
//Save all titles
$list_titles = array();
foreach( $list_posts as $post ) { $list_titles[] = $post->post_title; }
// To see more about this part check search.php from example
foreach( $list_titles as $title ) {
if( strpos( strtolower( $title ), $typing ) ){
echo $title;
}
}
?>
I added some comments trying to help you better.
Now stuff get easy, you only have to call your page through jQuery plugin like
$('#yourInput').autocomplete( "path_to/get_posts.php" );
You can directly use wordpress in-build feature to get all post titles
// The Query
query_posts( 'posts_per_page=-1' );
// The Loop
while ( have_posts() ) : the_post();
echo '<li>';
the_title();
echo '</li>';
endwhile;
None of the answers here answer your real question:
How to query JUST post titles
The "raw SQL" way:
Few important things:
escape search for SQL! (also do that for the tags search!) use $GLOBALS['wpdb']->esc_like()
if you only need 1 column, you can use $GLOBALS['wpdb']->get_col()$GLOBALS['wpdb']->get_results() is if you want to fetch more columns in one row
use $GLOBALS['wpdb']->tableBaseName to make your code portable - takes care of the prefixe.g. $GLOBALS['wpdb']->posts
When querying posts you must also think about which post_type and post_status you want to query=> usually the post_status you want ispublish, but post_type may vary based on what you want
WordPress table "posts" contains ALL post types - post, page, custom, but also navigation, contact forms etc. could be there! => I strongly advice to use explicit post_type condition(s) in WHERE ! :)
...$GLOBALS is same as globalizing variabl -today performance difference is little
<?php
// to get ALL published post titles of ALL post types (posts, pages, custom post types, ...
$search_post_titles = $GLOBALS['wpdb']->get_col(
"SELECT post_title from {$GLOBALS['wpdb']->posts}
WHERE (
(post_status = 'publish')
AND
(post_title LIKE '{$GLOBALS['wpdb']->esc_like($search)}%')
)
ORDER BY post_title ASC
"); // I also added ordering by title (ascending)
// to only get post titles of Posts(Blog)
// you would add this to conditions inside the WHERE()
// AND (post_type = 'post')
// for Posts&Pages
// AND ((post_type = 'post') OR (post_type = 'page'))
// test output:
foreach ($search_post_titles as $my_title) {
echo $my_title . " ";
}
?>
The WP_Query way
This is more wordpress but has a little overhead, because although there is a fields param for new WP_Query()/get_posts(), it only has options:
'all' - all fields (also default), 'ids' - just ids, 'id=>parent' - ... if you pass anything else, you still get all, so you still need to add "all" BUT - WP however has filters for altering fields in SELECT.
I tried to make it the same as the raw SQL version, but it depends on how does WP does it's "search" - which I think is %search% for 1 word + some more logic if there are more words. You could leverage the $clauses filter used for fields to also add your custom where INSTEAD of adding the 's' into $args (remember to append to not-lose existing WHEREs $clauses['where' .= "AND ...;). Also post_type => 'any' does not produce always the same results as the raw query in cases like Navigation, Contact forms etc...
Also WP_Query sanitizes the input variables so actually don't escape $args!
<?php
$args = [
'fields' => 'all', // must give all here and filter SELECT(fields) clause later!
'posts_per_page' => -1, // -1 == get all
'post_status' => 'publish',
's' => $search,
// I also added ordering by title (ascending):
'orderby' => 'title',
'order' => 'ASC',
'post_type' => 'any', // all "normal" post types
// 'post_type' => 'post', // only "blog" Posts
// 'post_type' => ['post', 'page'], // only blog Posts & Pages
];
$onlyTitlesFilter = function($clauses, $query) {
// "fields" overrides the column list after "SELECT" in query
$clauses['fields'] = "{$GLOBALS['wpdb']->posts}.post_title";
return $clauses; // !FILTER! MUST RETURN!
};
$onlyTitlesFilterPriority = 999;
// add filter only for this query
add_filter('posts_clauses', $onlyTitlesFilter, $onlyTitlesFilterPriority, 2);
// Pro-tip: don't use variable names like $post, $posts - they conflict with WP globals!
$my_posts = (new WP_Query($args))->get_posts();
// !IMPORTANT!
// !remove the filter right after so we don't affect other queries!
remove_filter('posts_clauses', $onlyTitlesFilter, $onlyTitlesFilterPriority);
// test output:
// note that I used "my"_post NOT just $post (that's a global!)
foreach($my_posts as $my_post) {
echo $my_post->post_title . " ";
}
?>
Don't be confused - you will still get the array of WP_Posts - WP will throw some default properties&values into it, but in reality it will only query and fill-in with real values the fields you specify in the filter.
PS: I've tested these - they are working codes (at least on WP 5.4 and PHP7 :) )

Categories