I am trying to load a post by ID using query_posts, however it always returns an empty array. I get a post Id at random using SQL as follows;
$randomProdSql = "SELECT ID FROM `posts` WHERE post_status = 'publish' ORDER BY RAND() LIMIT 0,1";
I then load that into a variable using;
$randomPost = $wpdb->get_var($randomProdSql);
This works fine and if I print it out I get an Id. I then call query_posts like this;
$args = array(
'p' => $randomPost
);
$posts = query_posts($args);
I would now expect the $posts variable to contain the post.. however, if I call;
print_r($args);
print_r($posts);
I get:
Array
(
[p] => 778
)
Array
(
)
Can anyone see what I am doing wrong?
Update your code as below:
query_posts('p='.'"$randomPost"');
Also, rather using the query_posts() method to get a single post, you can use get_post() method.
$my_post = get_post($randomPost);
echo $my_post->post_title;
As per your code, you shared you want post id's in random manner. The following code will get the post id's for you in random manner.
By using post_per_page you can control the number of posts returned in result. Also, fields will force the query to return id's of posts. However, in case you want to retrieve any other field also please remove it from here. As, it only supports id field only.
For details please refer to this link:
<?php
$args = array(
'post_status' => 'publish',
'orderby' => 'rand',
'fields' => 'ids',
'posts_per_page' => '1'
);
$posts = query_posts($args);
?>
Related
I have a query that takes posts of different types with the same title. Instead, I want to pull only posts with unique titles.
My query so far is as follows:
$args = array(
'post_type' => ['report', 'case-study', 'event'],
'posts_per_page' => $posts_to_get,
'post__not_in' => [$post->ID]
);
$query = new WP_Query($args);
However, this does not filter only unique titles.
I can get a list of unique titles using
$uniques = array_unique($titles); but that does not get me the actual posts. I wanted to know if there was a query method along the lines of 'post__title_not_in => $uniques;
I tried searching everywhere for this, but I was not able to find anything that worked. Would greatly appreciate any help.
$applicationQuery = new WP_Query(array( 'post_type' => 'page', 'post_status' => 'any' ));
if($applicationQuery->have_posts()){
$header_text = "Got post (GOOD)";
}
else{
$header_text = "No post (BAD)";
}
This same query, if I use page for post_type there are results in the query, but if I change post_type to post or my own custom_post_type there's no result. Why? How can I fix this and query my custom post type?
Try this code.
$applicationQuery = query_posts( array( 'post_type' => array('page') ) );
while (have_posts()) : the_post();
//echo the_title();
endwhile;
I fixed the problem by adding 'post_status' => 'published' into the query array.
Edit: The root cause was because the custom posts were programmatically created (not via admin dashboard), and the post_status of those posts were set to published.
Wordpress doesn't know published, by default it only recognize publish. The any value in the query doesn't actually look for "any" post_status, but "any recognized" post_status.
I've got some custom post types set up in Wordpress using Pods and linking them using relationship fields. Now I'd like to display (and link to) the related custom posts 'postB' from a single post 'postA'. I also just want to display those posts which got a date in the future, which is also stored in a custom field in 'postB'.
This is what I've currently got so far, put into a theme template file (single-posta.php):
<?php
$id = get_the_ID();
$params = array(
'where' => 'postB.ID IN ('.$id.')',
'limit' => -1, // Return all
//'oderby' => 'postB.customDate, (order is not working, so I commented it out)
//'order' => 'ASC'
);
$postsB = pods( 'postB', $params );
if ( 0 < $postsB->total() ) {
while ( $postsB->fetch() ) {
?>
<p>
<?php echo $postsB->display( 'title' ); ?><br>
<?php echo $postsB->display( 'customDate' ); ?><br>
</p>
<?php
}
}
?>
So how can I
order the results?
link to these posts?
limit them to dates in the future?
Btw. is this the right way to get those posts anyway?
You could use WP_Query too, but since you're using the Pods find() syntax, I'll give you the correct code for what you're after using that:
$params = array(
'where' => 'postB.ID IN ('.$id.')',
'limit' => -1, // Return all
'orderby' => 'customDate.meta_value ASC'
);
$postsB = pods( 'postB', $params );
Pods doesn't let you create fields with capital letters though, so it's likely you created that one outside of Pods, correct? Just double checking, if it was created with Pods it would be named 'customdate'
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 :) )
I have the following function that I've added to my functions.php file in WordPress. The idea is that it gathers all of the titles of 'fsmodel' posts (a custom post type that I've created). It then returns these as an array, which I then use to populate a select tag in the custom meta fields for a second custom post type.
Basically, 'fsmodel' will have posts with a boat model, and the 'fsboat' post type will have a drop-down with the names of each of the models to select from.
Now, this appears to works fine in the Dashboard - the drop-down is populated as expected. When I save, however, the post doesn't show up in the Edit list. Also on the website, all pages output as the 404 error page when this function is active.
I'm certain that the problem lies within the following code - does anyone have any idea what I might have done wrong?
function fs_model_array() {
$models_array = array();
$loop = new WP_Query(array(
'post_type' => 'fsmodel',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
'post_status' => 'publish'
));
while ( $loop->have_posts() ) : $loop->the_post();
$models_array[] = get_the_title();
endwhile;
return $models_array;
};
OK, I've come up with a solution (I hope - it's holding up for now).
Instead of creating a loop, I've just used the $wpdb->get_results to search the database for the column with a WHERE filter for the custom post type.
Then run an array builder:
$models_array = array();
$model_db = $wpdb->get_results("SELECT post_title FROM $wpdb->posts WHERE post_type='fsmodel' AND post_status = 'publish'");
foreach ($model_db as $model_db) {
$models_array[] = $model_db->post_title;
}
Thanks again for your time, hsatterwhite! :-)
I think you might find that adding wp_reset_query() to the end of your function will solve your problems :)
I like your solution, but I'd be inclined to say that you need to call the global variable of $post whenever you use the loop like this in a function, as it assigns it to that variable.
function fs_model_array(){
global $post;
$models_array = array();
$loop = new WP_Query(array(
...