WP Manifestindependent plugin directory
manifest / editor / hm-gutenberg-tools

HM Gutenberg Tools Plugin WP Registry grade D+. High-severity findings · 2 findingsWP RegistryHigh-severity findings · 2 findingsOpen the reportD+ #7 in Blocks & Editor

Useful helpers, components or tools for building things with Gutenberg

★ 187stars
111kcomposer installs
v1.7.4latest · 6mo ago

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/humanmade/hm-gutenberg-tools/archive/refs/heads/main.zip

On Packagist as humanmade/hm-gutenberg-tools:

composer require humanmade/hm-gutenberg-tools
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

Human Made Gutenberg Tools

[!WARNING]
This project is no longer actively developed. It is recommended that you the components from our Block Editor Components library instead.

A place to bundle useful reusable Gutenberg components and other tools.

What does this include?

  • Post Select button. Provides a media modal like user experience for selecting single or multiple posts. It supports searching, filtering, sorting and custom post types (and taxonomies). stying to work better in the sidebar.
  • More Sidebar controls. Other components wrapped up in as standardised sidebar control components.
    • Link control. A wrapper for the core UrlInput, but with some style improvements.
    • Image. Sidebar UI for selecting an image.
    • Post. A wrapper for the post select button component.

image

Installation Instructions

It is reccomended to install as a plugin or mu-plugin using composer.

composer require humanmade/hm-gutenberg-tools

If you install using another method (e.g. git submodule), note that the main branch does not include built assets, but tagged releases and the build branch do include them. You should not need to build the assets for this plugin as part of your project build process.

Bundling in a theme

You can bundle the plugin in a theme (or anywhere outside of plugins/mu-plugins directories). In order to do this you need to define HM_GB_TOOLS_DIR and HM_GB_TOOLS_URL. For example

define( 'HM_GB_TOOLS_DIR', get_stylesheet_directory() . '/lib/hm-gutenberg-tools' );
define( 'HM_GB_TOOLS_URL', get_stylesheet_directory_uri() . '/lib/hm-gutenberg-tools' );

Using components from HM Gutenberg Tools

You should specify the script hm-gb-tools-editor as a dependency of the script in which you are using it.

wp_enqueue_script( 'my-custom-block', plugins_url( 'my-custom-block.js', dirname(__FILE__) ), [ 'hm-gb-tools-editor' ], '1.0' );

HM Gutenberg Tools then exposes all functionality globally as window.hm. You can then use reference this in your project in much the the same way that you would use any other components from Gutenberg.

const { PostSelectButton } = window.hm.components;

function Edit( { attributes, setAttributes } ) {
    return (
        <PostSelectButton
            value={ attributes.postIds }
            onSelect={ posts => setAttributes( { postIds: posts.map( p => p.id ) } ) }
            postType="page"
            btnProps={ { isLarge: true } }
        >
    );
}

Refer to the Wiki for usage instructions on individual components

Development

  • npm run build Builds a production version of the code.
  • npm run watch Watches for changes and builds development versions of the code.
  • npm run lint Lints your JS. Run npm run lint -- --fix to fix it too.
  • composer run lint Lints your PHP code.

To assist with local development, you can define define( 'HM_GB_TOOLS_DEV', true ); to enable the "HM Gutenberg Tools Dev" block, which includes examples of many of features offered by this plugin.

Releasing a new version.

  1. Update the version numbers in plugin.php and package.json.
  2. Add the changelog to the readme for the new version.
  3. Commit your changes to main and push.
  4. Run the bash script: ./release.sh v1.2.3

The script will sync the the build branch with main, build assets and commit the changes, and publish a new tagged version.

Changelog

v1.7.4

  • Fix post-select endpoint response, where the rendered title should be rendered with get_the_title

v1.7.3

  • Restore built asset files not included in v1.7.2 due to release process error.

v1.7.2

  • Upgraded dependencies for enhanced performance, security and stability.
  • Audit fix dependency upgrade, improving code security.
  • Enhanced security by introducing sanitization for post.title.rendered mitigating XSS attack risks.

v1.7.1

  • Add filter for minimum search length for term select.
  • Add filter for term select query.

v1.7.0

  • Add post status field select.
  • Allow to accept status from the Rest API endpoint.
  • Add status field in the post list item.
  • Update deprecated mediaUpload function.

v1.6.3

  • Ignore sticky posts by default.

v1.6.2

  • Fix date filter label not being cleared when both selected dates are unset.
  • Switch from node-sass to sass and npm audit fix

v1.6.1

  • Reset PostSelect current page when filters are changed

v1.6.0

  • Adds date range filters for use when searching posts

v1.5.0

  • Handle current selections across multiple post types
  • Correctly handle post type filters in post selection modal
  • Preserbe specified Post Type list when clearing Types token list

v1.4.1

  • Adds a filter to allow the post select query to be modified

v1.4.0

  • Support thumbnails in post select components

v1.3.1

  • Switch selection when clicking off single-post selections

v1.1.0

  • Support for i18n.

v1.0.0

  • Refactor how it works for compatability with WordPress 5.0
    • Use core data store
    • Use custom endpoint to fetch content to handle multiple post types.

v0.2.0

  • Deprecate EditableHTML. You can now just use the Gutenberg component wp.editor.RichText and set the format prop to string.
  • Updates to work with the latest version of Gutenberg (3.5).

Releases

7 releases.

Tag
Published
v1.7.4 latest
Apr 13, 2026 6mo ago
Dec 14, 2023 2 years ago
Dec 7, 2023 2 years ago
Dec 7, 2023 2 years ago
Dec 7, 2023 2 years ago
Jul 6, 2023 3 years ago
Jul 6, 2023 3 years ago

These releases are tags only. The author does not attach a packaged zip, so there are no download counts to report.

D+ grade

Security

HM Gutenberg Tools Plugin 1.7.4 · audited by WP Registry

High-severity findings.

1 high 1 medium
Audited release
1.7.4
Findings
2
Worst severity
high
Content hash
b5fbffcf63e6fc80ca41ef50…

Findings

  • high Authenticated (Contributor+) stored XSS in PostControl current-selection titles

    xss_stored

    v1.7.2 added DOMPurify.sanitize around post.title.rendered in the post-select modal (post-list-item.js / selection-item.js) specifically to mitigate XSS. The sidebar CurrentSelection used by window.hm.controls.PostControl was left unsanitized: js/current-selection/components/current-selection.js writes post.title.rendered into a <li> via React dangerouslySetInnerHTML. That component is compiled into build/editor.js (the script always enqueued on enqueue_block_editor_assets). Title HTML comes from GET hm-gb-tools/v1/post-select, where prepare_item_for_response sets title.rendered to get_the_title($post) with no escaping. WordPress does not strip tags from post_title on save, so a Contributor can create a post titled <img src=x onerror=…> (or svg/event-handler markup). innerHTML does not run <script> but does run img/svg event handlers. When an Editor or Administrator uses PostControl (or any block that renders this CurrentSelection) with that post ID in value, the handler executes in wp-admin as the victim. The modal's sibling current-selection (js/post-select/components/current-selection.js) correctly renders the title as a React text child; only the PostControl path is live.

    js/current-selection/components/current-selection.js:19-23

    Recommendation

    Sanitize with DOMPurify.sanitize (same as post-list-item.js) or render the title as a React text node / wp.element.RawHTML after wp.dom.safeHTML. Do not pass get_the_title() HTML to innerHTML. Apply the same treatment anywhere title.rendered is assigned to __html in build/editor.js.

  • medium Post-select REST endpoint lists others' drafts/private posts for any edit_posts user

    information_disclosure

    GET /hm-gb-tools/v1/post-select is permission-checked only with current_user_can('edit_posts'). That is true for Contributor and Author, who in core cannot read other users' drafts or any private posts (read_post/edit_post meta caps deny it; WP_REST_Posts_Controller::get_items skips rows failing check_read_permission). This controller does not. get_items() puts $request->get_param('status') straight into WP_Query['post_status'] (default publish). PROP_STATUS is never registered in get_collection_params(), so there is no enum/capability sanitize — but WP_REST_Request::get_param still returns the query-string value, including arrays from the UI status filter (browse-filters.js always exposes get_post_stati(internal=false): draft, pending, private, future, publish) and crafted values such as any or trash. post_type defaults to every show_in_rest type except attachment (pages, wp_block, wp_template, …) after sanitize_post_types; a Contributor who cannot edit_pages can still query type[]=page. Results are returned in full (id, title.raw/rendered, slug, link, author, date, status, type, thumbnail) with no per-post current_user_can('read_post'). Observable from post-new.php with the localized wp_rest nonce: /wp-json/hm-gb-tools/v1/post-select?status=private&status=draft&type[]=post&type[]=page&per_page=100.

    inc/endpoints/class-post-select-controller.php:85-153

    Recommendation

    Register status in get_collection_params with an allow-list. For any non-public status require the post type's edit_posts cap (edit_pages for pages, etc.). After WP_Query, drop posts the user cannot current_user_can('read_post', $post->ID) (same as WP_REST_Posts_Controller::check_read_permission). Do not accept status=any/trash without an explicit extra capability.

WP Registry hashes the installable build and reports on that exact bytes-for-bytes copy. Embargoed findings are withheld until they are disclosed, so a clean verdict means nothing public is outstanding. WP Manifest does not audit code itself.