From cf357cfa596a36030e6d2e0cba105d7d16cc2d2f Mon Sep 17 00:00:00 2001 From: Sagar Jadhav Date: Wed, 11 Mar 2026 16:24:16 +0530 Subject: [PATCH 1/2] Add: Based Block Structure --- assets/src/blocks/example-block/block.json | 8 +++ assets/src/blocks/example-block/edit.js | 5 ++ assets/src/blocks/example-block/editor.css | 5 ++ assets/src/blocks/example-block/index.js | 9 +++ assets/src/blocks/example-block/save.js | 5 ++ assets/src/blocks/example-block/style.css | 4 ++ inc/classes/class-assets.php | 28 ++++++++++ package-lock.json | 65 +++++++++++++++++++++- package.json | 5 +- webpack.config.js | 64 +++++++++++++-------- 10 files changed, 173 insertions(+), 25 deletions(-) create mode 100644 assets/src/blocks/example-block/block.json create mode 100644 assets/src/blocks/example-block/edit.js create mode 100644 assets/src/blocks/example-block/editor.css create mode 100644 assets/src/blocks/example-block/index.js create mode 100644 assets/src/blocks/example-block/save.js create mode 100644 assets/src/blocks/example-block/style.css diff --git a/assets/src/blocks/example-block/block.json b/assets/src/blocks/example-block/block.json new file mode 100644 index 0000000..c0fac41 --- /dev/null +++ b/assets/src/blocks/example-block/block.json @@ -0,0 +1,8 @@ +{ + "apiVersion": 3, + "name": "elementary/example-block", + "title": "Example Block", + "category": "widgets", + "editorScript": "file:../../build/js/blocks/example-block/index.js", + "style": "file:../../build/css/blocks/example-block.css" +} diff --git a/assets/src/blocks/example-block/edit.js b/assets/src/blocks/example-block/edit.js new file mode 100644 index 0000000..f525e4e --- /dev/null +++ b/assets/src/blocks/example-block/edit.js @@ -0,0 +1,5 @@ +import { useBlockProps } from '@wordpress/block-editor'; + +export default function Edit() { + return
Example Block
; +} diff --git a/assets/src/blocks/example-block/editor.css b/assets/src/blocks/example-block/editor.css new file mode 100644 index 0000000..6df36bc --- /dev/null +++ b/assets/src/blocks/example-block/editor.css @@ -0,0 +1,5 @@ +.wp-block-elementary-example-block { + padding: 16px; + border: 1px dashed #ccc; + background: #f7f7f7; +} diff --git a/assets/src/blocks/example-block/index.js b/assets/src/blocks/example-block/index.js new file mode 100644 index 0000000..7d10d6a --- /dev/null +++ b/assets/src/blocks/example-block/index.js @@ -0,0 +1,9 @@ +import { registerBlockType } from '@wordpress/blocks'; +import Edit from './edit'; +import save from './save'; +import metadata from './block.json'; + +registerBlockType(metadata.name, { + edit: Edit, + save, +}); diff --git a/assets/src/blocks/example-block/save.js b/assets/src/blocks/example-block/save.js new file mode 100644 index 0000000..c2abb06 --- /dev/null +++ b/assets/src/blocks/example-block/save.js @@ -0,0 +1,5 @@ +import { useBlockProps } from '@wordpress/block-editor'; + +export default function save() { + return
Example Block
; +} diff --git a/assets/src/blocks/example-block/style.css b/assets/src/blocks/example-block/style.css new file mode 100644 index 0000000..01e6b12 --- /dev/null +++ b/assets/src/blocks/example-block/style.css @@ -0,0 +1,4 @@ +.wp-block-elementary-example-block { + padding: 16px; + border: 1px solid #ddd; +} diff --git a/inc/classes/class-assets.php b/inc/classes/class-assets.php index 18bca00..9dfd85a 100644 --- a/inc/classes/class-assets.php +++ b/inc/classes/class-assets.php @@ -32,6 +32,7 @@ protected function __construct() { * @since 1.0.0 */ public function setup_hooks() { + add_action( 'init', [ $this, 'register_blocks' ] ); add_action( 'wp_enqueue_scripts', [ $this, 'register_assets' ] ); add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_assets' ] ); add_filter( 'render_block', [ $this, 'enqueue_block_specific_assets' ], 10, 2 ); @@ -169,4 +170,31 @@ public function get_file_version( $file, $ver = false ) { public function enqueue_assets() { wp_enqueue_style( 'elementary-theme-styles' ); } + + /** + * Register theme blocks. + * + * @since 1.0.0 + * + * @return void + */ + public function register_blocks() { + + $blocks_dir = ELEMENTARY_THEME_TEMP_DIR . '/assets/build/blocks'; + + // print_r( $blocks_dir ); + // exit; + + if ( ! is_dir( $blocks_dir ) ) { + return; + } + + // List all subdirectories in 'inc/blocks' directory. + $blocks = array_filter( glob( $blocks_dir . '/*' ), 'is_dir' ); + + // Register each block. + foreach ( $blocks as $block ) { + register_block_type( $block ); + } + } } diff --git a/package-lock.json b/package-lock.json index 0bc763d..9e27bd5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,8 @@ "jest-silent-reporter": "0.6.0", "lint-staged": "16.3.0", "npm-run-all": "4.1.5", - "webpack-remove-empty-scripts": "1.1.1" + "webpack-remove-empty-scripts": "1.1.1", + "webpack-watched-glob-entries-plugin": "3.2.0" } }, "node_modules/@ampproject/remapping": { @@ -32202,6 +32203,68 @@ "node": ">=10.13.0" } }, + "node_modules/webpack-watched-glob-entries-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/webpack-watched-glob-entries-plugin/-/webpack-watched-glob-entries-plugin-3.2.0.tgz", + "integrity": "sha512-XAzGyRBUqQxkA4ZLE71/nDxMrN34aCC2RKloLai4S3uhNT7le8ZuGvlWAms0sWf4hb1VJ6ODMqvznenA2i1oCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^13.0.6", + "glob-parent": ">=6.0.2" + }, + "engines": { + "node": ">=18.0.0 <=25" + }, + "optionalDependencies": { + "fsevents": "^2.3.3" + } + }, + "node_modules/webpack-watched-glob-entries-plugin/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/webpack-watched-glob-entries-plugin/node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/webpack-watched-glob-entries-plugin/node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", diff --git a/package.json b/package.json index 92285bf..65d680f 100644 --- a/package.json +++ b/package.json @@ -45,11 +45,14 @@ "jest-silent-reporter": "0.6.0", "lint-staged": "16.3.0", "npm-run-all": "4.1.5", - "webpack-remove-empty-scripts": "1.1.1" + "webpack-remove-empty-scripts": "1.1.1", + "webpack-watched-glob-entries-plugin": "3.2.0" }, "scripts": { "build:dev": "cross-env NODE_ENV=development npm-run-all 'build:!(dev|prod)'", "build:prod": "cross-env NODE_ENV=production npm-run-all 'build:!(dev|prod)'", + "build:blocks": "wp-scripts build --webpack-copy-php --config ./node_modules/@wordpress/scripts/config/webpack.config.js --source-path=./assets/src/blocks --output-path=./assets/build/blocks", + "start:blocks": "wp-scripts start --webpack-copy-php --config ./node_modules/@wordpress/scripts/config/webpack.config.js --webpack-src-dir=./assets/src/blocks/ --output-path=./assets/build/blocks/", "build:js": "wp-scripts build --experimental-modules", "init": "./bin/init.js", "lint:all": "npm-run-all --parallel lint:*", diff --git a/webpack.config.js b/webpack.config.js index 9e37796..50c188f 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -5,34 +5,30 @@ const fs = require( 'fs' ); const path = require( 'path' ); const CssMinimizerPlugin = require( 'css-minimizer-webpack-plugin' ); const RemoveEmptyScriptsPlugin = require( 'webpack-remove-empty-scripts' ); +const WebpackWatchedGlobEntries = require( 'webpack-watched-glob-entries-plugin' ); /** * WordPress dependencies */ -const [ scriptConfig, moduleConfig ] = require( '@wordpress/scripts/config/webpack.config' ); +const [scriptConfig, moduleConfig] = require('@wordpress/scripts/config/webpack.config'); /** * Read all file entries in a directory. - * @param {string} dir Directory to read. - * @return {Object} Object with file entries. */ -const readAllFileEntries = ( dir ) => { +const readAllFileEntries = (dir) => { const entries = {}; - if ( ! fs.existsSync( dir ) ) { + if (!fs.existsSync(dir)) { return entries; } - if ( fs.readdirSync( dir ).length === 0 ) { - return entries; - } + fs.readdirSync(dir).forEach((fileName) => { + const fullPath = `${dir}/${fileName}`; - fs.readdirSync( dir ).forEach( ( fileName ) => { - const fullPath = `${ dir }/${ fileName }`; - if ( ! fs.lstatSync( fullPath ).isDirectory() && ! fileName.startsWith( '_' ) ) { - entries[ fileName.replace( /\.[^/.]+$/, '' ) ] = fullPath; + if (!fs.lstatSync(fullPath).isDirectory() && !fileName.startsWith('_')) { + entries[fileName.replace(/\.[^/.]+$/, '')] = fullPath; } - } ); + }); return entries; }; @@ -66,35 +62,57 @@ const sharedConfig = { }, }; -// Generate a webpack config which includes setup for CSS extraction. -// Look for css/scss files and extract them into a build/css directory. +// CSS build const styles = { ...sharedConfig, - entry: () => readAllFileEntries( './assets/src/css' ), - module: { - ...sharedConfig.module, + entry: WebpackWatchedGlobEntries.getEntries( + [ + path.resolve( __dirname, `assets/src/css/*.scss` ), + ], + { + ignore: [ + path.resolve( __dirname, `assets/src/css/**/_*.scss` ), + ], + }, + ), + output: { + ...sharedConfig.output, + path: path.resolve( process.cwd(), 'assets', 'build', 'css' ), }, plugins: [ ...sharedConfig.plugins.filter( - ( plugin ) => plugin.constructor.name !== 'DependencyExtractionWebpackPlugin', + ( plugin ) => { + return plugin.constructor.name !== 'DependencyExtractionWebpackPlugin' && plugin.constructor.name !== 'CopyPlugin'; + }, ), ], - }; +// JS build const scripts = { ...sharedConfig, entry: { - 'core-navigation': path.resolve( process.cwd(), 'assets', 'src', 'js', 'core-navigation.js' ), + ...sharedConfig.entry(), + ...WebpackWatchedGlobEntries.getEntries( + [ + path.resolve( __dirname, `assets/src/js/*.js` ), + ], + { + ignore: [ + path.resolve( __dirname, `assets/src/js/_*.js` ), + ], + }, + )(), }, }; +// module scripts. const moduleScripts = { ...moduleConfig, - entry: () => readAllFileEntries( './assets/src/js/modules' ), + entry: () => readAllFileEntries('./assets/src/js/modules'), output: { ...moduleConfig.output, - path: path.resolve( process.cwd(), 'assets', 'build', 'js', 'modules' ), + path: path.resolve(process.cwd(), 'assets', 'build', 'js', 'modules'), filename: '[name].js', chunkFilename: '[name].js', }, From fc881e7e9ec1296beb2cd49c66fdf2696d5eafd3 Mon Sep 17 00:00:00 2001 From: Sagar Jadhav Date: Wed, 11 Mar 2026 16:46:44 +0530 Subject: [PATCH 2/2] Add: Based Block Structure --- assets/src/blocks/example-block/block.json | 5 +++-- assets/src/blocks/example-block/{editor.css => editor.scss} | 0 assets/src/blocks/example-block/index.js | 3 +++ assets/src/blocks/example-block/{style.css => style.scss} | 0 4 files changed, 6 insertions(+), 2 deletions(-) rename assets/src/blocks/example-block/{editor.css => editor.scss} (100%) rename assets/src/blocks/example-block/{style.css => style.scss} (100%) diff --git a/assets/src/blocks/example-block/block.json b/assets/src/blocks/example-block/block.json index c0fac41..7ecff80 100644 --- a/assets/src/blocks/example-block/block.json +++ b/assets/src/blocks/example-block/block.json @@ -3,6 +3,7 @@ "name": "elementary/example-block", "title": "Example Block", "category": "widgets", - "editorScript": "file:../../build/js/blocks/example-block/index.js", - "style": "file:../../build/css/blocks/example-block.css" + "editorScript": "file:./index.js", + "editorStyle": "file:./index.css", + "style": "file:./style-index.css" } diff --git a/assets/src/blocks/example-block/editor.css b/assets/src/blocks/example-block/editor.scss similarity index 100% rename from assets/src/blocks/example-block/editor.css rename to assets/src/blocks/example-block/editor.scss diff --git a/assets/src/blocks/example-block/index.js b/assets/src/blocks/example-block/index.js index 7d10d6a..fda8258 100644 --- a/assets/src/blocks/example-block/index.js +++ b/assets/src/blocks/example-block/index.js @@ -3,6 +3,9 @@ import Edit from './edit'; import save from './save'; import metadata from './block.json'; +import './editor.scss'; +import './style.scss'; + registerBlockType(metadata.name, { edit: Edit, save, diff --git a/assets/src/blocks/example-block/style.css b/assets/src/blocks/example-block/style.scss similarity index 100% rename from assets/src/blocks/example-block/style.css rename to assets/src/blocks/example-block/style.scss