So I have a customised wordpress search page that groups the result into the custom post type header.
This works but it still shows the post type if there are no posts in it.
What can I do to check to see if the section has posts, and if not, hide the section.
Note: if( !empty ( $hasposts ) ) currently returns FULL for each check as the post types have posts, but they are not part of the search results.
<?php
if( have_posts() ){
//Define post types:
$types = array('post', 'promo_offers', 'product_manuals', 'support_posts','product');
foreach( $types as $type ){
// RETURN EMPTY IF THE RESLUTS FOR THE POST TYPE IS EMPTY
$hasposts = have_posts($type);
if( !empty ( $hasposts ) ) { echo '<div>FULL!</div>';} else {echo '<div>EMPTY!</div>';}
//BELOW CODE WORKS AS INTENDED
echo 'your container opens here for ' . $type;
echo '<ul>';
while( have_posts() ){
the_post();
if( $type == get_post_type() ){
echo '<li>';
the_title();
echo '</li>';
}
}
echo '</ul>';
rewind_posts();
echo 'your container closes here for ' . $type;
}
}
?>
So my understanding is that have_posts() doesn't take parameters, and actually I'm curious about what happens when you call
$hasposts = have_posts($type);
Your function is looping through all posts multiple times, but only displaying those posts that have the type of $type. The point is that have_posts() returns true every time because it's referring to all posts, not just of the specified type.
So I think that what you need is to make a separate query for each type, like so:
foreach( $types as $type ) {
query_posts("post_type=$type");
while (have_posts() ) {
//now this should only happen if the specific type has posts in it...
}
}
Related
I am working on the WordPress search. I am using the below code to get the data on the search page.
$s=get_search_query();
$args = array(
's' =>$s
);
$query = new WP_Query( $args );
if( $query->have_posts() ) { ?>
<ul>
<? while( $query->have_posts() ) {
$query->the_post();
// print_r($query);
?>
<li><h2><a href='<?php echo the_permalink();?>'><?php echo the_title();?></a></h2></li>
<?php } ?>
</ul>
<?php
};
?>
The above code is working. I am getting the title on the page.
Now, My concern is, Is it possible to get the specific content on the page?
I mean If I use post_content then I am getting all the content of the page. Is it possible to display only section heading on the search page?
Are you using Gutenberg?
You can actually loop through blocks by retrieving them from the content using parse_blocks().
Parses blocks out of a content string.
Source # https://developer.wordpress.org/reference/functions/parse_blocks/
if ( ! empty( get_the_content() ) ) {
$blocks = parse_blocks( get_the_content() );
foreach ( $blocks as $block ) {
if ( 'core/heading' === $block['blockName'] ) {
echo wp_strip_all_tags( render_block( $block ) );
};
};
};
see # https://gist.github.com/MDSilviu/bb5d33bcc76c45be93c6f5fd8622d6f1 for a complete list of core blocks type.
I just started with a wordpress tutorial series and one of the first things it does was make a simple "the loop", to print the title and description of all of the posts. When I did it though, it prints the name and description of the home page.
<?php
if ( have_posts() )
{
while ( have_posts() )
{
the_post();
the_title('<h2><a href="the_permalink();"','</a></h2>');
the_content();
// Post Content here
//
} // end while
} // end if
?>
I cannot figure out why it prints the home page information instead of post info.
To display wordpress posts on any page , you need to pass the arguments as the following in the WP_Query and then loop them via object.
// The Query
$the_query = new WP_Query( array( 'post_type' => 'post','posts_per_page' => -1 ) );
// 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>';
/* Restore original Post Data */
wp_reset_postdata();
} else {
// no posts found
}
Trying to write my first short-code that displays all post-titles in a specific Category. But it is not displaying the actual results, just the short code.
Here is what I have so far in my child theme's functions.php file:
function posts_in_cat() {
echo '<ul>';
query_posts('cat=3'); while (have_posts()) : the_post();
echo ('<li>' . the_title() . '</li>');
endwhile;
wp_reset_query();
echo '</ul>';
}
add_shortcode( 'display_posts_in_cat', 'posts_in_cat' );
And then I am calling the short code, like so [display_posts_in_cat].
Any help would be greatly appreciated as I try and learn this.
EDIT: I have gotten it to display but the link itself is being echo-ed in front of the title in text. Also, it is not displaying more than 10 of the titles and I want it to display them all. Any ideas...?? Thanks.
First and foremost, avoid using query_posts() – it's inefficient. Check out this SO answer for the skinny.
Additionally, shortcodes shouldn't make use of echo statements. Shortcodes only return text. Put simply, WordPress has PHP internally that says "when this specific shortcode is entered into the editor, replace it with the text returned from this function." Using echo causes you to immediately print those statements to the screen, rather than returning to WordPress so that it can continue with its regular process. More on the WP Codex.
And, finally, shortcode functions require $atts as a parameter.
So, with all that said, here's how I would rewrite your function:
<?php
function posts_in_cat( $atts ) {
$atts = shortcode_atts( array(
'cat' => '',
), $atts );
if ( empty( $atts['cat'] ) ) {
// If category provided, exit early
return;
}
$args = array(
'category' => $atts['cat'],
// Disable pagination
'posts_per_page' => -1
);
$posts_list = get_posts( $args );
if ( empty( $posts_list) ) {
// If no posts, exit early
return;
}
$opening_tag = '<ul>';
$closing_tag = '</ul>';
$post_content = '';
foreach ( $posts_list as $post_cat ) {
$post_content .= '<li>' . esc_html( get_the_title( $post_cat->ID ) ) . '</li>';
}
return $opening_tag . $post_content . $closing_tag;
}
add_shortcode( 'display_posts_in_cat', 'posts_in_cat' );
I'm just adding all of the content you were echoing into a handful of variables, and then returning them, concatenated, at the end. Also, I added in an if statement to exit early if there aren't any posts in the category. That way you don't have an empty <ul> element cluttering up the page.
I've also escaped the outputs, which you can read about on the Codex.
Please try this:
function posts_in_cat() { ?>
<ul class="posts">
<?php query_posts('cat=3&showposts=50'); while (have_posts()) : the_post();
?>
<li><a href='<?php the_permalink() ?>'><?php the_title(); ?></a></li>
<?php endwhile; ?>
<?php wp_reset_query(); ?>
</ul>
<?php
}
add_shortcode( 'display_posts_in_cat', 'posts_in_cat' );
I've created four custom post types -- videos, audio, programs, blogs -- with various custom fields and I've managed to created a custom archive page that displays certain custom fields depending on the post type. The archive page is working well when only viewing the archive of a certain custom post type. The issue I'm having is with the archive pages for categories.
Each custom post type has access to global 'post' categories, so all of my categories show up in each post type. I'd like to be able to query a category and show associated posts regardless of the post type. i.e. the 'business' category may pull up two videos, an audio post, and a blog. The problem is that my category pages are empty right now.
Here is my current loop in 'archive.php':
<?php
if ( have_posts() ) : ?>
<div class="container">
<div class="row">
<?php
/* Start the Loop */
while ( have_posts() ) : the_post();
get_template_part( 'template-parts/content-archive', get_post_format() );
endwhile;
the_posts_navigation(); ?>
</div><!-- .row -->
</div><!-- .container -->
<?php endif; ?>
This grabs the template for archive content 'content-archive.php':
<?php
/**
* Get featured posts from Archives
*/
if( is_post_type_archive( 'videos' ) ) {
$video_image = get_field( 'video_still_image' );
print_archive_post($video_image);
} elseif( is_post_type_archive( 'programs') ) {
$program_featured_image = get_field('program_featured_image');
print_archive_post($program_featured_image);
} elseif( is_post_type_archive( 'audio') ) {
$audio_featured_image = get_field('audio_featured_image');
print_archive_post($audio_featured_image);
} elseif( is_post_type_archive( 'blogs') ) {
$blog_featured_image = get_field('blog_featured_image');
print_archive_post($blog_featured_image);
}
?>
And, here is my function from 'functions.php' to build the content for the post:
// Function to print archive type posts
function print_archive_post($image) {
echo '<div class="col-md-4 featured-thumb-container">';
echo '<span class="featured-thumb" style="background: url(' . $image . ')"></span>';
echo '<h3>' . get_the_title() . '</h3>';
// The category list
$post_cats= array();
$categories = get_the_category();
echo '<p class="category-list">';
foreach($categories as $cat) :
echo '<a class="category-link" href="' . get_home_url() . '/category/' . $cat->slug . '">' . $cat->cat_name . '</a><span>,</span> ';
endforeach;
echo '</p>';
echo '</div>';
}
I know I'm missing a conditional to check for category, but I haven't been able to find a solution in my research. Any help would be greatly appreciated. :)
Not sure I understand your question correctly. If you want to query all custom post related to one category, you can use WP_Query in the archive page.
//if you're on a category archive, it will return the category object
$category_object = get_queried_object();
$args = array(
'post_type' => 'your-cpt',
'cat' => $category_object->term_id
);
$wp_query = new WP_Query( $args );
if ( $wp_query->have_posts() ) {
while ( $wp_query->have_posts() ) {
$wp_query->the_post();
//echo your posts
}
} else {
// aww, no posts... do other stuff
}
wp_reset_postdata();
So, after some research, I found the solution. I needed to add my custom post types to Wordpress's built-in categories and tags. Here is the code that I added to my functions.php file:
// Add custom post types to default WP categories and tags
function add_custom_types_to_tax( $query ) {
if( is_category() || is_tag() && empty( $query->query_vars['suppress_filters'] ) ) {
// Get all your post types
$post_types = get_post_types();
$query->set( 'post_type', $post_types );
return $query;
}
}
add_filter( 'pre_get_posts', 'add_custom_types_to_tax' );
I found the code here: https://premium.wpmudev.org/blog/add-custom-post-types-to-tags-and-categories-in-wordpress/
Additionally, I created a category.php file for category archives only. I used the same code as my archive.php file, but I swapped in a new template file for category content: 'content-category-archive.php'. Here's the code for that template:
<?php
/**
* Get featured posts from Category Archives
*/
if( get_post_type() == 'videos' ) {
$video_image = get_field( 'video_still_image' );
print_archive_post($video_image);
} elseif( get_post_type() == 'programs' ) {
$program_featured_image = get_field('program_featured_image');
print_archive_post($program_featured_image);
} elseif( get_post_type() == 'audio' ) {
$audio_featured_image = get_field('audio_featured_image');
print_archive_post($audio_featured_image);
} elseif( get_post_type()== 'blogs' ) {
$blog_featured_image = get_field('blog_featured_image');
print_archive_post($blog_featured_image);
}
?>
The difference between this and my other 'content-archive.php' template is the conditional for each post type. Instead of checking for is_post_type_archive('my custom post type') I'm now checking the post type for each post in the current category with get_post_type() == 'my custom post type'.
I hope this helps others who may be having the same issue. :)
I am making infinite scroll page. I created a page template where posts of certain category are loaded. Everything works fine with a single page and single category.
But I have three pages with this page template and each page should load articles from a specific category. I am using the is_page() if elseif block to determine on which page visitor is. But is_page() is not executed.
Here is the loop:
$cat = '';
if(is_page(703)){
$cat = 4;
} elseif (is_page(706)) {
$cat = 21;
}
$args = array(
'cat' => $cat,
'paged' => $paged
);
$infinite_news_query = new WP_Query($args);
if ( $infinite_news_query -> have_posts() ) : while ( $infinite_news_query -> have_posts() ) : $infinite_news_query -> the_post();
<?php endwhile; ?>
<?php else : ?>
<?php endif; ?>
<?php wp_reset_postdata();
?>
This code displays all the posts, regardless of category, and $cat is empty inside the loop.
What am I doing wrong?
Thanks!
Change the following:
$cat = '';
if(is_page(703)){
$cat = 4;
} elseif (is_page(706)) {
$cat = 21;
}
to:
if(is_page('703')){
$cat = 4;
} else { if(is_page('706')) {
$cat = 21;
}
Also removing $cat = '';
Look at it like this, at first you have the variable $cat set to empty value, respectively, to false , zero or 0.
Then you set a loop, with only two states, leaving out a default value.
So, what is going to happen, when your page ID is changed?
You get all the posts displayed.
In other words, I do not see anything bad in the code. I would rather recommend you to use is_page('slug') than with id.