• SB Children block – my first Single Block plugin


    Today I delivered my first Single Block ( SB ) plugin to wordpress.org. It’s called SB Children block and it’s in the Block Directory.

    I’ve written up some notes about the plugin. Suffice it to say there were a few challenges along the way. But I’ve left the details of these in the GitHub issues.

    About the SB Children block plugin

    • The plugin is called SB Children block – sb-children-block.
    • It delivers a block called Children.
    • Which “lists children of the current content as links”.
    • The core function it uses is wp_list_pages.
    • The internal block name is oik-sb/children.

    The block is a rather simple Server Side Rendered (SSR) block that uses core WordPress logic to create the list, which can be shown to display various levels of descendent content, based on a Depth parameter.

    Usage scenarios

    • When you want to create a simple list of child pages for the current page.
    • When you want to show the full hierarchy of descendants for the current page.
    • When you want to do this for other hierarchical post types.
    • To replace some shortcodes:
      • I’ll use the block to replace some instances of my [bw_tree] and/or [bw_list] shortcodes.
      • Other people may choose to switch from the shortcodes they’re using.

    Finding and installing the Children block

    Searching for sb-children-block v1.0.0

    The Block Directory search will be delivered in WordPress 5.5. If you already have the latest version of Gutenberg or a Release Candidate of WordPress 5.5 installed then Block Directory search will be enabled.

    You can therefore search for and install the Children block while using the editor.

    In my local development environment I have Gutenberg 8.7.0

    Search Results
    c Quite a few results including Audio, File, Group and several others that don’t appear to have a c in them
    ch Words with ch in them such as Search and Archives and Yoast SEO’s blocks that use the keyword Schema
    chi Archives and Calendar, which has a keyword of Archive.
    chil Goes away to search and returns “No blocks found in your library”.
    child Finds Cornell Note, SB Children block and Paypal Donation Block. It’s not at all obvious why it found the other two.
    childr Goes away to search and returns “No blocks found in your library”.
    childre As above for chil and childr
    children TADA!
    Searching for the Children block v1.0.0

    Why it found the other blocks

    Cornell Notes Gutenberg Block contains the following text in the readme.txt file.

    Cornell Notes contains a second block – an Idea block – this block is only made available as a child of the Cornell Note block – and enables you to add as many ideas (key ideas and long-form notes) you require.

    Paypal Donation Block contains the following text in the readme.txt file.

    [paypal_donation_block email ='yourpaypalemail@example.com' amount ='10' currency='USD' purpose='Charity for Child Health Care' ]

    Searching for sb-children-block v1.0.1

    In response to bobbingwide/sb-children-block#11 I updated the readme.txt file. I added the substrings of children. This table summarises the new results performing the same searches.

    Search Results Compare vs 1.0.0
    c Quite a few results including Audio, File, Group and several others that don’t appear to have a c in them Same
    ch Words with ch in them such as Search and Archives and Yoast SEO’s blocks that use the keyword Schema Same
    chi Archives and Calendar, which has a keyword of Archive. Same
    chil Goes away to search and returns SB Children block TADA!
    child Finds Cornell Note, SB Children block and Paypal Donation Block. We now know why it found the other two Same
    childr Finds SB Children block TADA!
    childre Finds SB Children block TADA!
    children Finds SB Children block TADA!
    Searching for the Children block v1.0.1

    Searching in other languages

    In v1.0.1 I also added translations of children to the readme.txt file.This table summarises the results of performing the search in different languages.

    Language Search Results
    French Enfants TADA!
    German Kinder TADA!
    Dutch Kinderen TADA!
    Italian prole TADA!
    Spanish ninas or niñas, ninos or niños TADA!
    Searching for the Children block v1.0.1 in other languages

    These results suggest that we can search for any string in the readme.txt file to get a result.

    Searching for any old bollocks in the readme.txt

    Let’s try some unexpected searches for strings in the readme.txt file for v1.0.1.

    Search Results
    5.5-RC2 TADA!
    SB TADA!
    Installation 10 blocks but not SB Children block
    page-attributes SB Children block and WooCommerce Product Table

    Some technical details

    The plugin is a Single Block plugin initially created using the WordPress create-block package ( @wordpress/create-block ).

    cd \apache\htdocs\wordpress\wp-content\plugins
    npx @wordpress/create-block

    I then changed the generated code:

    • To deliver a Server Side Rendered block.
    • To internationalise the build for both the block editor and the server side code.
    • To localise the language files into:
      • UK English ( en_GB locale )
      • and my i18n test language bbboing ( bb_BB locale ).
    • and I added a custom webpack.config.js for peaceful coexistence with other single block plugins generated using the same tool.

    Some of the source files

    Configuration files

    block.json

    The block.json file describes the block in a computer readable form.

    {
            "name": "oik-sb/children",
            "title": "Children",
            "category": "widgets",
            "icon": "list-view",
            "description": "List children of the current content as links.",
            "textdomain": "sb-children-block",
            "supports": {
                    "html": false
            },
            "editorScript": "file:./build/index.js",
            "editorStyle": "file:./build/index.css",
            "style": "file:./build/style-index.css"
    }
    package.json

    The package.json file is used to control the build, using npm ( Node Package Manager).

    {
            "name": "sb-children-block",
            "version": "1.0.0",
            "description": "List children of the current content as links.",
            "author": "bobbingwide",
            "license": "GPL-2.0-or-later",
            "main": "build/index.js",
            "scripts": {
                    "build": "wp-scripts build",
                    "format:js": "wp-scripts format-js",
                    "lint:css": "wp-scripts lint-style",
                    "lint:js": "wp-scripts lint-js",
                    "start": "wp-scripts start",
                    "dev": "wp-scripts start",
                    "packages-update": "wp-scripts packages-update",
                    "makepot": "wp i18n make-pot . languages/sb-children-block.pot --exclude=node_modules,vendor,src",
                    "makejson": "wp i18n make-json languages --no-purge",
                    "l10n": "l10n sb-children-block"
            },
            "devDependencies": {
                    "@wordpress/scripts": "^12.1.1"
            },
            "dependencies": {}
    }
     
    • I added steps to run makepot, l10n and makejson.
      • makepot uses a WP-CLI command to extract text strings for translation
      • l10n automatically translates these strings into UK English and bbboing
      • makejson uses a WP-CLI command to produce the translation files required in the editor.
    • I also added dev as an alias of start
    • I haven’t used the other npm run commands
    webpack.config.js

    After many battles ( documented in a number of GitHub issues ), I added a special webpack configuration file to set a custom jsonpFunction. Without this logic multiple single block plugin blocks which have been built using npm run build do not coexist peacefully.

    const config = require( '@wordpress/scripts/config/webpack.config' );

    /**
     * Because the block and the package have their own webpack configuration,
     * they must provide a unique name for the global scope (which is used to lazy-load chunks),
     * otherwise it throws a JS error when loading blocks compiled with `npm run build`
     * @see https://github.com/WordPress/gutenberg/issues/23607
     * @see https://webpack.js.org/configuration/output/#outputjsonpfunction
     * @see https://github.com/WordPress/gutenberg/issues/24321
     */

    // ------------------------------------------------------
    config.output.jsonpFunction = 'sb-children-block';
    // ------------------------------------------------------

    module.exports = config;

    JSX source files

    index.js, edit.js and save.js contain the JavaScript source of the block.

    • index.js does the block registration for the editor
    • edit.js defines the editor interface
    • save.js just returns null; the block is Server Side Rendered by PHP code.

    In each of these files WordPress components are imported from @wordpress/component-name where component-name was often a best guess.

    PHP files

    The runtime PHP code is in build/index.asset.php and sb-children-block.php.

    build/index.asset.php
    <?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-polyfill'), 'version' => '7b0281db299adf72321e4f16c36f3025');

    This file is generated by the wp-scripts routine which is invoked by npm start or npm run build. It’s used by the logic in the main plugin file to automatically determine the block’s dependencies and its version.

    If it doesn’t exist then your site crashes.

    sb-children-block.php

    The main plugin file registers scripts and styles needed for the block the registers the block itself.

    register_block_type( 'oik-sb/children', array(
                    'editor_script' => 'sb-children-block-block-editor',
                    'editor_style'  => 'sb-children-block-block-editor',
                    'style'         => 'sb-children-block-block',
                    'render_callback'=>'sb_children_block_dynamic_block',
                    'attributes' => [
                            'depth' => [ 'type' => 'string'],
                            'className' => [ 'type' => 'string'],
                    ]
            ) );

    Most of the plugins’ logic is done by sb_children_block_block_init in response to the init hook. The code for localization of the block in the editor, that was missing from the generated plugin file is:

    /*
     * Localise the script by loading the required strings for the build/index.js file
     * from the locale specific .json file in the languages folder
     */

    $ok = wp_set_script_translations( 'sb-children-block-block-editor', 'sb-children-block' , $dir .'/languages' );

    I was able to defer the logic to load the translation files to the actual logic that gets called to render the block

    function sb_children_block_dynamic_block( $attributes ) {
            load_plugin_textdomain( 'sb-children-block', false, 'sb-children-block/languages' );
            $className = isset( $attributes['className']) ? $attributes['className'] : 'wp-block-oik-sb-children';
            $depth = isset( $attributes['depth']) ? $attributes['depth'] : 0;
            $post = get_post();
            $args = [ 'child_of' => $post->ID, 'echo' => false, 'title_li' => null, 'depth' => $depth ];
            $html = '<ul class="'. $className . '">';
            $html .= wp_list_pages( $args );
            $html .= '</ul>';
            return $html;
    }

    Submitting a plugin to the block directory

    Apart from step 1., sharing your Block with the World is now a lot easier than it used to be.

    1. Develop your plugin, on GitHub.
    2. Run the Block Plugin Checker. https://wordpress.org/plugins/developers/block-plugin-validator/
    3. When it works package it up into a .zip file.
    4. Submit your plugin’s .zip file at Add Your Plugin https://wordpress.org/plugins/developers/add/
    5. When it’s approved publish it on wordpress.org using SVN
    6. Wait a while and you’ll receive an email to say that your plugin has been added to the Block Directory. Here: https://wordpress.org/plugins/browse/block/.

    Further reading

    Some child pages plugins

    Here’s a subset of plugins on wordpress.org that can be used to list child pages.

    Plugin name and description Plugin links Version, total downloads, last update, tested
    SB Children block
    List children of the current content as links.
    1.1.0
    1,057
    October 20, 2020
    5.5.7
    oik
    lazy smart shortcodes for your WordPress website
    4.4.1

    October 8, 2021
    5.8.1
    CC Child Pages
    Adds a responsive shortcode to list child and sibling pages. Pre-styled or specify your own CSS class for custom styling. Includes child pages widget.
    1.40
    82,526
    May 12, 2021
    5.7.4
    SB Child List
    The total in-page navigation solution for Wordpress. Using the shortcodes and widgets provided you can display navigation between your parent, child a …
    4.5
    36,273
    May 13, 2019
    Page-list
    [pagelist], [subpages], [siblings] and [pagelist_ext] shortcodes
    5.2
    298,714
    November 26, 2021
    5.8.2

    Notes:

    • The oik plugin provides a number of shortcodes that can be used to list child content in a variety of forms.
    • I wasn’t aware of sb-child-list until after I’d submitted my plugin.


    Published:

    Last updated:

    August 9, 2020

Categories

Tide times from tidetimes.co.uk

Tide Times & Heights for Langstone Harbour on
Monday, 06 December 2021
High Tide:00:17 ( 5.00m )
Low Tide:05:29 ( 0.70m )
High Tide:12:37 ( 5.00m )
Low Tide:17:53 ( 0.60m )

Tide times from tidetimes.org.uk

Tide Times & Heights for Northney on
6th December 2021
00:22 High Tide ( 4.93m )
05:33 Low Tide ( 0.54m )
12:38 High Tide ( 5m )
17:59 Low Tide ( 0.42m )