Extending Block Settings with Vue Inputs: A Deep Dive
Gutenberg, WordPress’s block editor, provides a powerful foundation for creating custom blocks. However, the default settings panel can feel limited when you need more sophisticated input controls beyond simple text fields and checkboxes. This is where integrating Vue.js, a progressive JavaScript framework, shines. Vue’s component-based architecture and declarative rendering allow us to seamlessly extend the Gutenberg block settings panel with rich, interactive UI elements. This blog post will guide you through the process of building a custom Gutenberg block with extended settings using Vue.js components for input. We’ll cover everything from setting up the development environment to deploying your enhanced block.
Part 1: Setting up the Development Environment
Before diving into the code, let’s ensure we have the necessary tools in place. We’ll use npm (or yarn) for package management and Webpack for bundling our Vue components. This setup allows for efficient development and modularity.
- Create a WordPress Plugin: Start by creating a new directory for your plugin. Inside, create a
plugin.php
file with the following basic structure:
<?php
/**
* Plugin Name: My Custom Gutenberg Block with Vue
* Plugin URI: YOUR_PLUGIN_URI
* Description: A custom Gutenberg block with extended settings using Vue.js.
* Version: 1.0.0
* Requires at least: 5.8
* Requires PHP: 7.0
* Author: YOUR_NAME
* Author URI: YOUR_WEBSITE
* License: GPL v2 or later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: my-custom-gutenberg-block
*/
// This line is essential for registering the block in WordPress. We'll define the register function later.
add_action( 'init', 'register_my_custom_block' );
- Install Dependencies: Navigate to the plugin’s directory in your terminal and run:
npm init -y
npm install vue vue-loader webpack webpack-cli @wordpress/scripts --save-dev
This installs Vue.js, Vue Loader (for processing Vue components in Webpack), Webpack, and the @wordpress/scripts
package, which provides helpful utilities for building WordPress plugins.
- Configure Webpack: Create a
webpack.config.js
file in the root of your plugin directory:
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'index.js',
},
module: {
rules: [
{
test: /.vue$/,
loader: 'vue-loader',
},
{
test: /.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js' // required to avoid conflicts
},
extensions: ['.js', '.vue']
},
};
This configures Webpack to bundle our Vue components. We specify the entry point (src/index.js
), output path, and rules for processing Vue and CSS files.
Part 2: Building the Vue Component
Now let’s create the Vue component that will handle our extended settings. Create a directory named src
in your plugin directory and inside it create index.js
and MySettingsPanel.vue
.
src/MySettingsPanel.vue
:
<template>
<div>
<p>Enter your custom text:</p>
<input type="text" v-model="customText">
<p>Select a color:</p>
<select v-model="selectedColor">
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</select>
</div>
</template>
<script>
export default {
data() {
return {
customText: '',
selectedColor: 'red',
};
},
};
</script>
This Vue component includes a text input and a dropdown for selecting a color. The v-model
directive binds the input values to the component’s data.
src/index.js
:
import MySettingsPanel from './MySettingsPanel.vue';
const { registerBlockType } = wp.blocks;
const { __ } = wp.i18n;
const { registerPlugin } = wp.plugins;
registerPlugin('my-custom-gutenberg-block', {
render: () => {
const VueComponent = MySettingsPanel;
return <VueComponent/>
}
});
registerBlockType('my-plugin/my-custom-block', {
title: __('My Custom Block'),
icon: 'align-wide',
category: 'common',
attributes: {
customText: { type: 'string', default: '' },
selectedColor: { type: 'string', default: 'red' },
},
edit: (props) => {
return (
<>
<div className="wp-block-my-plugin-my-custom-block">
<h2>My Custom Block</h2>
<p>Custom Text: {props.attributes.customText}</p>
<p style={{color: props.attributes.selectedColor}}>Colored Text</p>
</div>
{/*This will mount the Vue component in the block's settings panel */}
<MySettingsPanel />
</>
)
},
save: (props) => {
return (
<div className="wp-block-my-plugin-my-custom-block">
<p>{props.attributes.customText}</p>
<p style={{ color: props.attributes.selectedColor }}>Colored Text</p>
</div>
);
},
attributes: {
customText: {
type: 'string',
},
selectedColor: {
type: 'string',
default: 'red',
},
},
});
This Javascript file registers our block with WordPress and links our Vue component to it. The key is the edit
function, where we render our Vue component (MySettingsPanel
) within the block’s editor interface. The attributes
are crucial for communicating data between the Vue component and the WordPress block. We will need to update props
from the edit
function to send data to and receive data from the Vue component. Note that this is a simplified example, and error handling and more robust data management would be needed for production.
Part 3: Integrating with Gutenberg Settings Panel
To properly integrate the Vue component into the Gutenberg settings panel, we need to adjust the edit
function. Currently, the Vue component is rendered directly in the block’s content area. Instead, we’ll use the Gutenberg Inspector controls to manage our settings:
Modified src/index.js
:
import MySettingsPanel from './MySettingsPanel.vue';
import { InspectorControls } from '@wordpress/block-editor';
// ... other imports
registerBlockType('my-plugin/my-custom-block', {
// ... other properties
edit: (props) => {
const { attributes, setAttributes } = props;
return (
<>
<InspectorControls>
<MySettingsPanel
customText={attributes.customText}
selectedColor={attributes.selectedColor}
onChange={(data) => setAttributes(data)}
/>
</InspectorControls>
{/* ... Block content */}
</>
);
},
// ... rest of the block definition
});
We now use the InspectorControls
component from @wordpress/block-editor
to wrap our MySettingsPanel
component. We also pass the attributes
and setAttributes
functions as props to the Vue component. The onChange
prop is crucial: it’s a callback function that updates the block’s attributes whenever the Vue component’s data changes. We pass the new data to setAttributes
, thus keeping WordPress and Vue synchronized. We also need to update the Vue component to use these props:
Modified src/MySettingsPanel.vue
:
<template>
<div>
<p>Enter your custom text:</p>
<input type="text" v-model="customText">
<p>Select a color:</p>
<select v-model="selectedColor">
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</select>
</div>
</template>
<script>
export default {
props: ['customText', 'selectedColor', 'onChange'],
watch: {
customText: {
handler(newVal) {
this.onChange({ customText: newVal });
},
deep: true,
},
selectedColor: {
handler(newVal) {
this.onChange({ selectedColor: newVal });
},
deep: true,
}
},
data() {
return {
};
},
};
</script>
We add props to receive the initial attribute values and the onChange
callback. The watch
property ensures that every change in customText
and selectedColor
is sent back to WordPress via the onChange
prop and update the attribute in the block.
Part 4: Building and Activating the Plugin
Finally, run npm run build
(you might need to create a scripts
section in your package.json
file to define this command: "build": "webpack"
). This will compile your Vue components into the build
directory. Activate your plugin in the WordPress admin panel. You should now see your custom block with the extended settings panel in the editor. Test the inputs to ensure they correctly update the block’s content.
This detailed guide provides a solid foundation for extending Gutenberg block settings with Vue.js. Remember that this is a simplified example. Real-world applications might require more sophisticated state management, error handling, and data validation. This approach however illustrates the core principles of integrating Vue.js into Gutenberg for creating advanced and user-friendly block settings. Further enhancements could include implementing more complex UI components, form validation, and asynchronous data fetching.
Leave a Reply