Skip to content
Draft
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
2 changes: 2 additions & 0 deletions inc/Main.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace rtCamp\Theme\Elementary;

use rtCamp\Theme\Elementary\Modules\BlockExtensions\MediaTextInteractive;
use rtCamp\Theme\Elementary\Modules\Blocks\Registrar;
use rtCamp\Theme\Elementary\Framework\Traits\Singleton;
use rtCamp\Theme\Elementary\Core\Assets;

Expand Down Expand Up @@ -60,5 +61,6 @@ public function elementary_theme_support(): void {
*/
public function block_extensions(): void {
MediaTextInteractive::get_instance();
Registrar::get_instance();
}
}
98 changes: 98 additions & 0 deletions inc/Modules/Blocks/Registrar.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php
/**
* Block Registrar Module.
*
* @package rtCamp\Theme\Elementary
*/

declare( strict_types = 1 );

namespace rtCamp\Theme\Elementary\Modules\Blocks;

use rtCamp\Theme\Elementary\Framework\Traits\Singleton;

/**
* Class Registrar
*
* Discovers and registers blocks from the src/blocks directory.
*
* @since 1.0.0
*/
class Registrar {

use Singleton;

/**
* Constructor.
*/
protected function __construct() {
$this->setup_hooks();
}

/**
* Setup hooks.
*
* @return void
*/
protected function setup_hooks(): void {
add_action( 'init', [ $this, 'register_blocks' ] );
}

/**
* Register blocks.
*
* @return void
*/
public function register_blocks(): void {
/**
* Filters the directories where the theme looks for blocks to register.
*
* @since 1.0.0
*
* @param array<string> $paths Array of absolute paths to block directories.
*/
$block_paths = apply_filters(
'elementary_theme_block_paths',
[
get_stylesheet_directory() . '/src/blocks',
get_template_directory() . '/src/blocks',
]
);

if ( ! is_array( $block_paths ) || empty( $block_paths ) ) {
return;
}

$registered_blocks = [];

foreach ( $block_paths as $blocks_dir ) {
if ( ! is_dir( $blocks_dir ) ) {
continue;
}

$directories = glob( $blocks_dir . '/*', GLOB_ONLYDIR );

if ( empty( $directories ) ) {
continue;
}

foreach ( $directories as $block_dir ) {
$metadata_file = $block_dir . '/block.json';

if ( ! file_exists( $metadata_file ) ) {
continue;
}

$metadata = wp_json_file_decode( $metadata_file, [ 'associative' => true ] );
$block_name = is_array( $metadata ) && ! empty( $metadata['name'] ) ? (string) $metadata['name'] : basename( $block_dir );

if ( isset( $registered_blocks[ $block_name ] ) || \WP_Block_Type_Registry::get_instance()->is_registered( $block_name ) ) {
continue;
}

register_block_type( $block_dir );
$registered_blocks[ $block_name ] = true;
}
}
}
}
12 changes: 6 additions & 6 deletions inc/helpers/custom-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
*
* @since 1.0.0
*
* @param string $name Component name (e.g. 'Button', 'Card').
* @param array $args Arguments to pass to the component.
* @param array $options Optional. Resolution options. See ComponentLoader::render().
* @param string $name Component name (e.g. 'Button', 'Card').
* @param array<string, mixed> $args Arguments to pass to the component.
* @param array<string, mixed> $options Optional. Resolution options. See ComponentLoader::render().
*
* @return void
*/
Expand All @@ -38,9 +38,9 @@ function elementary_theme_component( string $name, array $args = [], array $opti
*
* @since 1.0.0
*
* @param string $name Component name (e.g. 'Button', 'Card').
* @param array $args Arguments to pass to the component.
* @param array $options Optional. Resolution options. See ComponentLoader::get().
* @param string $name Component name (e.g. 'Button', 'Card').
* @param array<string, mixed> $args Arguments to pass to the component.
* @param array<string, mixed> $options Optional. Resolution options. See ComponentLoader::get().
*
* @return string Rendered component HTML.
*/
Expand Down
34 changes: 34 additions & 0 deletions src/blocks/button/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "rtcamp/button",
"title": "Button (rtCamp)",
"category": "design",
"icon": "button",
"description": "A button block.",
"attributes": {
"label": {
"type": "string",
"default": "Get started"
},
"url": {
"type": "string",
"default": ""
},
"variant": {
"type": "string",
"default": "primary"
},
"size": {
"type": "string",
"default": "medium"
},
"class": {
"type": "string",
"default": ""
}
},
"editorScript": "file:./edit.js",
"viewScript": "file:./view.js",
"render": "file:./render.php"
}
11 changes: 11 additions & 0 deletions src/blocks/button/edit.asset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
/**
* Editor asset metadata for the rtcamp/button block.
*
* @package rtCamp\Theme\Elementary
*/

return [
'dependencies' => [ 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element' ],
'version' => filemtime( __DIR__ . '/edit.js' ),
];
79 changes: 79 additions & 0 deletions src/blocks/button/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/**
* Editor behavior for the rtcamp/button block.
*/
( function() {
const { registerBlockType } = wp.blocks;
const { InspectorControls, RichText, URLInputButton } = wp.blockEditor;
const { PanelBody, SelectControl, TextControl } = wp.components;
const { createElement: el } = wp.element;

registerBlockType( 'rtcamp/button', {
edit( { attributes, setAttributes } ) {
const label = attributes.label || '';
const url = attributes.url || '';
const variant = attributes.variant || 'primary';
const size = attributes.size || 'medium';
const className = [
'elementary-button',
`elementary-button--${ variant }`,
`elementary-button--${ size }`,
attributes.class || '',
]
.filter( Boolean )
.join( ' ' );

return el(
'div',
{},
el(
InspectorControls,
{},
el(
PanelBody,
{ title: 'Button settings' },
el( TextControl, {
label: 'URL',
value: url,
onChange: ( value ) => setAttributes( { url: value } ),
} ),
el( URLInputButton, {
url,
onChange: ( value ) => setAttributes( { url: value } ),
} ),
el( SelectControl, {
label: 'Variant',
value: variant,
options: [
{ label: 'Primary', value: 'primary' },
{ label: 'Secondary', value: 'secondary' },
{ label: 'Text', value: 'text' },
],
onChange: ( value ) => setAttributes( { variant: value } ),
} ),
el( SelectControl, {
label: 'Size',
value: size,
options: [
{ label: 'Small', value: 'small' },
{ label: 'Medium', value: 'medium' },
{ label: 'Large', value: 'large' },
],
onChange: ( value ) => setAttributes( { size: value } ),
} ),
),
),
el( RichText, {
tagName: 'span',
className,
value: label,
allowedFormats: [],
placeholder: 'Button label',
onChange: ( value ) => setAttributes( { label: value } ),
} ),
);
},
save() {
return null;
},
} );
}() );
26 changes: 26 additions & 0 deletions src/blocks/button/render.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php
/**
* Render callback for the rtcamp/button block.
*
* @package rtCamp\Theme\Elementary
*/

declare( strict_types = 1 );

if ( ! function_exists( 'elementary_theme_get_component' ) ) {
return;
}

// phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound

$attributes = $attributes ?? [];
$props = [
'label' => isset( $attributes['label'] ) ? sanitize_text_field( (string) $attributes['label'] ) : '',
'url' => isset( $attributes['url'] ) ? esc_url_raw( (string) $attributes['url'] ) : '',
'variant' => isset( $attributes['variant'] ) ? sanitize_key( (string) $attributes['variant'] ) : 'primary',
'size' => isset( $attributes['size'] ) ? sanitize_key( (string) $attributes['size'] ) : 'medium',
'class' => isset( $attributes['class'] ) ? sanitize_text_field( (string) $attributes['class'] ) : '',
];

// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo elementary_theme_get_component( 'Button', $props );
11 changes: 11 additions & 0 deletions src/blocks/button/view.asset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
/**
* Frontend asset metadata for the rtcamp/button block.
*
* @package rtCamp\Theme\Elementary
*/

return [
'dependencies' => [],
'version' => filemtime( __DIR__ . '/view.js' ),
];
4 changes: 4 additions & 0 deletions src/blocks/button/view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/**
* Frontend behavior for the rtcamp/button block.
*/
document.documentElement.classList.add( 'has-rtcamp-button-block' );
38 changes: 38 additions & 0 deletions src/blocks/card/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "rtcamp/card",
"title": "Card (rtCamp)",
"category": "design",
"icon": "index-card",
"description": "A card block backed by the shared Card component.",
"attributes": {
"title": {
"type": "string",
"default": "Card title"
},
"description": {
"type": "string",
"default": ""
},
"imageUrl": {
"type": "string",
"default": ""
},
"imageAlt": {
"type": "string",
"default": ""
},
"url": {
"type": "string",
"default": ""
},
"buttonLabel": {
"type": "string",
"default": "Read more"
}
},
"editorScript": "file:./edit.js",
"viewScript": "file:./view.js",
"render": "file:./render.php"
}
11 changes: 11 additions & 0 deletions src/blocks/card/edit.asset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
/**
* Editor asset metadata for the rtcamp/card block.
*
* @package rtCamp\Theme\Elementary
*/

return [
'dependencies' => [ 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element' ],
'version' => filemtime( __DIR__ . '/edit.js' ),
];
Loading
Loading