Support

Account

Home Forums Backend Issues (wp-admin) ACF add preview image for custom blocks

Solving

ACF add preview image for custom blocks

  • Hi all! I ran into a problem that there is no way to put a picture as a preview of the created block.

    I solved the problem through JS, so that when I hover the mouse over the block, it takes its url to picture, and makes it as background on preview block.

    How to do this:

    When you register block in block.json add “attributes” like that:

    {
        "name": "acf/price",
        "title": "Price",
        "description": "Block with price",
        "category": "custom_blocks",
        "icon": "money-alt",
        "keywords": ["Price"],
        "acf": {
            "mode": "edit",
            "renderTemplate": "price.php"
        },
        "align": "full",
        "attributes": {
            "previewImage": {
                "type": "string",
                "default": "YOUR_IMAGE_URL"
            }
        }
    }

    Don’t forget to change YOUR_IMAGE_URL to your image url.

    Then make a js file. My file name “admin_custom.js”:

    document.addEventListener("mouseover", function(e) {
    	// Selector to preview block where you want to show background image
    	const previewContainer = document.querySelector('.block-editor-inserter__preview-content-missing');
    
    	if (!previewContainer) {
    		return;
    	}
    
    	if (e.target.closest('.block-editor-block-types-list__item')) {
    		const hoveredBlock = e.target.closest('.block-editor-block-types-list__item');
    
    		// to find a name of the block we can extract it from block classes
    
    		// Retrieve classes from the block on which the mouse is hovered
    		const blockClasses = hoveredBlock.className.split(' ');
    
    		// Finding a class that starts with "editor-block-list-item-acf-"
    		const blockClass = blockClasses.find(cls => cls.startsWith("editor-block-list-item-acf-"));
    
    		// If such a class is found, extract the name from it
    		if (blockClass) {
    			const blockName = blockClass.replace("editor-block-list-item-acf-", "");
    
    			// Get the image URL for this block
    			const imageUrl = wp.data.select('core/blocks').getBlockType("acf/" + blockName)?.attributes?.previewImage?.default;
    
    			// adding our styles if there is a link to the picture
    			if (imageUrl) {
    				previewContainer.style.background = "url(${imageUrl}) no-repeat center";
    				previewContainer.style.backgroundSize = 'contain';
    				previewContainer.style.fontSize = '0px';
    			} else {
    				// remove our styles if there is no link
    				previewContainer.style.background = '';
    				previewContainer.style.backgroundSize = '';
    				previewContainer.style.fontSize = '';
    			}
    		}
    	}
    	});

    To add this file to the admin panel, add the following code to functions.php in your theme folder (don’t forget to change the url if yours is different ‘/js/admin_custom.js’):

    function enqueue_admin_scripts_and_styles() {
    	wp_enqueue_script('admin-scripts', get_template_directory_uri() . '/js/admin_custom.js', array('wp-blocks', 'wp-element', 'wp-hooks'), '', true);
    }
    add_action('admin_enqueue_scripts', 'enqueue_admin_scripts_and_styles');

    That’s all. Now you have a background image in your preview.

    ACF custom blocks preview image

  • This one worked better for me, but you have a typo in the js.
    Your using double quotes instead of the backtick for the image url.

    You’re a lifesaver tysm!

  • This is brilliant, it works like a charm with the backticks as RichCuer mentionned.

    I edited a bit of the imageUrl const if you want to put the image in the same block folder:

    const preimageUrl = wp.data.select('core/blocks').getBlockType("acf/" + blockName)?.attributes?.previewImage?.default;
    //Not ideal to make two const, but you get the idea, the next line write the absolute URL with the theme folder as template
    const imageUrl = passed_data.templateUrl+'/blocks/'+blockName+'/'+preimageUrl;

    And in the functions.php:

    function enqueue_admin_scripts_and_styles() {
    	wp_enqueue_script('admin-scripts', get_template_directory_uri() . '/js/admin_custom.js', array('wp-blocks', 'wp-element', 'wp-hooks'), '', true);
    //We use wp_localize_script to pass data
    wp_localize_script( 'admin-scripts', 'passed_data', array( 'templateUrl' => get_stylesheet_directory_uri() ) );
    }
    add_action('admin_enqueue_scripts', 'enqueue_admin_scripts_and_styles');

    Then, you can add it to the block.json:

    "previewImage": {
                "type": "string",
                "default": "preview.jpg"
            }
Viewing 3 posts - 1 through 3 (of 3 total)

You must be logged in to reply to this topic.