Exclude Wordpress Category - php

I have a loop do display the different categories to go on the archive page.
How can y only display the categories one time ?
Currently, if two posts had the same category, there is two time the category
This is my code below
<div class="row ptb-20">
<?php
$args = array(
'category_name' => 'actualites',
);
// Custom query.
$query = new WP_Query( $args );
// Check that we have query results.
if ( $query->have_posts() ) {
// Start looping over the query results.
while ( $query->have_posts() ) {
$query->the_post();?>
<div class="category-filter">
<div class="single-filter">
<?php
$categories = get_the_category();
$separator = ", ";
$output = ' ';
if ($categories) {
foreach ($categories as $category) {
$output .= '<li>' . $category->cat_name . '</li>';
}
echo trim($output, $separator);
}
?>
</div>
</div>
<?php
} // End while
} // End if
else { echo '<p>Aucune actualité trouvée</p>'; } ?>
<?php wp_reset_postdata(); ?>
</div>

Method 1: Exclude a Category from WordPress Using Plugin
First thing you need to do is to install and activate the Ultimate Category Excluder plugin. For more details, you should follow our guide on how to install a WordPress plugin.
Upon activation, you’ll need to go to Settings » Category Excluder page. It will display all the categories that are available on your WordPress blog.
Method 2: Exclude a Category from WordPress Homepage Using Code
This method requires you to add code to your WordPress files. If you haven’t done this before, then see our guide on how to copy and paste code snippets in WordPress.
You will need to add following code to your theme’s functions.php file or a site-specific plugin.
function exclude_category_home( $query ) {
if ( $query->is_home ) {
$query->set( 'cat', '-5' );
}
return $query;
}
add_filter( 'pre_get_posts', 'exclude_category_home' );
Don’t forget to replace ID (-5) with your category ID. It will hide all blog posts from homepage belonging to the category that matches this ID.
Note: Make sure to add a minus (-) sign with the category ID.
Please refer: https://www.wpbeginner.com/wp-tutorials/how-to-exclude-a-category-from-your-wordpress-homepage/

If I understand your issue correctly, you can introduce a variable in which you would remember what categories has already been used, so you don't include them more than once.
<div class="row ptb-20">
<?php
$args = array(
'category_name' => 'actualites',
);
// Custom query.
$query = new WP_Query( $args );
// Check that we have query results.
if ( $query->have_posts() ) {
// Start looping over the query results.
while ( $query->have_posts() ) {
$query->the_post();?>
<div class="category-filter">
<div class="single-filter">
<?php
$categories = get_the_category();
$categories_displayed = [];
$separator = ", ";
$output = ' ';
if ($categories) {
foreach ($categories as $category) {
if (!in_array($category->cat_name, $categories_displayed)) {
$output .= '<li>' . $category->cat_name . '</li>';
$categories_displayed[] = $category->cat_name;
}
}
echo trim($output, $separator);
}
?>
</div>
</div>
<?php
} // End while
} // End if
else { echo '<p>Aucune actualité trouvée</p>'; } ?>
<?php wp_reset_postdata(); ?>
</div>

Related

Wordpress loop: custom number of posts and sort by date

I have tried to find a solution to something I need on the website (example here: https://www.baiweb.nl/). I have been looking for a way to show a custom number of posts per category AND sort them by date. I have managed to get a single post per category, but I can't seem to fix the rest. It sorts the posts itself by date now, but not all of them.
So, my questions are:
Is it possible to sort this loop, with all different categories, by date?
Is it possible to control the number of posts shown per category? This one is extra for me, not essential, but it would be nice.
Hope someone can help! Thanks a lot in advance for your time!
Here is my code used in the loop now:
<?php
$categories = get_categories();
$cats = array();
foreach($categories as $category) {
$cats[] = $category->name . ", ";
}
$exclude_posts = array();
foreach( $cats as $cat ) {
// build query argument
$query_args = array(
'category_name' => $cat,
'showposts' => 1,
'post_type' => 'post',
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'DESC'
);
// exclude post that already have been fetched
// this would be useful if multiple category is assigned for same post
if( !empty($exclude_posts) )
$query_args['post__not_in'] = $exclude_posts;
// do query
$query = new WP_Query( $query_args );
// check if query have any post
if ( $query->have_posts() ) {
// start loop
while ( $query->have_posts() ) {
// set post global
$query->the_post();
// add current post id to exclusion array
$exclude_posts[] = get_the_ID();
?>
<article id="post-<?php the_ID(); ?>" <?php post_class('loop');?>>
<div class="corner"><span><?php foreach((get_the_category()) as $category){ echo $category->name.'<br> '; } ?></span></div>
<!-- thumbnail -->
<a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>" class="image">
<?php
$thumb_id = get_post_thumbnail_id();
$thumb_url = wp_get_attachment_image_src($thumb_id,'medium', true);
if ( in_category('2') || in_category('32') ) {
echo '<div class="newstitle">' . the_title() . '</div>';
}
else {
if ( has_post_thumbnail()) {
echo "<div class='ctr-image test2' style='background-image: url(" . $thumb_url[0] . ")'></div>";
}
else {
echo '<div class="newstitle">' . the_title() . '</div>';
}
}
?>
</a>
<div class="content">
<span class="date"><?php the_time('j/m/Y'); ?></span>
<h3>
<a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>">
<?php if ( in_category('2') || in_category('32') ) {}
else { echo the_title();} ?>
</a>
</h3>
<div class="text">
<?php html5wp_excerpt('html5wp_index'); // Build your custom callback length in functions.php ?>
</div>
</div>
</article>
<?php
// do something
}
} else {
// no posts found
}
// Restore original Post Data
wp_reset_postdata();
} ?>
You were close. Your categories foreach loop has to englobe everything. Then we do a simple loop but we specify what arguments to use depending on each categories.
Here is our final result.
<?php
$categories = get_categories(); // ... get all our categories
foreach( $categories as $category ) { // ... start foreach categories
if ( $category->name == 'Mercury' ) { // ... if our category name is 'Mercury'
$posts_per_page = 1; // ... 1 post per page if our category is named 'Mercury'
} else { // ... else, for all other categories
$posts_per_page = 3; // ... 3 posts per page
};
$args = array( // ... all our arguments
'posts_per_page' => $posts_per_page, // ... 1 or 3 posts per page depending on our categories
'post_type' => 'post',
'category_name' => $category->name,
'post_status' => 'publish',
'orderby' => 'date', // ... order by date
'order' => 'ASC', // ... most recent first
);
$query = new WP_Query( $args ); // .. start a new loop
if( $query->have_posts() ):
echo '<section>';
echo '<h1>' . $category->name . '</h1>'; // ... only display our section IF a post exist in the category
while( $query->have_posts() ): $query->the_post();
echo '<article>'; // ... our post template
the_title( '<h4>', '</h4>' );
echo '</article>';
endwhile;
echo '</section>';
endif;
wp_reset_postdata(); // ... After looping through a separate query, this function restores the $post global to the current post in the main query.
}; // ... end foreach categories
?>
Thank you so much for your quick and comprehensive answer! The part of the number of categories is working very well, however, the outcome is slightly different than I want. It may be that my question was not clear, apologies for that.
What you have already made beautiful is all the categories with posts that belong to it. What I want to achieve is that all messages are mixed up, sorted by date and, what was already done here, I can indicate how many posts are in per category. Is that even possible?
Some screenshotsof the outcome of your code:
This is what I am trying, except now I need to sort this by date:
This is the code slightly adjusted:
<?php
$categories = get_categories(); // ... get all our categories
foreach( $categories as $category ) { // ... start foreach categories
if ( $category->name == 'Mercury' ) { // ... if our category name is 'Mercury'
$posts_per_page = 1; // ... 1 post per page if our category is named 'Mercury'
} else { // ... else, for all other categories
$posts_per_page = 2; // ... 3 posts per page
};
$args = array( // ... all our arguments
'posts_per_page' => $posts_per_page, // ... 1 or 3 posts per page depending on our categories
'post_type' => 'post',
'category_name' => $category->name,
'post_status' => 'publish',
'orderby' => 'date', // ... order by date
'order' => 'ASC', // ... most recent first
);
$query = new WP_Query( $args ); // .. start a new loop
if( $query->have_posts() ):
// echo '<section>';
// echo '<h1>' . $category->name . '</h1>'; // ... only display our section IF a post exist in the category
while( $query->have_posts() ): $query->the_post();
echo '<article>'; // ... our post template
echo '<h1>' . $category->name . '</h1>';
the_time('j/m/Y');
the_title( '<h4>', '</h4>' );
echo '</article>';
endwhile;
// echo '</section>';
endif;
wp_reset_postdata(); // ... After looping through a separate query, this function restores the $post global to the current post in the main query.
}; // ... end foreach categories ?>
Hope this is clear, thanks again!

How can I turn this PHP snippet into a Wordpress shortcode?

This is a music website with multiple artist pages - one page per artist. New content is added as a post with a Wordpress tag to denote the artist. This is so that I can add a Wordpress loop on each artist page to show all the posts filtered with that artist's tag.
I've got the filtered loop working correctly, but unfortunately it's currently hardwritten inside the page template's HTML, so it's only filtering for one tag. I don't want to create a new page template for each artist, so I'd like to add it to my functions.php file instead, where I can instead create a new shortcode for each artist.
Here's the current code in my page template, which filters the loop for all posts with our seefour tag:
<?php
query_posts( "tag=seefour" );
if ( have_posts() ) { ?>
<?php while ( have_posts() ) { ?>
<?php the_post(); { ?>
<div class="jd-box">
<a href="<?php the_permalink(); ?>">
<?php the_post_thumbnail( ); ?>
<div class="jd-overlay"></div>
<div class="jd-overlay-text">
<?php the_title(); ?>
</div>
</a>
</div>
<?php } ?>
<?php } ?>
<?php } ?>
I'm assuming the best option is to turn this into a seefour shortcode inside my functions.php file - how can I achieve this?
Bonus question: is this sustainable in the long run (with 30-50+ artists) or will it cause a lot of redundant code? Open to suggestions...
P.S. I know this kind of question has been answered already (starting with raw PHP), but since I'm starting with a mix of HTML/PHP (and I'm a PHP newb), I just can't get it to work. So my apologies for asking again.
First of all, you should never ever use query_posts(). It is internal WordPress function to create and maintain the main WordPress cycle. Using it, you can crash your site in unpredictable manner. You should use get_posts() or WP_Query instead.
To have your custom shortcode, add the following to your functions.php:
function showtag_shortcode( $atts ) {
$atts = shortcode_atts( array(
'tag' => '', // Default value.
), $atts );
$posts = get_posts( 'tag=' . $atts['tag'] );
if ( $posts ) {
$output = '';
foreach ( $posts as $post ) {
setup_postdata( $post );
$output .= '<div class="jd-box">';
$output .= '<a href="' . get_the_permalink( $post ) . '">';
$output .= get_the_post_thumbnail( $post );
$output .= '<div class="jd-overlay"></div>';
$output .= '<div class="jd-overlay-text">';
$output .= get_the_title( $post );
$output .= '</div>';
$output .= '</a>';
$output .= '</div>';
}
} else {
$output = 'no data';
}
wp_reset_postdata();
return $output;
}
add_shortcode( 'showtag', 'showtag_shortcode' );
This function created [showtag] shortcode with one parameter: tag. You can use this shortcode on any page as follows:
[showtag tag="seefour"]
[showtag tag="disco"]
etc. You will have posts with relevant tags to be shown in place of your shortcode.
Putting a whole loop in a shortcode will make it messy, I know you can use shortcodes in Widgets etc as well but I guess that's not what you're after.
If so, the best option would be to make this code a page template say Artist and pass a variable in URL i.e. http://example.com/artist?t=seefour and then use the following code in the page template.
<?php
/**
* Template Name: Artist
*/
query_posts( "tag=" . $_GET['t'] );
if ( have_posts() ) {
?>
<?php while ( have_posts() ) { ?>
<?php the_post(); { ?>
<div class="jd-box">
<a href="<?php the_permalink(); ?>">
<?php the_post_thumbnail( ); ?>
<div class="jd-overlay"></div>
<div class="jd-overlay-text">
<?php the_title(); ?>
</div>
</a>
</div>
<?php
}
}
}
?>
This can be used for any number of artists, totally flexible because it is dependant on a variable that is provided on run time (when accessed).

How to display Posts on Wordpress home page, Order by last updated

I want to display Posts order by Last updated on the home page, how to right function for it and where to paste that function in wordpress?
Create your plugin and paste this function in plugin file.
function wpb_lastupdated_posts()
{
// Query Arguments
$lastupdated_args = array(
'orderby' => 'modified',
'ignore_sticky_posts' => '1'
);
//Loop to display 5 recently updated posts
$lastupdated_loop = new WP_Query( $lastupdated_args );
$counter = 1;
$string .= '<ul>';
while( $lastupdated_loop->have_posts() && $counter < 5 ) : $lastupdated_loop->the_post();
$string .= '<li> ' .get_the_title( $lastupdated_loop->post->ID ) . ' ( '. get_the_modified_date() .') </li>';
$counter++;
endwhile;
$string .= '</ul>';
return $string;
wp_reset_postdata();
}
//add a shortcode
add_shortcode('lastupdated-posts', 'wpb_lastupdated_posts');
use this shortcode : [lastupdated-posts]
There are 3 ways to do this
add this code in the functions.php file
function shortcode_latest_homepage_posts(){
$lquery = new WP_Query(array('order' => 'DESC'));
if($lquery->have_posts()){
while($lquery->have_posts()){
$lquery->the_post();
the_title();
the_content();
}
}
wp_reset_postdata();
}
add_shortcode('latest_posts', 'shortcode_latest_homepage_posts');
and add simply this [latest_posts] shortcode in the page editor that you have assign for the front page in cms
OR
add this code in functions.php
function latest_homepage_posts(){
$lquery = new WP_Query(array('order' => 'DESC'));
if($lquery->have_posts()){
while($lquery->have_posts()){
$lquery->the_post();
the_title();
the_content();
}
}
wp_reset_postdata();
}
add_action('latest_post', 'latest_homepage_posts');
and add this code at the place where you want to show the post in the template that assign for or made for a home page like home.php or front-page.php
<?php do_action('latest_post');?>
OR
3. simply add this code at the place where you want to show the post in the template that assign for or made for a home page like home.php or front-page.php
<?php
$lquery = new WP_Query(array('order' => 'DESC'));
if($lquery->have_posts()){
while($lquery->have_posts()){
$lquery->the_post();
the_title();
the_content();
}
}
wp_reset_postdata();
?>

Extract total number of posts from a specific tag

I have a category, I want to show in my sidebar with the total number of posts(how many posts this category has).
You can try this plugin https://wordpress.org/plugins/category-posts/
Or if you like code yourself. Here it is:
You can use the method get_posts for getting result which accepts single array parameter or string parameter as given below.
<?php $posts = get_posts('post_type=post&category=4');
$count = count($posts);
echo $count;
?>
Explanation for above code:
It fetches posts result from the table wp_posts whose post_type is post and belongs to the category id 4. Then we used php function count for getting total records.
If you need only published posts additionally add post_status=publish.
function wpb_postsbycategory() {
// the query
$the_query = new WP_Query( array( 'category_name' => 'announcements', 'posts_per_page' => 10 ) );
$posts = get_posts('post_type=post&category_name=announcements');
$count = count($posts);
// The Loop
if ( $the_query->have_posts() ) {
$string .= "<p>Total:<strong>{$count}</strong></p>";
$string .= '<ul class="postsbycategory widget_recent_entries">';
while ( $the_query->have_posts() ) {
$the_query->the_post();
if ( has_post_thumbnail() ) {
$string .= '<li>';
$string .= '' . get_the_post_thumbnail($post_id, array( 50, 50) ) . get_the_title() .'</li>';
} else {
// if no featured image is found
$string .= '<li>' . get_the_title() .'</li>';
}
}
} else {
// no posts found
}
$string .= '</ul>';
return $string;
/* Restore original Post Data */
wp_reset_postdata();
}
// Add a shortcode
add_shortcode('categoryposts', 'wpb_postsbycategory');
// Enable shortcodes in text widgets
add_filter('widget_text', 'do_shortcode');
By using the above function you can produce the resultant output. (for reference Show recent posts by category
Simply visit Appearance » Widgets menu and add a text widget to your sidebar. Next add [categoryposts] shortcode in the text widget and save it.
To count total number of post of a specific category this method can be used.
<?php
function count_cat_post($category) {
//you can pass name of the category such as 'js'
if(is_string($category)) {
$catID = get_cat_ID($category);
}
//you can also pass id of the category
elseif(is_numeric($category)) {
$catID = $category;
} else {
return 0;
}
$cat = get_category($catID);
return $cat->count;
}
//finally call the function
count_cat_post('js');//or pass the category id as argument
?>

Displaying post titles in a specific category in a shortcode (wordPress)

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' );

Categories