viget/viget-blocks-toolkit

Simplifying Block Registration and other block editor related features.

Maintainers

Package info

github.com/vigetlabs/viget-blocks-toolkit

Type:wordpress-plugin

pkg:composer/viget/viget-blocks-toolkit

Statistics

Installs: 730

Dependents: 0

Suggesters: 0

Stars: 7

Open Issues: 1

v1.1.5 2026-03-25 23:55 UTC

README

This toolkit was made to simplify the process of registering custom blocks with ACF Pro. It also adds several additional features to the block editor such as Block Icons and Breakpoint Visibility.

Creating Custom Blocks in your Theme

To create a block in your theme, simply create a blocks folder in the root of your theme directory. Each block should have its own folder and a block.json file. The block.json file should contain the block configuration. You can then use a render.php file (or render.twig file if Timber/Twig is supported) to render the block. By default, the blocks that support jsx will automatically render using the plugin's jsx.php file.

Customizations

block.json

tagName

Useful when using the built-in render file for jsx supported blocks, tagName can be set in block.json to specify the outer tag for the block. (By default it uses section).

innerContainer

You can disable the inner container wrapper by setting the value of innerContainer in supports to false.

blockId

Assign each block a unique, persistent blockId simply by adding the attribute to the block.json file.

mediaPosition

Adding the mediaPosition attribute will enable the Media Position toggle buttons in the block toolbar and apply transforms based on the mediaPosition: transformations array in the supports object. The transformations rules will apply:

  • Root level transformations will apply to all child blocks.
  • reverse will reverse the order of the child blocks.
  • attributes will modify the block's attributes.
    • Each value will be determined based on the value of mediaPosition. See example below.
  • Nested innerBlocks will apply transformations only to child blocks when present within the parent block.

In the following example scenario:

  • All columns will be reversed.
  • All buttons will have their layout justified based on the mediaPosition value. (mediaPosition is on the left, the attribute value is on the right)
  • Any images within a column block will have their alignment switched based on the mediaPosition value.
{
  "supports": {
    "mediaPosition": {
      "transformations": [
        {
          "core/columns": {
            "reverse": true
          }
        },
        {
          "core/buttons": {
            "attributes": {
              "layout": {
                "justifyContent": {
                  "left": "right",
                  "right": "left"
                }
              }
            }
          }
        },
        {
          "core/column": {
            "innerBlocks": [
              {
                "core/image": {
                  "attributes": {
                    "align": {
                      "left": "right",
                      "right": "left"
                    }
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}

This is an example of a block.json file with all the supported customizations.

{
  "tagName": "article",
  "attributes": {
    "blockId": {
      "type": "string",
      "default": ""
    },
    "mediaPosition": {
      "type": "string",
      "default": "left"
    }
  },
  "supports": {
    "innerContainer": false,
    "mediaPosition": {
      "transformations": [
        {
          "core/columns": {
            "reverse": true
          }
        }
      ]
    }
  }
}

blockPattern

You can set a blockPattern attribute default in block.json to seed <InnerBlocks /> from block markup instead of template.json.

Resolution order:

  1. Registered pattern slug (exact match).
  2. If the value contains /, the basename is checked as a registered slug.
  3. If still not found, look for a local file in patterns/:
    • {slug}.php
    • {slug}.html
    • {slug}.twig (when Timber is available)

Both namespaced (wp-starter/cta-default) and basename (cta-default) values are supported.

templateLock

Set a templateLock attribute default in block.json to pass through to <InnerBlocks />.

When set to "contentOnly", the toolkit automatically passes that lock value to inner_blocks() render calls so ACF blocks can behave like content-only container blocks.

lock

Set a default lock object on the parent block and it will be recursively applied to seeded child blocks unless a child already defines its own lock value.

{
  "attributes": {
    "lock": {
      "type": "object",
      "default": {
        "move": false,
        "remove": true
      }
    }
  }
}

sync

Set a sync attribute to true when the blockPattern markup should be the render-time source of truth (instead of saved inner block content). This is optional and defaults to false.

template.json fallback

If there is a template.json file present, the contents of template are used as the innerBlocks template when blockPattern is not provided. Example:

{
  "template": [
      [ "core/heading" ],
      [ "core/paragraph" ]
    ]
}

block.php

If there a block.php file present, it will automatically be loaded during block registration.

render.php

There are several variables available in the render.php file:

/**
 * @global array     $block      The block data.
 * @global array     $context    The block context data.
 * @global bool      $is_preview Whether the block is being previewed.
 * @global int       $post_id    The current post ID. (Be careful, you may want to use $context['postId'] when in a loop)
 * @global \WP_Block $wp_block   The WP_Block object.
 */

The $block variable also has some additional values:

$block['url'] // The URL to the block folder.
$block['path'] // The path to the block folder.
$block['template'] // The template.json file contents.
$block['templateLock'] // The runtime template lock value for inner blocks.
$block['blockPattern'] // The block pattern slug used for editor seeding/render sync.
$block['lock'] // Default lock object propagated to nested blocks.
$block['sync'] // Whether render-time pattern sync is enabled.
$block['slug'] // The slug of the block, without the `acf/` prefix.

Breakpoint Visibility

This block settings panel is available on any supported block in the Full Site Editor and in post block editor. It allows you to set visibility for each block at different breakpoints, so blocks can be hidden or shown based on the screen size. There is a setting to also specify a breakpoint and whether the block should be hidden or shown at that breakpoint.

When a parent block is using templateLock: "contentOnly", quick visibility and icon controls remain available in block toolbar controls.

Main Helper Functions

vgtbt()

Returns an instance of the Viget Blocks Toolkit Core class.

<?php
// Retrieve a specific block icon array.
vgtbt()->block_icons->get_icon( 'my-custom-icon' );

block_attrs()

Outputs the block attributes as a string. Supported arguments:

  • $block array - The block data.
  • $custom_class string - Additional classes to add to the block.
  • $attrs array - Additional attributes to add to the block.

inner_blocks()

Outputs the <innerBlocks /> element of a block. Supported arguments:

  • $props array - The properties of innerBlocks
    • template array - The template for the inner blocks. This value is automatically json_encoded.
    • templateLock string - The lock value for the inner blocks.
    • allowedBlocks array - The allowed blocks for the inner blocks. This value is automatically json_encoded.

Hooks

vgtbt_block_locations (Filter)

Filter the block locations. This allows you to add or change where custom blocks can be found.

<?php
add_filter(
	'vgtbt_block_locations',
	function ( array $locations ): array {
		$locations[] = get_template_directory() . '/other-blocks';
		return $locations;
	}
);

vgtbt_button_icons (Filter)

Filter the button icons.

<?php
add_filter(
	'vgtbt_button_icons',
	function ( array $icons ): array {
		$icons['my-custom-icon'] = [ // The key is the unique icon slug.
			'label'       => __( 'My Custom Icon', 'my-text-domain' ),
			'icon'        => '<svg ... ></svg>',
			'defaultLeft' => false, // Optional, defaults icon to align left.
		];
		
		return $icons;
	}
);

vgtbt_supported_icon_blocks (Filter)

Filter the supported icon blocks. Note: the frontend and editor CSS may need to be manually added for additional blocks.

<?php
add_filter(
	'vgtbt_supported_icon_blocks',
	function ( array $blocks ): array {
		$blocks[] = 'core/heading';
		return $blocks;
	}
);

vgtbt_button_icons_editor_css (Filter)

Filter the editor CSS for the button icons. This is useful when some icons do not use outline fill the fill property causes issues. Or can also be used to specify icon dimensions using max-height.

add_filter(
	'vgtbt_button_icons_editor_css',
	function ( string $css ): string {
		return $css . '.components-button.button-icon-picker__icon-my-custom-icon svg { fill:none; }';
	}
);

vgtbt_unregister_block_styles (Filter)

Unregister block styles from core blocks.

add_filter(
	'vgtbt_unregister_block_styles',
	function ( array $styles ): array {
		$styles[] = [
			'core/separator',
			'dots',
		];

		return $styles;
	}
);

vgtbt_unregister_block_variations (Filter)

Unregister block variations from core blocks.

add_filter(
	'vgtbt_unregister_block_variations',
	function ( array $variations ): array {
		$variations[] = [
			'core/social-link',
			'bluesky',
		];
		return $variations;
	}
);