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.

  1. 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' );
  1. 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.

  1. 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

Your email address will not be published. Required fields are marked *

Trending