wp-lemon Docs
Block controller
Block controller
The block controller is where you'll probably spend most time while developing a custom block. This is where you process any dynamic data and control how your block behaves based on input from the editor. The idea is to put all of our logic in here, so that when you're working in the view layer, you only have to focus on creating a beautiful front end.
Anatomy of a block controller
In the block controller you will find 2 methods you can use to expand your block:
block_context()
add_fields()
The block_context() function is used to query the data from the database and add it to the block context.
Block content
There are two main ways to add content to your block.
- InnerBlocks
- ACF fields
We prefer InnerBlocks over ACF fields because it uses native WordPress functionality. The reason you might want to use ACF fields is for repeater fields like slides or testimonials. Below we'll show you how to use both methods.
InnerBlocks
InnerBlocks are blocks within blocks. This way you can create complex blocks with multiple child blocks. This gives the user a lot of control over the layout of the block. To learn how to use InnerBlocks, take a look at the InnerBlocks documentation.
Adding ACF fields to the block
You can add any type of ACF field to the block. To find out all the possibilities take a look at the ACF documentation. Here you'll find all the different field types and how to use them. Below is a simple example of what your add_fields() function could look like.
public function add_fields(): object{ $this->registered_fields ->addRepeater( 'slides', [ 'layout' => 'block', 'min' => 1, 'max' => 4, ] ) ->addImage('image', [ 'label' => 'Image', 'return_format' => 'id', 'preview_size' => 'medium', ]) ->addText('caption', [ 'label' => 'Bijschrift', ]) ->endRepeater(); return $this->registered_fields;}
To learn how to use these fields in your block view, take a look at the block view documentation.
Extending the block context
Every block is different but we will give some common examples on how to expand your block.
Block that displays an x amount of (custom)posts
Take a look at the news-recent.php
block in the parent theme. You will find a method block_context().
When going through these lines you will find several notable things.
1public function block_context($context): array2{3 $amount = get_field('amount') ? get_field('amount') : 3;4 $items = latest_items_query('news', $amount);5 $context['items'] = $items;6 $context['card_type'] = 'news';7 $context['holder_classes'] = 'col-12 col-md-6 col-lg-4';8 $message = __("You haven't added any news yet, so this block will be empty.", "wp-lemon");9
10 if ($items->found_posts == 0) {11 self::add_notification($message, 'warning');12 }13
14 return $context;15}
- wp-lemon comes with a set of predefined queries. Here we use latest_items_query() to get the latest posts of a specific posttype
- We have a card_type variable that defines what card type will be loaded.
- We have a add_notification method that will setup a notification inside the block when previewed in the backend.
Block that displays a post archive with load more button
Take a look at the news-overview.php
block in the parent theme. You will again find a method block_context() that will query the data from the database and add it to the block context.
1public function block_context($context): array2{3 $items = archive_query('news', 6); // query the news posttype4 $context['items'] = $items;5 $context['nav'] = true; // show nav6 $context['count'] = get_total_posts('news', count($items)); // get a count array that feeds information to the postholder.7 $context['post_type'] = 'news'; // sets post type for the ajax calls.8 $context['card_type'] = 'news'; // sets the twig partial to render the actual posts in the loop.9 $context['holder_classes'] = 'col-12 col-md-6 col-lg-4'; // holder classes around the cards in the loop.10
11 if (isset($this->fields['show_filter']) && $this->fields['show_filter'] == true) {12 $context['show_filter'] = true;13 $context['terms'] = get_terms('category', array('hide_empty' => true));14 }15
16 // add notification when no posts are found.17 if ($items->found_posts == 0) {18 self::add_notification(__('You haven\'t added any news yet, so this block will be empty.', 'wp-lemon'), 'warning');19 }20
21 return $context;22}
The linked blocks/news-overview.twig
file will include components/archive-loop.twig
that will display the initial posts and setup everything for receiving new posts via an ajax call.
When reusing above code make sure to:
- set the post type correctly
- create a new card twig file
- include the
components/archive-loop.twig
inside your twig file that is linked to your block. - Update the notice to inform the administrator/editors of the website when no posts are found of the posttype you want to query.
- include the right functions in your file like so
1namespace WP_Lemon\Child\Blocks;2
3use HighGround\Bulldozer\BlockRenderer;4
5++ use function WP_Lemon\API\archive_query;6++ use function WP_Lemon\API\get_total_posts;
Block with custom assets
You might want to add a specific asset to the blocks context as it is only used by this specific block. You can use the asset()
helper function for that.
1public function block_context($context): array2{3 // Check if shape exists.4 if(true == asset('images/banner.png')->exists()){5 // get URL to image/shape6 $context['banner_uri'] = asset('images/banner.png')->uri();7 }8
9 // get contents of the svg to use directly in to your block.10 $context['sphere'] = asset('images/sphere.svg')->contents();11
12 return $context;13}
Block that needs conditional modifier classes
You might want to add conditional classes based on a field setting. This is where $this->add_modifier_class('yourmodifier');
comes in.
This method adds a BEM modifier class to your block. An example:
1public function block_context($context): array2{3 4 if (isset($this->fields['show_pagination']) && true == $this->fields['show_pagination']) {5 $context['show_pagination'] = true;6 $this->add_modifier_class('has-pagination');7 }8 9 return $context;10}
will result in
1<div class="acf-block slider slider--has-pagination" id="block_5f8ffdc0349e1">2...3</div>
Wp-lemon queries
When you want to use post objects within your custom block you can use the following queries in your block context:
Function | Description |
---|---|
latest_items_query | Retrieves the latest posts of a specific type, optionally filtered by taxonomy and terms. |
other_items_query | Fetches posts of a specific type, excluding a given post, optionally filtered by taxonomy and terms. |
specific_items_query | Retrieves specific posts by their IDs and type. |
archive_query | Fetches a set of posts of a specific type for archive display, supporting pagination. |
get_total_posts | Calculates the total number of posts available for an AJAX "load more" functionality. |
adjacent_post_info | Gets information about the next or previous post, or returns the first/last post if unavailable. |
next_post_info | Returns information about the next post or the first post if no next post exists. |
previous_post_info | Returns information about the previous post or the last post if no previous post exists. |
taxonomy_post_collection | Retrieves a collection of posts organized by category, based on a taxonomy and post type. |