Dynamic Block without Render PHP

User
we have created
npx @wordpress/create-block@latest –namespace="my-plugin" –slug="my-block" –variant="dynamic"
but don't want to use render.php
Assistant
If you've created a dynamic block using `npx @wordpress/create-block` and prefer not to use `render.php`, you can utilize the `render_callback` function in your block's registration to handle server-side rendering directly in your block's JavaScript file. Here’s how you can set this up:

1. **Update Your Block Registration:**
In your block's main PHP file (usually found in the `src/` directory), you can register your block with a `render_callback` function that handles the rendering logic without using `render.php`.

Here's an example of how to modify your block registration:

function my_plugin_register_my_block() {
       register_block_type('my-plugin/my-block', array(
           'api_version' => 2,
           'render_callback' => 'my_plugin_render_my_block',
           // other block settings...
       ));
   }
   add_action('init', 'my_plugin_register_my_block');

   function my_plugin_render_my_block($attributes) {
       // Logic to generate the block output
       ob_start();
       ?>
       <div class="my-block">
           <h2><?php echo esc_html($attributes['title']); ?></h2>
           <p><?php echo esc_html($attributes['content']); ?></p>
       </div>
       <?php
       return ob_get_clean();
   }

2. **Update Your Block's JavaScript:**
Ensure your JavaScript file defines the attributes you want to use in the block and registers them correctly. For example:

import { registerBlockType } from '@wordpress/blocks';

   registerBlockType('my-plugin/my-block', {
       apiVersion: 2,
       attributes: {
           title: {
               type: 'string',
               source: 'text',
               selector: 'h2',
           },
           content: {
               type: 'string',
               source: 'text',
               selector: 'p',
           },
       },
       edit({ attributes, setAttributes }) {
           // Edit function logic...
       },
       save() {
           // You can return null if you're handling rendering via PHP
           return null;
       },
   });

3. **Remove render.php:**
Since you're not using `render.php`, you can safely remove it from your block directory.

By following these steps, you can effectively create a dynamic block without relying on `render.php`, keeping all rendering logic within your plugin's main PHP file. Let me know if you need any further assistance!

User
use view.js at front end
Assistant
To use Vue.js for rendering your dynamic Gutenberg block on the front end while avoiding the use of `render.php`, you can set up your block to enqueue a Vue.js component. This approach allows you to handle the front-end rendering directly with Vue. Here's how to achieve this:

### Step 1: Set Up Your Block

First, ensure that your block is set up correctly in your PHP file, and make sure to enqueue your Vue.js script.

#### PHP File (e.g., `my-plugin.php`)

function my_plugin_register_my_block() {
    // Register the block
    register_block_type('my-plugin/my-block', array(
        'api_version' => 2,
        'render_callback' => 'my_plugin_render_my_block',
        'editor_script' => 'my-plugin-editor-script',
        // Add this to load your Vue.js script on the front end
        'script' => 'my-plugin-vue-script',
    ));
}
add_action('init', 'my_plugin_register_my_block');

function my_plugin_render_my_block($attributes) {
    // Output a div where the Vue component will be mounted
    return '<div id="my-block" class="my-block"></div>';
}

// Enqueue Vue.js and your Vue component script
function my_plugin_enqueue_scripts() {
    wp_enqueue_script('my-plugin-vue-script', plugin_dir_url(__FILE__) . 'build/my-block.js', array('vue'), '1.0', true);
}
add_action('wp_enqueue_scripts', 'my_plugin_enqueue_scripts');

### Step 2: Create Your Vue Component

Next, you need to create the Vue component that will render your block's content. You can do this in your JavaScript file.

#### Vue Component (e.g., `src/vue/MyBlock.vue`)

<template>
    <div class="my-block">
        <h2>{{ title }}</h2>
        <p>{{ content }}</p>
    </div>
</template>

<script>
export default {
    props: {
        title: {
            type: String,
            required: true,
        },
        content: {
            type: String,
            required: true,
        },
    },
}
</script>

<style>
.my-block {
    /* Add your styles here */
}
</style>

### Step 3: Mount Your Vue Component

Finally, modify your main JavaScript file to mount the Vue component when the block is rendered on the front end.

#### Main JavaScript File (e.g., `src/index.js`)

import { createApp } from 'vue';
import MyBlock from './vue/MyBlock.vue';

document.addEventListener('DOMContentLoaded', () => {
    const blockElement = document.getElementById('my-block');
    if (blockElement) {
        const title = blockElement.getAttribute('data-title');
        const content = blockElement.getAttribute('data-content');

        const app = createApp(MyBlock, {
            title,
            content,
        });

        app.mount(blockElement);
    }
});

### Step 4: Update Your Block Attributes

Ensure that you set up your block attributes to pass down to the Vue component when registering your block. You might need to adjust your block's registration to pass the necessary data through `data-*` attributes.

function my_plugin_render_my_block($attributes) {
    $title = esc_html($attributes['title']);
    $content = esc_html($attributes['content']);

    // Output a div where the Vue component will be mounted, including data attributes
    return '<div id="my-block" class="my-block" data-title="' . $title . '" data-content="' . $content . '"></div>';
}

### Step 5: Build Your Scripts

Make sure to build your scripts using your build tool (Webpack, Vite, etc.) to generate the final JavaScript files. The built file should be correctly enqueued in your PHP.

### Conclusion

With this setup, you can effectively use Vue.js for rendering your Gutenberg block on the front end, while managing the attributes from the block in your Vue component. This method maintains a clean separation of concerns and allows you to leverage the reactivity of Vue.js within your WordPress block. Let me know if you need further clarification or assistance!

User
still want to use save.js to display at front end even we have dynamic block
Assistant
If you want to use a `save.js` file to handle the front-end rendering of a dynamic block in Gutenberg while still leveraging Vue.js, you can configure your block to save static markup in the post content but allow for dynamic data fetching or interaction through Vue.js.

Here's how to set this up:

### Step 1: Create the Block with Dynamic Rendering

1. **Block Registration**: Register your block in your main PHP file, making sure to set up both the `render_callback` for dynamic content and the `editor_script` to enqueue your JavaScript.

#### PHP File (e.g., `my-plugin.php`)

function my_plugin_register_my_block() {
    // Register the block
    register_block_type('my-plugin/my-block', array(
        'api_version' => 2,
        'render_callback' => 'my_plugin_render_my_block', // Dynamic render callback
        'editor_script' => 'my-plugin-editor-script', // For the block editor
        'script' => 'my-plugin-vue-script', // For front-end Vue.js
    ));
}
add_action('init', 'my_plugin_register_my_block');

function my_plugin_render_my_block($attributes) {
    // Here, we can return static markup to be saved in the post content
    $title = esc_html($attributes['title']);
    $content = esc_html($attributes['content']);

    return '<div id="my-block" class="my-block" data-title="' . $title . '" data-content="' . $content . '"></div>';
}

### Step 2: Set Up Your JavaScript Files

2. **Editor Script**: Create the block's editor script to define the attributes and how the block behaves in the editor.

#### Editor Script (e.g., `src/index.js`)

import { registerBlockType } from '@wordpress/blocks';

registerBlockType('my-plugin/my-block', {
    apiVersion: 2,
    attributes: {
        title: {
            type: 'string',
            source: 'text',
            selector: 'h2',
        },
        content: {
            type: 'string',
            source: 'text',
            selector: 'p',
        },
    },
    edit({ attributes, setAttributes }) {
        return (
            <div>
                <input
                    type="text"
                    value={attributes.title}
                    onChange={(e) => setAttributes({ title: e.target.value })}
                />
                <textarea
                    value={attributes.content}
                    onChange={(e) => setAttributes({ content: e.target.value })}
                ></textarea>
            </div>
        );
    },
    save() {
        // This will generate static markup that is saved in the post content
        return null; // Returning null means dynamic rendering is handled by PHP
    },
});

3. **Vue Component**: Create your Vue component to handle the dynamic behavior or UI on the front end.

#### Vue Component (e.g., `src/vue/MyBlock.vue`)

<template>
    <div class="my-block">
        <h2>{{ title }}</h2>
        <p>{{ content }}</p>
    </div>
</template>

<script>
export default {
    props: {
        title: {
            type: String,
            required: true,
        },
        content: {
            type: String,
            required: true,
        },
    },
}
</script>

<style>
.my-block {
    /* Add your styles here */
}
</style>

### Step 3: Set Up the Front-End Script

4. **Front-End Script (e.g., `src/save.js`)**: This script will handle the mounting of your Vue component using the static attributes set in the post content.

#### Front-End Script (e.g., `src/save.js`)

import { createApp } from 'vue';
import MyBlock from './vue/MyBlock.vue';

document.addEventListener('DOMContentLoaded', () => {
    const blockElement = document.getElementById('my-block');
    if (blockElement) {
        const title = blockElement.getAttribute('data-title');
        const content = blockElement.getAttribute('data-content');

        const app = createApp(MyBlock, {
            title,
            content,
        });

        app.mount(blockElement);
    }
});

### Step 4: Enqueue the Front-End Script

5. **Enqueue Your Front-End Script**: Make sure to enqueue your Vue component script in the `my_plugin_enqueue_scripts` function.

#### Updated Enqueue Function

function my_plugin_enqueue_scripts() {
    // Enqueue Vue.js if you haven't done it already
    wp_enqueue_script('vue-js', 'https://cdn.jsdelivr.net/npm/vue@next');

    // Enqueue your Vue component script
    wp_enqueue_script('my-plugin-vue-script', plugin_dir_url(__FILE__) . 'build/save.js', array('vue-js'), '1.0', true);
}
add_action('wp_enqueue_scripts', 'my_plugin_enqueue_scripts');

### Conclusion

With this setup, your block will save static markup to the database, and when it renders on the front end, Vue.js will dynamically mount the component based on the attributes provided. This allows you to combine the flexibility of dynamic blocks with the reactivity of Vue.js.

If you have any further questions or need additional modifications, feel free to ask!

Leave a Comment

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