Viewing 10 posts - 1 through 10 (of 10 total)
  • Author
    Posts
  • #44680
    David Perez
    Participant

    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 }[0m

    at 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:66

    Any 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>

    );
    },
    },
    );

    #44700
    Zac Gordon
    Keymaster

    When 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!

    #44747
    David Perez
    Participant

    When 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?

    #44772
    Zac Gordon
    Keymaster

    Hey 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.

    #45178
    David Perez
    Participant

    Ok, 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>
                    
                );
            },
        },
    );
    
    #45210
    Zac Gordon
    Keymaster

    Okay 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!

    #45879
    David Perez
    Participant

    Yes, It’s solved… thanks!

    #45901
    David Perez
    Participant

    Hello 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…

    #46896
    Zac Gordon
    Keymaster

    That is just part of the development process if you make changes to a block 🙂

    #47460
    David Perez
    Participant

    I don’t understand what you mean exactly…

Viewing 10 posts - 1 through 10 (of 10 total)
  • You must be logged in to reply to this topic.