I am trying to insert a sorting option into my wordpress site. I already have it working, but need help using it with the wordpress loop correctly. Currently, I have:
On a page, there are options to sort alphabetically or chronologically:
Newest
Alphabetical
Sorting Code starts here, placed above the loop:
<?php $sort= $_GET['sort'];
if($sort == "title") { $order= "'orderby'=>'title','order'=>ASC'"; }
elseif($sort == "date") { $order= "'orderby'=>'date'"; }
else{ $order= "'orderby'=>'date','order'=>'DESC'"; }
?>
note: I am pretty sure the problem lies above in the variable $order
Wordpress Loop Using Variable $order as an argument
<?php $loop = new WP_Query( array( $order, 'post_type' => 'films', 'post_parent' => 0, 'posts_per_page' => -1 ) ); ?>
<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
Wordpress loop stuff here
<?php endwhile; ?>
The loop displays items correctly, but the sorting links are not working. This code works very well with query_posts but I am trying to get this to work for WP_Query (above). Any ideas here?
UPDATE: This technique works great using query_posts like below (but I still need it working for WP_Query):
<?php $sort= $_GET['sort'];
if($sort == "title") { $order= "&orderby=title&order=ASC"; }
elseif($sort == "date") { $order= "&orderby=date"; }
else{ $order= "&orderby=date&order=DESC"; }
?>
<?php $posts = query_posts($query_string . $order); ?>
<?php if(have_posts()) : while(have_posts()) : the_post(); ?>
Wordpress Stuff Here
<?php endwhile; ?>
<?php endif; ?>
WP_Query expects associative array of parameters (array('param' => 'value')), whereas query_posts accepts only "query strings" ("param=value¶m=value"). You are mixing both options, that's why it doesn't work. You need to change $order variable to be array instead of string, for example: $order = array('orderby' => 'title', 'order' => ASC');.
Answer above is not complete and may be misleading. WP_Query docs are here: https://codex.wordpress.org/Class_Reference/WP_Query . This class accepts boths styles, but they must be somewhat different formed. I don't know how exactly to do this, because it is not written in class docs, but you better use arrays, so:
if($sort == "title") { $order = array('orderby' => 'title', 'order' => 'ASC'); }
elseif($sort == "date") { $order= array('orderby' => 'date'); }
else{ $order= array('orderby' => 'date', 'order' => 'DESC'); }
FYI to convert between both types use functions parse_str(): http://php.net/manual/en/function.parse-str.php and http_build_query(): http://www.php.net/manual/en/function.http-build-query.php .
Related
I'm attempting to avoid querying all of my site's posts, as there are many and the site becomes slow when this script runs.
I've read every similar question and done the following without success:
using showposts parameter
adding wp_reset_query();
passing args as an array
but nothing seems to work, it always returns all the posts.
$the_query = new WP_Query( 'posts_per_page=8' );
$blogs = [];
while ($the_query -> have_posts()): $the_query -> the_post();
$post_categories = [];
foreach (get_the_category($post->ID) as $key => $cat) {
if($cat->term_id == 2) continue;
array_push($post_categories,
"<a href='". get_category_link($cat->term_id) ."'>{$cat->name}</a>"
);
}
$blogs[] = [
'title' => get_the_title($post->ID),
'abstract' => substr(wp_strip_all_tags($post->post_content), 0, 80)
];
endwhile;
}
I'm using an AJAX search to pull 3 custom post types from wordpress (post, guides, advice). As you can see in my if while loop, the results show which results are which but I'm trying to section them out individually so it will show something like this:
section 1
blog posts
section 2
guides
The problem seems to be that I need to edit the if while loop because adding anything inside that loop will just cause it to be in that loop. Does anyone know the best way to modify the if while loop to achieve this?
function data_fetch(){
$the_query = new WP_Query(
array(
'posts_per_page' => 6,
's' => esc_attr( $_POST['keyword'] ),
'post_type' => array('post' , 'guides', 'advice'),
'post_status' => 'publish'
)
);
global $post;
if( $the_query->have_posts()) :
while( $the_query->have_posts() ): $the_query->the_post(); ?>
<?php $type = get_post_type();
$term = $_POST['keyword'];
$i++;
$total = $the_query->found_posts;
?>
<span class="search-title">
<?php if ($type == 'post'):?>
<?php echo 'Article: ';?>
<?php elseif($type == 'guide' ):?>
<?php echo 'Guide: ';?>
<?php elseif($type == 'advice' ):?>
<?php echo 'advice: ';?>
<?php endif;?>
<?php the_title();?><br>
</span>
<?php endwhile; ?>
<?php
wp_reset_postdata();
else:
echo '<h3>No Results Found</h3>';
endif;
die();
}
If I were you, I'd probably just do three separate queries. They seem simple enough that it shouldn't cause any issues at all. Otherwise you have to either sort through or reorder the WP_Query results somehow.
If you're set on the single query, however - since these are such short HTML strings, I'd probably just control the output with the Output Buffer.
Basically you can create an associative array, and add the HTML strings to the appropriate keys. You could get a bit more elaborate and have them be nested arrays, but since your output is so light, you can probably get by just by having HTML strings as the values for the keys.
I took the liberty of cleaning up your code a little bit and removing some unused variables, etc.
function data_fetch(){
// Build the Query Arguments
$the_query = new WP_Query( array(
's' => esc_attr($_POST['keyword']),
'posts_per_page' => 6,
'post_type' => array('post' , 'guides', 'advice'),
'post_status' => 'publish'
) );
// Do we have posts?
if( $the_query->have_posts()){
// We do. Start an array that will fill with HTML from the output buffer
$output = array(
'post' => '',
'guides' => '',
'advice' => '',
);
// Loop through the posts
while( $the_query->have_posts() ){
$the_query->the_post();
ob_start(); // Turn on the output buffer
$type = get_post_type(); ?>
<span class="search-title">
<?php echo ($type == 'post') ? 'Article: ' : ucwords($type).': '; // Output "Articles: " for posts, or just capitalize the other post type names ?>
<?php the_title();?><br>
</span>
<?php $output[$type] .= ob_get_clean(); // Add the HTML output from the buffer to our array
}
wp_reset_postdata();
// Here we have an array with 3 HTML strings that we can output wherever
echo $output['post'];
echo $output['guides'];
echo $output['advice'];
} else {
echo '<h3>No Results Found</h3>';
}
}
if I understood your concern, I propose to divide your code by creating a generic class.
and you make calls to the different Post Type :
class Custom_Query {
public $post_type;
public $key_word;
public function __construct($post_type, $keyword) {
$this->post_type = $post_type;
$this->key_word = $keyword;
}
public function getResult() {
echo '<h1>Article : ' . $this->post_type . '</h1>';
$the_query = new WP_Query(
array(
'posts_per_page' => 6,
's' => esc_attr($this->key_word),
'post_type' => array($this->post_type),
'post_status' => 'publish'
)
);
if ($the_query->have_posts()):
while ($the_query->have_posts()): $the_query->the_post();
echo '<span class="search-title">';
echo '' . the_title() . '<br>';
echo '</span>';
endwhile;
else:
echo '<h3>No Results Found</h3>';
endif;
wp_reset_postdata();
}
}
global $post;
$type = get_post_type();
$term = $_POST['keyword'];
$article = new Custom_Query($type, $term);
$article->getResult();
You were on the right track initially. You can just use the standard post objects to check for post type. You can adjust to fit your needs, but try something like this:
<?php
query = new WP_Query( array(
's' => esc_attr($_POST['keyword']),
'posts_per_page' => 6,
'post_type' => array('post' , 'guides', 'advice'),
'post_status' => 'publish'
) );
if ($query->have_posts()) {
while ($query->have_posts()):
$query->the_post();
?>
<div class="posts">
<?php
if ($query->post->post_type === 'post') {
// add your content
} else if ($query->post->post_type === 'guides' {
// add your content
} else {
// add your content
}
?>
</div>
<?php endwhile;
} else {
// no posts found
}
I used this code to my category.php and I want it to convert for my page template, this code is fully functional and working on category.php.
<?php
if (in_category('interior')) {
$cat = get_query_var('cat');
$this_category = get_category($cat);
$this_category = wp_list_categories('hide_empty=0&hierarchical=false&order=ASC&orderby=title&show_count=0&title_li=&use_desc_for_title=1&child_of='.$this_category->cat_ID."&echo=0");
if($this_category !='<li>No categories</li>') {
echo '<ul class="ul-menu">'.$this_category.'</ul>';
}
}
?>
Image Attached Sample
Use this code into your page template.
$args = array (
'cat' => array(2,6,9,13),//use category id
'posts_per_page' => -1, //showposts is deprecated
'orderby' => 'date' //You can specify more filters to get the data
);
$cat_posts = new WP_query($args);
if ($cat_posts->have_posts()) : while ($cat_posts->have_posts()) : $cat_posts->the_post();
get_template_part( 'content', 'page' );
endwhile; endif;
I think its work for you. check and let me know
Can anyone explain why this only returns the 1st result only. I want to return all results that have the same custom field value as the current url. It will ony return 1. Does it need a for each or something? Thank you!!
<?php add_shortcode( 'feed', 'display_custom_post_type' );
function display_custom_post_type(){
$url = 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
$args = array(
'post_type' => 'custom_post_type',
'posts_per_page' => -1
);
$new_query = new WP_Query($args);
while($new_query->have_posts()) : $new_query->the_post();
return get_title();
endwhile;
};?>
Because you have added the return inside the loop it will only display the last one. You have to place the return outside the loop for it to display all.
Just a small example to see it work, change this bit:
while($new_query->have_posts()) : $new_query->the_post();
return get_title();
endwhile;
to this:
while($new_query->have_posts()) : $new_query->the_post();
$all_titles .= get_title();
endwhile;
return $all_titles;
It will most probably show all the titles in a single row, so just format as you wish!
You "return" from the function after the first element inside the while loop.
example returning all the posts:
$args = array(
'post_type' => 'custom_post_type',
'posts_per_page' => -1
);
$results = get_posts($args);
return $results;
Here is an example loop:
$args = array('s' => 'Example search term', 'cat' => 100, 'posts_per_page' => -1);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) { $query->the_post();
foreach((get_the_category()) as $category) {
echo $category->cat_name . '<br />';
}
}
}
wp_reset_query();
Assuming that the category with the id# 100 is a parent category for several subcategories, this loop successfully returns a list of heavily duplicated category names.
How could I list only unique category names and count them? And put both values into appropriate variables.
Along with the complete list of all found results and their count, too...
Of course I'll try to figure out the solution myself while waiting for your kind answer, as always. But, actually, a little help would be much appreciated.
So, I'll respond to myself. Again )
Thanks to #Perumal93's hint which directed me the correct way, I now have the solution.
In case it would be usable for anyone like me, here is the commented code ready for copy and paste:
$args = array('s' => 'Example search term', 'cat' => 100, 'posts_per_page' => -1);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
$categories = array(); // 1. Defining the empty array outside of the loop
while ( $query->have_posts() ) { $query->the_post();
foreach((get_the_category()) as $category) {
$categories[] = $category->cat_name; // 2. Filling the array with required data
}
}
$u_categories = array_unique($categories); // 3. Clearing the array from repeated data
$u_categories_cnt = count($u_categories); // 4. Counting the cleared array items
foreach( $u_categories as $category ) { // 5. Outputting
if($category == end($u_categories)) { echo $category.'.'; } // the cleared
elseif($category == prev($u_categories)) { echo $category.' and '; } // array in a
else {echo $category.', '; } // human
} // friendly way
echo $u_categories_cnt; // 6. Outputting the cleared array items count
}
wp_reset_query();
That's it