Created
December 18, 2018 18:08
-
-
Save javiermarinros/d415f17b4650995458e54cd416b420aa to your computer and use it in GitHub Desktop.
Easy shortcode and Gutenberg block creation. Shared render function and no JS coding required
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function create_block($namespace, $name, $params, $render_callback) | |
{ | |
static $config = null; | |
if (!isset($config) && is_admin()) { | |
$config = []; | |
add_action( | |
'init', | |
function () use ($namespace, &$config) { | |
wp_add_inline_script('wp-editor', 'loadGutenbergShortcodeBlocks();'); | |
add_action( | |
'admin_footer', | |
function () use ($namespace, &$config) { | |
?> | |
<script> | |
function loadGutenbergShortcodeBlocks() { | |
var wp = window.wp; | |
var registerBlockType = wp.blocks.registerBlockType; | |
var el = wp.element.createElement; | |
var __ = wp.i18n.__; | |
function clone(obj) { | |
if (null == obj || "object" != typeof obj) return obj; | |
var copy = obj.constructor(); | |
for (var attr in obj) { | |
if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr]; | |
} | |
return copy; | |
} | |
var config = <?= json_encode($config) ?>; | |
for (var blockName in config) { | |
if (!config.hasOwnProperty(blockName)) { | |
continue; | |
} | |
var blockConfig = config[blockName]; | |
var generateController = function (blockConfig) { | |
return function (props) { | |
var content = [el('h5', {}, blockConfig.title)]; | |
for (var attributeName in blockConfig.attributes) { | |
if (!blockConfig.attributes.hasOwnProperty(attributeName)) { | |
continue; | |
} | |
var attrConfig = blockConfig.attributes[attributeName]; | |
if (attrConfig.options) { | |
var editor = el(wp.components.SelectControl, { | |
value: props.attributes[attributeName], | |
options: attrConfig.options, | |
onChange: function (content) { | |
props.setAttributes({[attributeName]: content}); | |
}, | |
}); | |
} else { | |
var editor = el(wp.editor.PlainText, { | |
value: props.attributes[attributeName], | |
placeholder: attrConfig.label, | |
required: true, | |
onChange: function (content) { | |
props.setAttributes({[attributeName]: content}); | |
}, | |
}); | |
} | |
content.push(el('label', {}, attrConfig.label, editor)); | |
} | |
return el('div', {style: {backgroundColor: '#f8f9f9', padding: '14px'}}, content); | |
} | |
}; | |
registerBlockType(<?= json_encode($namespace) ?> +'/' + blockName, { | |
title: blockConfig.title, | |
category: <?= json_encode($namespace) ?>, | |
icon: blockConfig.icon, | |
attributes: clone(blockConfig.attributes), | |
edit: generateController(blockConfig), | |
save: function () { | |
return null; | |
} | |
}); | |
} | |
}; | |
</script> | |
<?php | |
}, | |
9999 | |
); | |
// Register block category | |
add_filter( | |
'block_categories', | |
function ($categories, $post) use ($namespace) { | |
if ($post->post_type !== 'post') { | |
return $categories; | |
} | |
return array_merge( | |
$categories, | |
[ | |
[ | |
'slug' => $namespace, | |
'title' => $namespace | |
], | |
] | |
); | |
}, | |
10, | |
2 | |
); | |
} | |
); | |
} | |
$config[$name] = $params; | |
$render = function ($block_params) use ($render_callback, $params) { | |
// Set default parameters | |
foreach ($params['attributes'] as $k => $param_info) { | |
if (!array_key_exists($k, $block_params)) { | |
$block_params[$k] = $param_info['default']; | |
} | |
} | |
return call_user_func($render_callback, $block_params); | |
}; | |
// Register shortcode | |
add_shortcode($name, $render); | |
// Register Gutenberg block | |
if (function_exists('register_block_type')) { | |
add_action( | |
'init', | |
function () use ($namespace, $name, $render) { | |
register_block_type( | |
"{$namespace}/{$name}", | |
[ | |
'attributes' => [ | |
'match' => ['type' => 'string'], | |
'side' => ['type' => 'string'] | |
], | |
'render_callback' => $render | |
] | |
); | |
} | |
); | |
} | |
} | |
// Usage | |
create_block( | |
'mycompany', | |
'hello-word', | |
[ | |
'title' => __('Hello world'), | |
'icon' => 'groups', | |
'attributes' => [ | |
'name' => [ | |
'label' => __('Name'), | |
'type' => 'string', | |
'default' => 'World' | |
] | |
] | |
], | |
function ($params) { | |
return "Hello " . $params['name']; | |
} | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment