This is a simple WordPress plugin template for you to easily add your web components to WordPress.
<?php
//index.php
/*
Plugin Name: DIY EZ Web Components
Plugin URI: https://undead.institute/diy-ez-web-components/
Description: Easily Add Web Components to Your WordPress Site
Version: 1.0.0
Author: John Rhea
Author URI: https://johnrhea.com
License: GPL2
License URI: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*/
/** How to use this template **/
/*
1. Set the $webcompname variable to your web component's name e.g. zombie-profile for <zombie-profile></zombie-profile>
2. Set the path to your JavaScript file.
3. Set the path to your CSS file. If not using one, set to false.
4. Paste your HTML Template content into diy_ezwebcomp_footer().
5. Edit diy-ezwebcomp-block.js with the fields you need
*/
$webcompname = 'zombie-profile';
$path2js = get_template_directory_uri() . '/js/ezwebcomp.js';
$path2style = get_template_directory_uri() . '/ezwebcomp.css'; //Set $path2style to false if not using this
function diy_ezwebcomp_footer()
{
?>
<!-- Replace me with your HTML template code -->
<?php
}
add_action('wp_footer', 'diy_ezwebcomp_footer');
wp_enqueue_script($webcompname . '_js', $path2js, '', '1.0', true);
if ($path2style) {
wp_enqueue_style($webcompname . '_style', $path2style, '', '1.0', 'screen');
}
function add_diy_ezwebcomp_to_kses_allowed($the_allowed_tags)
{
global $webcompname;
$the_allowed_tags[$webcompname] = array();
foreach ($the_allowed_tags as &$tag) {
$tag['slot'] = true;
$tag['part'] = true;
}
return $the_allowed_tags;
}
add_filter('wp_kses_allowed_html', 'add_diy_ezwebcomp_to_kses_allowed');
//Custom block PHP
function diy_ezwebcomp_register_block()
{
global $webcompname;
//Enqueues the JavaScript needed to build the custom block
wp_register_script(
'diy-ezwebcomp',
plugins_url('diy-ezwebcomp-block.js', __FILE__),
array('wp-blocks', 'wp-element', 'wp-editor'),
filemtime(plugin_dir_path(__FILE__) . 'diy-ezwebcomp-block.js')
);
//Enqueues the CSS file for anything you need in the editor
wp_register_style(
'diy-ezwebcomp',
plugins_url('diy-ezwebcomp-style.css', __FILE__),
array(),
filemtime(plugin_dir_path(__FILE__) . 'diy-ezwebcomp-style.css')
);
//Registers the actual block
register_block_type('diy-ezwebcomp/' . $webcompname, array(
'editor_style' => 'diy-ezwebcomp',
'editor_script' => 'diy-ezwebcomp',
));
}
add_action('init', 'diy_ezwebcomp_register_block');
Code language: HTML, XML (xml)//diy-ezwebcomp-block.js
//set the variable below to the same as $webcompname from index.php
var webcompname = 'zombie-profile',
userFriendlyTitle = 'Zombie Profile';
(function (blocks, editor, element, components) {
var el = element.createElement;
var RichText = editor.RichText;
var MediaUpload = editor.MediaUpload;
blocks.registerBlockType('diy-ezwebcomp/' + webcompname, {
title: userFriendlyTitle,
icon: 'id-alt',
category: 'layout',
//The attributes are all the different fields to use.
attributes: {
textinput: {
type: 'string', //the type of content
source: 'text', //where to pull the info from e.g. the text of an element, from an attribute, from child elements etc.
selector: '.textinput', //selectors are how Gutenberg selects and grabs the content. These should be unique within an instance of a block. If you only have one img or one ul, you can use element selectors.
},
mediaID: {
type: 'number',
},
mediaURL: {
type: 'string',
source: 'attribute',
selector: 'img',
attribute: 'src',
},
list: {
type: 'array',
source: 'children',
selector: 'ul',
},
},
//the edit function deals with how the information will be displayed in the editor.
edit: function (props) {
var attributes = props.attributes;
var onSelectImage = function (media) {
return props.setAttributes({
mediaURL: media.url,
mediaID: media.id,
});
};
return el(
'div', {
className: props.className
},
el('h3', {}, 'Text Input'),
el(RichText, {
tagName: 'p',
className: 'textinput',
placeholder: 'Some Text Input…',
value: attributes.textinput,
onChange: function (value) {
props.setAttributes({
textinput: value
});
},
}),
el( //an image
'div', {
className: 'pic'
},
el(MediaUpload, {
onSelect: onSelectImage,
allowedTypes: 'image',
value: attributes.mediaID,
render: function (obj) {
return el(
components.Button, {
className: attributes.mediaID ?
'image-button' : 'button button-large',
onClick: obj.open,
},
!attributes.mediaID ?
'Upload Image' :
el('img', {
src: attributes.mediaURL
})
);
},
})
),
el('h3', {}, 'List'), //heading
el(RichText, { //where you add list items one at a time
tagName: 'ul',
multiline: 'li', //creates a new li when you hit enter
placeholder: 'Write a list…',
value: attributes.list,
onChange: function (value) {
props.setAttributes({
list: value
});
},
className: 'list',
}),
);
},
save: function (props) {
var attributes = props.attributes;
return el(
webcompname, //the component name
{}, //the web component does not need any HTML attributes so this can remain empty
attributes.mediaURL && //ensure a URL exists before you print it
el('img', { //print the image
src: attributes.mediaURL,
slot: 'profile-image'
}),
attributes.textinput &&
el(RichText.Content, { //print the name
tagName: 'span',
slot: 'text-input',
className: 'textinput',
value: attributes.textinput,
}),
attributes.list[0] && //Since list's type is array we need to verify there is something in the first element.
el(RichText.Content, {
tagName: 'ul',
slot: 'list',
value: attributes.list,
}), );
},
});
})(
//import the dependencies
window.wp.blocks,
window.wp.blockEditor,
window.wp.element,
window.wp.components
);Code language: PHP (php)/* diy-ez-webcomp-style.css */
#editor .pic img {
max-width: 300px;
height: 300px;
}
#editor .pic button.components-button {
overflow: visible;
height: auto;
}Code language: CSS (css)