Display random thumbnail from each category - Wordpress - php

I tried posting this on the WordPress exchange, but unfortunately I didn't get any further along, so I'm trying it here. Hopefully this works!
I have a feeling that I'm on the right track, I just don't have enough solid PHP knowledge to get much further than where I'm currently at.
I'm currently using the following code to return a list of child categories from a single category:
<?php
$taxonomyName = "category";
$terms = get_terms($taxonomyName,array('parent' => 79));
echo '<ul>';
foreach($terms as $term) {
echo '<li>';
echo ''.$term->name.'<br/>';
$thumbnails = get_posts('numberposts=1&orderby=rand');
foreach ($thumbnails as $thumbnail) {
echo '<a href="' . get_permalink( $thumbnail->ID ) . '" title="' . esc_attr( $thumbnail->post_title ) . '">';
if ( has_post_thumbnail($thumbnail->ID)) {
echo get_the_post_thumbnail($thumbnail->ID, 'thumbnail');
} else {
echo 'no thumbnail';
}
echo '</a>';
}
echo '<li>';
}
echo '</ul>';
?>
This code works somewhat. It returns a list of all six sub categories under the parent, ID 79. However, I want to also return one random thumbnail in each of the list items for each of the 6 sub categories.
Unfortunately, this code returns a random thumbnail from all of my posts, not just ID 79 and it's specific child. I need it to return one thumbnail from the same category that is returned in it's parent <li>.
Additionally, the code returns "no thumbnail" if there is no code, or if I take the else out, it returns nothing. I'd like to make it to where it returns at least one image every time, so ideally there would be some kind of logic that says to always return at least one image. I just don't know how to do that.
Is there some easy way to do this? I'm thinking I need to sort through that array and return the category in the nested foreach loop, but unfortunately it's over my head.
I think I'm looking for something similar to this person, but unfortunately, they didn't get any replies. -> https://stackoverflow.com/questions/18750040/random-featured-image-based-on-category
Thanks in advance for any help!

So in order to do this, I needed to first do a for each loop, store the category slug as a variable, JAMterm, and then use that in a query to pull one random thumbnail from the category.
Thanks to #Renishkhunt for helping me along the way to get this answer.
<?php
$taxonomyName = "category";
$terms = get_terms($taxonomyName,array('parent' => 79));
echo '<ul>';
foreach($terms as $term) {
echo '<li>'.$term->name.'<br/>';
$JAMterm = $term->slug;
global $wp_query;
$term = $wp_query->queried_object;
$args=array(
'orderby' => 'rand',
'posts_per_page' => 1,
'post_type' => 'post',
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $JAMterm
)
)
);
$new_query = null;
$new_query = new WP_Query($args);
while ($new_query->have_posts()) : $new_query->the_post();
the_post_thumbnail();
endwhile;
wp_reset_postdata();
echo '</li>';
}
echo '</ul>';
?>

Related

Displaying the category of posts but returning empty array

Whenever I try to get the category name of a post, it returns an empty "array". I am not proficient with PHP in WordPress, though I have tried many things to get this to work. I have tried using both get_the_category() and the_category(', '), but the latter pulls the category names and puts them entirely at the beginning of the function (it looks like it strips the div off of them entirely).
I'd like to display a list of categories that each post belongs to and still keep them within my div ID's. Strangely enough (to me), get_the_date() works perfectly fine as is, but get_the_category() doesn't.
"Array" in orange should be showing category names separated by commas (ideally):
This is the code I'm using to get the posts inside of my functions.php file.
function ctmblog_posts() {
// Query Arguments
$ctmblog_args = array(
'orderby' => 'date',
'ignore_sticky_posts' => '1',
'cat' => 8,88,87,5 // Use the category id, can also replace with category_name which uses category slug
//'category_name' => array(SLUG OF FOO CATEGORY),
);
//Loop to display 10 recently updated posts
$ctmblog_loop = new WP_Query( $ctmblog_args );
$counter = 1;
$string .= '<ul><div id="timeline">';
while( $ctmblog_loop->have_posts() && $counter < 10 ) : $ctmblog_loop->the_post();
$string .= '<div id="timeline_event"><span id="timeline_date">'. get_the_date() .'</span> — '.'<span id="timeline_category">' .get_the_category() . '</span>'.' <br><li> ' .get_the_title( $ctmblog_loop->post->ID ) . '</li></div>';
$counter++;
endwhile;
$string .= '</div></ul>';
return $string;
wp_reset_postdata();
}
//add a shortcode
add_shortcode('blog-posts', 'ctmblog_posts');
If I could get any pointers, I'd really appreciate it! This is a great learning experience for me. I've searched the web and tried solutions other people have suggested to others, but I think this might be a unique case for me.
Let's read the documentation for the get_the_category() function: https://developer.wordpress.org/reference/functions/get_the_category/
It should work, right? Let's remember that in WordPress each post can have multiple categories - this results in the function returning an array.
Code by wordpress.org user Stefano
$categories = get_the_terms( $post->ID, 'taxonomy' );
// now you can view your category in array:
// using var_dump( $categories );
// or you can take all with foreach:
foreach( $categories as $category ) {
echo $category->term_id . ', ' . $category->slug . ', ' . $category->name . '<br />';
}

Wordpress query that sorts by category and time

I have found this question:
Wordpress outside loop sort by category and time
But there is not a lot of context provided in the question or answer to know if it is applicable to me. I am using the popular genesis framework and a child theme. I don't want to modify any core WP files because they would be overwritten on updates. I think this can be done through my functions.php or front-page.php file.
I have 25 posts listed at a time. Within those 25 posts, I would like to have any post that is from category one be listed on top and those from category two listed afterwards. Within the category one and category two loops, the posts would be listed by time of entry as normal.
What would be the best way to do this?
SDS
You need two loop one for categories and one for posts.
So you can try this type of code
/*category args for listed according to name in assending order*/
$category_arg = array(
'orderby' => 'name',
'order' => 'ASC'
);
$all_cat = get_categories($category_arg);
/*Loop for all category*/
foreach ($all_cat as $key => $cat) {
/*Query for post of perticular category with orderby posted date*/
$args = array(
'cat' => $cat->cat_ID,
'posts_per_page' => -1,
'orderby' => 'date',
'order' => 'DESC',
) ;
query_posts( $args );
echo '
<div class="one-category-block">
<h1>'.$cat->cat_name.'</h1>';
echo '<ul>';
while ( have_posts() ) : the_post();
echo '<li>';
the_title();
echo '</li>
';
endwhile;
echo '</ul>
</div>';
wp_reset_query();
}
Try this type of code , then let me know the result.
Thanks
All right. You won't be able to do that on the query directly, I'm afraid.
However, it's still easy to do. First, get the posts out of the query into an array:
$posts = array();
while ( have_posts() ) {
the_post();
array_push($posts, $post);
}
Then sort that array:
usort($posts, function($a, $b) {
if(has_term("mycategory", "mytaxonomy", $a->ID) && !has_term("mycategory", "mytaxonomy", $b->ID)) return -1;
if(!has_term("mycategory", "mytaxonomy", $a->ID) && has_term("mycategory", "mytaxonomy", $b->ID)) return 1;
return $b->post_date - $a->post_date;
});
I've made it so that posts having mycatgegory in the mytaxonomy taxonomy will be on top, but generally sorted by post date.
Then just use a regular foreach loop to iterate over the (now sorted) posts
foreach($posts as $post) {
setup_postdata($post);
// continue outputting the posts here
}
wp_reset_postdata();
setup_postdata() is there to make sure that you can use get_the_ID(), get_permalink() et cetera without changing your code.

Wordpress display thousands of posts

I'm working on a project where I need to list all the categories, sub-categories (children, grand-children etc. to about 5th level) and posts inside them. At the moment I've managed to get the site working, but the issue is that the site takes minutes to load.
To be clear on what I want the site to look like, here's a drawing:
Category
Sub-category
Subsubcategory
Content
Subsubcategory
Content
Sub-category
You get the picture
And here's the code:
<?php
function listing($parentcat, $list_id='', $list_name='', $path=false) {
// parentcat is the desired category parent category, which is defined because the function is called a few times with different sets on the page.
// list_id, list_name and path are used for purposes not related to the question
echo "<ul><li name='$list_name'><h2><a href='#$list_name'>$list_name</a></h2>";
}
$args = array(
'parent' => $parentcat,
'include' => $cat_ids,
'hide_empty' => 1,
'orderby' => 'id'
);
$categories = get_categories( $args );
echo "<ul>";
foreach ($categories as $cat) {
if ($cat->cat_name != 'Uncategorized') {
$flat_path = substr(get_category_parents($cat->cat_ID, false, ' »' ), 14);
$catnam = $cat->cat_name;
$listtitle = ($path ? $flat_path : $catnam);
echo ('<li name="' . $cat->cat_ID . '"><h2>' . $listtitle . '</h2>' );
if (get_posts( "category_name=$catnam" ) ) {
if (have_posts()) : while (have_posts()) : the_post();
if (in_category($cat->cat_ID)) {
echo '<ul><li><div>';
the_content();
echo '</div></li></ul>';
} endwhile;
else :
_e('Empty list');
endif;
}
// Here's a recursive call for the function
listing($cat->cat_ID);
echo '</li>';
}
}
echo '</ul>';
}
?>
You might be missing 'posts_per_page' for posts
Have a look here http://codex.wordpress.org/Function_Reference/get_posts
&
'number' for categories
Have a look here http://codex.wordpress.org/Function_Reference/get_categories
Solution found! I'll answer to myself, so that if anybody else needs something similar, the answer is here.
Basically, the point is to first create an array which contains all the categories. After that one can simply loop through the array. This way we were able to avoid recursively using The Loop, which probably was the biggest issue in the previous solution.
Even this solution is really slow, but an incredible improvement over the last. First idea loaded few hundred posts tops before timeout after roughly 30 seconds. This one gets the whole site (about 1500 posts) in under 5-10 seconds. The speed is awful, but with the way our site will be used and the added functionality from dividing everything to separate posts outnumbers the speed issues.
$categories = get_categories('orderby=id');
$cats_by_parent = array();
foreach ($categories as $cat) {
$parent_id = $cat->category_parent;
if (!array_key_exists($parent_id, $cats_by_parent)) {
$cats_by_parent[$parent_id] = array();
}
$cats_by_parent[$parent_id][] = $cat;
}
$posts = get_posts(['posts_per_page' => 10000000]);
$posts_by_cats = array();
foreach ($posts as $post) {
$cat_id = wp_get_post_categories($post->ID)[0];
$posts_by_cats[$cat_id] = $post->post_content;
}
// Loop through the array and print with:
echo $posts_by_cats[$cat->cat_ID];

Trying to get all post using wp_count_posts - WordPress PHP array

I'm trying to get a list of authors on my site & their total posts.
All of this code is working, except the $count_posts($author->ID) part in the loop.
I think there may also be issues with my array for get_users - as I'm trying to more parts to the array.
function all_authors_list() {
$authors = get_users(array(
'role' => 'subscriber',
'orderby' => 'post_count',
'order' => 'DESC',
'number' => '20',
)
);
$authors = $count_posts;
$count_posts = wp_count_posts('page');
$published_posts = $count_posts->publish;
foreach($authors as $author) {
echo '<div class="author-name">' . $author->first_name . ' ' . $author->last_name . '</div>';
echo '<div class="author-post-count">' . $count_posts($author->ID) . '</div>';
}
}
So the final output should be something like:
John Smith
20
Patricia Long
35
...etc.
Write this below code in your post loop:
<p><?php the_author(); ?> has <?php echo number_format_i18n( get_the_author_posts() ); ?>
posts</p>
Reference: http://codex.wordpress.org/Function_Reference/get_the_author_posts
You can possibly use count_many_users_posts to achieve that.
Basically you will get User's ID in to an array that is generated by the $authors and you can use that user ID in count_many_users_posts.
There is three parameters in count_many_users_posts function and you can use $post_type parameter to get only pages.

Wordpress - custom post type, displaying the parent and child categories

So I'm reasonably new to Wordpress, but have been able to solve most issues by myself up until now.
I have a custom post type - lets call it Machines. And in those machines, there is a category called Machine_type. And say I've made a machine type called Scissor Lifts, then another machine type called electric scissor lifts which is a child of scissor lifts.
I'd like to display this information on the single post page - so on the electric scissor lifts page, i'd like to display breadcrumbs like Machines - Scissor Lifts - Electric Scissor Lifts. But this seems almost impossible! I have tried using many different tutorials, but they seem to always display Machines - - - Final machine name, without the actual 2 categories I'd like to display!
It seems sort of crazy that there's no simple inbuilt call for Category and Child Category! I was using this:
<?php
$terms = get_the_terms( $post->ID , 'machine_type' );
foreach ( $terms as $term ) {
$term_link = get_term_link( $term, 'machine_type' );
if( is_wp_error( $term_link ) )
continue;
echo '<p>Machine Type: ' . $term->name . '</p>';
}
?>
But this obviously just dumps all the information out, no way to separate the parent and child categories nicely.
EDIT:
Update on this problem: I've finally found some code which seems like it's tackling the right problem:
<?php
// get top level terms
$parents = get_terms( 'machine_type', array( 'parent' => 0 ) );
// get post categories
$categories = get_the_terms( $post->ID, 'machine_type' );
// output top level cats and their children
foreach( $parents as $parent ):
// output parent name and link
echo '' . $parent->name . ': ';
// initialize array to hold child links
$links = array();
foreach( $categories as $category ):
if( $parent->term_id == $category->parent ):
// put link in array
$links[] = '' . $category->name . '';
endif;
endforeach;
// join and output links with separator
echo join( ', ', $links );
endforeach;
?>
However, what it outputs isn't quite right. For example, on a machine which is categorised as a Boom Lift, and also an Articulated Electric Boom Lift, it's now displaying: "Boom lift: Articulated Booms (electric)Scissor lift: Spider-lift:"
So it's adding on 2 other categories which aren't applicable to this machine. Any ideas?
$wcatTerms = get_terms('product_cat', array('hide_empty' => 0, 'orderby' => 'ASC', 'parent' =>0));
foreach($wcatTerms as $wcatTerm) :
echo $wcatTerm->name;
$wsubargs = array('hierarchical'=>1,'show_option_none'=>'','hide_empty'=>0,'parent'=>$wcatTerm->term_id,'taxonomy'=>'product_cat');
$wsubcats = get_categories($wsubargs);
foreach ($wsubcats as $wsc):
echo $wsc->name;
endforeach;
endforeach;
Use this it's display two level of category name and product name.
This may help yo
<?php
/********************** List out the parent and child inside parent ***/
$taxonomyName = "your_taxonomy";
$term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) );
if ($term->parent == 1) {
wp_list_categories('taxonomy=your_taxonomy&depth=1&show_count=0
&title_li=&child_of=' . $term->term_id);
} else {
wp_list_categories('taxonomy=your_taxonomy&show_count=0
&title_li=&child_of=' . $term->parent);
}
?>

Categories