0

I created a custom gutenberg block that contain two images. The blocks works fine until y reload the editor page or I close it and come back and my block has this message: "This block contains unexpected or invalid content." When I click on "Resolve" it marks the closing tag in the img tags.enter image description here

export default function save({ attributes}) {
  
      const blockProps = useBlockProps.save();
      return (
  
      <div  { ...blockProps }>
          
      <div className='col-text col'>
          <div className='name-icon'>
          <figure className='icon'>
          <a href={attributes.customUrl}>
          <img
                  className="icon-app"
                  src={ attributes.mediaURL }
                  alt="icono app"
              />
              </a>
          </figure>
          <h4>{attributes.softwareName}</h4>
          </div>
          <p>{attributes.softwareDescription}</p>
      </div>
      <figure className='col col-image'>
          <a href={attributes.customUrl}>
              <img src={ bannerImg } alt='imagen banner descarga' style='width: 100%;'></img>
          </a>
      </figure>
      
      </div>
  
      );
  
}

export default function Edit({attributes, setAttributes}) {
    

    return (
        <div className='banner-bsc' { ...useBlockProps() }>
        <div className='col-text col'>
            <div className='col-icon'>
        <MediaUpload
                    onSelect={
                        ( media ) => setAttributes( { mediaURL: media.url,
                                                        mediaID: media.id, })
                      }
                    allowedTypes="image"
                    value={ attributes.mediaID }
                    render={ ( { open } ) => (
                        <Button
                            className={
                                attributes.mediaID ? 'image-button' : 'button button-large'
                            }
                            onClick={ open }
                        >
                            { ! attributes.mediaID ? (
                                __( 'Sube el icono de la app', 'bsc-blocks' )
                            ) : (
                                <img
                                    className='icon-app'
                                    src={ attributes.mediaURL }
                                    alt={ __(
                                        'Sube el icono de la app',
                                    ) }
                                />
                            ) }
                        </Button>
                    ) }
                />
                </div>
        <RichText
                tagName="h4"
                placeholder={ __(
                    'CYPE Architecture'
                ) }
                value={ attributes.softwareName }
                onChange={( val ) => setAttributes( { softwareName: val }) }
                className="nombre-programa"
            />
            <RichText
                tagName="p"
                placeholder={ __(
                    '3D architectural modelling program, specifically designed for multidisciplinary collaboration.'
                ) }
                value={ attributes.softwareDescription }
                onChange={( val ) => setAttributes( { softwareDescription: val }) }
                className="descripcion-programa"
            />
        
            
        </div>
        <figure className='col col-image'>
        <TextControl
            label="Url banner"
            value={ attributes.customUrl }
            onChange={ ( val ) => setAttributes( {customUrl: val} ) }
        />
            <img src={ bannerImg } />
        </figure>
        </div>
    );
}
{
    "$schema": "https://schemas.wp.org/trunk/block.json",
    "apiVersion": 2,
    "name": "create-block/banner-descarga",
    "version": "0.1.0",
    "title": "Banner descarga",
    "category": "bimservercenter-categories",
    "icon": "smiley",
    "description": "Example block scaffolded with Create Block tool.",
    "supports": {
        "html": false
    },
    "textdomain": "banner-descarga",
    "editorScript": "file:./index.js",
    "editorStyle": "file:./index.css",
    "style": "file:./style-index.css", 
    "attributes": {
        "softwareName": {
            "type": "string",
            "source": "text",
            "selector": "div",
            "default": "CYPE Architecture"
        },
        "softwareDescription": {
            "type": "string",
            "source": "text",
            "selector": "div",
            "default": "3D architectural modelling program, specifically designed for multidisciplinary collaboration."
        }, 
        "customUrl" : {
            "type": "string",
            "source": "attribute",
            "selector": "a",
            "attribute": "href",
            "default": "https://store.bimserver.center/en/"

        },
        "mediaID": {
            "type": "number"
        },
        "mediaURL": {
            "type": "string",
            "source": "attribute",
            "selector": "img",
            "attribute": "src"
        }
        
    }
}


lauselfe
  • 3
  • 3
  • Can you please attach your code of edit.js and the attribute you have defined in index.js? – Krunal Bhimajiyani Nov 15 '22 at 05:44
  • All attached :) – lauselfe Nov 15 '22 at 08:11
  • This may be an issue with the parser itself, [this question](https://stackoverflow.com/questions/14860492/how-to-close-img-tag-properly) highlights that the self closing tag `` you have used is perfectly valid for HTML5, it could be that the parser itself is unhappy since it cannot understand the self close. Does your code work if you left it as ``? – Harrison Nov 15 '22 at 13:06
  • I can't leave the tag without the closing tag because it's an jsx element in the code and it needs a closing tag. – lauselfe Nov 15 '22 at 14:28
  • In my experience, everytime this happens it is: your edit HTML does not match the saved one. This may be you not doing the same thing in edit and in save - OR it could be that you are actually not saving to existing variables, or saving a integer to a string... – Frizzant Nov 21 '22 at 14:36

1 Answers1

0

In your block.json, the attributes softwareName and softwareDescription both have "source": "text" and "selector": "div" which matches the text content of the outermost <div>...</div>. Any change to any attribute value from Edit() then invalidates the block as the content of <div>...</div> has changed.

There is also a mismatch in your save() function as the attribute selectors don't match the generated content, ref:

export default function save({ attributes}) {
    ...
      <div className='col-text col'>
          <div className='name-icon'>
          ...
          <h4>{attributes.softwareName}</h4> // softwareName selector should be "h4"
          </div>
          <p>{attributes.softwareDescription}</p> // softwareDescription selector should be "p"
      </div>
    ...
    ); 
}

There are multiple selector matches for <div> and more than one match for selectors <a> and <img>.

To resolve this, each attribute selector should be specific and unique. In your Edit() function, you have already assigned unique classnames to the RichText components; so you can use these as the attribute selectors.

Eg. for softwareName:

Edit()

<RichText
    tagName="h4"
    ...
    className="nombre-programa"
/>

save()

<h4 className="nombre-programa">{attributes.softwareName}</h4>

block.json

"softwareName": {
    "type": "string",
    "source": "text",
    "selector": ".nombre-programa",
    "default": "CYPE Architecture"
},

Once you have updated your attributes and save() function, the generated output from save() should map to the attributes and the block save correctly.

S.Walsh
  • 3,105
  • 1
  • 12
  • 23