WordPress

rozwój wtyczki – Tablica atrybutów nie zapisuje wartości

  • 16 lutego, 2024
  • 4 min read
rozwój wtyczki – Tablica atrybutów nie zapisuje wartości


Postępowałem zgodnie z tym przepełnieniem stosu, wszystko działało, z wyjątkiem wartości zapisanych w tablicy atrybutów myTest. Z jakiegoś powodu tak nie jest i głowię się nad tym od ponad tygodnia. Oto mój pełny kod w celach informacyjnych.


import React, { useState, useEffect } from 'react';

import { __ } from '@wordpress/i18n';
import { registerBlockType } from "@wordpress/blocks"
import {
    useBlockProps,
    RichText,
    InspectorControls,
    PanelColorSettings
} from '@wordpress/block-editor';
import {
    PanelBody,
    PanelRow,
    SelectControl
} from '@wordpress/components';

import apiFetch from '@wordpress/api-fetch';

import './editor.scss';



registerBlockType('blog-post-block/blog-post-container-block', {
    // Block name. Block names must be string that contains a namespace prefix. Example: my-plugin/my-custom-block.
    title: __('SfS Post block', 'sfs-block'), // Block title.
    icon: 'shield', // Block icon from Dashicons → 
    category: 'design', // Block category — Group blocks together based on common traits E.g. common, formatting, layout widgets, embed.
    attributes: {
        myTest: {
            type: 'array',
            source: 'query',
            selector: ' div.blog-stamp > * ',
            default: [],
            query: {
                image: {
                    type: 'string',
                    source: 'attribute',
                    selector: 'img',
                    attribute: 'src'
                },
                title: {
                    type: 'string',
                    selector: 'h3',
                    source: 'html'
                },
                excerpt: {
                    type: 'string',
                    selector: 'p',
                    source: 'html'
                },
                link: {
                    type: 'string',
                    source: 'attribute',
                    selector: 'a',
                    attribute: 'href'
                },
            }
        },
        backgroundColor: {
            type: "string"
        },
        textColor: {
            type: "string"
        },
        selectedValue: {
            type: "string",
            default: "vtalk"
        },
        myNumber: {
            type: "number",
            default: "3"
        },
    },
    edit({ className, attributes, setAttributes }) {
        const blockProps = useBlockProps();
        const { backgroundColor, textColor, selectedValue, myNumber, myTest } = attributes;
        const [teams, setTeams] = useState([]);
        const catagories = [];
        const newArray = [];
        useEffect(() => {
            apiFetch({ path: '/wp/v2/posts?_embed=wp:term' }).then((teams) => {
                setTeams(teams);
            });

        }, []);

        for (var i = 0; i < teams.length; i++) {
            catagories.push({ catagory: teams[i]._embedded['wp:term']['0']['0']['name'] });
            newArray.push({ value: teams[i].id, label: teams[i].title.rendered, content: teams[i].excerpt.rendered, image: teams[i].featured_image_url, link: teams[i].link, catagory: teams[i]._embedded['wp:term']['0']['0']['name'] });
        }
        const onChangeBackgroundColor = (BackgroundColor) => {
            setAttributes({ backgroundColor: BackgroundColor })
        }
        const onChangeTextColor = (TextColor) => {
            setAttributes({ textColor: TextColor })
        }
        const onChangeNumber = (number) => {
            setAttributes({ myNumber: number })
        }
        function updateAttributes(string1, string2, string3, string4, index){
            const theAttributeUpdate = [...myTest];
            theAttributeUpdate[index] = { image: {string1}, title: {string2}, excerpt: {string3}, link: {string4} };
            setAttributes({ myTest: theAttributeUpdate })
        }
        const stringArray = catagories.map(JSON.stringify);
        const uniqueStringArray = new Set(stringArray);
        const uniqueArray = Array.from(uniqueStringArray, JSON.parse);
        const handleSelectChange = (event) => {
            setAttributes({ selectedValue: event.target.value })
            console.log(event.target.value);
        }
        return (
            <div {...blockProps}>
                <InspectorControls>
                    <PanelColorSettings
                        title={__('Button Color settings', 'sfs-block')}
                        initialOpen={false}
                        colorSettings={[
                            {
                                value: textColor,
                                onChange: onChangeTextColor,
                                label: __('Button Text color', 'sfs-block')
                            },
                            {
                                value: backgroundColor,
                                onChange: onChangeBackgroundColor,
                                label: __('Button Background color', 'sfs-block')
                            }
                        ]}
                    />
                    <PanelBody
                        title={__('catagory filter', 'sfs-block')}
                        initialOpen={true}
                    >
                        <PanelRow>
                            <fieldset>
                                <select value={selectedValue} onChange={handleSelectChange}>
                                    {uniqueArray.map((cat) => {
                                        return <option value={cat.catagory}>{cat.catagory}</option>
                                    })}
                                </select>
                            </fieldset>
                        </PanelRow>
                    </PanelBody>
                    <SelectControl
                        label="How many"
                        value={myNumber}
                        options={[
                            { label: 'Three in a row', value: '3' },
                            { label: 'Six in a row', value: '6' },
                        ]}
                        onChange={onChangeNumber}
                    />
                </InspectorControls>
                <div class="blog-stamp-parent">
                    { newArray.filter((m, idx) => m.catagory == selectedValue).map((m) => {

                        return (
                            <div class="foo blog-stamp">
                                <img class="stamp-image" src={m.image} width="200" height="200" />
                                <RichText
                                    tagName="h3"
                                    value={m.label}
                                    class="foo stamp-title"
                                    onChange={({string2}) => updateAttributes(string1, string2, string3, string4, index)}

                                />
                                <RichText
                                    tagName="p"
                                    value={m.content}
                                    class="foo stamp-excerpt"
                                    onChange={({string3}) => updateAttributes(string1, string2, string3, string4, index)}
                                />
                                <p class="button-parent">
                                    <a
                                        href={m.link}
                                        className="foo sfs-button"
                                        style={{ backgroundColor: backgroundColor, color: textColor }}
                                    >
                                        {'Read more'}
                                    </a>
                                </p>
                            </div>)
                    })};
                    {console.log(myTest)}
                </div>
            </div>
        )
    },

    save({ attributes }) {
        const blockProps = useBlockProps.save();
        const { backgroundColor, textColor, selectedValue, myNumber, menuItems, myTest, para, src, href } = attributes;
        return (
            <div{...useBlockProps.save()}>
                <div class="blog-stamp-parent" >
                            {myTest && myTest.map(({ image, title, excerpt, link }) => {

return (
                    <div class="blog-stamp">
                        <img src={image} width="200" height="200" />
                        <RichText.Content className="stamp-title" tagName="h3" value={title} />
                        <RichText.Content className="stamp-excerpt" tagName="p" value={excerpt} />
                        <p class="button-parent">
                            <a href={link} class="sfs-button" style={{ backgroundColor: backgroundColor, color: textColor }}>Read more</a>
                        </p>
                        </div>)
                    })};
                </div>
            </div>
        )
    },
});



W edycji pod instrukcją return mapuję newArray i stosuję wartości do elementów blokowych. Następnie zmiana onchange w elemencie block ma wywołać funkcję updateAttributes, która zapisuje wartość w tablicy atrybutów przy użyciu atrybutu myTest. Ale kiedy to zrobię i console.log myTest, wraca jako pusty i bez wartości. Tylko []. Masz pomysł dlaczego?

Warto przeczytać!  przepisywanie adresów URL - Przepisz zagnieżdżone adresy URL dla niestandardowego typu postu


Źródło