Sometimes we need to add specific styling to particular posts inside a repeater. Posts from the ‘recipe’ category may need a different coloured title or more padding applied to those not in that category.
The Problem:
By default, every post in a repeater comes with the same markup. This makes it impossible to target individual posts or groups of posts for styling as there are no distinguishing class names to work with.
On the frontend, you have this type of markup. All posts are identical. (IDs not shown for brevity)
<div class="oxy-dynamic-list">
<div class="ct-div-block your-custom-class">
...
</div>
<div class="ct-div-block your-custom-class">
...
</div>
<div class="ct-div-block your-custom-class">
...
</div>
</div>
We could target using nth-child, nth-of-type, etc but with dynamic content, this isn’t too helpful.
Using Post Classes
WordPress comes with a function ‘post_class()’ that adds some useful classes to posts. Similar to body classes, the classes have information about the post that can help us with styling them. Which category the post is in, the post’s ID, whether or not it has a featured image, what type of post it is..
Ideally, we would be adding these post classes to the main div found inside the repeater. Then we could style each post individually based on the classes. We can’t do that as we have no access to that div.
Note – I’ve asked for this to be added to repeaters as a feature request.
As a workaround, what we can do instead is create a new element inside that div, which we can make dynamic, so changes for each post found inside the repeater.
Using the Shortcode Wrapper
The shortcode wrapper is perfect for this. We can wrap the entire contents of the repeater inside a shortcode wrapper, then create a shortcode that utilises the post_class function that we need, before returning the rest of the content.
To create the shortcode we need, we add this code to our code snippets.
add_shortcode( 'repeater_post_class', 'lit_post_class_sc' );
/**
* Shortcode for adding post classes inside Oxygen Repeater
*/
function lit_post_class_sc( $atts, $content = null ) {
$postclasses = join( ' ', get_post_class() );
return '<div class="'. $postclasses . '">' . $content . '</div>';
}
Now we have a shortcode that we can use anytime we’re using a repeater element for displaying posts. (Not to be used when displaying ACF repeater fields)
Using the shortcode wrapper, we can add our new shortcode like so;
[repeater_post_class][/repeater_post_class]
Then we can add all of our elements for the repeater inside that shortcode wrapper.
Now when we inspect our posts on the front end, we see a number of class names inside the shortcode div that can be used to target style groups of similar posts.
<div class="oxy-dynamic-list">
<div class="ct-div-block">
<div class="ct-nestable-shortcode">
<div class"post post-1032 has-post-thumbnail category-featured...">
...
</div>
</div>
</div>
<div class="ct-div-block">
<div class="ct-nestable-shortcode">
<div class"post post-1032 has-post-thumbnail category-featured...">
...
</div>
</div>
</div>
<div class="ct-div-block">
<div class="ct-nestable-shortcode">
<div class"post post-1032 has-post-thumbnail category-featured...">
...
</div>
</div>
</div>
</div>
More markup than we would have liked? Absolutely. Having these classes on the repeater’s top-level div would be ideal, but it solves the problem we have.
Easier Targeting with CSS
Now we have some markup that we can use for specific targeting.
eg If we now wanted to make sure that all of the posts in the ‘featured’ category have a red border below the title, then we could target these easily by adding something like this to our stylesheet.
.oxy-dynamic-list .post.category-featured .title {
border-bottom: 1px solid red;
}
Or perhaps we want to target all the posts that don’t have a featured image, so we can adjust the padding for those posts only..
.oxy-dynamic-list .post:not(.has-post-thumbnail) {
padding: 30px;
}
This can make it easier to style posts individually for content-heavy sites with many different types of content & categories.