Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async load business hours and blogging prompt blocks #32256

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions projects/packages/blocks/changelog/add-blocks-metadata-file
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: added

Allow block registration with path to metadata file
7 changes: 4 additions & 3 deletions projects/packages/blocks/src/class-blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ class Blocks {
* @type array $version_requirements Array containing required Gutenberg version and, if known, the WordPress version that was released with this minimum version.
* @type bool $plan_check Should we check for a specific plan before registering the block.
* }
* @param string $metadata_dir Directory where the block's metadata is located.
*
* @return WP_Block_Type|false The registered block type on success, or false on failure.
*/
public static function jetpack_register_block( $slug, $args = array() ) {
public static function jetpack_register_block( $slug, $args = array(), $metadata_dir = '' ) {
if ( 0 !== strpos( $slug, 'jetpack/' ) && ! strpos( $slug, '/' ) ) {
_doing_it_wrong( 'jetpack_register_block', 'Prefix the block with jetpack/ ', 'Jetpack 9.0.0' );
$slug = 'jetpack/' . $slug;
Expand Down Expand Up @@ -94,12 +95,12 @@ function () use ( $feature_name, $method_name ) {

// Ensure editor styles are registered so that the site editor knows about the
// editor style dependency when copying styles to the editor iframe.
if ( ! isset( $args['editor_style'] ) ) {
if ( ! isset( $args['editor_style'] ) && ! $metadata_dir ) {
$args['editor_style'] = 'jetpack-blocks-editor';
}
}

return register_block_type( $slug, $args );
return register_block_type( $metadata_dir ? $metadata_dir : $slug, $args );
}

/**
Expand Down
4 changes: 4 additions & 0 deletions projects/plugins/jetpack/changelog/add-blocks-metadata-file
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: enhancement

Add metadata file to blogging-prompt and business-hours blocks
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "jetpack/blogging-prompt",
"title": "Writing Prompt",
"description": "Answer a new and inspiring writing prompt each day.",
"keywords": [ "writing", "blogging" ],
"version": "12.5.0",
"textdomain": "jetpack",
"category": "text",
"supports": {
"align": false,
"alignWide": false,
"anchor": false,
"className": true,
"color": {
"background": true,
"gradients": true,
"link": true,
"text": true
},
"customClassName": true,
"html": false,
"inserter": true,
"multiple": false,
"reusable": true,
"spacing": {
"margin": [ "top", "bottom" ],
"padding": true,
"blockGap": false
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,15 @@
*/
function register_block() {
if ( ( defined( 'IS_WPCOM' ) && IS_WPCOM ) || \Jetpack::is_connection_ready() ) {
$dir = dirname( JETPACK__PLUGIN_FILE );
$json_dir = $dir . '/_inc/blocks/' . FEATURE_NAME;

Blocks::jetpack_register_block(
BLOCK_NAME,
array( 'render_callback' => __NAMESPACE__ . '\load_assets' )
array(
'render_callback' => __NAMESPACE__ . '\load_assets',
),
$json_dir
);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "jetpack/business-hours",
"title": "Business Hours",
"description": "Display opening hours for your business.",
"keywords": [ "opening hours", "closing time", "schedule", "working day" ],
"version": "12.5.0",
"textdomain": "jetpack",
"category": "grow",
"supports": {
"html": true,
"color": {
"gradients": true
},
"spacing": {
"margin": true,
"padding": true
},
"typography": {
"fontSize": true,
"lineHeight": true
},
"align": [ "wide", "full" ]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,15 @@
* registration if we need to.
*/
function register_block() {
$dir = dirname( JETPACK__PLUGIN_FILE );
$json_dir = $dir . '/_inc/blocks/' . FEATURE_NAME;

Blocks::jetpack_register_block(
BLOCK_NAME,
array(
'render_callback' => __NAMESPACE__ . '\render',
'supports' => array(
'color' => array(
'gradients' => true,
),
'spacing' => array(
'margin' => true,
'padding' => true,
),
'typography' => array(
'fontSize' => true,
'lineHeight' => true,
),
'align' => array( 'wide', 'full' ),
),
)
),
$json_dir
);
}
add_action( 'init', __NAMESPACE__ . '\register_block' );
Expand Down
10 changes: 10 additions & 0 deletions projects/plugins/jetpack/extensions/bundles.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"name": "first-bundle",
"title": "First Bundle",
"description": "This is a proof of concept",
"blocks": [ "blogging-prompt" ],
"version": "1.0.0"
},
"business-hours"
]
155 changes: 129 additions & 26 deletions projects/plugins/jetpack/tools/webpack.config.extensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,42 +20,60 @@ const viewSetup = path.join( __dirname, '../extensions', 'view' );
const blockEditorDirectories = [ 'plugins', 'blocks' ];
const noop = function () {};

/**
* Filters block editor scripts
*
* @param {string} type - script type
* @param {string} inputDir - input directory
* @param {Array} presetBlocks - preset blocks
* @returns {Array} list of block scripts
*/
function presetProductionExtensions( type, inputDir, presetBlocks ) {
return presetBlocks
.flatMap( block =>
blockEditorDirectories.map( dir => path.join( inputDir, dir, block, `${ type }.js` ) )
)
.filter( fs.existsSync );
}

const presetPath = path.join( __dirname, '../extensions', 'index.json' );
const presetIndex = require( presetPath );
const presetProductionBlocks = presetIndex.production || [];
const presetNoPostEditorBlocks = presetIndex[ 'no-post-editor' ] || [];

const presetExperimentalBlocks = [
...presetProductionBlocks,
...( presetIndex.experimental || [] ),
];
// Beta Blocks include all blocks: beta, experimental, and production blocks.
const presetBetaBlocks = [ ...presetExperimentalBlocks, ...( presetIndex.beta || [] ) ];

// Bundled blocks are built individually or grouped together in bundles.
const bundlesPath = path.join( __dirname, '../extensions', 'bundles.json' );
const bundlesIndex = require( bundlesPath );
const bundles = bundlesIndex || [];
const bundledBlocks = bundles
.reduce(
( blocks, bundle ) =>
'string' === typeof bundle ? [ ...blocks, bundle ] : [ ...blocks, ...bundle.blocks ],
[]
)
.filter( Boolean );

/**
* Filters block editor scripts
*
* @param {string} type - script type
* @param {string} inputDir - input directory
* @param {Array} presetBlocks - preset blocks
* @returns {Array} list of block scripts
*/
function presetProductionExtensions( type, inputDir, presetBlocks ) {
return (
presetBlocks
// Exclude blocks that are bundled separately from the production/experimental/beta bundles.
.filter( block => ! bundledBlocks.includes( block ) )
.flatMap( block =>
blockEditorDirectories.map( dir => path.join( inputDir, dir, block, `${ type }.js` ) )
)
.filter( fs.existsSync )
);
}

// Helps split up each block into its own folder view script
const viewBlocksScripts = presetBetaBlocks.reduce( ( viewBlocks, block ) => {
const viewScriptPath = path.join( __dirname, '../extensions/blocks', block, 'view.js' );
if ( fs.existsSync( viewScriptPath ) ) {
viewBlocks[ block + '/view' ] = [ viewSetup, ...[ viewScriptPath ] ];
}
return viewBlocks;
}, {} );
const viewBlocksScripts = presetBetaBlocks
// Exclude blocks that are bundled separately from the production/experimental/beta bundles.
.filter( block => ! bundledBlocks.includes( block ) )
.reduce( ( viewBlocks, block ) => {
const viewScriptPath = path.join( __dirname, '../extensions/blocks', block, 'view.js' );
if ( fs.existsSync( viewScriptPath ) ) {
viewBlocks[ block + '/view' ] = [ viewSetup, ...[ viewScriptPath ] ];
}
return viewBlocks;
}, {} );

// Combines all the different production blocks into one editor.js script
const editorScript = [
Expand Down Expand Up @@ -170,8 +188,78 @@ const sharedWebpackConfig = {
},
};

// We export two configuration files: One for admin.js, and one for components.jsx.
// The latter produces pre-rendered components HTML.
/**
* Bundles logic
*/

const bundlesEntry = {};
const bundlesPlugins = [];

bundles.forEach( bundle => {
const name = 'string' === typeof bundle ? bundle : bundle.name;
const blocks = 'string' === typeof bundle ? [ bundle ] : bundle.blocks;

// Bundle editor assets
bundlesEntry[ name + '/editor' ] = blocks.reduce( ( arr, block ) => {
const editorScriptPath = path.join( __dirname, '../extensions/blocks', block, 'editor.js' );

if ( fs.existsSync( editorScriptPath ) ) {
arr.push( editorScriptPath );
}

return arr;
}, [] );

// Bundle view assets
bundlesEntry[ name + '/view' ] = blocks.reduce( ( arr, block ) => {
const viewScriptPath = path.join( __dirname, '../extensions/blocks', block, 'view.js' );

if ( fs.existsSync( viewScriptPath ) ) {
arr.push( viewScriptPath );
}

return arr;
}, [] );

// Copy block.json files and set assets paths
blocks.forEach( block => {
bundlesPlugins.push(
new CopyWebpackPlugin( {
patterns: [
{
from: `${ block }/block.json`,
to: `${ block }/[path][name][ext]`,
context: path.join( __dirname, '../extensions/blocks' ),
transform( content ) {
let metadata = {};

try {
metadata = JSON.parse( content.toString() );
} catch ( e ) {}

return JSON.stringify( {
...metadata,
editorScript: `file:../${ name }/editor.js`,
editorStyle: `file:../${ name }/editor.css`,
viewScript: `file:../${ name }/view.js`,
style: `file:../${ name }/view.css`,
} );
},
noErrorOnMissing: true,
},
],
} )
);
} );
} );

const bundlesConfig = {
...sharedWebpackConfig,
entry: bundlesEntry,
plugins: [ ...sharedWebpackConfig.plugins, ...bundlesPlugins ],
};

// We export three configuration files: One for admin.js, one for components.jsx (produces pre-rendered components HTML), and one for bundles.
module.exports = [
{
...sharedWebpackConfig,
Expand All @@ -192,6 +280,20 @@ module.exports = [
},
],
} ),
// Copy the block.json files to the matching block folder in the build directory.
new CopyWebpackPlugin( {
patterns: [
{
from: '**/block.json',
to: '[path][name][ext]',
context: path.join( __dirname, '../extensions/blocks' ),
globOptions: {
ignore: bundledBlocks.map( block => `**/${ block }/**` ),
},
noErrorOnMissing: true,
},
],
} ),
new CopyBlockEditorAssetsPlugin(),
],
},
Expand Down Expand Up @@ -268,4 +370,5 @@ module.exports = [
} ),
],
},
bundlesConfig,
];