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
Related
I am having trouble with Wordpress pagination. I have a custom archive page displaying custom post types from the specific category. I want to use pagination and display 12 posts per page. My problem is that pagination works correctly but only up to the 8th page. After that I am being presented with "Page not found".
I am using theme built-in function to display page navigation (1, 2... 10, 11). It correctly shows 11 pages in total, but they seem not to work after the 8th page.
$taxonomy = 'product_cat';
$term_id = get_queried_object()->term_id;
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'product',
'paged' => $paged,
'posts_per_page' => '12',
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $term_id
)
)
);
<?php $wp_query = new WP_query( $args ); ?>
<?php if( $wp_query->have_posts() ): ?>
<?php while( $wp_query->have_posts() ): ?>
<?php $wp_query->the_post(); ?>
//post content
<?php endwhile; ?>
<?php endif; ?>
<?php s7upf_paging_nav();?>
<?php wp_reset_postdata(); ?>
#edit
When I go to a different category page which should have 12 pages they work correctly up to the 9th page.
If I go to the one that has 2 pages, only the first one works.
I tried updaing permalinks. Setting posts per page to 12 in wordpress settings.
When i change posts per page in my query args to -1 it correctly shows all the posts on one page.
When manually setting the number of a page to display ('paged' => '11') it also displays correct page with correct posts.
You are using the wrong query. On page you are creating your own query instead of the actual query the page already did.
This will also be better for performance.
Step 1. Check what is in the normal query.
At the top of taxonomy-product_cat.php
global $wp_query;
var_dump( $wp_query->query_vars );
That probably fits mostly.
Step 2. Do the normal loop
Remove all your query stuff (maybe keep a backup of the $args for the next step)
example: Replace
<?php if( $wp_query->have_posts() ): ?>
with
<?php if( have_posts() ): ?>
And so on.
Step 3. Edit the main query
We are going to use the hook pre_get_posts
add_action('pre_get_posts', 'so_53315648');
function so_53315648( WP_Query $wp_query ){
// only check this on the main query
if (! $wp_query->is_main_query() ){
return;
}
// only check this on the product_cat taxonomy
if ( ! $wp_query->is_tax('product_cat')) {
return;
}
// maybe do some more checks?
$wp_query->query_vars['posts_per_page'] = 12;
// Is this really needed??
//$wp_query->query_vars['posts_type'] = 'product';
// tweak the query the way you like.
}
As you can see $wp_query->query_vars should pretty much be the same $args. But do not overwrite it. This might break other stuff.
Of course I could not test your specific site. But the answer should be inside the pre_get_posts hook. And tweaking the main query instead of doing a extra separate one.
Test, also check the var_dump of step 1 that your changes are coming through.
The checks at the top are to stop other pages from being affected, maybe you need more?
Let me know.
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} ";
}
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 :) )
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?
How do I include the page content of one or more page in another page?
ex. I have pageA, pageB and pageC and I want to include the contents of these pages in pageX
is there a wordpress function that loads the post of a specified page/post?
like show_post("pageA")??
There is not a show_post() function per se in WordPress core but it is extremely easy to write:
function show_post($path) {
$post = get_page_by_path($path);
$content = apply_filters('the_content', $post->post_content);
echo $content;
}
Note that this would be called with the page's path, i.e.:
<?php show_post('about'); // Shows the content of the "About" page. ?>
<?php show_post('products/widget1'); // Shows content of the "Products > Widget" page. ?>
Of course I probably wouldn't name a function as generically as show_post() in case WordPress core adds a same-named function in the future. Your choice though.
Also, and no slight meant to #kevtrout because I know he is very good, consider posting your WordPress questions on StackOverflow's sister site WordPress Answers in the future. There's a much higher percentage of WordPress enthusiasts answering questions over there.
I found this answer posted on the Wordpress forums. You add a little code to functions.php and then just use a shortcode whenever you like.
function get_post_page_content( $atts ) {
extract( shortcode_atts( array(
'id' => null,
'title' => false,
), $atts ) );
$the_query = new WP_Query( 'page_id='.$id );
while ( $the_query->have_posts() ) {
$the_query->the_post();
if($title == true){
the_title();
}
the_content();
}
wp_reset_postdata();
}
add_shortcode( 'my_content', 'get_post_page_content' );
For the shortcode,
[my_content id="Enter your page id number" title=Set this to true if you want to show title /]
Pages are just posts, with a post_type of 'page' in the database. You can show the content of multiple pages on another page by writing a post query in your pageX template that gets the posts you specify and output them in a Loop.
There are three ways to get post content from the database:
get_posts
query_posts
WP_Query
These links all point to the WordPress Codex. Get_posts and query_posts have an argument available, 'page_id', where you can specify the id of the page you'd like to retrieve and display.
You could install a Plugin "Improved Include Page". Once installed, you create page X and enter:
[include-page id="123"]
[include-page id="124"]
[include-page id="125"]
where these are the ID's of pages A, B and C respectively
<?php query_posts('p=43');
global $more;
//set $more to 0 in order to only get the first part of the post
$more = 0;
// the Loop
while (have_posts()) : the_post();
// the content of the post ?>
the_title();
the_content();
endwhile; ?>
This is obviously a portion of the post, I got the detail from the wordpress codex.
Interesting... I looked around for how to embed Wordpress content elsewhere (as in, on another website), and found some things...
www . shooflydesign.org/buzz/past/embedding_wordpress . html
Shows how to embed Wordpress content in another site with a php script; maybe just use the same thing to embed Wordpress into itself?
www . corvidworks . com/articles/wordpress-content-on-other-pages
Similar concept; embed Wordpress on another page; just try to use that tool in a new WP post
feeds themselves
My searching pulled up some suggestions to just use a feed to your own blog to embed into a post. There's nothing preventing that. You might want it automated and so restructuring the feed to look right might be problematic, but it's worth a shot depending on what you want to do.
Hope those are quasi-helpful. While they all are solutions for getting your WP content on some place other than WP... they might work for your given question and allow you to display A, B, and C on X.
There is a Wordpress function to display the content of a particular page inside another using query_posts() it is:
<?php query_posts("posts_per_page=1&post_type=page&post_id=134"); the_post(); ?>
You set the number of pages to be displayed to 1, post type is page instead of post and the page id
Kit Johnson's wordpress forum solution with creating a shortcode works, but adds the inserted page in the top of the new page, not where the shortcode was added. Close though, and may work for other people.
from the wordpress post, I pieced together this which inserts the page where the shortcode is put:
function get_post_page_content( $atts ) {
extract( shortcode_atts( array(
'id' => null,
'title' => false,
), $atts ) );
$output = "";
$the_query = new WP_Query( 'page_id='.$id );
while ( $the_query->have_posts() ) {
$the_query->the_post();
if($title == true){
$output .= get_the_title();
}
$output .= get_the_content();
}
wp_reset_postdata();
return $output;
}
Then, the shortcode bit works as expected. If you don't want the title, title=false does not work, you need to leave title off entirely.