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.
Related
I'm using a custom loop to show a selection of products.
The loop works fine and shows the products with the correct title, image and the other stuff.
But the permalink is the URL of the current page.
If I add $post inside the permalink, everything works fine: get_permalink($post)
Here's my current code:
<?php $featured_posts = $products_select; if( $products_select ): ?>
<div>
<ul>
<?php foreach( $featured_posts as $post ): setup_postdata($post); ?>
<?php wc_get_template_part( 'content', 'product' ); ?>
<?php endforeach; ?>
</ul>
<?php wp_reset_postdata(); ?>
</div>
I checked the content of $products_select and saw, that there is no link stored.
Could that be the problem? Is there any way to correct the permalink?
The variable $products_select is the output of a custom field based on relationship field from Advanced Custom Fields. It is stored as post object.
Update
Don't use get_posts() function, instead use a real WP_Query like in the following example:
<?php
$loop = new WP_Query( array(
'post_status' => 'publish',
'post_type' => 'product',
'posts_per_page' => 10,
) );
?>
<div>
<ul><?php
if ( $loop->have_posts() ) :
while ( $loop->have_posts() ) : $loop->the_post();
echo '<pre>ID: '.get_the_id().' | Title: '. get_the_title() . ' | Link: ' . get_permalink() . '</pre>';
wc_get_template_part( 'content', 'product' );
endwhile;
wp_reset_postdata();
endif;?>
</ul>
</div>
This time it will works, without any issue.
An alternative: To avoid this problem, you could use instead WooCommerce [products] shortcode as follows:
<?php
$featured_posts = $products_select; if( $products_select ):
// get a comma separated string of product Ids
$post_ids = implode( ',', wp_list_pluck( $featured_posts, 'ID' ) );
// Use [products] shortcode with the comma separated string of product Ids
echo do_shortcode("[products ids='$post_ids']" ); ?>
</div>
Tested and works.
I also found a soultion that will work with Advanced Custom Fields and keeps the custom order of the relationship field:
<?php
$args = array(
'post_type' => 'product',
'post__in' => $products_select,
'posts_per_page' => 4,
'orderby' => 'post__in'
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) : ?>
<div>
<ul>
<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
<?php wc_get_template_part( 'content', 'product' ); ?>
<?php endwhile; ?>
</ul>
</div>
<?php endif; wp_reset_postdata(); ?>
Only two categories need to be showed in the homepage. Can anyone help.
You can use WP_Query to get your posts list, and display it with the loop
Example :
$the_query = new WP_Query( array( 'category_name' => 'staff,news' ) );
// 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
}
In your functions.php file paste the below code:
I am assuming that you want to show categories from two categories which are having ids 5 and 9.
function kiran_home_category( $query ) {
if ( $query->is_home() && $query->is_main_query() ) {
$query->set( 'cat', '5,9');
}
}
add_action( 'pre_get_posts', 'kiran_home_category' );
Explanation:
kiran_home_category is just a custom name for the function. That can be any name. The way it works is you attach a function to the action hook pre_get_posts. So before getting the posts the function kiran_home_category will be called. And then inside the function I am changing the query here to only load categories with ID 5 and 9
In wordpress WP_query, category__in parameter used to select category with posts.
<?php
$query = new WP_Query( array( 'category__in' => array( 2, 6 ),'post_status'=>'publish','orderby'=>'menu_order','order'=>'Asc' ) );
if($query->have_posts()):
echo '<ul>';
while ( $query->have_posts() ) : the_post();
echo '<li>' . get_the_title() . '</li>';
endwhile;
echo '</ul>';
endif;
?>
For more information about wordpress query click here , you can read more information.
<?php
$args = array( 'post_type' => 'post', 'posts_per_page' => -1,'category_name' => array('Latest News','News') );
$loop = new WP_Query( $args );
if($loop->have_posts()):
?><ul>
<?php
while ( $loop->have_posts() ) : $loop->the_post();
?>
<li> <span class="date"><?php echo get_the_date( 'd F Y');?></span>
<h3><?php echo get_the_title();?></h3>
<?php echo $description = get_the_content(); ?>
</li>
<?php endwhile;?>
</ul>
<?php endif;?>
<?php wp_reset_postdata(); ?>
Do the following, usually in page.php or single.php or if you want a custom page for a category, you can do, category-samplecat.php..
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'category_name' => array('samplecat', 'anothercat'),
'paged' => $paged
);
$arr_posts = new WP_Query($args);
Then do the usual if, while statement..
if($arr_posts->have_posts() ) :
// Start the loop.
while ( $arr_posts->have_posts() ) :
$arr_posts->the_post();?>
<?php endwhile;
endif;
I am using Advanced Custom Fields with Wordpress.
I have a custom post type called VIDEOS which has two fields - video_link and video_artist.
I can call and output the video_link field, but I cannot seem to display the 'video_artist' field using the code below...
<?php
$posts = get_posts(array(
'post_type' => 'videos',
'posts_per_page' => -1
)
));
if( $posts ): ?>
<?php foreach( $posts as $post ):
setup_postdata( $post )
?>
<?php echo wp_oembed_get( get_field( 'video_link' ) ); ?>
<?php the_title(); ?>
<?php the_field('video_artist'); ?>
</div>
<?php endforeach; ?>
<?php wp_reset_postdata(); ?>
<?php endif; ?>
In fact, this line...
<?php the_field('video_artist'); ?>
...breaks the site and displays nothing at all after it appears. No html of any kind.
It's more or less the same code as your, just tested, and it works fine
As #admcfadn said, your are note in a wordpress loop, so you need to add the post id as a parameter of the_field
$posts = get_posts(array(
'post_type' => 'videos',
'posts_per_page' => -1
));
if( $posts ):
foreach( $posts as $post ):
setup_postdata( $post );
the_title();
the_field('video_link', $post->ID);
the_field('video_artist', $post->ID);
endforeach;
wp_reset_postdata();
endif;
If you like to use the loop without arg in the_field that will look like that:
$options = array(
'post_type' => 'videos',
'posts_per_page' => -1
);
$query = new WP_Query( $options );
if ( $query->have_posts() ) : while ( $query->have_posts() ) : $query->the_post();
the_title();
the_field('video_link');
the_field('video_artist');
endwhile; endif;
ps: you don't need to use <?php ?> on each line
$post->the_field('video_artist');
you're using get_posts, not wp_query, so you might need to refer to the variables via $post.
&/or troubleshoot it with the following:
the_field('video_artist', $post->ID);
might get if for you.
Or...
$baz = get_field( 'video_artist' ); echo $baz;
Also, looks like you're missing a semi-colon after setup_postdata( $post ) and have an extra closing parentheses after get_posts
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...
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)