Skip to content

Instantly share code, notes, and snippets.

@carlodaniele
Created September 28, 2022 14:56
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carlodaniele/5f3dba8fff19d8ea836bdef5a2be7556 to your computer and use it in GitHub Desktop.
Save carlodaniele/5f3dba8fff19d8ea836bdef5a2be7556 to your computer and use it in GitHub Desktop.
An example Gutenberg block for Kinsta readers
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "ka-example-block/ka-example-block",
"version": "0.1.0",
"title": "Kinsta Academy Block",
"category": "widgets",
"icon": "superhero-alt",
"description": "An example block for Kinsta Academy students",
"supports": {
"html": false
},
"attributes": {
"content": {
"type": "string",
"source": "html",
"selector": "p"
},
"align": {
"type": "string",
"default": "none"
},
"backgroundColor": {
"type": "string"
},
"textColor": {
"type": "string"
},
"kaLink": {
"type": "string",
"default": ""
},
"linkLabel": {
"type": "string",
"default": "Check it out!"
},
"hasLinkNofollow": {
"type": "boolean",
"default": false
}
},
"styles": [
{
"name": "default",
"label": "Default",
"isDefault": true
},
{
"name": "border",
"label": "Border"
}
],
"textdomain": "ka-example-block",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css"
}
import { registerBlockType } from "@wordpress/blocks";
import { __ } from "@wordpress/i18n";
import {
useBlockProps,
InnerBlocks
} from "@wordpress/block-editor";
const TEMPLATE = [ [ 'core/columns', { backgroundColor: 'yellow', verticalAlignment: 'center' }, [
[ 'core/column', { templateLock: 'all' }, [
[ 'core/image' ],
] ],
[ 'core/column', { templateLock: 'all' }, [
[ 'ka-example-block/ka-example-block', { placeholder: 'Enter side content...' } ],
] ],
] ] ];
registerBlockType('ka-example-block/ka-example-container-block', {
title: __( 'KA Container block', 'ka-example-block' ),
category: 'design',
edit( { className } ) {
return(
<div className={ className }>
<InnerBlocks
template={ TEMPLATE }
templateLock="all"
/>
</div>
)
},
save() {
const blockProps = useBlockProps.save();
return(
<div { ...blockProps }>
<InnerBlocks.Content />
</div>
)
},
});
/**
* Retrieves the translation of text.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-i18n/
*/
import { __ } from '@wordpress/i18n';
/**
* React hook that is used to mark the block wrapper element.
* It provides all the necessary props like the class name.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-block-editor/#useblockprops
*/
import {
useBlockProps,
RichText,
AlignmentControl,
BlockControls,
InspectorControls,
PanelColorSettings
} from '@wordpress/block-editor';
import {
TextControl,
PanelBody,
PanelRow,
ToggleControl,
ExternalLink
} from '@wordpress/components';
/**
* Lets webpack process CSS, SASS or SCSS files referenced in JavaScript files.
* Those files can contain any CSS code that gets applied to the editor.
*
* @see https://www.npmjs.com/package/@wordpress/scripts#using-css
*/
import './editor.scss';
/**
* The edit function describes the structure of your block in the context of the
* editor. This represents what the editor will render when the block is used.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#edit
*
* @return {WPElement} Element to render.
*/
export default function Edit( { attributes, setAttributes } ) {
const { content, align, backgroundColor, textColor, kaLink, linkLabel, hasLinkNofollow } = attributes;
const onChangeContent = ( newContent ) => {
setAttributes( { content: newContent } )
}
const onChangeAlign = ( newAlign ) => {
setAttributes( {
align: newAlign === undefined ? 'none' : newAlign,
} )
}
const blockProps = useBlockProps( {
className: `has-text-align-${ align }`
} );
const onChangeBackgroundColor = ( newBackgroundColor ) => {
setAttributes( { backgroundColor: newBackgroundColor } )
}
const onChangeTextColor = ( newTextColor ) => {
setAttributes( { textColor: newTextColor } )
}
const onChangeKaLink = ( newKaLink ) => {
setAttributes( { kaLink: newKaLink === undefined ? '' : newKaLink } )
}
const onChangeLinkLabel = ( newLinkLabel ) => {
setAttributes( { linkLabel: newLinkLabel === undefined ? '' : newLinkLabel } )
}
const toggleNofollow = () => {
setAttributes( { hasLinkNofollow: ! hasLinkNofollow } )
}
return (
<div
{ ...blockProps }
style={ { backgroundColor: backgroundColor } }
>
<InspectorControls>
<PanelColorSettings
title={ __( 'Color settings', 'ka-example-block' ) }
initialOpen={ false }
colorSettings={ [
{
value: textColor,
onChange: onChangeTextColor,
label: __( 'Text color', 'ka-example-block' )
},
{
value: backgroundColor,
onChange: onChangeBackgroundColor,
label: __( 'Background color', 'ka-example-block' )
}
] }
/>
<PanelBody
title={ __( 'Link Settings', 'ka-example-block' )}
initialOpen={true}
>
<PanelRow>
<fieldset>
<TextControl
label={__( 'KA link', 'ka-example-block' )}
value={ kaLink }
onChange={ onChangeKaLink }
help={ __( 'Add your Academy link', 'ka-example-block' )}
/>
</fieldset>
</PanelRow>
<PanelRow>
<fieldset>
<TextControl
label={__( 'Link label', 'ka-example-block' )}
value={ linkLabel }
onChange={ onChangeLinkLabel }
help={ __( 'Add link label', 'ka-example-block' )}
/>
</fieldset>
</PanelRow>
<PanelRow>
<fieldset>
<ToggleControl
label="Add rel = nofollow"
help={
hasLinkNofollow
? 'Has rel nofollow.'
: 'No rel nofollow.'
}
checked={ hasLinkNofollow }
onChange={ toggleNofollow }
/>
</fieldset>
</PanelRow>
</PanelBody>
</InspectorControls>
<BlockControls>
<AlignmentControl
value={ align }
onChange={ onChangeAlign }
/>
</BlockControls>
<RichText
tagName="p"
onChange={ onChangeContent }
allowedFormats={ [ 'core/bold', 'core/italic' ] }
value={ content }
placeholder={ __( 'Write your text...' ) }
style={ { textAlign: align, color: textColor } }
/>
<ExternalLink
href={ kaLink }
className="ka-button"
rel={ hasLinkNofollow ? "nofollow" : "" }
>
{ linkLabel }
</ExternalLink>
</div>
);
}
/**
* The following styles get applied inside the editor only.
*
* Replace them with your own styles or remove the file completely.
*/
.wp-block-ka-example-block-ka-example-block {
border: 1px dotted #f00;
}
/**
* Registers a new block provided a unique name and an object defining its behavior.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-registration/
*/
import { registerBlockType } from '@wordpress/blocks';
/**
* Lets webpack process CSS, SASS or SCSS files referenced in JavaScript files.
* All files containing `style` keyword are bundled together. The code used
* gets applied both to the front of your site and to the editor.
*
* @see https://www.npmjs.com/package/@wordpress/scripts#using-css
*/
import './style.scss';
/**
* Internal dependencies
*/
import Edit from './edit';
import save from './save';
import metadata from './block.json';
import './container';
/**
* Every block starts by registering a new block type definition.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-registration/
*/
registerBlockType( metadata.name, {
/**
* @see ./edit.js
*/
edit: Edit,
/**
* @see ./save.js
*/
save,
} );
/**
* React hook that is used to mark the block wrapper element.
* It provides all the necessary props like the class name.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-block-editor/#useblockprops
*/
import { useBlockProps, RichText } from '@wordpress/block-editor';
/**
* The save function defines the way in which the different attributes should
* be combined into the final markup, which is then serialized by the block
* editor into `post_content`.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#save
*
* @return {WPElement} Element to render.
*/
export default function save( { attributes } ) {
const { content, align, backgroundColor, textColor, kaLink, linkLabel, hasLinkNofollow } = attributes;
const blockProps = useBlockProps.save( {
className: `has-text-align-${ align }`
} );
return (
<div
{ ...blockProps }
style={ { backgroundColor: backgroundColor } }
>
<RichText.Content
tagName="p"
value={ content }
style={ { color: textColor } }
/>
<p>
<a
href={ kaLink }
className="ka-button"
rel={ hasLinkNofollow ? "nofollow" : "noopener noreferrer" }
>
{ linkLabel }
</a>
</p>
</div>
);
}
/**
* The following styles get applied both on the front of your site
* and in the editor.
*
* Replace them with your own styles or remove the file completely.
*/
.wp-block-ka-example-block-ka-example-block {
background-color: #21759b;
color: #fff;
padding: 2px;
&.is-style-default{
border: 0;
}
&.is-style-border{
border: 2px solid #F00;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment