Wordpress query to show only sticky posts - php

Following is my wordpress query in which i want to show only sticky posts but the query is not showing any posts. Also I set two posts as sticky so that part is checked!!!. Kindly let me know how to modify this query so it will only show the posts which are sticky
<?php
$wp_query = null;
$wp_query = new WP_Query(array(
'posts_per_page' => 2,
//'paged' => get_query_var('paged'),
'post_type' => 'post',
'post__in' => 'sticky_posts',
//'post__not_in' => array($lastpost),
'post_status' => 'publish',
'caller_get_posts'=> 0 ));
while ($wp_query->have_posts()) : $wp_query->the_post(); $lastpost[] = get_the_ID();
?>

Query which will show only sticky posts:
// get sticky posts from DB
$sticky = get_option('sticky_posts');
// check if there are any
if (!empty($sticky)) {
// optional: sort the newest IDs first
rsort($sticky);
// override the query
$args = array(
'post__in' => $sticky
);
query_posts($args);
// the loop
while (have_posts()) {
the_post();
// your code
}
}

The query_posts() function creates a new WP_Query() not before the current query is set up, meaning this is not the best efficient method and will perform extra SQL requests.
Use the 'pre_get_posts' hook to be safe, like
function sticky_home( $query ) {
$sticky = get_option('sticky_posts');
if (! empty($sticky)) {
if ( $query->is_home() && $query->is_main_query() ) {
$query->set( 'post__in', $sticky );
}
}
} add_action( 'pre_get_posts', 'sticky_home' );

Related

Querying post by ID always returning the latest post (WordPress)

I'm trying to retrieve a single post by the ID. Stories is my custom post type and it currently has three posts:
Blog 1 (ID: 1)
Blog 2 (ID: 14)
Blog 3 (ID: 49)
I have a variable called $story_one. $story_one has the value of 14.
I'm now trying to retrieve information from the post with the ID of 14, so I've done:
<?php
$args = array(
'post_type' => 'stories',
'id' => $story_one,
'posts_per_page' => 1
);
$query = new WP_Query( $args );
if( $query->have_posts() ) {
while( $query->have_posts() ) {
$query->the_post();
the_title();
}
wp_reset_postdata();
}
?>
This returns Blog 3. Blog 3 is the newest post in stories. When I've specified it to pull content from the post with the ID of 14 (Blog 2), why is it. showing me content from the latest blog?
The query_var for post ID is p not id
$args = array(
'post_type' => 'stories',
'p' => $story_one,
'posts_per_page' => 1
);
$query = new WP_Query( $args );
if( $query->have_posts() ) {
while( $query->have_posts() ) {
$query->the_post();
the_title();
}
wp_reset_postdata();
}
Instead of using WP_Query(), you can use get_post(), like this:
<?php
$post = get_post($story_one);
if(!empty($post)):
echo $post->post_title;
echo get_field("field name", $story_one);
endif;
?>
About getting only from stories post type. Every post type is stored in the same posts table, so they have to use different post IDs.
The second parameter of get_field() function is the post ID.
I would suggest continuing to use WP_Query. The issue is just one of the query parameters.
I would ad 'p', to yours $args variable...like this...
$args = array(
'post_type' => 'stories',
'p' => $story_one,
'posts_per_page' => 1
);
And that should get you the result you're after.
Good luck!

Wordpress - Using variables from 'header.php' in 'index.php' to exclude posts from query

In 'header.php' I have a post query for a section called "Featured Posts". In that query I defined a variable called "ids". I want to use it in the loop from 'index.php' with 'post__not_in' so this posts from the "Featured Posts" section will not show in the post query from 'index.php". But I'm getting an error like "Undefined variable: ids".
How can I use that variable from 'header.php' in 'index.php'?
This is what I have so far:
<!-- HEADER.PHP -->
<?php
$custom_query_args = array(
'post_type' => array( 'post', 'reviews'),
'meta_key' => '_is_ns_featured_post',
'meta_value' => 'yes',
'posts_per_page' => '3',
'showposts' => '3'
);
$custom_query_args['paged'] = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
$custom_query = new WP_Query( $custom_query_args ); ?>
<?php
// Pagination fix
global $wp_query;
$temp_query = $wp_query;
$wp_query = NULL;
$wp_query = $custom_query;
$ids = array();
?>
<!-- INDEX.PHP: -->
<?php
$args = array(
'post_type' => array( 'post', 'reviews'),
'posts_per_page'=> 10,
'post__not_in' => $ids
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post();
?>
There are a few different approaches you can follow to solve this issue. The use of a global variable is how a couple of the top selling premium themes do it.
1) Use a global variable.
In header.php:
$ids = array(1,3,5,7,9);
global $my_globals;
$my_globals['ids'] = $ids;
In index.php:
global $my_globals;
$ids = $my_globals['ids'];
See #3 below for why some WordPress programmers say using global is not optimal.
2) Create a function that creates and then returns the $ids array. Run the function both in header.php and index.php / Disadvantage here is overworking the mysql on a low end server resulting in slow page load.
3) Another solution would be to use cache to hold the array between the two pages. The approach is explained very clearly here, so it would be easier to just go and see it here https://wordpress.stackexchange.com/a/89271/19155 ... along with a bunch of reasons as to why using global is considered by some to be an incorrect approach.
4) Use the 'NS Featured Posts' plugin, (4.7/5 rating, ~2000 downloads) which contains the functionality you seek. https://wordpress.org/plugins/ns-featured-posts/
The use of the $globals should do this..
$args = array(
'post_type' => array( 'post', 'reviews'),
'posts_per_page'=> 10,
'post__not_in' => $GLOBALS['ids']
);
In your header.php
$GLOBALS['ids']= array();

How to check if a post is in two given categories

I have category named news and featured post. I want to show if the post is both in news and featured-post.
$args = array('category_name' => 'news','featured-post','posts_per_page'=>1);
$lastposts = get_posts( $args );
foreach ( $lastposts as $post ) : setup_postdata( $post );
Any help will be appreciated.
I can't help you out with using get_posts.
However you may try it with WP_Queryas stated in wordpress' documentation under Display posts that have "all" of these categories:
$args = array(
'posts_per_page' => 1,
'category_name=news+featured-post' );
);
$my_query = new WP_Query( $args );
while( $my_query->have_posts() ):
$my_query->the_post();
//do things with the post
endwhile;
wp_reset_postdata();
If you are not bound to get_posts you can use WP_Query with category__and (note the double underscore!) to return posts which are placed in two (or more) categories.
$args = array('category__and' => array(1, 2));
$result = new WP_Query($args);
while($result->have_posts())
{
// do whatever you want
}

Wordpress query for sticky posts that are scheduled

I am using the below query to show 4 most recent sticky posts in Wordpress.
<?php
$sticky = get_option( 'sticky_posts' ); // Get all sticky posts
rsort( $sticky ); // Sort the stickies, latest first
$sticky = array_slice( $sticky, 0, 4 ); // Number of stickies to show
query_posts( array( 'post__in' => $sticky, 'caller_get_posts' => 1 ) ); // The query
if (have_posts() ) { while ( have_posts() ) : the_post(); ?>
ALL OF MY OUTPUTTED CODE GOES HERE - EDITED OUT TO SAVE SPACE
<?php endwhile;?>
<?php } else { echo ""; }?>
<?php wp_reset_query(); ?>
This works great but if I have a scheduled sticky post (to appear at a future date), the query ignores it as one of the sticky posts and only shows 3 - not the 4 it should?
How can I modify below code to make sure no scheduled sticky posts show AND I still retain 4 slots for sticky posts?
UPDATED CODE BELOW SHOWS ALL POSTS - NOT JUST THE MOST RECENT 4 STICKY ONES.
<?php
$sticky = get_option( 'sticky_posts' );
$args = array(
'posts_per_page' => 4,
'post__in' => $sticky,
'paged' => 1,
'ignore_sticky_posts' => 1
);
if (have_posts() ) { while ( have_posts() ) : the_post(); ?>
ALL OF MY OUTPUTTED CODE GOES HERE - EDITED OUT TO SAVE SPACE
<?php endwhile;?>
<?php } else { echo ""; }?>
<?php wp_reset_query(); ?>
Limit the number of posts you return in the query, not by slicing the array.
From http://codex.wordpress.org/Class_Reference/WP_Query#Post_.26_Page_Parameters
$sticky = get_option( 'sticky_posts' );
$args = array(
'posts_per_page' => 4,
'post__in' => $sticky,
'ignore_sticky_posts' => 1
);
Take a look at the Codex reference above for examples of loops. Here's the gist of what you need.
// The Query
$the_query = new WP_Query( $args );
// The Loop
if ( $the_query->have_posts() ) {
echo '<ul>';
while ( $the_query->have_posts() ) {
$the_query->the_post();
echo '<li>' . get_the_title() . '</li>';
}
echo '</ul>';
} else {
// no posts found
}
/* Restore original Post Data */
wp_reset_postdata();
Notice how the new WP_Query accepts the args from above. In the code you posted you weren't doing anything with them.

Specify the first post in while loop by taxonomy

I'm trying to query posts in wordpress, so far so good. However, I would like to show a post with a specific tag 'info' in front of all (even in front of sticky).
Now the query of the theme is like this:
$sticky = get_option( 'sticky_posts' );
rsort( $sticky );
if(of_get_option('sticky-posts') == 'show_sticky'){
query_posts (array( 'post__in' => $sticky, 'order' => $order_posts, 'ignore_sticky_posts' => 1, 'paged' => $paged ) );
}
And after that the loop starts:
//BEGIN LOOP
//=====================================================?>
<article id="articlehold">
<?php
if(have_posts()) : while ( have_posts() ) : the_post();
Now I've done some editing in the query to get the post with the 'info' tag in front, but no luck. Now I'm not sure where the best place is to edit this, in the loop or before the loop?
How could I do this?

Categories