Compare commits

...

16 Commits

29 changed files with 336 additions and 264 deletions

View File

@@ -72,7 +72,8 @@
}, },
"require-dev": { "require-dev": {
"roave/security-advisories": "dev-latest", "roave/security-advisories": "dev-latest",
"laravel/pint": "^1.18" "laravel/pint": "^1.18",
"wpackagist-plugin/ajax-thumbnail-rebuild": "^1.14"
}, },
"config": { "config": {
"optimize-autoloader": true, "optimize-autoloader": true,

20
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "45d0a582ae7850e497fe7f2b3d7752a7", "content-hash": "7666943446e3342a3e30a48917611260",
"packages": [ "packages": [
{ {
"name": "badegguk/bad-egg-digital-login-page", "name": "badegguk/bad-egg-digital-login-page",
@@ -2846,6 +2846,24 @@
} }
], ],
"time": "2025-12-12T23:06:01+00:00" "time": "2025-12-12T23:06:01+00:00"
},
{
"name": "wpackagist-plugin/ajax-thumbnail-rebuild",
"version": "1.14",
"source": {
"type": "svn",
"url": "https://plugins.svn.wordpress.org/ajax-thumbnail-rebuild/",
"reference": "tags/1.14"
},
"dist": {
"type": "zip",
"url": "https://downloads.wordpress.org/plugin/ajax-thumbnail-rebuild.1.14.zip"
},
"require": {
"composer/installers": "^1.0 || ^2.0"
},
"type": "wordpress-plugin",
"homepage": "https://wordpress.org/plugins/ajax-thumbnail-rebuild/"
} }
], ],
"aliases": [], "aliases": [],

View File

@@ -10,6 +10,8 @@ class Colour
if($colour == 'black'): if($colour == 'black'):
$hex = '#000000'; $hex = '#000000';
elseif($colour == 'grey'):
$hex = '#808080';
elseif($colour == 'white'): elseif($colour == 'white'):
$hex = '#FFFFFF'; $hex = '#FFFFFF';
else: else:
@@ -27,20 +29,23 @@ class Colour
public function values() public function values()
{ {
$colours = get_field('badegg_colours', 'option');
$values = []; $values = [];
if($colours): if(function_exists('get_field')):
foreach($colours as $index => $props): $colours = get_field('badegg_colours', 'option');
$index = $index + 1;
$hex = @$props['hex'];
if($hex) $values[$this->latinate($index)] = $hex; if($colours):
endforeach; foreach($colours as $index => $props):
$index = $index + 1;
$hex = @$props['hex'];
if($hex) $values[$this->latinate($index)] = $hex;
endforeach;
endif;
endif; endif;
$values['white'] = '#FFFFFF'; $values['white'] = '#FFFFFF';
$values['grey'] = '#808080';
$values['black'] = '#000000'; $values['black'] = '#000000';
return $values; return $values;
@@ -49,13 +54,13 @@ class Colour
public function tints() public function tints()
{ {
return [ return [
'lightest' => 100, 'lightest' => 40,
'lighter' => 66, 'lighter' => 25,
'light' => 33, 'light' => 10,
'0' => 0, '0' => 0,
'dark' => -33, 'dark' => -10,
'darker' => -66, 'darker' => -25,
'darkest' => -100, 'darkest' => -40,
]; ];
} }

View File

@@ -30,17 +30,17 @@ class CssClasses {
'tint' => $props['bg_tint'], 'tint' => $props['bg_tint'],
]); ]);
if(($knockout && $Colour->is_dark($hex) || $props['contrast'] == 'light')) if(($props['contrast'] && $knockout))
$classes[] = 'knockout'; $classes[] = 'knockout';
if($props['padding_top']) if(!$props['padding_top'])
$classes[] = 'section-zero-top'; $classes[] = 'section-zero-top';
if($props['padding_bottom']) if(!$props['padding_bottom'])
$classes[] = 'section-zero-bottom'; $classes[] = 'section-zero-bottom';
if($props['bg_image']) if($props['bg_image'])
$classes[] = "bg-watermarked"; $classes[] = "has-bg-image";
return $classes; return $classes;
} }
@@ -89,7 +89,7 @@ class CssClasses {
if($args['align']) if($args['align'])
$classes[] = 'align-' . $args['align']; $classes[] = 'align-' . $args['align'];
if(($Colour->is_dark($hex) || $bg_props['contrast'] == 'light')) if(($bg_props['contrast']))
$classes[] = 'knockout'; $classes[] = 'knockout';
return $classes; return $classes;

View File

@@ -103,59 +103,7 @@ add_action('init', function () {
'style' => "{$slug}-style", 'style' => "{$slug}-style",
'script' => "{$slug}-script", 'script' => "{$slug}-script",
'view_script' => "{$slug}-view-script", 'view_script' => "{$slug}-view-script",
'attributes' => [ 'attributes' => attributes(),
'container_width' => [
'type' => 'string',
'default' => '',
],
'alignment' => [
'type' => 'string',
],
'padding_top' => [
'type' => 'boolean',
'default' => true
],
'padding_bottom' => [
'type' => 'boolean',
'default' => true
],
'background_colour' => [
'type' => 'string',
'default' => '',
],
'background_hex' => [
'type' => 'string',
'default' => '',
],
'background_tint' => [
'type' => 'string',
'default' => '0',
],
'background_image' => [
'type' => 'integer',
'default' => 0,
],
'background_url' => [
'type' => 'string',
'default' => '',
],
'background_opacity' => [
'type' => 'integer',
'default' => 30
],
'background_position' => [
'type' => 'string',
'default' => '',
],
'background_fixed' => [
'type' => 'boolean',
'default' => false,
],
'background_contrast' => [
'type' => 'boolean',
'default' => false,
],
],
]; ];
if(!property_exists($json, 'acf') && \Roots\view()->exists("blocks.{$slug}.render")) { if(!property_exists($json, 'acf') && \Roots\view()->exists("blocks.{$slug}.render")) {
@@ -176,12 +124,20 @@ add_action('init', function () {
function list_inner() function list_inner()
{ {
$file = file_get_contents(get_theme_file_path("resources/json/core-block-whitelist.json")); $file = file_get_contents(get_theme_file_path("resources/json/block-core-whitelist.json"));
$json = json_decode($file); $json = json_decode($file);
return $json; return $json;
} }
function attributes()
{
$file = file_get_contents(get_theme_file_path("resources/json/block-attributes.json"));
$json = json_decode($file, true);
return $json;
}
function list_all() function list_all()
{ {
$blocks = array_map(function($block) { $blocks = array_map(function($block) {

View File

@@ -17,9 +17,12 @@
"id": "" "id": ""
}, },
"choices": { "choices": {
"0": "auto", "0": "None",
"primary": "<i class=\"fas fa-circle\" style=\"color: #dd3333\"><\/i> Punch", "primary": "<i class=\"fas fa-circle\" style=\"color: #dd3333\"><\/i> Punch",
"secondary": "<i class=\"fas fa-circle\" style=\"color: #81d742\"><\/i> Atlantis",
"tertiary": "<i class=\"fas fa-circle\" style=\"color: #8224e3\"><\/i> Purple Heart",
"white": "<i class=\"fas fa-circle\" style=\"color: #FFFFFF\"><\/i> White", "white": "<i class=\"fas fa-circle\" style=\"color: #FFFFFF\"><\/i> White",
"grey": "<i class=\"fas fa-circle\" style=\"color: #808080\"><\/i> Gray",
"black": "<i class=\"fas fa-circle\" style=\"color: #000000\"><\/i> Black" "black": "<i class=\"fas fa-circle\" style=\"color: #000000\"><\/i> Black"
}, },
"default_value": 0, "default_value": 0,
@@ -91,10 +94,10 @@
}, },
{ {
"key": "field_67350f526abf1", "key": "field_67350f526abf1",
"label": "Text Contrast", "label": "",
"name": "contrast", "name": "contrast",
"aria-label": "", "aria-label": "",
"type": "select", "type": "true_false",
"instructions": "", "instructions": "",
"required": 0, "required": 0,
"conditional_logic": 0, "conditional_logic": 0,
@@ -103,20 +106,12 @@
"class": "", "class": "",
"id": "" "id": ""
}, },
"choices": { "message": "Text Contrast",
"0": "Auto",
"dark": "Force dark text",
"light": "Force light text"
},
"default_value": 0, "default_value": 0,
"return_format": "value", "allow_in_bindings": 0,
"multiple": 0, "ui_on_text": "Light",
"allow_null": 0, "ui_off_text": "Dark",
"ui": 0, "ui": 1
"ajax": 0,
"placeholder": "",
"create_options": 0,
"save_options": 0
} }
], ],
"location": [ "location": [
@@ -137,5 +132,6 @@
"active": true, "active": true,
"description": "", "description": "",
"show_in_rest": 0, "show_in_rest": 0,
"modified": 1765746167 "display_title": "",
"modified": 1767548180
} }

View File

@@ -36,56 +36,6 @@
}, },
"layout": "block", "layout": "block",
"sub_fields": [ "sub_fields": [
{
"key": "field_67350eb62cdf9",
"label": "Top Padding",
"name": "padding_top",
"aria-label": "",
"type": "radio",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "50",
"class": "",
"id": ""
},
"choices": [
"On",
"Off"
],
"default_value": "",
"return_format": "value",
"allow_null": 0,
"other_choice": 0,
"layout": "horizontal",
"save_other_choice": 0
},
{
"key": "field_673510c1dc830",
"label": "Bottom Padding",
"name": "padding_bottom",
"aria-label": "",
"type": "radio",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "50",
"class": "",
"id": ""
},
"choices": [
"On",
"Off"
],
"default_value": "",
"return_format": "value",
"allow_null": 0,
"other_choice": 0,
"layout": "horizontal",
"save_other_choice": 0
},
{ {
"key": "field_6800097e61765", "key": "field_6800097e61765",
"label": "Container Width", "label": "Container Width",
@@ -119,6 +69,66 @@
"create_options": 0, "create_options": 0,
"save_options": 0 "save_options": 0
}, },
{
"key": "field_67350eb62cdf9",
"label": "",
"name": "padding_top",
"aria-label": "",
"type": "true_false",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"message": "Top Padding",
"default_value": 1,
"allow_in_bindings": 0,
"ui_on_text": "On",
"ui_off_text": "Off",
"ui": 1
},
{
"key": "field_673510c1dc830",
"label": "",
"name": "padding_bottom",
"aria-label": "",
"type": "true_false",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"message": "Bottom Padding",
"default_value": 1,
"allow_in_bindings": 0,
"ui_on_text": "On",
"ui_off_text": "Off",
"ui": 1
},
{
"key": "field_695aa550e16d4",
"label": "Background",
"name": "",
"aria-label": "",
"type": "message",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"message": "",
"new_lines": "wpautop",
"esc_html": 0
},
{ {
"key": "field_67350aeb146ca", "key": "field_67350aeb146ca",
"label": "Background", "label": "Background",
@@ -181,5 +191,5 @@
"description": "", "description": "",
"show_in_rest": 0, "show_in_rest": 0,
"display_title": "", "display_title": "",
"modified": 1765815052 "modified": 1767548583
} }

View File

@@ -63,7 +63,7 @@ p,
li, li,
td, td,
label { label {
color: colours.$grey-dark; color: colours.$grey-darker;
font-family: fonts.$font; font-family: fonts.$font;
font-weight: 400; font-weight: 400;
line-height: 1.5em; line-height: 1.5em;

View File

@@ -24,7 +24,7 @@
} }
} }
#{$button}.#{$name}.inverted { #{$button}.#{$name}.outline {
color: $hex; color: $hex;
background: transparent; background: transparent;
border-color: $hex; border-color: $hex;

View File

@@ -13,48 +13,50 @@ $secondary: #5bc0de;
$tertiary: color.invert($primary); $tertiary: color.invert($primary);
$quaternary: color.invert($secondary); $quaternary: color.invert($secondary);
//== Shades
$white: #FFFFFF;
$grey: #808080;
$black: #000000;
//== Primary Tints //== Primary Tints
$primary-darkest: color.adjust($primary, $lightness: -30%); $primary-darkest: color.adjust($primary, $lightness: -45%);
$primary-darker: color.adjust($primary, $lightness: -20%); $primary-darker: color.adjust($primary, $lightness: -30%);
$primary-dark: color.adjust($primary, $lightness: -10%); $primary-dark: color.adjust($primary, $lightness: -15%);
$primary-light: color.adjust($primary, $lightness: 10%); $primary-light: color.adjust($primary, $lightness: 15%);
$primary-lighter: color.adjust($primary, $lightness: 20%); $primary-lighter: color.adjust($primary, $lightness: 30%);
$primary-lightest: color.adjust($primary, $lightness: 30%); $primary-lightest: color.adjust($primary, $lightness: 45%);
//== Secondary Tints //== Secondary Tints
$secondary-darkest: color.adjust($secondary, $lightness: -30%); $secondary-darkest: color.adjust($secondary, $lightness: -45%);
$secondary-darker: color.adjust($secondary, $lightness: -20%); $secondary-darker: color.adjust($secondary, $lightness: -30%);
$secondary-dark: color.adjust($secondary, $lightness: -10%); $secondary-dark: color.adjust($secondary, $lightness: -15%);
$secondary-light: color.adjust($secondary, $lightness: 10%); $secondary-light: color.adjust($secondary, $lightness: 15%);
$secondary-lighter: color.adjust($secondary, $lightness: 20%); $secondary-lighter: color.adjust($secondary, $lightness: 30%);
$secondary-lightest: color.adjust($secondary, $lightness: 30%); $secondary-lightest: color.adjust($secondary, $lightness: 45%);
//== Tertiary Tints //== Tertiary Tints
$tertiary-darkest: color.adjust($tertiary, $lightness: -30%); $tertiary-darkest: color.adjust($tertiary, $lightness: -45%);
$tertiary-darker: color.adjust($tertiary, $lightness: -20%); $tertiary-darker: color.adjust($tertiary, $lightness: -30%);
$tertiary-dark: color.adjust($tertiary, $lightness: -10%); $tertiary-dark: color.adjust($tertiary, $lightness: -15%);
$tertiary-light: color.adjust($tertiary, $lightness: 10%); $tertiary-light: color.adjust($tertiary, $lightness: 15%);
$tertiary-lighter: color.adjust($tertiary, $lightness: 20%); $tertiary-lighter: color.adjust($tertiary, $lightness: 30%);
$tertiary-lightest: color.adjust($tertiary, $lightness: 30%); $tertiary-lightest: color.adjust($tertiary, $lightness: 45%);
//== quaternary Tints //== quaternary Tints
$quaternary-darkest: color.adjust($quaternary, $lightness: -30%); $quaternary-darkest: color.adjust($quaternary, $lightness: -45%);
$quaternary-darker: color.adjust($quaternary, $lightness: -20%); $quaternary-darker: color.adjust($quaternary, $lightness: -30%);
$quaternary-dark: color.adjust($quaternary, $lightness: -10%); $quaternary-dark: color.adjust($quaternary, $lightness: -15%);
$quaternary-light: color.adjust($quaternary, $lightness: 10%); $quaternary-light: color.adjust($quaternary, $lightness: 15%);
$quaternary-lighter: color.adjust($quaternary, $lightness: 20%); $quaternary-lighter: color.adjust($quaternary, $lightness: 30%);
$quaternary-lightest: color.adjust($quaternary, $lightness: 30%); $quaternary-lightest: color.adjust($quaternary, $lightness: 45%);
//== Shades //== six shades of grey
$white: white; $grey-darkest: color.adjust(grey, $lightness: -40%);
$grey-lightest: color.adjust(black, $lightness: 95%); $grey-darker: color.adjust(grey, $lightness: -25%);
$grey-lighter: color.adjust(black, $lightness: 80%); $grey-dark: color.adjust(grey, $lightness: -10%);
$grey-light: color.adjust(black, $lightness: 70%); $grey-light: color.adjust(grey, $lightness: 10%);
$grey: color.adjust(black, $lightness: 50%); $grey-lighter: color.adjust(grey, $lightness: 25%);
$grey-dark: color.adjust(black, $lightness: 40%); $grey-lightest: color.adjust(grey, $lightness: 40%);
$grey-darker: color.adjust(black, $lightness: 20%);
$grey-darkest: color.adjust(black, $lightness: 05%);
$black: black;
//## Colour Array (used in generating colour classes). //## Colour Array (used in generating colour classes).
$colors: ( $colors: (

View File

@@ -85,6 +85,7 @@ export default function BlockSettings({ attributes, setAttributes }) {
background_hex, background_hex,
background_tint, background_tint,
background_image, background_image,
background_url,
background_opacity, background_opacity,
background_contrast, background_contrast,
background_fixed, background_fixed,
@@ -156,24 +157,26 @@ export default function BlockSettings({ attributes, setAttributes }) {
/> />
{ 'background_colour' in attributes && attributes.background_colour && ![0, '0', 'white', 'black'].includes(attributes.background_colour) ? ( { 'background_colour' in attributes && attributes.background_colour && ![0, '0', 'white', 'black'].includes(attributes.background_colour) ? (
<SelectControl
label={ __("Background Tint", "badegg") }
value={ background_tint }
options={ configOptions.tints }
onChange={ (value) => setAttributes({ background_tint: value }) }
__next40pxDefaultSize={ true }
__nextHasNoMarginBottom={ true }
/>
) : null }
{ background_image != 0 && (
<> <>
<SelectControl
label={ __("Background Tint", "badegg") }
value={ background_tint }
options={ configOptions.tints }
onChange={ (value) => setAttributes({ background_tint: value }) }
__next40pxDefaultSize={ true }
__nextHasNoMarginBottom={ true }
/>
<ToggleControl <ToggleControl
label={ __('Text Contrast', 'badegg') } label={ __('Text Contrast', 'badegg') }
checked={ background_contrast } checked={ background_contrast }
onChange={(value) => setAttributes({ background_contrast: value }) } onChange={(value) => setAttributes({ background_contrast: value }) }
__nextHasNoMarginBottom __nextHasNoMarginBottom
/> />
</>
) : null }
{ background_image != 0 && (
<>
<ToggleControl <ToggleControl
label={ __('Fixed Position', 'badegg') } label={ __('Fixed Position', 'badegg') }
checked={ background_fixed } checked={ background_fixed }
@@ -216,7 +219,7 @@ export default function BlockSettings({ attributes, setAttributes }) {
{ background_image != 0 && ( { background_image != 0 && (
<Button <Button
onClick={ () => setAttributes({ background_image: 0 }) } onClick={ () => setAttributes({ background_image: 0, background_url: '' }) }
isDestructive isDestructive
variant="secondary" variant="secondary"
> >

View File

@@ -1,4 +1,4 @@
export function containerClassNames(attributes, bgProps) export function containerClassNames(attributes, extraClasses = [])
{ {
let classNames = [ let classNames = [
@@ -11,6 +11,9 @@ export function containerClassNames(attributes, bgProps)
if('alignment' in attributes) if('alignment' in attributes)
classNames.push(`align-${attributes.alignment}`); classNames.push(`align-${attributes.alignment}`);
// combine arrays
classNames = classNames.concat(extraClasses);
return classNames; return classNames;
} }

View File

@@ -1,44 +1,12 @@
import domReady from '@wordpress/dom-ready'; import domReady from '@wordpress/dom-ready';
import blockWhitelist from '../json/core-block-whitelist.json'; import blockParents from '../json/block-parents.json';
import blockWhitelist from '../json/block-core-whitelist.json';
import.meta.glob('../views/blocks/**/{index.jsx,index.js}', { eager: true }) import.meta.glob('../views/blocks/**/{index.jsx,index.js}', { eager: true })
domReady(() => { domReady(() => {
const TEXT_EDITOR_BLOCKS = [
// Design
'core/separator',
'core/spacer',
// Media
'core/cover',
'core/file',
'core/gallery',
'core/image',
'core/media-text',
'core/audio',
'core/video',
// Text
'core/footnotes',
'core/heading',
'core/list',
'core/code',
'core/details',
'core/list-item',
'core/missing',
'core/paragraph',
'core/preformatted',
'core/pullquote',
'core/quote',
'core/table',
'core/verse',
];
const restrictEditorParentBlocks = (settings, name) => { const restrictEditorParentBlocks = (settings, name) => {
if (TEXT_EDITOR_BLOCKS.includes(name)) { if (blockWhitelist.includes(name)) {
settings.parent = [ settings.parent = blockParents;
'acf/badegg-editor',
'badegg/article',
];
} }
return settings return settings
@@ -46,8 +14,7 @@ domReady(() => {
wp.hooks.addFilter( wp.hooks.addFilter(
'blocks.registerBlockType', 'blocks.registerBlockType',
'your-project-name/restrict-parent-blocks', 'badegg/restrict-parent-blocks',
restrictEditorParentBlocks restrictEditorParentBlocks
); );
}); });

View File

@@ -1,12 +0,0 @@
export default function isInsideMyACFBlock(blockName)
{
const editor = wp.data.select('core/block-editor');
const selectedId = editor.getSelectedBlockClientId();
if (!selectedId) return false;
const parents = editor.getBlockParents(selectedId);
const parentNames = parents.map(id => editor.getBlockName(id));
return parentNames.includes(blockName);
}

View File

@@ -0,0 +1,53 @@
{
"container_width": {
"type": "string",
"default": ""
},
"alignment": {
"type": "string"
},
"padding_top": {
"type": "boolean",
"default": true
},
"padding_bottom": {
"type": "boolean",
"default": true
},
"background_colour": {
"type": "string",
"default": ""
},
"background_hex": {
"type": "string",
"default": ""
},
"background_tint": {
"type": "string",
"default": "0"
},
"background_image": {
"type": "integer",
"default": 0
},
"background_url": {
"type": "string",
"default": ""
},
"background_opacity": {
"type": "integer",
"default": 30
},
"background_position": {
"type": "string",
"default": ""
},
"background_fixed": {
"type": "boolean",
"default": false
},
"background_contrast": {
"type": "boolean",
"default": false
}
}

View File

@@ -0,0 +1,4 @@
[
"acf/badegg-editor",
"badegg/article"
]

View File

@@ -0,0 +1,25 @@
# Bad Egg's Article Builder
Designed as a full width component, Article Builder bundles core wordpress blocks commonly used in articles into a classic editor like experience.
## Features
- Uses the `<InnerBlocks/>` component with a whitelist defined in `resources/json/core-block-whitelist.json`
- Provides spacing and background configuration options
- Default block attributes are defined in `resources/json/block-attributes.json` so that they are not needed in duplicate in `block.json`
- A reusable customisation UI is defined in `resources/js/blocks/components/BlockSettings.jsx` so that multiple blocks can rely on the same controls
## Theme-level changes
- All core wordpress blocks are disabled at the top level to prevent them from being used alongside full-width blocks designed to craft page layouts
- Blocks that can use core whitelisted inner blocks are defined in `resources/json/block-parents.json`
## Attributes
- Top Padding
- Bottom Padding
- Container width
- Background
- Colour
- Tint
- Image
- Image opacity
- Text contrast toggle
- Fixed position toggle

View File

@@ -1,4 +0,0 @@
// block.json's editorStyle, applied in block editor and front end
.wp-block-badegg-article.block-editor-block-list__block {
display: block;
}

View File

@@ -9,7 +9,7 @@ import {
InnerBlocks, InnerBlocks,
} from '@wordpress/block-editor'; } from '@wordpress/block-editor';
import allowedBlocks from '../../../json/core-block-whitelist.json'; import allowedBlocks from '../../../json/block-core-whitelist.json';
import { containerClassNames, sectionClassNames } from '../../../js/blocks/lib/classNames'; import { containerClassNames, sectionClassNames } from '../../../js/blocks/lib/classNames';
import BackgroundImage from '../../../js/blocks/components/BackgroundImage'; import BackgroundImage from '../../../js/blocks/components/BackgroundImage';
import BlockSettings from '../../../js/blocks/components/BlockSettings'; import BlockSettings from '../../../js/blocks/components/BlockSettings';
@@ -17,7 +17,7 @@ import BlockSettings from '../../../js/blocks/components/BlockSettings';
registerBlockType(metadata.name, { registerBlockType(metadata.name, {
edit({ attributes, setAttributes }) { edit({ attributes, setAttributes }) {
const blockProps = useBlockProps(); const blockProps = useBlockProps();
blockProps.className = sectionClassNames(attributes, blockProps.className, [ 'wysiwyg' ]).join(' '); blockProps.className = sectionClassNames(attributes, blockProps.className).join(' ');
return ( return (
<div { ...blockProps }> <div { ...blockProps }>
@@ -26,7 +26,7 @@ registerBlockType(metadata.name, {
setAttributes={ setAttributes } setAttributes={ setAttributes }
/> />
<div className={ containerClassNames(attributes).join(' ') }> <div className={ containerClassNames(attributes, [ 'wysiwyg' ]).join(' ') }>
<InnerBlocks <InnerBlocks
allowedBlocks={ allowedBlocks } allowedBlocks={ allowedBlocks }
defaultBlock={ defaultBlock={
@@ -51,7 +51,7 @@ registerBlockType(metadata.name, {
return ( return (
<div { ...blockProps }> <div { ...blockProps }>
<div className={ containerClassNames(attributes).join(' ') }> <div className={ containerClassNames(attributes, [ 'wysiwyg' ]).join(' ') }>
<InnerBlocks.Content /> <InnerBlocks.Content />
</div> </div>

View File

@@ -1 +0,0 @@
// block.json's script, loaded in block editor and front end

View File

@@ -1,4 +0,0 @@
// block.json's style, applied in block editor and front end
.wp-block-badegg-article {
display: block;
}

View File

@@ -1 +0,0 @@
// block.json's viewScript, applied on front end only

View File

@@ -0,0 +1,40 @@
# Bad Egg's Native Wordpress Block Example
This block serves as a placeholder that can be copied and extended to build native Wordpress blocks.
## Features
- Automatic registration and asset building through the theme's `app/blocks.php` file and `vite.config.js`
- Automatic enqueueing of block scripts and styles if the correct files are included in the block's directory
- Supports Laravel Blade templates if the `render.blade.php` file is present, with access to the `$attributes`, `$block`, and `$content` variables.
- Default block attributes are defined in `resources/json/block-attributes.json` so that they are not needed in duplicate in `block.json`
- A reusable customisation UI is defined in `resources/js/blocks/components/BlockSettings.jsx` so that multiple blocks can rely on the same controls
## Directory Structure
```
app
│ ...
│ blocks.php -> this is where the auto registration functions live
resources
│ ...
└── js
│ └── editor.js
└── views
│ ...
└── blocks
│ ...
└── example
│ README.md -> this file
│ block.json -> (required) the block's metadata
│ index.jsx -> (required) EditorScript
│ script.js -> (optional) Editor & Front end
│ view.js -> (optional) Front end
│ editor.scss -> (optional) Editor
│ style.scss -> (optional) Editor & Front end
│ render.blade.php -> (optional) falls back to index.jsx save
```

View File

@@ -1,17 +1,22 @@
// block.json's editorScript, loaded only in the block editor // block.json's editorScript, loaded only in the block editor
import metadata from './block.json';
import { registerBlockType } from '@wordpress/blocks'; import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps } from '@wordpress/block-editor'; import { useBlockProps } from '@wordpress/block-editor';
import metadata from './block.json'; import { containerClassNames, sectionClassNames } from '../../../js/blocks/lib/classNames';
registerBlockType(metadata.name, { registerBlockType(metadata.name, {
edit() { edit({ attributes }) {
const blockProps = useBlockProps(); const blockProps = useBlockProps();
blockProps.className = sectionClassNames(attributes, blockProps.className, ['bg-success', 'knockout']).join(' ');
return ( return (
<section { ...blockProps }> <div { ...blockProps }>
<h2>Bad Egg Block Example</h2> <div className="container align-center wysiwyg">
</section> <h2>Bad Egg Block Example</h2>
</div>
</div>
); );
} }
}); });

View File

@@ -1,3 +1,7 @@
<div class="block-badegg-example"> <div {!! get_block_wrapper_attributes([
<h2>Bad Egg Example Block (Blade)</h2> 'class' => 'section bg-success knockout',
]) !!}>
<div class="container wysiwyg align-center">
<h2>Bad Egg Example Block (Blade)</h2>
</div>
</div> </div>

View File

@@ -1 +1,2 @@
// block.json's script, loaded in block editor and front end // block.json's script, loaded in block editor and front end
console.log('bad egg example block script.js loaded.');

View File

@@ -1 +1,2 @@
// block.json's viewScript, applied on front end only // block.json's viewScript, applied on front end only
console.log('bad egg example block view.js loaded.');

View File

@@ -1,4 +1,4 @@
@if($props['blurb']) @if($props['blurb'] || $props['links'])
@php @php
$containerProps = [ $containerProps = [
'width' => $props['container_width'], 'width' => $props['container_width'],