Skip to content

Instantly share code, notes, and snippets.

@mort1305
Forked from jasperf/block.php
Last active April 1, 2022 08:05
Show Gist options
  • Save mort1305/2529c0543e4ecc82637f9837a89bb1c4 to your computer and use it in GitHub Desktop.
Save mort1305/2529c0543e4ecc82637f9837a89bb1c4 to your computer and use it in GitHub Desktop.
blocks/highlights/block.php or new blocks/recent/block.php
<?php
/**
* First, let's compile an array of the things we want to display. The
* posts are the easy part, so let's do those first.
*/
$mort = array();
// Go thru the post types and the number of them we want. Can change these numbers to get more/less of each post type.
foreach(array(
'post' => 3,
'molecule' => 3,
'resource' => 3,
) as $post_type => $numberposts) {
// Get the `n` most recent posts of each type.
foreach(get_posts(array(
// By default, returns published posts descend sorted by date.
'numberposts' => $numberposts,
'post_type' => $post_type,
)) as $p) {
// Save date as key so we can easily sort later.
$mort[date('Y-m-d', strtotime( get_post_datetime($p, 'date', 'gmt')->getTimestamp() )).'-0'] = $p;
}
}
/**
* Time to query taxonomies. As the terms of the taxonomy are assigned to
* posts, we can use the month/year of each post as the term's month/year
* and the last day of that month as the term's day. We don't have to look
* at the name of the term because the user ought be smart enough not to
* assign "January" and "1981" to a "molecule" post dated 15 October 2021.
* As we already have a list of WP_Post objects, we can use their dates as
* the maximum and minimum boundries as well as look at their terms.
*/
foreach($mort as $p) {
// Grab the post's molecules_of_the_month terms
$terms = get_the_terms($p, 'molecules_of_the_month');
// Check is required as might be FALSE or WP_Error.
if(is_array($terms)) {
// Look at all the terms (could be empty if a 'resource' or
// 'post' in which case this foreach-block will not execute).
foreach($terms as $term) {
if(!empty($term->parent)) {
// We found a month MOTM term. The post might have a publish date in
// a diffrent month, so it is necessary to generate a key for sorting
// from the term itself.
$date_str = '1 '. $term->name .' '. get_term($term->parent, $term->taxonomy)->name;
$date_str = date('Y-m-t', strtotime($date_str));
$mort[$date_str.'-1'] = $term;
}
}
}
}
/**
* All done adding stuff to the array. It's now time to sort this big pile
* of goop. As we saved each object in a key having a specially formatted
* date, all we need to do is sort by that key. We want the most recently
* dated object to be at index=0, so we key sort decending.
*
* A word on our date keys: they are in YYYY-MM-DD format. Also, notice
* the -0 and -1 appended to the end of the date (0 for posts, 1 for terms)?
* That's so taxonomies are sorted closer to index=0 than posts. (Rather have
* posts be given priority: change -0 suffix to -1 on line 21; change
* -1 suffix to -0 on line 48; and change the "Y-m-t" to "Y-m-01" on line 47.
*/
krsort($mort);
/**
* Now that we have our array of data, its time to display. For
* simplicity, let's create two functions for HTML output: one to
* output a term; and another to output a post. It seems as though
* whereever you put this file, it is getting called multipule times, so we
* have to protect our functions from becoming redefined.
*/
if(!function_exists('mort_output_term_block')) {
function mort_output_term_block($term) {
?><a href="<?php echo get_term_link($term); ?>"><?php
//get featured image
$featured_image = get_field('tax_featured_image', $term);
if($featured_image) {
?><figure class="post-featured-image">
<?php echo wp_get_attachment_image($featured_image, 'full'); ?>
</figure><?php
}
?><ul class="cat-pill-list">
<li class="cat-pill" style="background: #38E8AD;">
<?php _e('Molecules of the Month') ?>
</li>
</ul>
<h2 class="post-grid-title"><?php echo $term->name; ?></h2>
<?php
$description = get_term_meta( $term, 'intro_text', true );
if($description) {
?><p><?php echo wp_trim_words($description, 19); ?></p><?php
} else {
echo wp_trim_words(term_description($term), 19);
}
?><p class="reading-time"><?php echo dh_display_read_time(); ?></p>
</a><?php
}
}
if(!function_exists('mort_output_post_block')) {
function mort_output_post_block($_post) {
// Set the global post so we don't have to pass it to all of the
// template functions. Also, remember the old global post so we can
// restored it when we're done with the output of this block.
global $post;
$post_saved = $post;
$post = $_post;
?><a href="<?php the_permalink(); ?>">
<figure class="post-featured-image">
<?php the_post_thumbnail(); ?>
</figure><?php
switch(get_post_type($post)) {
case 'resource':
$cats = get_the_terms($post, 'resource_category');
if($cats) {
?><ul class="cat-pill-list"><?php
foreach($cats as $cat) {
$text_color = get_field('cat_text_color', $cat);
$cat_color = get_field('category_color', $cat);
?><li class="cat-pill <?php echo $text_color; ?>" style="background: <?php echo $cat_color; ?>;">
<?php echo $cat->name; ?>
</li><?php
}
?></ul><?php
}
break;
case 'molecule':
?><ul class="cat-pill-list">
<li class="cat-pill" style="background: #38E8AD;">
<?php _e('Molecules of the Month'); ?>
</li>
</ul><?php
break;
default:
?><ul class="cat-pill-list">
<li class="cat-pill light" style="background: #EB546B">
<?php _e('Article'); ?>
</li>
</ul><?php
}
?><h2 class="post-grid-title"><?php the_title(); ?></h2>
<?php echo dh_excerpt(); ?>
<p class="reading-time"><?php echo dh_display_read_time(); ?></p>
</a><?php
// Restore the global post
$post = $post_saved;
}
}
/**
* Now that we're all setup, it's finally time for the big show! Let's
* display the blocks!
*/
// Create id attribute allowing for custom "anchor" value.
$id = 'highlights-' . $block['id'];
if( !empty($block['anchor']) ) {
$id = $block['anchor'];
}
// Create class attribute allowing for custom "className" and "align" values.
$className = 'block-highlights ';
if( !empty($block['className']) ) {
$className .= ' ' . $block['className'];
}
if( !empty($block['align']) ) {
$className .= ' align' . $block['align'];
}
?><div id="<?php echo esc_attr($id); ?>" class="<?php echo esc_attr($className); ?>"><?php
if($mort) {
?><div class="slider mobile-slider splide" data-splide='{ "type" : "loop", "perPage": "3", "arrows": 0, "breakpoints": { "99999": { "destroy": 1 }, "767": { "perPage": "1" } } }'>
<div class="splide__track">
<ul class="post-grid splide__list">
<?php
foreach($mort as $display_me) {
?><li class="post-grid-post splide__slide"><?php
// Each object is displayed depending on what it is.
switch(get_class($display_me)) {
// It's a term!
case 'WP_Term':
mort_output_term_block($display_me);
break;
// It's a post!
case 'WP_Post':
default:
mort_output_post_block($display_me);
}
?></li><?php
}
?></ul>
</div>
</div><?php
}
?></div>
@mort1305
Copy link
Author

mort1305 commented Mar 31, 2022

This code arises out of a StackOverflow question for his client (dev site).

OK @jasperf, the $mort array contains molecule_of_the_month terms, molecule CPTs, resource CPTs, and post (article) posts. This data array is sorted by date and output via line 142 with the blocks themselves being output either by the function of line 69 (for terms) or the function of line 94 (for posts). I used your HTML for the output. Also, seeing as you changed <?= with <?php, there were some output issues as <?= is shorthand for echoing the thing in the tag (fixed those). Please advise.

@jasperf
Copy link

jasperf commented Mar 31, 2022

@mort1305 Thanks for that. Tested it briefly now and updated my gist some as some code was no longer needed it seems. Working well. I may change to three per item to have 3 rows of three. Even could see if we want to add an option to set number of items per content group and so on. But this code by you is already amazing. Perhaps you can update your answer on Stack Overflow as well.. and I will award you the 100 points and working solution.

@mort1305
Copy link
Author

Thanks jasper. I'll update the code on Stack.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment