auto-registering blocks in php and javascript with dynamic enqueuing of associated styles and scripts with support for scss and blade
This commit is contained in:
@@ -36,64 +36,75 @@ add_action('init', function () {
|
||||
$blocks = glob(get_theme_file_path('resources/views/blocks/*/block.json'));
|
||||
|
||||
foreach ($blocks as $block_json) {
|
||||
$json = json_decode($block_json);
|
||||
$json = json_decode(file_get_contents($block_json));
|
||||
$slug = basename(dirname($block_json));
|
||||
$blockPath = "resources/views/blocks/{$slug}";
|
||||
|
||||
// Editor JS
|
||||
$editor_js_path = "resources/views/blocks/{$slug}/index.jsx";
|
||||
if (file_exists(get_theme_file_path($editor_js_path))) {
|
||||
$viewScript = "{$blockPath}/view.js";
|
||||
$script = "{$blockPath}/script.js";
|
||||
$editorCSS = "{$blockPath}/editor.scss";
|
||||
$style = "{$blockPath}/style.scss";
|
||||
|
||||
// editorStyle
|
||||
if (file_exists(get_theme_file_path($editorCSS))) {
|
||||
wp_register_style(
|
||||
"{$slug}-editor-style",
|
||||
\Vite::asset($editorCSS),
|
||||
[],
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
// script
|
||||
if(file_exists(get_theme_file_path($script))) {
|
||||
wp_register_script(
|
||||
"{$slug}-editor-script",
|
||||
\Vite::asset($editor_js_path),
|
||||
['wp-blocks', 'wp-element', 'wp-editor'],
|
||||
"{$slug}-script",
|
||||
\Vite::asset($script),
|
||||
[],
|
||||
null,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// Editor SCSS (compiled to CSS)
|
||||
$editor_css_path = "resources/views/blocks/{$slug}/editor.scss";
|
||||
if (file_exists(get_theme_file_path($editor_css_path))) {
|
||||
// style
|
||||
if (file_exists(get_theme_file_path($style))) {
|
||||
wp_register_style(
|
||||
"{$slug}-editor-style",
|
||||
\Vite::asset($editor_css_path),
|
||||
"{$slug}-style",
|
||||
\Vite::asset($style),
|
||||
[],
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
// Frontend SCSS (compiled to CSS)
|
||||
$style_css_path = "resources/views/blocks/{$slug}/style.scss";
|
||||
if (file_exists(get_theme_file_path($style_css_path))) {
|
||||
wp_register_style(
|
||||
"{$slug}-style",
|
||||
\Vite::asset($style_css_path),
|
||||
// viewScript
|
||||
if(file_exists(get_theme_file_path($viewScript))) {
|
||||
wp_register_script(
|
||||
"{$slug}-view-script",
|
||||
\Vite::asset($viewScript),
|
||||
[],
|
||||
null
|
||||
null,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
$props = [
|
||||
'editor_script' => "{$slug}-editor-script",
|
||||
'editor_style' => "{$slug}-editor-style",
|
||||
'style' => "{$slug}-style",
|
||||
'render_callback' => function ($attributes, $content, $block) {
|
||||
$slug = basename($block->name);
|
||||
$view = "blocks.{$slug}.render";
|
||||
|
||||
if (\Roots\view()->exists($view)) {
|
||||
return \Roots\view($view, [
|
||||
'attributes' => $attributes,
|
||||
'content' => $content,
|
||||
'block' => $block,
|
||||
]);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
'editor_style' => "{$slug}-editor-style",
|
||||
'style' => "{$slug}-style",
|
||||
'script' => "{$slug}-script",
|
||||
'view_script' => "{$slug}-view-script",
|
||||
];
|
||||
|
||||
if(!@$json['render_callback']) unset($props['render_callback']);
|
||||
if(!property_exists($json, 'acf') && \Roots\view()->exists("blocks.{$slug}.render")) {
|
||||
$props['render_callback'] = function ($attributes, $content, $block) {
|
||||
$slug = basename($block->name);
|
||||
|
||||
return \Roots\view("blocks.{$slug}.render", [
|
||||
'attributes' => $attributes,
|
||||
'content' => $content,
|
||||
'block' => $block,
|
||||
]);
|
||||
};
|
||||
}
|
||||
|
||||
register_block_type($block_json, $props);
|
||||
}
|
||||
@@ -136,3 +147,36 @@ function list_allowed()
|
||||
apply_filters('badegg_block_types_allow', $add_allowed),
|
||||
);
|
||||
}
|
||||
|
||||
function render_acf($block, $content = '', $is_preview = false, $post_id = 0, $wp_block = false, $context = false) {
|
||||
$slug = basename($block['name']);
|
||||
$block['slug'] = $slug;
|
||||
|
||||
$blade = \Roots\view("blocks.{$slug}.render", [
|
||||
'block' => $block,
|
||||
'content' => $content,
|
||||
'is_preview' => $is_preview,
|
||||
'post_id' => $post_id,
|
||||
'wp_block' => $wp_block,
|
||||
'context' => $context,
|
||||
]);
|
||||
|
||||
if($blade) {
|
||||
echo $blade;
|
||||
} else {
|
||||
ob_start(); ?>
|
||||
|
||||
<section class="section bg-error knockout">
|
||||
<div class="container container-small align-centre wysiwyg">
|
||||
<h2>Missing Blade Template</h2>
|
||||
<p>(resources/views/blocks/<?= $slug ?>/render.blade.php)</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<?php echo ob_get_clean();
|
||||
}
|
||||
}
|
||||
|
||||
add_action('wp_footer', function(){
|
||||
echo '<pre>',print_r(list_allowed()),'</pre>';
|
||||
});
|
||||
|
||||
@@ -3,8 +3,11 @@ import.meta.glob([
|
||||
'../fonts/**',
|
||||
]);
|
||||
|
||||
// import.meta.glob('../views/blocks/**/{style.scss,script.js,view.js}', { eager: true })
|
||||
|
||||
import Header from '../views/sections/header/header.js';
|
||||
import LazyLoad from './lib/Lazy.js';
|
||||
|
||||
LazyLoad();
|
||||
Header();
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import domReady from '@wordpress/dom-ready';
|
||||
import blockWhitelist from '../json/core-block-whitelist.json';
|
||||
import.meta.glob('../views/blocks/**/{index.jsx,index.js}', { eager: true })
|
||||
|
||||
domReady(() => {
|
||||
const TEXT_EDITOR_BLOCKS = [
|
||||
|
||||
@@ -66,7 +66,7 @@ class Editor
|
||||
|
||||
$data = array_merge($data, $block);
|
||||
$data['section_classes'] = $CssClasses->section($data);
|
||||
$data['allowed_blocks'] = \App\block_whitelist();
|
||||
$data['allowed_blocks'] = \App\Blocks\list_inner();
|
||||
$data['template'] = $this->default_template();
|
||||
$data['block'] = $block;
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "badegg/acfdemo",
|
||||
"title": "ACF Demo",
|
||||
"category": "badegg",
|
||||
"icon": "media-document",
|
||||
"description": "An example block powered by ACF",
|
||||
"keywords": ["acf", "demo"],
|
||||
|
||||
"editorScript": "acfdemo-editor-script",
|
||||
"editorStyle": "acfdemo-editor-style",
|
||||
"script": "acfdemo-script",
|
||||
"style": "acfdemo-style",
|
||||
"viewScript": "acfdemo-view-script",
|
||||
|
||||
"acf": {
|
||||
"mode": "preview",
|
||||
"validate": "false",
|
||||
"renderCallback": "\\App\\Blocks\\render_acf"
|
||||
},
|
||||
"supports": {
|
||||
"anchor": true,
|
||||
"align": false,
|
||||
"jsx": true
|
||||
},
|
||||
"example": {
|
||||
"attributes": {
|
||||
"mode": "preview",
|
||||
"data": {
|
||||
"inserter": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// block.json's editorStyle, applied in block editor and front end
|
||||
.wp-block-acf-demo.block-editor-block-list__block {
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
// block.json's editorScript, loaded only in the block editor
|
||||
console.log('loaded: resources/views/blocks/acfdemo/index.js')
|
||||
@@ -0,0 +1,3 @@
|
||||
<section class="wp-block-{{ $block['slug'] }}">
|
||||
<h2>ACF Example</h2>
|
||||
</section>
|
||||
@@ -0,0 +1,2 @@
|
||||
// block.json's script, loaded in block editor and front end
|
||||
console.log('loaded: resources/views/blocks/acf-demo/script.js')
|
||||
@@ -0,0 +1,4 @@
|
||||
// block.json's style, applied in block editor and front end
|
||||
.wp-block-acf-demo {
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
// block.json's viewScript, applied on front end only
|
||||
console.log('loaded: resources/views/blocks/acf-demo/view.js')
|
||||
@@ -3,8 +3,17 @@
|
||||
"name": "badegg/article",
|
||||
"title": "Article Builder",
|
||||
"category": "badegg",
|
||||
"icon": {
|
||||
"src": "format-aside",
|
||||
"foreground": "#f58762"
|
||||
},
|
||||
"description": "A wrapper to contain core blocks",
|
||||
"editorScript": "article-editor-script",
|
||||
"editorStyle": "article-editor-style",
|
||||
"style": "article-style"
|
||||
"supports": {
|
||||
"html": true,
|
||||
"align": ["wide", "full"],
|
||||
"color": {
|
||||
"background": true,
|
||||
"text": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
.block-badegg-example-editor {
|
||||
// block.json's editorStyle, applied in block editor and front end
|
||||
.wp-block-badegg-article.block-editor-block-list__block {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
// block.json's editorScript, loaded only in the block editor
|
||||
|
||||
import { registerBlockType } from '@wordpress/blocks';
|
||||
import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
|
||||
import metadata from './block.json';
|
||||
import allowedBlocks from '../../../json/core-block-whitelist.json';
|
||||
|
||||
registerBlockType(metadata.name, {
|
||||
icon: {
|
||||
src: 'format-aside',
|
||||
foreground: '#f58762',
|
||||
},
|
||||
edit({ attributes, setAttributes }) {
|
||||
const blockProps = useBlockProps();
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
<section class="block-badegg-article">
|
||||
<h2>Bad Egg Article Block (Blade)</h2>
|
||||
</section>
|
||||
@@ -0,0 +1,2 @@
|
||||
// block.json's script, loaded in block editor and front end
|
||||
console.log('loaded: resources/views/blocks/article/script.js')
|
||||
@@ -1,3 +1,4 @@
|
||||
.block-badegg-hero {
|
||||
// block.json's style, applied in block editor and front end
|
||||
.wp-block-badegg-article {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
// block.json's viewScript, applied on front end only
|
||||
console.log('loaded: resources/views/blocks/article/view.js')
|
||||
@@ -4,9 +4,12 @@
|
||||
"title": "Example",
|
||||
"category": "badegg",
|
||||
"icon": "cover-image",
|
||||
"description": "This is an example of a custom Wordpress Block created using the offical method.",
|
||||
"description": "This is an example of a custom native block",
|
||||
"editorScript": "example-editor-script",
|
||||
"editorStyle": "example-editor-style",
|
||||
"style": "example-style",
|
||||
"render": "resources/blocks/example/render.blade.php"
|
||||
"script": "example-script",
|
||||
"supports": {
|
||||
"html": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.block-badegg-example-editor {
|
||||
// block.json's editorStyle, applied in block editor and front end
|
||||
.wp-block-badegg-example.block-editor-block-list__block {
|
||||
display: block;
|
||||
border: 2px solid red;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
import { registerBlockType } from '@wordpress/blocks';
|
||||
// block.json's editorScript, loaded only in the block editor
|
||||
|
||||
registerBlockType('badegg/example', {
|
||||
import { registerBlockType } from '@wordpress/blocks';
|
||||
import { useBlockProps } from '@wordpress/block-editor';
|
||||
import metadata from './block.json';
|
||||
|
||||
registerBlockType(metadata.name, {
|
||||
edit() {
|
||||
const blockProps = useBlockProps();
|
||||
|
||||
return (
|
||||
<section className="block-badegg-example">
|
||||
<section { ...blockProps }>
|
||||
<h2>Bad Egg Block Example</h2>
|
||||
</section>
|
||||
);
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
// block.json's script, loaded in block editor and front end
|
||||
console.log('loaded: resources/views/blocks/example/script.js')
|
||||
@@ -1,3 +1,4 @@
|
||||
.block-badegg-hero {
|
||||
// block.json's style, applied in block editor and front end
|
||||
.wp-block-badegg-example {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
// block.json's viewScript, applied on front end only
|
||||
console.log('loaded: resources/views/blocks/example/view.js')
|
||||
@@ -1,21 +1,49 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import laravel from 'laravel-vite-plugin'
|
||||
import { wordpressPlugin, wordpressThemeJson } from '@roots/vite-plugin';
|
||||
import fg from 'fast-glob'
|
||||
import fg from 'fast-glob';
|
||||
import path from 'path';
|
||||
|
||||
const blockEntries = fg.sync('resources/views/blocks/**/{index.jsx,style.scss,editor.js,editor.scss}')
|
||||
function blockAsset(file)
|
||||
{
|
||||
const files = fg.sync('resources/views/blocks/**/' + file);
|
||||
let list = {};
|
||||
|
||||
files.forEach(file => {
|
||||
const parts = file.split(path.sep);
|
||||
const fileName = parts[parts.length - 1];
|
||||
const extension = fileName.split('.').pop();
|
||||
const blockName = parts[parts.length - 2];
|
||||
|
||||
list[`blocks/${blockName}/${fileName.replace('.' + extension, '')}`] = `resources/views/blocks/${blockName}/${fileName}`;
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
const editorStyle = blockAsset('editor.scss');
|
||||
const script = blockAsset('script.js');
|
||||
const viewScript = blockAsset('view.js');
|
||||
const style = blockAsset('style.scss');
|
||||
|
||||
export default defineConfig({
|
||||
base: '/app/themes/badegg/public/build/',
|
||||
plugins: [
|
||||
laravel({
|
||||
input: [
|
||||
'resources/css/app.scss',
|
||||
'resources/js/app.js',
|
||||
'resources/css/editor.scss',
|
||||
'resources/js/editor.js',
|
||||
...blockEntries,
|
||||
],
|
||||
input: {
|
||||
// 'resources/css/app.scss',
|
||||
// 'resources/js/app.js',
|
||||
// 'resources/css/editor.scss',
|
||||
// 'resources/js/editor.js',
|
||||
'css/app': 'resources/css/app.scss',
|
||||
'js/app': 'resources/js/app.js',
|
||||
'css/editor': 'resources/css/editor.scss',
|
||||
'js/editor': 'resources/js/editor.js',
|
||||
...editorStyle,
|
||||
...viewScript,
|
||||
...script,
|
||||
...style,
|
||||
},
|
||||
refresh: true,
|
||||
url: process.env.APP_URL,
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user