I have a website in development and the customer wanted a news and F.A.Q page. Not a problem! He wanted to be able to add his own posts (to both news and F.A.Q.. Again, not a problem! The last thing he requested was that he was able to manage the amount of posts showing and what kind of posts that were shown. Now this is where i got confused. I've already build a system where the customer can select a category to show. (i'm using AwesomeBuilder for this). Now we have three different types of posts. Regular, Regular + Sticky, and Sticky. Should the client select the option to only show Regular posts i can turn the sticky posts off by using post__not_in. However if the client selects either Regular + Sticky or Sticky the amount function doesn't work anymore.
Lets say the client selects a maximum amount of 10 posts. At the regular category this gets maxed at 10 and that's it. At the sticky posts however this doesn't happen, it just shows all the sticky posts since stickies are told to always stay on top. Regular + Sticky would show all the sticky posts followed by 10 regular posts. I hope my situation and problem is clear.
Code below.
$sticky = get_option( 'sticky_posts' );
$number = $atts['number'];
if ($atts['sticky'] == 'nieuws') {
$args = array('post__not_in' => $sticky, 'posts_per_page' => $number );
} elseif ($atts['sticky'] == 'nieuws-sticky') {
$sticky_count = count($sticky);
if ($sticky_count <= $number){
$number_sticky = $number - $sticky_count;
$args = array('post_type' => post, 'posts_per_page' => $number_sticky);
}
else {
// $sticky = array_slice($sticky,0, 1);
// echo 'hello'. $sticky;
$args = array('post__in' => $sticky );
}
} else {
// $sticky = array_slice($sticky,1, 2);
$args = array('post__in' => $sticky, 'posts_per_page' => $number );
}
ps. I know THIS is the about the same question but it hasnt been answered yet.
Make sure that the $number variable is getting 10, and also make sure that you are using the $args in the query_posts functions, like query_posts($args);
https://codex.wordpress.org/Sticky_Posts
You can refer to this "Display just the first sticky post, if none return the last post published: " from the link.
Related
There's something I try to understand about the process of querying posts in wordpress:
Lets say I have this code:
$args = array{
'cat' => 'animals',
'posts_per_page' => 3
}
$the_query = new WP_Query($args);
So theoretically wordpress go to the database, going through all posts, and for each post, from the first to the last, it "asks" the post for it's category, if the answer is "animals" it grabs that post and move to the one after, if the category is something else, it skip that post and move to the one after. And repeat that process n times?
Or, since I set posts_per_page to 3, after the third post that matchs "animals", the process it stops?
If the answer is the first, How can I optimize the code if, let's say I have 300 posts under "animals", but I need only the latest 3. How can I tell wordpress to stop checking after the third one that match "animals"?
I'm asking this since I'm working on a custom theme for site with more then 40000 posts, the homepage need to have at least 5 different queries like the one above, and I want to make it as efficient as possible.
I hope that's make sense.
Thanks in advance!
If you look into the WP core, you will see this piece of code in wp-includes/query.php, in the get_posts function:
if ( empty($q['offset']) ) {
$pgstrt = absint( ( $page - 1 ) * $q['posts_per_page'] ) . ', ';
} else { // we're ignoring $page and using 'offset'
$q['offset'] = absint($q['offset']);
$pgstrt = $q['offset'] . ', ';
}
$limits = 'LIMIT ' . $pgstrt . $q['posts_per_page'];
This mean that the posts_per_page parameter is translated to a basic sql LIMIT. So you don't have to worry for performance on this side.
How does 'LIMIT' parameter work in sql?
Considering the wp_terms_taxonomy.term_taxonomy_id, wp_terms_taxonomy.term_id_taxonomy, wp_term_relationships.term_taxonomy_id are all indexes the LIMIT should not select all rows, as far as I know.
I'm creating a Wordpress site were I would like to show "tiles" with content from the site on the front page. These tiles are custom post types from the site like "our services", "consultants", "blog posts" and so on.
I know how to show one custom post type in Wordpress, but the problem is that I need to pull multiple post types in the same loop as I want them to be displayed in a matrix. Another problem is that I need to shuffle all the items in a random order, so that for example not all blogs just show in one place but all objects show after different items in random.
The third problem is that I need to show all items for a certain post type and just the latest for another. For example do I need to show all "our services" tiles, but only a couple of the "blog" tiles.
Is this possible to do, or can you not pull out records in this way using Wordpress?
Thank you for the help!
I suggest reading up on custom wordpress queries https://codex.wordpress.org/Class_Reference/WP_Query
For the first question you just need to specify
'post_type' => array( 'tiles', 'consultants', 'post' )
for the second question
'orderby' => 'rand'
so you will have something like
$args = array(
'post_type' => array( 'tiles', 'consultants', 'post' ),
'orderby' => 'rand'
);
$query = new WP_Query( $args );
For the third question - I'm not sure if it is possible to achieve with one query.
you can customise the things like this ,
$posttypes = array('post_typ1','post_typ2','post_typ3');
$randompost_typs = shuffle($posttypes);
$counter = count($posttypes);
for($i=0; $i<$counter;$i++) {
// suppose you want to show all posts from post_type1 then
if($randompost_typs[$i]=='post_typ1') {
$posts_per_page = -1;
} elseif($randompost_typs[$i]=='post_typ2') { // will work for 2nd post type
$post_per_page = 5; // show 5 posts from this post type
} else {
$post_per_page = 3; // show 3 posts from last post type
}
// here you will use the WP_Query class from wordpress
$args = array(
'post_type' => $posttypes[$i],
'orderby' => 'rand',
'posts_per_page' => $post_per_page
);
$query = new WP_Query( $args );
if($query->have_posts()) : while($query->have_posts()): $query->the_post();
// all the remaining wp loop content for example
the_title();
the_excerpt();
endwhile;
else:
echo 'no posts';
endif;
}
hope this will help, let me know if it has any issue.
I would like to show the actual number of a post + all like: „No. 3 of 19 Posts“.
I've tried with – it shows all posts but I don't how I show the current post number.
No. {POST NUMER} of <?php $count_posts = wp_count_posts(); echo $count_posts->publish; ?> Posts
If this is inside a wp_query, you can do:
echo $wp_query->current_post+1;
Source: https://wordpress.stackexchange.com/questions/20789/print-current-post-index-number-within-loop
If not, I think you would need to explain Wordpress what exactly do you mean by "post number" - that is by which criteria should it be counted. For that, you would probably need to reconstruct wp_query with $args relevant to you (e.g. post_status => publish). Although maybe there is some builtin way I don't know about.
Edit
This is untested:
/** Your current post id*/
$curr_id = get_the_ID();
/** Your posts query */
$args = ('post_status' => 'publish', 'orderby' => 'this depends on you'); // ... and all other args you would need
$posts = get_posts($args);
$posts_count = count($posts);
for ($i=0;$i<$posts_count;$i++) {
if ($posts[$i]->ID === $curr_id) {
$current_post_num = $i;
break;
}
}
echo "No. $current_post_num of $posts_count Posts";
Some tips:
Use Google more! "get current post number wordpress" brought me straight to Wordpress Stack Exchange question mentioned above.
Post similar questions to Wordpress Stackexchange, the odds for you getting your answer would simply be higher.
I can't seem to figure the following out:
In a Wordpress theme I'm developing, 10 excerpts will be displayed at a time on the index screen. Naturally, then, if there are 20 posts the newest 10 posts will be displayed on page 1 and the 10 oldest on page 2 of the index screen.
When viewing any single post I would like to have a function which prints the page number upon which the current post would be found when viewing the index screen.
I've tried doing WP_queries, like:
$args = array(
'date_query' => array(
array(
'after' => get_the_date,
...
$query = new WP_Query( $args );
but with no luck.
Would anybody out there have any suggestions in which direction I should go about for figuring this one out!?! Any help is much obliged!
you could do a query on your page and figure out where your post would be....
$id = get_the_ID(); // set within your loop
$args = array(
'date_query' => array(
array(
'after' => get_the_date,
$query = new WP_Query( $args );
$i=1;
foreach($query as $post=>$key){
if($key->ID == $id) {//not tested have a look at the object to get correct location
$postnumber= $i;
}
$i++;
}
$page= $postnumber / 10;
$pagenumber= round($page, 0, PHP_ROUND_HALF_DOWN);
seems heavy on resources though!
I would probably opt for counting posts newer than the current one.
// This is not tested code, just a wild guess really. Sorry.
global $wpdb;
$query = "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type='post' AND post_status='publish' AND post_date > %s";
$count = $wpdb->get_var(
$wpdb->prepare(
$query,
get_the_date( /* probably needs a better date format here */ )
)
);
Another option I can think of is to append a GET parameter on your links from your front page, since you get the posts there anyway.
<?php $count++ // in the loop right? ?>
<a href="<?php echo the_permalink();?>?index=<?php echo $count?>"?>
This would of course not work unless everyone uses the frontpage to go to your pages, but then you could count newer posts as a fallback.
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 :) )