This directory contains the source code for extensions in the block editor, also known as Gutenberg, that was introduced in WordPress 5.0.
We define different types of block editor extensions:
- Blocks are available in the editor itself.
- Plugins are available in the Jetpack sidebar that appears on the right side of the block editor.
Extensions in the extensions/blocks
folder loosely follow this structure:
.
└── block-or-plugin-name/
├── block-or-plugin-name.php ← PHP file where the block and its assets are registered.
├── editor.js ← script loaded only in the editor
├── editor.scss ← styles loaded only in the editor
├── view.js ← script loaded on the frontend
└── view.scss ← styles loaded on the frontend
If your block depends on another block, place them all in extensions folder:
.
├── block-name/
└── sub-blockname/
- Use the Jetpack Docker environment.
- Start a new branch.
- Add your new extension's source files to the extensions/blocks directory.
And add your extensions' slug to the beta array in
extensions/index.json
. You can use Jetpack-CLI command to scaffold the block (see below). By keeping your extension in the beta array, it's safe to do small PRs and merge frequently. - Or modify existing extensions in the same folder.
- Run
yarn build-extensions [--watch]
to compile your changes. - Now test your changes in your Docker environment's wp-admin.
- Open a PR, and a WordPress.com diff will be automatically generated with your changes.
- Test the WordPress.com diff
- Once the code works well in both environments and has been approved by a Jetpack crew member, you can merge your branch!
- When your block is ready to be shipped, move your extensions' slug from beta to production array in
extensions/index.json
Generally, all new extensions should start out as a beta.
- Before you develop, remember to add your extension's slug to the beta array in
extensions/index.json
. - In the
wp-config.php
for your Docker environment (docker/wordpress/wp-config.php
) or in your custom mu-plugins file (docker/mu-plugins/yourfile.php
), enable beta extensions with the following snippet:define( 'JETPACK_BETA_BLOCKS', true );
- When you use this constant, you'll get all blocks: Beta blocks, Experimental blocks, and Production blocks.
- In the WordPress.com environment, Automatticians will be able to see beta extensions with no further configuration
- In a Jurassic Ninja site, you must go to Settings > Jetpack Constants, and enable the
JETPACK_BETA_BLOCKS
option there. - Once you've successfully beta tested your new extension, you can open new PR to make your extension live!
- Simply move the extension's slug out of the beta array and into the production array in
extensions/index.json
.
We also offer an "experimental" state for extensions. Those extensions will be made available to anyone having the JETPACK_EXPERIMENTAL_BLOCKS
constant defined in wp-config.php
. When you use this constant, you'll get Experimental blocks as well as Production blocks.
Experimental extensions are usually considered ready for production, but are served only to sites requesting them.
We have a command in WP-CLI that allows to scaffold Jetpack blocks. Its syntax is as follows:
wp jetpack scaffold <type> <title> [--slug] [--description] [--keywords] [--variation]
Currently the only type
is block
.
- title: Block name, also used to create the slug. This parameter is required. If it's something like Logo gallery, the slug will be
logo-gallery
. It's also used to generate the class name when an external edit component is requested. Following this example, it would beLogoGalleryEdit
. - --slug: Specific slug to identify the block that overrides the one generated base don the title.
- --description: Allows to provide a text description of the block.
- --keywords: Provide up to three keywords separated by a comma so users when they search for a block in the editor.
- --variation: Allows to decide whether the block should be a production block, experimental, or beta. Defaults to Beta when arg not provided.
All files will be created in a directory under extensions/blocks/
named after the block title or a specific given slug. For a hypothetical Jukebox block, it will create the following files
extensions/blocks/jukebox/
extensions/blocks/jukebox/jukebox.php
extensions/blocks/jukebox/index.js
extensions/blocks/jukebox/editor.js
extensions/blocks/jukebox/editor.scss
extensions/blocks/jukebox/edit.js
Additionally, the slug of the new block will be added to the beta
array in the file extensions/index.json
.
Since it's added to the beta array, you need to load the beta blocks as explained above to be able to test this block.
wp jetpack scaffold block "Cool Block"
wp jetpack scaffold block "Amazing Rock" --slug="good-music" --description="Rock the best music on your site"
wp jetpack scaffold block "Jukebox" --keywords="music, audio, media"
wp jetpack scaffold block "Jukebox" --variation="experimental"
Run yarn test-extensions [--watch]
to run tests written in Jest.
Note that adding Jest snapshot tests for block's save
methods is problematic because many core packages relying on window
that is not present when testing with Jest. See prior exploration.
Yes! Just like any other changes in Jetpack, also blocks work in Jurassic Ninja.
Simply add branch name to the URL: jurassic.ninja/create/?jetpack-beta&branch=master or use other ninjastic features.
- Jetpack is released once a month, so be sure your team is aware of upcoming code freezes.
- Make sure you and your team have tested your PR in both the Jetpack environment, and the WordPress.com environment.
- Additionally, your PR will require approval from a Jetpack crew member.
- Once merged, your extension will appear in the next release.
- Merge to Jetpack master first.
- Now, merge the auto-generated diff on WordPress.com.
- There's no need to wait on release schedules, in fact it is best if you merge your WordPress.com diff immediately after you've merged to Jetpack master.
You can build extensions from the Jetpack folder to your local sandbox folder and sync the whole sandbox like you always do:
yarn clean-extensions
yarn build-extensions \
--output-path /PATH_TO_YOUR_SANDBOX/wp-content/mu-plugins/jetpack/_inc/blocks/ \
--watch
Alternatively, if you don’t need to touch PHP files, you can build extensions in the Jetpack folder without --output-path and use rsync to push files directly to your sandbox:
rsync -az --delete _inc/blocks/ \
YOUR_WPCOM_SANDBOX:/BLOCKS_PATH_IN_YOUR_SANDBOX/
To test extensions for a Simple site in Calypso, sandbox the simple site URL (example.wordpress.com
). Calypso loads Gutenberg from simple sites’ wp-admin in an iframe.
- Compiled extensions are output to
_inc/blocks
- You can view the various build commands in
package.json
- You can see the build configuration in
webpack.config.extensions.js
If you need to modify the build process, bear in mind that config files are also synced to WordPress.com via Fusion. Consult with a Jetpack crew member to ensure you test the new build in both environments.
Setting these might be useful for debugging with block editor:
define( 'SCRIPT_DEBUG', true );
define( 'GUTENBERG_DEVELOPMENT_MODE', true );
You could modify SCRIPT_DEBUG
from docker/wordpress/wp-config.php
in your Docker environment and add GUTENBERG_DEVELOPMENT_MODE
there as well, or in your custom mu-plugins file (docker/mu-plugins/yourfile.php
).
G Debugger plugin might come handy, too.
The build takes care of core dependencies for both editor and view scripts. React, Lodash and @wordpress/*
dependencies are externalized and automatically enqueued in PHP for your extension.
Extensions always get Gutenberg's polyfill scripts enqueued so you can safely use methods not supported by older browsers such as IE11.
Jetpack adds its own plugin sidebar to the block editor. You can find it by choosing "Jetpack" from block the editor's ellipsis menu or by pressing the Jetpack icon in the "pinned plugins" toolbar.
The sidebar itself is always registered in the editor and populated using the Slot Fill mechanism.
Use the JetpackPluginSidebar
component to render from anywhere in your plugin's code:
import JetpackPluginSidebar from '../../shared/jetpack-plugin-sidebar';
<JetpackPluginSidebar>
<PanelBody title={ __( 'My sidebar section', 'jetpack' ) }>
<p>Jetpack is Bestpack!</p>
</PanelBody>
</JetpackPluginSidebar>
The sidebar won't show up at all if nothing is being rendered in the sidebar's "slot".
Remember to be mindful of what post types you want to enable your sidebar section for: e.g. posts, pages, custom post types, and re-usable block post type (/wp-admin/edit.php?post_type=wp_block
).
See Publicize and Shortlinks for examples how to limit functionality only to some specific post types or posts. The Likes & Sharing extensions are a great example of how to output content from several extensions to one sidebar section using "slots".
As of 04/2019, wp.i18n
doesn't support React elements in strings. You will have to structure your copy so that links and other HTML can be translated separately.
Not possible:
__( 'Still confused? Check out <a>documentation</a> for more!' )
Possible:
{ __( 'Still confused?' ) } <a>{ __( 'Check out documentation for more!' ) }</a>
To stay consistent with Gutenberg, your extensions should follow Gutenberg styles and visuals.
Use Gutenberg color variables where possible by importing extensions/shared/styles/gutenberg-base-styles.scss
, which in turn imports all variables and mixins published in @wordpress/base-styles
package.
The build pipeline also supports Color studio via SASS variables ($studio-pink-50
) and CSS custom properties (var( --studio-pink-50 )
) without specifically importing them first. Prefer CSS custom properties when possible.
Please use outline versions of Material icons to stay in line with Gutenberg. Don't rely on icons used in WordPress core to avoid visual mixing up with core blocks.