Archived topic
CPT archive with dynamic colours
10 replies · Started by Mike on April 5, 2022
Hi - I have a CPT and would like to have an archive page with a different background colour for each post - based on taxonomy.
So Books = green, Documents = Blue, Cards = Red
I've created a colour-picker, and store the category colour in term-meta 'cat_color'.
Is there a way with a Block Template (or any way) to set the background colour of each container (article) to the value of 'cat_color'.
In other words - to create a CPT archive, with different colour background for each post. e.g.
[Books article (grn background]
[Books article (grn background]
[Cards article (red background] etc.
Hope that's clear.
Hi there,
on a standard post the taxonomy-term gets added as a post_class to the article container.
https://developer.wordpress.org/reference/functions/post_class/
This should apply, or could be applied to a CPT.
Do you have the CPT archive setup so i can take a look?
I can't use fixed css - because the client might add categories later, or choose a new colour... so I need to enable the colour to be added dynamically.
You can sniff around on the site. As I say, a CPT taxonomy 'resource_type' - which allows you to save a colour to the term meta 'cat_color'.
It's a test-site so you can do whatever you need.
Well. I have achieved it by using a HOOK - generate_before_entry_title - targeting the cpt archives, with this code:
<?php
$post_con = get_the_ID();
if ( $terms = get_the_terms( $post_con, 'resource_type' ) ) {
$term_ids = wp_list_pluck( $terms, 'term_id' );
}
$term_one = $term_ids[0];
$cat_color = get_term_meta($term_one, 'cat_color', true);
?>
<style>
#post-<?php echo $post_con; ?> .inside-article {background-color: <?php echo $cat_color; ?>}
</style>
This retrieves the cat_color and dynamically adds in-line styles... but the whole thing feels like a crime against code! So if you know of a neater way, I'd really appreciate it - especially as I'd like to use BLOCKS template to style the archive.
Thanks
Hi Mike,
This is actually fine but consider hooking it on wp_head instead hooks within the actual <body> of the page for uniformity.
I don't think this would work? Or am I misunderstanding?
If I hook to the HEAD I'd have to iterate over IDs from the loop and create a stylesheet. But if I have infinite scroll, I'd potentially have to make a style-sheet for 1000's of posts which would get silly.
A better way would be to modify the archive.php and add the style in-line. However - I am hopeless at code. Looking at your archive.php all it does is generate_do_template_part( ‘archive’ );
I understand this is a custom function. But could you help me out by giving an idiots guide to creating the right file structure so that I have (is it content.php?) the right files in my child-theme to edit the output of the loop. Let's call my CPT 'resources'. I know I need something like resources-content.php (copied from content.php) and resources-archive.php (copied from archive) - is this right? and where do i put the copies.
I'd really appreciate it. thanks.
Is it possible to access the site ? That login failed to recognise the user ?
Hi David,
Sorry to mess about - I removed the user. I've created archive-(slug) and content-(slug) in my child theme and now have the background style applied there, which should solve things. I'm sure you have enough to do - but if you want to have a look please do - I've added the user back. If you have an inspiration for the 'least effort' and 'most bullet-proof against future theme changes' way of doing this - that will apply to the archives and the single-posts... - or can modify the code to be more efficient - I will have a little wee of joy ;)
Thanks
Ok... so my thoughts would be to loop through the taxonomy terms, get the term meta and print out some CSS variables.
Something to play with:
add_action('wp_head', 'db_term_colors');
function db_term_colors(){
$termArgs = array(
// add term args if necessary
);
$taxonomy = 'your_tax_slug';
$taxterms = get_terms( $taxonomy, $termArgs );
$css = '<style>';
foreach ($taxterms as $term) {
$term_color = get_term_meta( $term->term_id, 'color', true);
$css .= '.' . $taxonomy . '-' . $term->slug . '{--term-bg:' . $term_color . ';}';
}
$css .= '</style>';
echo $css;
}
You need to set the $taxonomy = 'your_tax_slug';
What this will do is print out a bunch of style like this:
.your_tax_slug-entertainment {
--term-bg: #dd3333;
}
.your_tax_slug-food {
--term-bg: #eeee22;
}
.your_tax_slug-technology {
--term-bg: #ef32ef;
}
.your_tax_slug-travel {
--term-bg: #72160c;
}
Now you can do this:
.element-selector {
background-color: var(--term-bg);
}
The beauty of using CSS Variables also means you can set a default color at the root:
:root {
--term-bg: #ffoooo;
}
or just add that color variable in the GP Customizer > Colors and that will do it for you.
What the dynamic CSS function is doing is updating the CSS Variable at the local post_class level. So theres no need to address and post-classes in your CSS :)
This is beautifully done and works like a charm for archives and single... many thanks :)
Awesome - glad to hear that worked!!