This seems a little noob, but I didn't found a better option. I created a custom loop to display only the title of custom post type I created.
Example:
Custom Post Type: Atuação
Contratos (Cível e Societário)
Direito Penal Empresarial
The problem is: I can't "validate" at the menu if the post is active or only a link. Example: My visitor is visiting the Direito Penal Empresarial page. But the menu don't display any class so I can customize it. It just shows the <a href> link.
See the code of the custom loop below.
<ul class="menu-advogados">
<?php
// WP_Query arguments
$args = array (
'post_type' => 'atuacao_posts',
'pagination' => false,
'order' => 'ASC',
'orderby' => 'title',
);
// The Query
$exibir_atuacao_posts = new WP_Query( $args );
// The Loop
if ( $exibir_atuacao_posts->have_posts() ) {
while ( $exibir_atuacao_posts->have_posts() ) {
$exibir_atuacao_posts->the_post();
?>
<li><?php the_title(); ?></li>
<?php
}
} else {
echo "Nenhum post encontrado";
}
// Restore original Post Data
wp_reset_postdata();
?>
</ul>
There is any better solution for this? Or if not, how can I add the "active" class to the href?
UPDATE: You can check out the website live.
You need to store current post ID in a variable then you need to compare current Post ID with list item Post ID if both are same then apply active class. So your code will be something like this-
<ul class="menu-advogados">
<?php
global $post;
$post_id = $post->ID; // Store current page ID in a variable.
// WP_Query arguments
$args = array (
'post_type' => 'atuacao_posts',
'pagination' => false,
'order' => 'ASC',
'orderby' => 'title',
);
// The Query
$exibir_atuacao_posts = new WP_Query( $args );
// The Loop
if ( $exibir_atuacao_posts->have_posts() ) {
while ( $exibir_atuacao_posts->have_posts() ) {
$exibir_atuacao_posts->the_post();
?>
<li><a href="<?php the_permalink(); ?>" <?php echo ($post_id==$post->ID)?'class="active"':''; ?> ><?php the_title(); ?></a></li>
<?php
}
} else {
echo "Nenhum post encontrado";
}
// Restore original Post Data
wp_reset_postdata();
?>
</ul>
use this
// WP_Query arguments
$args = array (
'post_type' => 'atuacao_posts',
'post_status' => 'publish',
'pagination' => false,
'order' => 'ASC',
'orderby' => 'title',
);
// The Query
$query = new WP_Query( $args );
<?php if ( $query ->have_posts() ) : ?>
<!-- the loop -->
<?php while ( $query ->have_posts() ) : $query ->the_post(); ?>
<h2><?php the_title(); ?></h2>
<?php endwhile; ?>
<!-- end of the loop -->
<?php wp_reset_postdata(); ?>
<?php else : ?>
<p><?php _e( 'Sorry, no posts matched your criteria.' ); ?></p>
<?php endif; ?>
for WP_Query consider this link it's great article...
Related
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!
I have a custom loop that pulls all the child pages of the current page, and displays them. However, I need to order this query by the $first_row_image variable that is pulled inside the loop.
This is done by grabbing the title row at the end() of an array (The array being a repeater field in Advanced Custom Fields).
I know my below code isn't right, but I can't work out how to do it.
<?php function flo_add_child_pages() {
global $post;
$args = array(
'post_type' => 'page',
'post_parent' => $post->ID,
'cat' => '3368',
'posts_per_page' => -1,
'meta_key' => $first_row_image,
'orderby' => 'meta_value',
'order' => 'ASC'
);
$the_query = new WP_Query( $args );
?>
<?php if ( $the_query->have_posts() ) : ?>
<div class="child-flex">
<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
<?php
$rows = get_field('breadcrumbs' ); // get all the rows
$first_row = end($rows); // get the first row
$first_row_image = $first_row['title' ]; // get the sub field value
?>
<?php if($first_row_image) : ?>
<a href="<?php the_permalink(); ?>" rel="post-<?php the_ID(); ?>" class="one-half">
<?php echo $first_row_image; ?><i class="fa fa-angle-right rotate-icon" style="float: right; margin-top: 5px;"></i>
</a>
<?php endif;?>
<?php endwhile; ?>
</div><?php wp_reset_postdata(); ?>
<?php endif;
}
In my experience, it's usually better to do complex sorting after the query instead of as part of the query.
For one thing, you defined 'meta_key' => $first_row_image, but $first_row_image is undefined at that point, so the query can't execute on it. For another thing, given the way that ACF stores repeater values, it'd be almost impossible to query on them.
I'd do it this way:
Run the query
Check to see if you have posts
Use usort to write a custom sorting function on the $query->posts array.
<?php
function reorder_by_last_title($page1, $page2) {
$page1_rows = get_field('breadcrumbs', $page1['ID']); // get all the rows
$page1_first_row = end($page1_rows); // get the first row
$page1_first_row_image = $page1_first_row['title']; // get the sub field value
$page2_rows = get_field('breadcrumbs', $page2['ID']);
$page2_first_row = end($page2_rows);
$page2_first_row_image = $page2_first_row['title'];
return $page1_first_row_image > $page2_first_row_image;
}
function flo_add_child_pages() {
global $post;
$args = array(
'post_type' => 'page',
'post_parent' => $post->ID,
'cat' => '3368', // Not sure why this is needed-- did you enable categories for pages?
'posts_per_page' => 500, // Use a big number instead of -1
);
$child_pages_query = new WP_Query($args);
if ($child_pages_query->have_posts()) :
// Reorder child pages by last breadcrumbs title.
usort($child_pages_query->posts, 'reorder_by_last_title' );
?>
<div class="child-flex">
<?php while ($child_pages_query->have_posts()) : $child_pages_query->the_post(); ?>
<?php
$rows = get_field('breadcrumbs'); // get all the rows
$first_row = end($rows); // get the first row
$first_row_image = $first_row['title']; // get the sub field value
?>
<?php if ($first_row_image) : ?>
<a href="<?php the_permalink(); ?>" rel="post-<?php the_ID(); ?>" class="one-half">
<?php echo $first_row_image; ?><i class="fa fa-angle-right rotate-icon"
style="float: right; margin-top: 5px;"></i>
</a>
<?php endif; ?>
<?php endwhile; ?>
</div><?php wp_reset_postdata(); ?>
<?php endif;
}
The following is my index.php file
<?php get_header(); ?>
<?php
if(get_option('zens_home') == "blog") { ?>
<?php include (TEMPLATEPATH . '/lib/blog-home.php'); ?>
<?php } else { ?>
<div id="home-content" class="clearfix">
<ul id="shelf">
<?php
?>
<?php while (have_posts()) : the_post(); ?>
/*Start of mark*/
<li class="box" id="post-<?php the_ID(); ?>">
<?php $disc = get_post_meta($post->ID, 'fabthemes_discount', true); ?>
<?php if ( $disc ) { ?>
<span class="salebadge"></span>
<?php }?>
<img class="productshot" width="172" height="243" src="<?php get_image_url(); ?>" alt="<?php the_title(); ?>"/>
<div class="pricetab clearfix">
<?php if ( $disc ) { ?>
<span class="oldprice"><del> <?php echo get_post_meta($post->ID, 'fabthemes_disc-price', true) ?> </del></span>
<?php }?>
<span class="prodetail"><?php $price=get_post_meta($post->ID, 'fabthemes_price', true); echo $price; ?></span>
</div>
</li>
/*End of mark*/
<?php endwhile; ?>
<div class="clear"></div>
<?php getpagenavi(); ?>
</ul>
</div>
On top of the loop it is already using, I also want to place the following custom query
$args = [
'posts_per_page' => -1,
'post_type' => 'products',
'orderby' => 'rand', // Order these posts randomly
'tax_query' => [
[
'taxonomy' => 'product-category',
'terms' => 27
]
]
];
$vip_posts = new WP_Query( $args );
// Run the loop
if ( $vip_posts->have_posts() ) {
while ( $vip_posts->have_posts() ) {
$vip_posts->the_post();
// Display what you want in your loop like
echo '</br>';
}
wp_reset_postdata();
}
However, I failed to do it properly without having it as either plaintext on my mainpage or finding myself in some sort of syntax error.
The problem is that I can't get the elements that I marked in the code of index.php and start after the loop in the to work with the custom query
A cleaner approach here would be to add your custom query via the loop_start action. The advantage of doing this is that you do not need to alter template files at all. You can simply drop your code in functions.php or a plugin if you wish (which I always prefer)
Another advantage is that the loops are apart from each other, something that you needed according to another question, so this approach would fit perfectly
The following code is untested, but should give you an idea of how to use the action
add_action( 'loop_start', function ( \WP_Query $q )
{
// Make sure we only target the main query, if not, bail
if ( !$q->is_main_query() )
return;
// Set a static counter to make sure this runs only once to avoid infinitive loops
static $count = 0;
// Make sure our counter is 0, if not, bail
if ( 0 != $count )
return;
// Update our counter
$count++;
// This is the main query, lets target specific pages only
if ( $q->is_home()
|| $q->is_post_type_archive( 'products' )
|| $q->is_tax( 'product-category' )
) {
// Bail on vip pages
if ( $q->is_tax( 'product-category', 'vip' ) ) // Make sure about vip slug
return;
// Bail if this is not the first page
if ( $q->is_paged() )
return;
// Lets add our custom loop
global $wp_query;
$args = [
'posts_per_page' => -1,
'post_type' => 'products',
'orderby' => 'rand', // Order these posts randomly
'tax_query' => [
[
'taxonomy' => 'product-category',
'terms' => 27
]
]
];
$vip_posts = new WP_Query( $args );
// Run the loop
if ( $vip_posts->have_posts() ) {
while ( $vip_posts->have_posts() ) {
$vip_posts->the_post();
// Display what you want in your loop like
the_title();
echo '</br>';
}
wp_reset_postdata();
}
// Lets make sure our main loop counter starts at -1
$wp_query->rewind_posts();
}
});
I'm using the following PHP script to find the most recent post on the Team area of my site.
I also use a very similar one to find the most recent news entry on my home page.
To reduce the amount of repeated code (DRY), is there a way I can use a function and just pull in a specific custom post type e.g. most_recent('team'); would show the most recent post from my Team CPT.
Here's my existing code:
<?php
// find most recent post
$new_loop = new WP_Query( array(
'post_type' => 'team',
'posts_per_page' => 1,
"post_status"=>"publish"
));
?>
<?php if ( $new_loop->have_posts() ) : ?>
<?php while ( $new_loop->have_posts() ) : $new_loop->the_post(); ?>
<h2><?php the_title(); ?></h2>
<?php the_content(); ?>
<?php endwhile;?>
<?php else: ?>
<?php endif; ?>
<?php wp_reset_query(); ?>
<?php
function most_recent($type) {
$new_loop = new WP_Query( array(
'post_type' => $type,
'posts_per_page' => 1,
"post_status"=>"publish"
));
if ( $new_loop->have_posts() ) {
while ( $new_loop->have_posts() ) : $new_loop->the_post();
echo '<h2>'.the_title().'</h2>';
the_content();
endwhile;
}
wp_reset_query();
}
?>
Yes, It is indeed possible.
First what you need to do is ,
Add below code to your theme's functions.php file:
function most_recent($name){
// find most recent post
$new_loop = new WP_Query( array(
'post_type' => $name,
'posts_per_page' => 1,
"post_status"=>"publish"
));
if ( $new_loop->have_posts() ) :
while ( $new_loop->have_posts() ) : $new_loop->the_post();
echo "<h2>".the_title()."</h2>";
the_content();
endwhile;
else:
endif;
wp_reset_query();
}
Now you can use it any where in your theme folder template like below:
$most_recent = most_recent('product');
echo $most_recent;
So in your case, it would be most_recent('team') or even you can use for other as well just like I did for product.
Tell me if you have any doubt.
I'm trying to make a little "latest news" section on my custom homepage in Wordpress, that outputs:
2 most recent news stories
Their titles
The excerpt
The link
I've tried taking the standard loop from the codex to see what I get first, but I get nothing. I am a bit confused, as I can't work out why it's not even outputting ANY posts, no content at all using just the basic loop:
<?php
// The Query
$the_query = new WP_Query( 'post_count=2' );
// 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>';
} else {
// no posts found
echo 'No news is good news!';
}
/* Restore original Post Data */
wp_reset_postdata();
?>
This code presently shows the "no news is good news" message. There are two published posts.
Your code does render output on my side, so it is working. You have one problem though, post_count is a property and not a parameter of WP_Query. You should be using posts_per_page
What I do believe is happening why you don't get any output, is that you are using custom post types, and not normal posts, which in this case will render no output as you don't have any normal posts.
Just change this line
$the_query = new WP_Query( 'post_count=2' );
to
$the_query = new WP_Query( 'posts_per_page=2&post_type=NAME_OF_POST_TYPE' );
You're passing the variable $args into WP_Query but not actually defining it.
Try this:
$args = array(
'post_type' => 'post',
'posts_per_page' => 2,
'no_found_rows' => false,
);
$the_query = new WP_Query( $args );
Then to output the content you need:
if ( $the_query->have_posts() ) :
echo '<ul>';
while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
<li>
<h3><?php the_title(); ?></h3>
<?php the_excerpt(); ?>
</li>
<?php endwhile;
echo '</ul>';
else :
// no posts found
echo 'No news is good news!';
endif;
wp_reset_postdata();
You don't need to use this alternative syntax for the if statement but it's common to see it written this way.
I noticed since writing this answer you updated your question passing in 'post_count=2' to WP_Query. You need to use 'posts_per_page' instead. post_count is a property of the query object and not a parameter.
This should only return the last two posts published.
<?php
$args=array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 2,
);
$my_query = null;
$my_query = new WP_Query($args);
if( $my_query->have_posts() )
{
echo '<ul>';
while ($my_query->have_posts()) : $my_query->the_post(); ?>
<li>
<h1><?php the_title(); ?></h1>
<?php the_excerpt(); ?>
</li>
<?php endwhile;
echo '</ul>';
<?php
}
else
{
echo 'No news is good news!';
}
wp_reset_query(); // Restore global post data stomped by the_post().
?>
(The above is slightly changed from the post here)