Hollands Spoor

The Notebooks

  • Fixing Pagination

    Excerpt: A common layout need: left-aligned ā€œpreviousā€ link, centered page numbers, right-aligned ā€œnextā€ link. Setting the Pagination block’s items justification to ā€œSpace Betweenā€ achieves this — until you reach the first or last page. The previous/next child block is not rendered when not applicable, so the pagination block ends up with two items and the center/nav shift left or right. This note explains two practical fixes and an accessible, performant filter-based solution.

    The Gutenberg core pagination-block can be used inside a Query-loopblock and contains three childblocks: a block showing a link to the previous page with posts, a block with pagenumbers and a block showing a link to the next page. The links to the next and previous page can be a textlabel or an arrow or a combination of the two.

    I wanted this pagination on the bottom of my page and i wanted the previous-page arrow to align left, the pagenumbers in the middle and the next-page arrow to align right. To achieve this, i selected the pagination block and in its toolbar I selected ‘Change Items Justification’. After selecting ‘Space Between Items’, I accomplished what I wanted.

    However, when visiting the first page, all got mis-aligned because when there is no ‘Previous Page’ ( when you are on the first page ) the block does not render into an empty page-element, but it gets not rendered at all. That leaves the pagination-block with only two items and since alignment is set to space between this means the pagenumbers move to the left. Something similar happens on the last page of the query.

    I want the elements of pagination to be fixed and not be moving around while navigating between pages.

    My first thought was to use the child blocks of the pagination-block on their own. I made a block with 3 columns and tried to move the ‘Previous Page’ block to the left column, the ‘Page numbers’ block to the middle column and the ‘Next Page’ to the right column. That way, i thought, when the ‘Previous Page’ element disappears, the column that contains it is still there, keeping the layout fixed.

    I reconned being a child of the Query Loop block would give these blocks enough context to work on their own. But regretably this was not possible.

    In the block-meta of the query-pagination-previous block, I found that only the pagination block is an allowed parent:

    {
    	"$schema": "https://schemas.wp.org/trunk/block.json",
    	"apiVersion": 3,
    	"name": "core/query-pagination-previous",
    	"title": "Previous Page",
    	"category": "theme",
    	"parent": [ "core/query-pagination" ],
    	"description": "Displays the previous posts page link.",

    You just can’t drag the Previous-Page-Block to an empty column or other block to help you fix its position.

    First solution

    You can’t move a pagination childblock outside the pagination-block. But you can remove them from the pagination block. You can make three columns each containing a Pagination-block. Since all three instances of the pagination block get their context from the same Query-loopblock, they act in excactly the same way. Now you can remove the pagenumbers and the next-page blocks from the left pagination-block. You remove both previous- and nextpage blocks from the middle pagination block and then remove previous-pageblock and pagenumbers from the right pagination block.

    I did not investigate on the cost of extra queries that need to be made using this admittedly not very elegant solution. But it works.

    Second solution

    The previous-page and next-page render to empty content when they are not applicable. But ofcourse after rendering, all blocks go through some filters, also when they result in empty content.

    So adding a filter to the rendering of these blocks enables us to replace the empty content with some empty placeholder element that ensures justifying the items always takes place with the same numbers of items. Some inline style regarding the margins is added here, but this can ofcourse also be achieved by adding some classes / css*.

    add_filter('render_block_core/query-pagination-previous', function(  $block_content, $parsed_block, $block_object ) {
        if( '' === $block_content) {
            $block_content = '<span class="wp-block-query-pagination-previous" style="margin-inline-end: auto;"></span>';
        }
        return $block_content;
    }, 10, 3 );
    
    add_filter('render_block_core/query-pagination-next', function(  $block_content, $parsed_block, $block_object ) {
        if( '' === $block_content) {
            $block_content = '<span class="wp-block-query-pagination-next" style="margin-inline-start: auto;"></span>';
        }
        return $block_content;
    }, 10, 3 );

    Since this is obviously something that attributes to the looks of the website, it should probably be added to the theme’s functions.php or somewhere that gets invoked from there.

    Conclusion

    Two pragmatic options: three synchronized Pagination blocks (no code) or the lightweight filter+CSS approach (recommended). The filter approach preserves layout, is accessible and performant, and keeps editor ergonomics unchanged.

    * You can ask Copilot for this, but I did it for you and it provided also some accessability additions on the run:

    For your functions.php:

    <?php
    add_filter( 'render_block_core/query-pagination-previous', function( $block_content, $parsed_block, $block ) {
        if ( '' === trim( $block_content ) ) {
            return '<span class="my-pagination-placeholder pagination-previous" aria-hidden="true" role="presentation"></span>';
        }
        return $block_content;
    }, 10, 3 );
    
    add_filter( 'render_block_core/query-pagination-next', function( $block_content, $parsed_block, $block ) {
        if ( '' === trim( $block_content ) ) {
            return '<span class="my-pagination-placeholder pagination-next" aria-hidden="true" role="presentation"></span>';
        }
        return $block_content;
    }, 10, 3 );

    And for the style.css

    .my-pagination-placeholder {
      display: inline-block;
      width: 1rem; /* reserve horizontal space, tune as needed */
      height: 1em;
      vertical-align: middle;
    }
    .wp-block-query-pagination { /* ensure flex layout remains */
      display: flex;
      align-items: center;
    }
    .pagination-previous { margin-inline-end: auto; }
    .pagination-next { margin-inline-start: auto; }

  • Asanoha, seigaiha and more.

    Asanoha, seigaiha and more.

    I needed backgrounds with wallpaper patterns that you can seamlessly place next to each other, like these for example:

    There are plenty of examples to be found if you search for something like ‘seamless pattern images’. If the license allows it, you can use them as a background for, for example, a Gutenberg Group block or Cover block. (In the settings dialogs for the background of these blocks, you can specify that the image should not be stretched but tiled next to each other, resulting in corresponding CSS background-size and background-repeat rules).

    You might want to customize these kinds of patterns to your own taste: color, line thickness, shape, size of the repeated base element, etc. Of course, you can also draw/create something yourself in, for example, Illustrator or Inkscape (the latter is preferred due to the views on intellectual property that Adobe imposes on its users). There are also online generators available that produce these kinds of patterns (add the words ā€˜online generator’ when searching).

    In any case, it would be better if you had this functionality within the WordPress block editor. Then you wouldn’t have to keep switching between the generator and WordPress, and you wouldn’t have to keep downloading and uploading patterns (and possibly exporting them to a usable format). This would also serve users who find all of this too cumbersome when they need new or customized patterns.

    What is really desirable, then, is such an online SVG pattern generator, but as part of the Gutenberg editor. To achieve this, I went through several steps, starting with the background pattern below:

    With this pattern in mind, I went through the following eight steps:

    1. Creating the SVG
    2. Creating JSON
    3. Passing JSON to the block editor
    4. Adding Functions that work with parameters
    5. Adding Inspector Controls to the Block Editor
    6. Creating a Renderer for Template, Parameters, and Function Results
    7. Presets
    8. Insert the SVG as a block background image

    Finally, I created some additional patterns with different presets for the parameters. At the end, there is an overview of these.

    1. Create SVG

    2. Create JSON

    3. Pass JSON to the Block Editor

    4. Adding Functions

    5. Add Inspector Controls to the Block-editor

    6. Render template, parameters and functions

    7. Presets

    8. An SVG as a background

    Patterns and Presets

    Asanoha

    Dark Night

    Black River

    Star Blazer

    Soup

    Beach

    Red

    Blue

    Gump

    Free

    Crates

    Metalic

    Anatomy

    Fragile

    Ant

    Diamond

    Cardinal

    Leaves

    Polka

    Candy

    Rings

    Elegant

    Horrible 70

    Awefull 80

    Store

    Seigaiha

    Pink

    Pink Gradiƫnt

    Lime

    Classic 2