4
votes

I am creating a custom WordPress Gutenberg block and I want to use image assets (PNGs, JPGs) from my plugin folder, to be shown in both the Gutenberg editor and on the rendered page.

I am using Webpack to bundle my files for JS and SCSS. I tried adding the webpack image loader, which saves images into an 'assets' folder in my main plugin directory.

However, when I try to use my image assets from my Block's main JS file, I cannot find a way to access the full URL path of my images as running on my WordPress server, currently running in a docker container on localhost.

My hope was to find a WordPress method to return the path of my plugin directory, and use that to point to the image assets regardless of how they are bundled, but I have not been able to find a solution in the documentation.

It's possible to get the plugin directory using PHP using WordPress' built-in function:

function _get_plugin_directory() {
  return __DIR__;
}

This seems like it could help, however I do not know if it's possible to pass the returned plugin path into my JS file.

My plugin structure looks like this:

/assets // generated by Webpack
  - image.png
  - main.js
/blocks
  /block-example
    - image.png // <-- My image asset
    - index.js // <-- I want to use image.png here
  - index.js // loads in my block
blocks.php

The index.js file is where I want to show the image, using the standard WordPress edit and save functions:

import image from './image.png';

edit: props => {
  ...
  <img src={image} />
}

In the WordPress Gutenberg editor, images point to just the image file name (./image.png or assets/image.png etc), instead of the full path of the image where it sits inside the plugin directory (ie localhost:8080/plugins/my-blocks/assets/image.png) which results in the image not being found.

1

1 Answers

10
votes

I'm still looking into whether there's an official Gutenberg way to do this, but for now I've got this working in my plugin with wp_localize_script.

This works to pass data from PHP into enqueued Javascript so that data usually only accessible in PHP is accessible in Javascript as well.

So (likely inside blocks.php from your example), you would have something like:

wp_enqueue_script(
    'my-main-script',
    plugins_url( 'assets/main.js', __FILE__ ),
    array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-editor', 'wp-components' ),
    '20190804',
    true
);

You can then enqueue any values you want to pass into your JS:

wp_localize_script(
    'my-main-script',
    'js_data',
    array(
        'my_image_url' => plugins_url( 'blocks/block-example/image.png', __FILE__ )
    )
);

This will ensure that the image path is accessible to javascript. Then from within your block itself, you can reference it:

<img src={js_data.my_image_url} />

You should now see your static image asset rendered within your block.