将自定义PanelColorSetting控件添加到核心块,并在自定义类名称中使用颜色块

时间:2022-01-28 作者:Michael Bourne

我正在尝试向组块和覆盖块添加自定义颜色控件,如果选择了颜色,请为块构造自定义类名。此自定义类用于节分隔符。

What I\'ve done:

<我已过滤blocks.registerBlockType 并添加了customattributeeditor.BlockEdit正确并添加PanelColorSettings 控件仅限于组和覆盖块blocks.getSaveContent.extraProps在保存时添加自定义类editor.BlockListBlock 在编辑时将同一个自定义类添加到块包装中,以便我可以动态查看更改我已经能够在正确保存帖子时将控件显示出来,并将类名保存到块中。在前端,它可以工作。第一次编辑时,它就起作用了。

What\'s missing:

我现在遇到的问题是,当您在颜色面板中选择不同的颜色并发布更改时,这些自定义类名不会被替换。如果选择1种颜色,单击“发布”、“刷新”,然后选择第二种颜色“发布”、“刷新”,则块将具有两种颜色的自定义类。

第一次在未选择前一种颜色的块上选择颜色时,可以在编辑器中动态查看更改。当您点击发布和刷新,然后在颜色之间循环时,您不会看到动态变化,因为第一种颜色的类名仍然存在于块上。

What I think the problem is:

我需要这些过滤器来删除它们以前应用的自定义类?或“之间的抽象”;用户在高级框中键入的类;vs“;“我的过滤器”添加到块的类;。文件中的任何内容似乎都不能满足这一点。

My code (updated):

/**
 * External Dependencies
 */
import classnames from \'classnames\';

/**
 * WordPress Dependencies
 */
const { __ } = wp.i18n;
const { addFilter } = wp.hooks;
const { Fragment } = wp.element;
const { createHigherOrderComponent } = wp.compose;
const { InspectorControls, getColorObjectByColorValue, PanelColorSettings } = wp.blockEditor;
const { select } = wp.data;


// Restrict to specific block names
const allowedBlocks = [\'core/group\', \'core/cover\'];

/**
 * Add custom attribute for section separator.
 *
 * @param {Object} settings Settings for the block.
 *
 * @return {Object} settings Modified settings.
 */
function addAttributes(settings) {

    //check if object exists for old Gutenberg version compatibility
    //add allowedBlocks restriction
    if (typeof settings.attributes !== \'undefined\' && allowedBlocks.includes(settings.name)) {

        settings.attributes = Object.assign(settings.attributes, {
            dividerColor: {
                type: \'string\',
                default: null,
            }
        });

    }

    return settings;
}

/**
 * Add section divider controls on Advanced Block Panel.
 *
 * @param {function} BlockEdit Block edit component.
 *
 * @return {function} BlockEdit Modified block edit component.
 */
const withAdvancedControls = createHigherOrderComponent((BlockEdit) => {
    return (props) => {

        if (!allowedBlocks.includes(props.name)) {
            return(<BlockEdit {...props} />);
        }

        const {
            name,
            attributes,
            setAttributes,
            isSelected,
        } = props;

        const {
            dividerColor
        } = attributes;

        const changeColor = (value) => {
            setAttributes({ dividerColor: value });
            console.log(props);
        }

        return (
            <Fragment>
                <BlockEdit {...props} />
                {isSelected && allowedBlocks.includes(name) &&
                    <InspectorControls>
                        <PanelColorSettings 
                            title={__(\'Section Divider\')}
                            colorSettings={[
                                {
                                    value: dividerColor,
                                    onChange: changeColor,
                                    label: __(\'Choose a color to enable the divider.\')
                                }
                            ]}
                        />
                    </InspectorControls>
                }
            </Fragment>
        );
    };
}, \'withAdvancedControls\');

/**
 * Add custom element class in save element.
 *
 * @param {Object} extraProps     Block element.
 * @param {Object} blockType      Blocks object.
 * @param {Object} attributes     Blocks attributes.
 *
 * @return {Object} extraProps Modified block element.
 */
function applyExtraClass(extraProps, blockType, attributes) {

    const { dividerColor } = attributes;

    //check if attribute exists for old Gutenberg version compatibility
    //add class only when dividerColor is not empty
    //add allowedBlocks restriction
    if (typeof dividerColor !== \'undefined\'
        && dividerColor
        && allowedBlocks.includes(blockType.name)) {
        const settings = select(\'core/editor\').getEditorSettings();
        const colorObject = getColorObjectByColorValue(settings.colors, dividerColor);
        if (colorObject) {
            extraProps.className = classnames(extraProps.className, \'divider divider-\' + colorObject.slug);
        }
    }

    return extraProps;
}

/**
 * Add size class to the block in the editor
 *
 * @param {Object} BlockListBlock  BlockListBlock object.
 *
 * @return {Object}                Modified BlockListBlock object.
 */
 const addDividerClass = createHigherOrderComponent((BlockListBlock) => {
    return (props) => {
      const {
        attributes,
        className,
        name,
      } = props;

      const { dividerColor } = attributes;
  
      if (!allowedBlocks.includes(name)) {
        return <BlockListBlock {...props} />;
      }

      const settings = select(\'core/editor\').getEditorSettings();
      const colorObject = getColorObjectByColorValue(settings.colors, dividerColor);

      if (!colorObject) {
        return <BlockListBlock {...props} />;
      }
  
      return (
        <BlockListBlock
          {...props}
          className={classnames(className, \'divider divider-\' + colorObject.slug)}
        />
      );
    };
  }, \'addDividerClass\');

//add filters

addFilter(
    \'blocks.registerBlockType\',
    \'ursa6/custom-attributes\',
    addAttributes
);

addFilter(
    \'editor.BlockEdit\',
    \'ursa6/custom-advanced-control\',
    withAdvancedControls
);

addFilter(
    \'blocks.getSaveContent.extraProps\',
    \'ursa6/applyExtraClass\',
    applyExtraClass
);

addFilter(
    \'editor.BlockListBlock\',
    \'ursa6/addDividerClass\',
    addDividerClass
 );
在我的主题的功能中,我为上述内容设置了自定义调色板getColorObjectByColorValue 找到匹配项。

add_theme_support( \'editor-color-palette\', array(
    array(
        \'name\' => __( \'Dark 1\', \'textdomain\' ),
        \'slug\' => \'dk1\',
        \'color\' => \'#282828\',
    ),
    array(
        \'name\' => __( \'Light 1\', \'textdomain\' ),
        \'slug\' => \'lt1\',
        \'color\' => \'#FCFCF8\',
    ),
    array(
        \'name\' => __( \'Mid\', \'textdomain\' ),
        \'slug\' => \'mid\',
        \'color\' => \'#F7F7F7\',
    ),
    array(
        \'name\' => __( \'Accent 1\', \'textdomain\' ),
        \'slug\' => \'accent1\',
        \'color\' => \'#E6A225\',
    ),
    array(
        \'name\' => __( \'Accent 2\', \'textdomain\' ),
        \'slug\' => \'accent2\',
        \'color\' => \'#048081\',
    ),
    array(
        \'name\' => __( \'Accent 3\', \'textdomain\' ),
        \'slug\' => \'accent3\',
        \'color\' => \'#882437\',
    ),
  )
);
有人能告诉我哪里出了问题吗?

1 个回复
SO网友:margarita - boomCodes

您的代码看起来不错,可以在颜色以外的任何其他组件中工作,因为颜色需要具有颜色的高阶组件。在过去,我也在努力处理您描述的行为,并找到了以下两种解决方案:

如果要插入自己的颜色组件,请检查下面的第二个示例https://awhitepixel.com/blog/add-custom-settings-to-existing-wordpress-gutenberg-blocks/.

否则,只需在块中添加颜色支持即可。registerBlockType。这也是我现在正在使用的,效果很好:if( [\'core/quote\'].includes(name) ){ const supports = { ...props.supports, color: true, }; props = { ...props, supports }; }

这里还有一个链接https://css-tricks.com/a-crash-course-in-wordpress-block-filters/

相关推荐