Creating a Custom Store
With gratitude to Darren Ethier’s series on registering a custom store, here’s the why and how to register a custom store.
Why (and when) we need a custom store
On the latest version of the Choctaw Print site, I ran into a problem: users may choose a post from the work
CPT to highlight on a page and also include a query loop of all work
posts. Because blocks live in isolation, there was a world where the same post could featured 3 times on a page:
- A two-column layout using the custom
Featured Work
post where both blocks feature the same post, “Project 1.” - The custom query block
Work Gallery
that shows thework
posts would include “Project 1” as well.
Unlike building with PHP, where you always know what’s going to be on a page, blocks are rendered on-demand. To highlight this, here’s a sample:
<?php
// some pseudo-code as an example.
// imagine this is part of larger php file.
$featured_posts = [];
while (have_rows('posts_to_feature') {
the_row();
$featured_posts[] = get_sub_field('featured_post');
}
$args = array(
'post_type' => 'work',
'post__not_in' => $featured_posts
);
$work_posts = new WP_Query($args);
// show the posts...
In this example, we (the devs) know which posts are featured and which to exclude because we can just grab the ACF fields (that are probably required).
The block editor inverts this power: the $featured_posts
array will only exist if the Featured Work
block exists on the page, but the Work Gallery
block has no way of knowing what blocks exist around it.
How the Store is Registered and Used
Any time a Featured Work
block gets rendered to the page, we want it to add a post id to a custom store so that other instances of the Featured Work
block and the Work Gallery
block can know which IDs are already in use on the page.
I won’t get into the nuts and bolts of building the store, but here’s a link to what I did for the Choctaw Print site where you can read the code for yourself.
While we’re building a WordPress flavored Redux store, this is simple enough that if you’re familiar with React’s Context + reducer API, it should make sense.
An overview of store.ts
- Create a custom store with
createReduxStore
, passing it the store namespace and an object of args.- the
reducer
andactions
are stored in their own files (a WordPress convention) because I wasn’t sure if it would need to grow or not. These files are small enough on their own for this to be unnecessary.
- the
- Register the store to WordPress with
register
.
Using the store
The Featured Work
block uses the store in two ways: it gets current posts (if any) from the Set and it also gets the addPost
action to (you guessed it) add a post to the set. This functionality is abstracted into a custom hook for cleaner separation of concerns; you can see the relevant code at lines 23-29 on Github.
The Work Gallery
block uses the store to get current posts (if any) in the store and immediately updates the block’s attributes (so the data can be consumed on the php side). Again, this functionality is abstracted into a custom hook (relevant code is on lines 12–22). The IDs in the store are saved to the block’s excludedIds
attribute and immediately consumed in the render template of the block (line 12).