JavaScript for WordPress › Forums › Gutenberg Development › Error in
- This topic has 9 replies, 2 voices, and was last updated 6 years, 4 months ago by David Perez.
-
AuthorPosts
-
April 9, 2018 at 7:16 am #44680David PerezParticipant
Hello!
I’ve writting a block, but it gives me this error, but I don’t understand it…
Uncaught Error: Module build failed: SyntaxError: Adjacent JSX elements must be wrapped in an enclosing tag (237:20)
[0m [90m 235 | [39m [33m<[39m[33mbutton[39m[33m>[39m[33m<[39m[33ma[39m href[33m=[39m{ url }[33m>[39m{ text }[33m<[39m[33m/[39m[33ma[39m[33m>[39m[33m<[39m[33m/[39m[33mbutton[39m[33m>[39m
[90m 236 | [39m [33m<[39m[33m/[39m[33mdiv[39m[33m>[39m
[31m[1m>[22m[39m[90m 237 | [39m [33m<[39m[33mdiv[39m [36mclass[39m[33m=[39m[32m”one-third”[39m[33m>[39m
[90m | [39m [31m[1m^[22m[39m
[90m 238 | [39m [33m<[39m[33mp[39m[33m>[39m
[90m 239 | [39m [33m<[39m[33mimg[39m
[90m 240 | [39m src[33m=[39m{ imgURL }[0mat eval (1:1)
at Object.<anonymous> (editor.blocks.js:78)
at __webpack_require__ (editor.blocks.js:20)
at eval (index.js?8193:1)
at Object.<anonymous> (editor.blocks.js:71)
at __webpack_require__ (editor.blocks.js:20)
at editor.blocks.js:63
at editor.blocks.js:66Any help please?
`/**
* Block dependencies
*/
import icon from ‘./../icon’;
import ‘./editor.scss’;
import icons from ‘./icons’;/**
* Internal block libraries
*/
const { Fragment } = wp.element;
const {
registerBlockType,
MediaUpload,
UrlInput,
RichText
} = wp.blocks;
const {
Button,
IconButton,
Tooltip,
TextControl
} = wp.components;/**
* Register example block
*/
export default registerBlockType(
‘closemarketing/col-teximgtel’,
{
title: ‘3 Columnas, texto y teléfono’,
category: ‘common’,
icon: icon,
keywords: [
‘closemarketing’,
‘destacada’,
‘imagen’,
],
attributes: {
imgURL: {
type: ‘string’,
source: ‘attribute’,
attribute: ‘src’,
selector: ‘img’,
},
imgID: {
type: ‘number’,
},
imgAlt: {
type: ‘string’,
source: ‘attribute’,
attribute: ‘alt’,
selector: ‘img’,
},
message: {
type: ‘array’,
source: ‘children’,
selector: ‘.message-body’,
},
title: {
type: ‘array’,
source: ‘children’,
selector: ‘.message-body’,
},
phone: {
type: ‘array’,
source: ‘children’,
selector: ‘.message-body’,
},
claim: {
type: ‘array’,
source: ‘children’,
selector: ‘.message-body’,
},
text: {
type: ‘string’,
source: ‘text’,
selector: ‘a’,
},
url: {
type: ‘string’,
source: ‘attribute’,
attribute: ‘href’,
selector: ‘a’,
}
},
edit: props => {
const { attributes: { imgID, imgURL, imgAlt, title, message, text, url, phone, claim },
className, setAttributes, isSelected } = props;
const onSelectImage = img => {
setAttributes( {
imgID: img.id,
imgURL: img.url,
imgAlt: img.alt,
} );
};
const onRemoveImage = () => {
setAttributes({
imgID: null,
imgURL: null,
imgAlt: null,
});
};
const onChangeMessage = message => { setAttributes( { message } ) };
const onChangeTitle = title => { setAttributes( { title } ) };
const onChangePhone = phone => { setAttributes( { phone } ) };
const onChangeClaim = claim => { setAttributes( { claim } ) };
return (
<div className={ className }>
<div className=”one-third first”>
<RichText
tagName=”h2″
placeholder={ ‘Añade el Título’ }
onChange={ onChangeTitle }
value={ title }
/>
<RichText
tagName=”div”
placeholder={ ‘Añade el texto’ }
onChange={ onChangeMessage }
value={ message }
/>
{ isSelected ? (<Fragment>
<TextControl
id=”example-input-field”
label=”Enlace del botón”
value={ text }
onChange={ text => setAttributes( { text } ) }
/>
<p>{ ‘URL del botón’ }</p>
<form
className=”blocks-format-toolbar__link-modal-line blocks-format-toolbar__link-modal-line”
onSubmit={ event => event.preventDefault() }
>
<Tooltip text=”Add Link”>
{icon}
</Tooltip>
<UrlInput
className=”url”
value={ url }
onChange={ url => setAttributes( { url } ) }
/>
<IconButton
icon=”editor-break”
label=”Guardar”
type=”submit”
/>
</form>
</Fragment>) : (
<p>
<button>
{ text || ‘Editar enlace’ }
</button>
</p>)}
</div><div className=”one-third”>
{ ! imgID ? (<MediaUpload
onSelect={ onSelectImage }
type=”image”
value={ imgID }
render={ ( { open } ) => (
<Button
className={ “button button-large” }
onClick={ open }
>
{ icons.upload }
{ ‘Sube una imagen’ }
</Button>
) }
>
</MediaUpload>) : (
<p class=”image-wrapper”>
<img
src={ imgURL }
alt={ imgAlt }
/>{ isSelected ? (
<Button
className=”remove-image”
onClick={ onRemoveImage }
>
{ icons.remove }
</Button>) : null }
</p>
)}
</div>
<div className=”one-third”>
<RichText
tagName=”h2″
placeholder=”Teléfono”
onChange={ onChangePhone }
value={ phone }
/>
<RichText
tagName=”div”
placeholder=”Añade el texto”
onChange={ onChangeClaim }
value={ claim }
/></div>
</div>
);
},
save: props => {
const { imgURL, imgAlt, title, message, text, url, phone, claim } = props.attributes;
return (<div class=”one-third first”>
<h2 class=”widget-title”>
{ title }
</h2>
<p class=”message-body”>
{ message }
</p>
<button>{ text }</button>
</div>
<div class=”one-third”>
<p>
<img
src={ imgURL }
alt={ imgAlt }
/>
</p>
</div>
<div class=”one-third”>
<h2 class=”widget-title”>{ phone }</h2>
<p class=”message-body”>{ claim }</p>
</div>);
},
},
);April 9, 2018 at 9:46 am #44700Zac GordonKeymasterWhen you return elements in React they have to be wrapped inside a single element. So you can either take your elements and wrap in a div or import Fragment from wp.element and wrap it in a
component. Hope that helps!
April 9, 2018 at 4:45 pm #44747David PerezParticipantWhen I put <div></div> gives the same error. Sorry I don’t understand the fragment from wp.element. In which video can i see it?
April 9, 2018 at 10:38 pm #44772Zac GordonKeymasterHey David,
Do you mind trying to format this code a bit so can help you try to spot the error? Can put in a code block or use single backtick before and after 🙂
Code
I don’t know if I cover Fragments in this course. I do cover them in my JS course.
Let’s get this formated or put in a gist and we’ll get fixed.
April 15, 2018 at 8:25 pm #45178David PerezParticipantOk, I give you attached. Thanks Zac.
/** * Block dependencies */ import icon from './../icon'; import './editor.scss'; import icons from './icons'; /** * Internal block libraries */ const { Fragment } = wp.element; const { registerBlockType, MediaUpload, UrlInput, RichText } = wp.blocks; const { Button, IconButton, Tooltip, TextControl } = wp.components; /** * Register example block */ export default registerBlockType( 'closemarketing/col-teximgtel', { title: '3 Columnas, texto y teléfono', category: 'common', icon: icon, keywords: [ 'closemarketing', 'destacada', 'imagen', ], attributes: { imgURL: { type: 'string', source: 'attribute', attribute: 'src', selector: 'img', }, imgID: { type: 'number', }, imgAlt: { type: 'string', source: 'attribute', attribute: 'alt', selector: 'img', }, message: { type: 'array', source: 'children', selector: '.message-body', }, title: { type: 'array', source: 'children', selector: '.message-body', }, phone: { type: 'array', source: 'children', selector: '.message-body', }, claim: { type: 'array', source: 'children', selector: '.message-body', }, text: { type: 'string', source: 'text', selector: 'a', }, url: { type: 'string', source: 'attribute', attribute: 'href', selector: 'a', } }, edit: props => { const { attributes: { imgID, imgURL, imgAlt, title, message, text, url, phone, claim }, className, setAttributes, isSelected } = props; const onSelectImage = img => { setAttributes( { imgID: img.id, imgURL: img.url, imgAlt: img.alt, } ); }; const onRemoveImage = () => { setAttributes({ imgID: null, imgURL: null, imgAlt: null, }); }; const onChangeMessage = message => { setAttributes( { message } ) }; const onChangeTitle = title => { setAttributes( { title } ) }; const onChangePhone = phone => { setAttributes( { phone } ) }; const onChangeClaim = claim => { setAttributes( { claim } ) }; return ( <div className={ className }> <div className="one-third first"> <RichText tagName="h2" placeholder={ 'Añade el Título' } onChange={ onChangeTitle } value={ title } /> <RichText tagName="div" placeholder={ 'Añade el texto' } onChange={ onChangeMessage } value={ message } /> { isSelected ? ( <Fragment> <TextControl id="example-input-field" label="Enlace del botón" value={ text } onChange={ text => setAttributes( { text } ) } /> <p>{ 'URL del botón' }</p> <form className="blocks-format-toolbar__link-modal-line blocks-format-toolbar__link-modal-line" onSubmit={ event => event.preventDefault() } > <Tooltip text="Add Link"> {icon} </Tooltip> <UrlInput className="url" value={ url } onChange={ url => setAttributes( { url } ) } /> <IconButton icon="editor-break" label="Guardar" type="submit" /> </form> </Fragment> ) : ( <p> <button><a href={ url }> { text || 'Editar enlace' } </a></button> </p> )} </div> <div className="one-third"> { ! imgID ? ( <MediaUpload onSelect={ onSelectImage } type="image" value={ imgID } render={ ( { open } ) => ( <Button className={ "button button-large" } onClick={ open } > { icons.upload } { 'Sube una imagen' } </Button> ) } > </MediaUpload> ) : ( <p class="image-wrapper"> <img src={ imgURL } alt={ imgAlt } /> { isSelected ? ( <Button className="remove-image" onClick={ onRemoveImage } > { icons.remove } </Button> ) : null } </p> )} </div> <div className="one-third"> <RichText tagName="h2" placeholder="Teléfono" onChange={ onChangePhone } value={ phone } /> <RichText tagName="div" placeholder="Añade el texto" onChange={ onChangeClaim } value={ claim } /> </div> </div> ); }, save: props => { const { imgURL, imgAlt, title, message, text, url, phone, claim } = props.attributes; return ( <div class="one-third first"> <h2 class="widget-title"> { title } </h2> <p class="message-body"> { message } </p> <button><a href={ url }>{ text }</a></button> </div> <div class="one-third"> <p> <img src={ imgURL } alt={ imgAlt } /> </p> </div> <div class="one-third"> <h2 class="widget-title">{ phone }</h2> <p class="message-body">{ claim }</p> </div> ); }, }, );
April 16, 2018 at 11:35 am #45210Zac GordonKeymasterOkay so like it says you can’t do this:
<div>1</div> <div>2</div>
And have to have a single element returned like this:
<div> <div>1</div> <div>2</div> </div>
I think I see an example of this in your save method. There might be another instance but that is the situation you are looking for 🙂
Hope that helps!
April 27, 2018 at 2:15 pm #45879David PerezParticipantYes, It’s solved… thanks!
April 27, 2018 at 7:24 pm #45901David PerezParticipantHello Zac, I’ve managed to work, but when I go to the editor it says that the block has been modified externally, and it breaks it.
I don’t understand what I need else…
May 11, 2018 at 8:25 pm #46896Zac GordonKeymasterThat is just part of the development process if you make changes to a block 🙂
May 16, 2018 at 9:12 pm #47460David PerezParticipantI don’t understand what you mean exactly…
-
AuthorPosts
- You must be logged in to reply to this topic.