admin管理员组文章数量:1430540
I am trying to create a home page where it is a list of categories with an associated thumbnail for each. I would like it so it returns each category once and returns the associated thumbnail from the latest post, or even better does not require me to add a featured image to each post, but rather grabs the thumbnail from the image of the post, using post_mime_type ? I am still a ways off as it is returning the category for each post that is within that category and then associating the image with every category.
Here is the function I am working with:
function home_filter() {
if ( is_home() )
{
add_filter( 'the_content', 'home_cats' );
}
}
add_action('template_redirect', 'home_filter');
function home_cats(){
$args=array(
'orderby' => 'name',
'order' => 'ASC',
);
$categories=get_categories($args);
foreach($categories as $category) {
echo '<li><a href="' . get_category_link( $category->term_id ) . '" title="' . sprintf( __( "View all posts in %s" ), $category->name ) . '" ' . '>' . get_the_post_thumbnail($page->ID, 'thumbnail') . $category->name.'</a></li> ';
}
}
The home page is simply :
<ul>
<?php while ( have_posts() ) : the_post(); ?>
<?php the_content();?>
<?php endwhile; ?>
</ul>
The output is something like:
<ul>
<li><a href="../?cat=1" title="View all posts in Cat A" ><img src="..image-A.jpg" />Cat A</a></li>
<li><a href="../?cat=3" title="View all posts in Cat B" ><img src="..image-A.jpg" />Cat B</a></li>
<li><a href="../?cat=1" title="View all posts in Cat A" ><img src="..image-B.jpg" />Cat A</a></li>
<li><a href="../?cat=3" title="View all posts in Cat B" ><img src="..image-B.jpg" />Cat B</a></li>
<li><a href="../?cat=1" title="View all posts in Cat A" ><img src="..image-C.jpg" />Cat A</a></li>
<li><a href="../?cat=3" title="View all posts in Cat B" ><img src="..image-C.jpg" />Cat B</a></li>
</ul>
Can someone please help me understand how to return each category only once and include the thumb from the latest post in that category? And even better can anyone think of a way to accomplish this without having to set the feature image every time?
I am trying to create a home page where it is a list of categories with an associated thumbnail for each. I would like it so it returns each category once and returns the associated thumbnail from the latest post, or even better does not require me to add a featured image to each post, but rather grabs the thumbnail from the image of the post, using post_mime_type ? I am still a ways off as it is returning the category for each post that is within that category and then associating the image with every category.
Here is the function I am working with:
function home_filter() {
if ( is_home() )
{
add_filter( 'the_content', 'home_cats' );
}
}
add_action('template_redirect', 'home_filter');
function home_cats(){
$args=array(
'orderby' => 'name',
'order' => 'ASC',
);
$categories=get_categories($args);
foreach($categories as $category) {
echo '<li><a href="' . get_category_link( $category->term_id ) . '" title="' . sprintf( __( "View all posts in %s" ), $category->name ) . '" ' . '>' . get_the_post_thumbnail($page->ID, 'thumbnail') . $category->name.'</a></li> ';
}
}
The home page is simply :
<ul>
<?php while ( have_posts() ) : the_post(); ?>
<?php the_content();?>
<?php endwhile; ?>
</ul>
The output is something like:
<ul>
<li><a href="../?cat=1" title="View all posts in Cat A" ><img src="..image-A.jpg" />Cat A</a></li>
<li><a href="../?cat=3" title="View all posts in Cat B" ><img src="..image-A.jpg" />Cat B</a></li>
<li><a href="../?cat=1" title="View all posts in Cat A" ><img src="..image-B.jpg" />Cat A</a></li>
<li><a href="../?cat=3" title="View all posts in Cat B" ><img src="..image-B.jpg" />Cat B</a></li>
<li><a href="../?cat=1" title="View all posts in Cat A" ><img src="..image-C.jpg" />Cat A</a></li>
<li><a href="../?cat=3" title="View all posts in Cat B" ><img src="..image-C.jpg" />Cat B</a></li>
</ul>
Can someone please help me understand how to return each category only once and include the thumb from the latest post in that category? And even better can anyone think of a way to accomplish this without having to set the feature image every time?
Share Improve this question asked Jan 22, 2011 at 20:30 zaczac 6503 gold badges10 silver badges21 bronze badges 2- How many posts do you have/are displaying on the home page? Is that number three by chance? It looks like your filter is running multiple times on that page. – mtekk Commented Jan 22, 2011 at 20:45
- Yes you are right it returns the category for every post that exists in that category – zac Commented Jan 22, 2011 at 22:25
2 Answers
Reset to default 2Normally I like to shy away from recommending direct SQL, but in your use-case I think it is warranted.
I've coded this up as a direct SQL query; as you may notice is a bit complex. You can copy the following code to your theme's functions.php
file or add it to the .php
file of a plugin you might be writing:
function home_cats($max_image_height=150){
$categories= get_taxonomy_latest_posts_with_attachment('category');
echo '<h1>Categories</h1>';
foreach($categories as $category) {
$category_link = get_category_link( $category->term_id );
$category_title = sprintf( __( "View all posts with category: '%s'" ),$category->term_name );
$post_title = get_the_title($category->post_id);
$post_link = get_permalink($category->post_id);
$img_html = wp_get_attachment_image( $category->attachment_id, array( 'thumbnail',$max_image_height ) );
$html = <<<HTML
<div id="category-{$category->term_slug}" class="category">
<span style="float:right;">{$img_html}</span>
<span style="float:left;">
<h2><a href="{$category_link}" title="{$category_title}">{$category->term_name}</a></h2>
<p style="float:left;">Latest post: <a href="{$post_link}" title="{$post_title}">$post_title</a></p>
</span>
</div>
<br clear="both" />
HTML;
echo $html;
}
}
function get_taxonomy_latest_posts_with_attachment($taxonomy) {
global $wpdb;
$sql =<<<SQL
SELECT
categorized_posts.rownum,
categorized_posts.term_id,
categorized_posts.term_name,
categorized_posts.term_slug,
categorized_posts.post_id,
categorized_posts.post_date,
categorized_posts.post_title,
attachments.ID AS attachment_id,
attachments.post_title AS attachment_title,
attachments.post_mime_type AS attachment_mime_type,
attachments.guid AS attachment_guid
FROM
(
SELECT
rownum,
term_id,
term_name,
term_slug,
post_id,
post_date,
post_title,
post_parent,
post_name,
post_type
FROM (
SELECT
IF( @prev <> {$wpdb->terms}.term_id, @rownum := 1, @rownum := @rownum+1 ) AS rownum,
@prev := {$wpdb->terms}.term_id,
{$wpdb->terms}.term_id,
{$wpdb->terms}.name AS term_name,
{$wpdb->terms}.slug AS term_slug,
{$wpdb->posts}.ID as post_id,
{$wpdb->posts}.post_date,
{$wpdb->posts}.post_title,
{$wpdb->posts}.post_parent,
{$wpdb->posts}.post_name,
{$wpdb->posts}.post_type
FROM
{$wpdb->term_taxonomy}
INNER JOIN {$wpdb->terms} ON {$wpdb->term_taxonomy}.term_id={$wpdb->terms}.term_id
INNER JOIN {$wpdb->term_relationships} ON {$wpdb->term_relationships}.term_taxonomy_id={$wpdb->term_taxonomy}.term_taxonomy_id
INNER JOIN {$wpdb->posts} ON {$wpdb->posts}.ID={$wpdb->term_relationships}.object_id
INNER JOIN (SELECT @rownum := NULL, @prev := 0) AS rownum_initializer ON 1=1
WHERE 1=1
AND {$wpdb->posts}.post_type='post'
AND {$wpdb->posts}.post_status='publish'
AND {$wpdb->term_taxonomy}.taxonomy='%s'
ORDER BY {$wpdb->posts}.post_parent DESC, {$wpdb->posts}.post_date DESC
) x
) categorized_posts
INNER JOIN (SELECT MAX(ID) AS post_id,post_parent FROM {$wpdb->posts} WHERE post_type='attachment' GROUP BY post_parent) attachment_join ON attachment_join.post_parent=categorized_posts.post_id
INNER JOIN {$wpdb->posts} attachments ON attachments.ID=attachment_join.post_id
WHERE
categorized_posts.rownum=1
GROUP BY
categorized_posts.term_id
ORDER BY
categorized_posts.term_name
SQL;
return $wpdb->get_results($wpdb->prepare($sql,$taxonomy));
}
You'll note I separated the logic so that you can get the list of any taxonomy terms and their latests posts with a photo by calling the get_taxonomy_latest_posts_with_attachment()
function and passing it a taxonomy identifier, like this:
$post_tags = get_taxonomy_latest_posts_with_attachment('post_tags');
Because of the complexity of the SQL in that function I'm not going to try to explain it (or I'd be here all night) but if you have specific follow up questions, just ask. Anyway, here's what the code looks like on my test side with test data:
(source: mikeschinkel)
P.S. The people in the photos are friends of mine and all work with WordPress in one way or another. Hope they don't mind me using their likeness. :)
That hook contraption is kinda messy, why not just call home_cats()
in template?
Try this (note that it is query per category and can get ugly for performance):
function home_cats() {
$args = array(
'orderby' => 'name',
'order' => 'ASC',
);
$categories = get_categories($args);
echo '<ul>';
foreach ( $categories as $category ) {
$link = get_category_link($category->term_id);
$title = sprintf(__("View all posts in %s"), $category->name);
$posts = get_posts( array(
'cat' => $category->term_id,
'numberposts' => 1,
) );
$post = $posts[0];
$thumbnail = get_the_post_thumbnail($post->ID);
echo "<li><a href='{$link}' title='{$title}'>{$thumbnail}{$category->name}</a></li>";
}
echo '</ul>';
}
There are different ways to mine for images, I usually go with Get The Image.
本文标签: categoriesLimit getcategories to show each category once
版权声明:本文标题:categories - Limit get_categories to show each category once 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745554957a2663130.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论