You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义Gutenberg区块:前端类名切换失效问题排查

自定义Gutenberg区块Callout Block前端类名不生效问题

我开发了一款名为Callout Block的自定义Gutenberg区块,包含标题、文本和按钮组件。需求是在区块检查器侧边栏添加切换选项,允许用户选择水平或垂直布局,该切换需同时控制编辑器与前端的内容堆叠方式。

布局示例:

  • 垂直堆叠(示例1):
    • 主标题
    • 文本内容
    • 按钮
  • 水平堆叠(示例2):
    • 主标题、文本内容、按钮(横向排列)

核心目标是通过切换类名提升区块灵活性,目前编辑器端的类名切换已正常工作,但前端无法应用对应的类名。相关代码文件如下:

edit.js 代码

import { __ } from '@wordpress/i18n';
import {
  RichText,
  InspectorControls,
  MediaUpload,
  useBlockProps,
  InnerBlocks,
} from '@wordpress/block-editor';
import { PanelBody, Button, ToggleControl } from '@wordpress/components';

const ALLOWED_BLOCKS = ['core/button'];

import './editor.scss';

const Edit = ({ attributes, setAttributes }) => {
  const { toggleOn, customClass } = attributes;

  const onToggleChange = (newValue) => {
    setAttributes({ toggleOn: newValue });
  };

  const blockProps = useBlockProps();

  const { blockBackground } = attributes;

  function onSelectBlockBackground(newBlockBackground) {
    setAttributes({
      blockBackground: newBlockBackground.sizes.full.url,
    });
  }

  return (
    <div {...blockProps}>
      <InspectorControls>
        <PanelBody title={__('Toggle on horizontal or vertical layout')}>
          <ToggleControl
            label={__('Toggle On')}
            checked={toggleOn}
            onChange={onToggleChange}
          />
        </PanelBody>
        <PanelBody title={__('Select Background Image')}>
          <p>
            <strong>{__('Select a Background Image:')}</strong>
          </p>
          <MediaUpload
            onSelect={onSelectBlockBackground}
            type="image"
            value={attributes.blockBackground.url}
            render={({ open }) => (
              <Button
                className="editor-media-placeholder__button is-button is-default is-large"
                icon="upload"
                onClick={open}
              >
                {__('Select Image')}
              </Button>
            )}
          />
        </PanelBody>
      </InspectorControls>

      <div
        className={`wp-block-create-block-callout-block ${toggleOn ? 'toggle-on-horizontal-cta' : ''}`}
      >
        <div
          className="callout-cta"
          style={{
            backgroundImage: blockBackground ? `url("${blockBackground}")` : 'none',
            backgroundSize: 'cover',
            backgroundPosition: 'center',
            backgroundRepeat: 'no-repeat',
          }}
        >
          <RichText
            tagName="h2"
            value={attributes.mainHeading}
            onChange={(mainHeading) => setAttributes({ mainHeading })}
            placeholder={__('Main Heading')}
            className="main-heading"
          />
          <RichText
            tagName="p"
            value={attributes.mainContent}
            onChange={(mainContent) => setAttributes({ mainContent })}
            placeholder={__('Main Content')}
            className="main-content"
          />
          <InnerBlocks allowedBlocks={ALLOWED_BLOCKS} />
        </div>
      </div>
    </div>
  );
};

export default Edit;

index.js 代码

import { registerBlockType } from '@wordpress/blocks';
import { __ } from '@wordpress/i18n';
import { RichText, InspectorControls, MediaUpload, useBlockProps } from '@wordpress/block-editor';
import { PanelBody, Button } from '@wordpress/components';
import './style.scss';
import Edit from './edit';
import save from './save';

const validAlignments = ['full'];

registerBlockType('create-block/callout-block', {
    title: __('Callout Block', 'callout-block'),
    supports: {
        html: false,
        align: true,
    },
    attributes: {
        mainHeading: {
            type: 'string',
            source: 'html',
            selector: '.main-heading',
        },
        mainContent: {
            type: 'string',
            source: 'html',
            selector: '.main-content',
        },
        blockBackground: {
            type: 'string',
            default: '',
        },
        align: {
            type: 'string',
            default: 'full',
        },
        toggleOn: {
          type: 'boolean',
          default: false,
          source: 'attribute',
          attribute: 'data-toggle-on', // Use the attribute name that corresponds to the class you're toggling
        },
    },
    getEditWrapperProps( attributes ) {
      const { align } = attributes;
      if (-1 !== validAlignments.indexOf( align ) ) {
        return { 'data-align': align };
      }
    },
    edit: Edit,
    save,
});

save.js 代码

import { __ } from '@wordpress/i18n';
import {
  RichText,
  InspectorControls,
  MediaUpload,
  useBlockProps,
  InnerBlocks,
} from '@wordpress/block-editor';
import { PanelBody, Button } from '@wordpress/components';

export default function save({ className, attributes }) {
  const blockProps = useBlockProps.save({
    'data-align': attributes.align, // Add the data-align attribute with the align value
  });

  const { toggleOn } = attributes;

  return (
    <div className={`wp-block-create-block-callout-block ${className} ${toggleOn ? 'toggle-on-horizontal-cta' : ''}`} {...blockProps}>
      <div
        className="callout-cta"
        style={{
          backgroundImage: attributes.blockBackground !== '' ? `url("${attributes.blockBackground}")` : 'none',
          backgroundSize: 'cover',
          backgroundPosition: 'center',
          backgroundRepeat: 'no-repeat',
        }}
      >
        <RichText.Content
          tagName="h2"
          value={attributes.mainHeading}
          className="main-heading"
        />
        <RichText.Content
          tagName="p"
          value={attributes.mainContent}
          className="main-content"
        />
        <InnerBlocks.Content {...blockProps} />
      </div>
    </div>
  );
}

内容的提问来源于stack exchange,提问作者Chris Brennan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 21:15:26