How to edit post meta outside of a Gutenberg Block?

The Block API of Gutenberg supports post meta as a attribute source. But what if you want to use post meta in say a plugin sidebar?

With the help of the @wordpress/data package and so called “higher-order components” it’s as easy as for blocks. 🙌

First we import all the required dependencies. This assumes that you’re using webpack and define your externals like this.

/**
 * WordPress dependencies
 */
import {
	withSelect,
	withDispatch,
} from '@wordpress/data';
import {
	PluginSidebar,
	PluginSidebarMoreMenuItem,
} from '@wordpress/edit-post';
import {
	PanelColor,
} from '@wordpress/editor';
import {
	Component,
	Fragment,
	compose,
} from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { registerPlugin } from '@wordpress/plugins';

To render the UI we extend Component and implement the render() method. For this example I used a PanelColor component which allows a user to select a color. We’ll save the hex value in the post meta my_color_one:

/**
 * Custom component with a simple color panel.
 */
class MyPlugin extends Component {

	render() {
		// Nested object destructuring.
		const {
			meta: {
				my_color_one: colorOne,
			} = {},
			updateMeta,
		} = this.props;

		return (
			<Fragment>
				<PluginSidebarMoreMenuItem
					name="my-plugin-sidebar"
					type="sidebar"
					target="my-plugin-sidebar"
				>
					{ __( 'Color it!', 'my-plugin' ) }
				</PluginSidebarMoreMenuItem>
				<PluginSidebar
					name="my-plugin-sidebar"
					title={ __( 'Color it!', 'my-plugin' ) }
				>
					<PanelColor
						colorValue={ colorOne}
						initialOpen={ false }
						title={ __( 'Color 1', 'my-plugin' ) }
						onChange={ ( value ) => {
							// value is undefined if color is cleared.
							updateMeta( { my_color_one: value || '' } );
						} }
					/>
				</PluginSidebar>
			</Fragment>
		);
	}
}

(Please ignore the incorrect syntax highlighting.)

Now we need a higher-order component which is used to fetch the data, in this case our post meta.

// Fetch the post meta.
const applyWithSelect = withSelect( ( select ) => {
	const { getEditedPostAttribute } = select( 'core/editor' );

	return {
		meta: getEditedPostAttribute( 'meta' ),
	};
} );

The second higher-order component is used to update the data.

// Provide method to update post meta.
const applyWithDispatch = withDispatch( ( dispatch, { meta } ) => {
	const { editPost } = dispatch( 'core/editor' );

	return {
		updateMeta( newMeta ) {
			editPost( { meta: { ...meta, ...newMeta } } ); // Important: Old and new meta need to be merged in a non-mutating way!
		},
	};
} );

Since we now have two higher-order components we have to combine them with compose:

// Combine the higher-order components.
const render = compose( [
	applyWithSelect,
	applyWithDispatch
] )( MyPlugin );

Having a fully renderable component we can finally register our custom plugin:

registerPlugin( 'my-plugin', {
	icon: 'art',
	render,
} );

And that’s it! 🚢

PS: Make sure to register the post meta properly with 'show_in_rest' => true.


Photo by Kimberly Farmer.

My Sublime Text 3 Packages

I hate Java. I hate Java IDEs. They’re slow and bloated. I really want to give JetBrains PhpStorm a chance, but they lost me on the settings screen.

I use Sublime Text 3. It’s fast as hell. And thanks to Package Control you can build your own development environment. Even though it’s just a text editor.

An overview of the packages I use:

  • Alignment: A simple key-binding for aligning multi-line and multiple selections.
  • ApacheConf: Syntax highlighting for Apache configuration files.
  • Autoprefixer: You shouldn’t have to care about vendor prefixes.
  • Case Conversion: Convert a word between pascal, camel, snake, dot, dash (hyphen) cases.
  • DocBlockr: Makes writing documentation a breeze.
  • EditorConfig: Helps to maintain coding styles per project, see EditorConfig.
  • Emmet: Ultra-fast coding.
  • FileDiffs: Lets you compare two tabs for diffs.
  • HTML5: HTML5 snippets.
  • jQuery: Syntax highlighting for jQuery, includes also snippets.
  • La​Te​XTools: Not just development, I write my thesis with Sublime too!
  • nginx: Syntax highlighting for Nginx configuration files.
  • Sass: Syntax highlighting for Sass files.
  • rsub: One of three simple (one-time) steps to get the subl command working on your remote server.
  • Side​Bar​Enhancements: Improves the context menu with entries like new file/folder, rename, move, copy, refresh etc.
  • Sublime​Linter: The framework for linters.
  • SublimeLinter-jshint: Lints your JavaScript files with JSHint.
  • SublimeLinter-php: Lints your PHP files with php -l.
  • SublimeLinter-phpcs: Lints your PHP files with Code Sniffer. (Rules for WordPress coding standards)

Sublime supports custom themes too. I’m using the Spacegray theme.

Continue reading My Sublime Text 3 Packages