繁体   English   中英

如何将 static gutenberg 块转换为使用 PHP 注册它的动态块?

[英]How can I convert a static gutenberg block into a dynamic block registering it using PHP?

我正在尝试将我为 WordPress 创建的 static Gutenberg 块转换为动态块。 我一直在寻找其他解决方案,但没有成功。 这个问题( 将使用@wordpress/create-block 创建的 static gutenberg 块转换为使用 PHP 注册它的动态块的正确方法是什么? )与我正在寻找的非常相似,但我的 static 块不是使用@wordpress/create-block 在完成所有建议的步骤后,我发现似乎是弃用问题。

class-hello-tools-custom-blocks.php(注册块)

static 版本如下所示:

register_block_type( 'hello-tools/custom-cta', array(
    'style' => $this->plugin_slug . '-public',
    'editor_style' => 'hello-gutenberg-admin',
    'editor_script' => $this->plugin_slug . '-custom-blocks',
) );

动态变化如下:

register_block_type( __DIR__ . '/src/js/blocks/custom-cta/custom-cta-block.json', array(
    'style' => $this->plugin_slug . '-public',
    'editor_style' => 'hello-gutenberg-admin',
    'editor_script' => $this->plugin_slug . '-custom-blocks',
    'render_callback' => array( $this, 'hello_tools_custom_cta_callback' )
) );

并且同一插件文件中的回调 function 如下所示:

public function hello_tools_custom_cta_callback( $attributes, $content ) {
    ob_start();
    require plugin_dir_path( __DIR__ ) . 'includes/partials/block-callbacks/hello-custom-cta-callback.php';
    $output = ob_get_contents();
    ob_end_clean();
    return $output;
}

custom-cta-block.json(定义块属性)

正如上面register_block_type()中所引用的,这是 block.json 文件。

{
    "$schema": "https://schemas.wp.org/trunk/block.json",
    "apiVersion": 2,
    "name": "hello-tools/custom-cta",
    "title": "Custom CTA",
    "category": "hello-blocks",
    "icon": "align-center",
    "description": "Create call to action element with photo image, text, and button link",
    "keywords": [ "call", "action" ],
    "version": "1.0.1",
    "textdomain": "hello-tools",
    "editorScript": "hello-tools-custom-blocks",
    "editorStyle": "hello-gutenberg-admin",
    "style": "hello-tools-public",
    "attributes": {
        "switchOrientation": {
            "type": "boolean",
            "default": false
        },
        "imageID": {
            "type": "integer"
        },
        "imageURL": {
            "type": "string"
        },
        "imageALT": {
            "type": "string",
            "default": ""
        },
        "imageBgColor": {
            "type": "string",
            "default": "orange"
        },
        "hideCTAImageOnMobile": {
            "type": "boolean",
            "default": false
        },
        "renderWithoutImageBg": {
            "type": "boolean",
            "default": false
        },
        "imageRatio": {
            "type": "string",
            "default": "golden"
        },
        "textBgColor": {
            "type": "string",
            "default": "faint-gray"
        },
        "hasIcon": {
            "type": "boolean",
            "default": false
        },
        "iconID": {
            "type": "integer"
        },
        "iconURL": {
            "type": "string"
        },
        "iconALT": {
            "type": "string",
            "default": ""
        },
        "hasSuperHeading": {
            "type": "boolean",
            "default": false
        },
        "superHeading": {
            "type": "string"
        },
        "headline": {
            "type": "string"
        },
        "blurb": {
            "type": "string"
        },
        "ctaButtonText": {
            "type": "string"
        },
        "ctaLinkURL": {
            "type": "string"
        },
        "textClasses": {
            "type": "string",
            "default": "hello-custom-cta__description flex-fill hello-flex hello-flex--fixed-size align-self-stretch align-items-center p-3 p-sm-4 p-lg-5"
        },
        "blockClasses": {
            "type": "string",
            "default": "hello-block--fullwidth px-sm-3 mb-5 mb-md-6 mb-lg-7 mb-7"
        }
    },
    "supports": {
        "multiple": true
    },
    "example": {
        "attributes": {
            "headline": "This is a custom CTA!",
            "blurb": "<p>Add a catchy headline and body text to capture people's attention</p>",
            "ctaButtonText": "Click here"
        }
    }
}

自定义cta.js

原来的save() function 已被删除,以告诉 Wordpres 它应该动态呈现,但以前的弃用版本已被保留。

import { registerBlockType } from '@wordpress/blocks';
import { __ } from '@wordpress/i18n';
import { InspectorControls, MediaUpload, MediaUploadCheck, RichText, URLInput } from '@wordpress/blockEditor';
import { Button, PanelBody, TextControl, TextareaControl, ToggleControl, SelectControl, IconButton } from '@wordpress/components';
import { omit } from 'lodash';
import settings from './custom-cta-block.json';
const blockAttributes = settings.attributes;

registerBlockType( settings, {

  edit: ( props ) => {

    const { attributes: { switchOrientation, imageID, imageURL, imageALT, imageBgColor, imageRatio, hideCTAImageOnMobile, textBgColor, hasIcon, iconID, iconURL, iconALT, hasSuperHeading, superHeading, headline, blurb, ctaButtonText, ctaLinkURL, blockClasses, textClasses, renderWithoutImageBg }, setAttributes, className, isSelected } = props;
    const ctaButtonPlaceholderText = __( "Button text", "hello-tools" );
    const flexClasses = `hello-flex hello-wrap--content align-items-center ${switchOrientation && 'switch-orientation'}`;

    const onImageSelect = ( imageObj ) => {

      // use the medium_large image size of it exists, otherwise use the full-size image
      const imageObjURL = ( imageObj.sizes.medium_large ) ? imageObj.sizes.medium_large.url : imageObj.sizes.full.url;
      
      // set the image attributes
      setAttributes( { imageID: imageObj.id } );
      setAttributes( { imageURL: imageObjURL } );
      setAttributes( { imageALT: imageObj.alt } );
    
    }

    const onImageBgChange = ( value ) => {
      setAttributes( { imageBgColor: value } );
      setAttributes( { renderWithoutImageBg: ( value == 'none') ? true : false } );
    }

    const onIconSelectorChange = ( value ) => {
      setAttributes( { hasIcon: value } );
      
      // clear icon image attributes if show icon toggle is changed to false
      if ( !value ) {
        setAttributes( { iconID: '' } );
        setAttributes( { iconURL: '' } );
        setAttributes( { iconALT: '' } );
      }

    }

    const onIconSelect = ( imageObj ) => {
      setAttributes( { iconID: imageObj.id } );

      if ( imageObj.sizes.thumbnail ) {
        setAttributes( { iconURL: imageObj.sizes.thumbnail.url } );  
      } else {
        setAttributes( { iconURL: imageObj.sizes.full.url } );
      }

      setAttributes( { iconALT: imageObj.alt } );
    }

    return (
      <div className="hello-custom-cta-editor p-0 mb-0">
        <InspectorControls>
          <PanelBody
            title={ __( 'Image settings', 'hello-tools' ) }
            initialOpen={ true }
          >
            { imageID && __( 'You can change the CTA image here', 'hello-tools' ) }
            { imageID && (
              <div style={{ margin: '0 0 15px 0', }}>
                <MediaUploadCheck>
                  <MediaUpload
                    onSelect={ onImageSelect }
                    allowedTypes="image"
                    value={ imageID }
                    render={ ( { open } ) => (
                      <Button className="hello-components-button" onClick={ open }>
                        { __( 'Choose new image', 'hello-tools' ) }
                      </Button>
                    ) }
                  />
                </MediaUploadCheck>
              </div>
            ) }
            <SelectControl
              label={ __( 'Image background color', 'hello-tools' ) }
              value={ imageBgColor }
              onChange={ onImageBgChange }
              options={ [
                  { value: 'orange', label: __( 'Orange', 'hello-tools' ) },
                  { value: 'blue', label: __( 'Blue', 'hello-tools' ) },
                  { value: 'powder-blue', label: __( 'Light blue', 'hello-tools' ) },
                  { value: 'faint-gray', label: __( 'Gray', 'hello-tools' ) },
                  { value: 'green', label: __( 'Green', 'hello-tools' ) },
                  { value: 'none', label: __( 'No background color', 'hello-tools' ) },
              ] }
            />
            <SelectControl
              label={ __( 'Image ratio', 'hello-tools' ) }
              value={ imageRatio }
              onChange={ value => setAttributes( { imageRatio: value } ) }
              options={ [
                  { value: 'golden', label: '16:9' },
                  { value: 'half', label: '1:1' },
              ] }
            />
            <ToggleControl
              label={ __( 'Hide image on mobile phones?', 'hello-tools' ) }
              checked={ hideCTAImageOnMobile }
              onChange={ value => setAttributes( { hideCTAImageOnMobile: value } ) }
            />
            <ToggleControl
              label={ __( 'Move photo to the right of the text?', 'hello-tools' ) }
              help='The default is to have the photo to the left of the text, but you can switch it here.'
              checked={ switchOrientation }
              onChange={ value => setAttributes( { switchOrientation: value } ) }
            />
          </PanelBody>
          <PanelBody
            title={ __( 'Text settings', 'hello-tools' ) }
            initialOpen={ true }
          >
            <SelectControl
              label={ __( 'Background color', 'hello-tools' ) }
              value={ textBgColor }
              onChange={ value => setAttributes( { textBgColor: value } ) }
              options={ [
                  { value: 'faint-gray', label: __( 'Gray', 'hello-tools' ) },
                  { value: 'white', label: __( 'White', 'hello-tools' ) },
              ] }
            />
            <ToggleControl
              label={ __( 'Show icon above the text?', 'hello-tools' ) }
              checked={ hasIcon }
              onChange={ onIconSelectorChange }
            />
            { hasIcon && (
              <div style={{ margin: '-15px 0 15px 0', }}>
                <MediaUploadCheck>
                  <MediaUpload
                    onSelect={ onIconSelect }
                    allowedTypes="image"
                    value={ iconID }
                    render={ ( { open } ) => (
                      <Button className="hello-components-button" onClick={ open }>
                        { !iconID && __( 'Choose icon image', 'hello-tools' ) }
                        { iconID && __( 'Replace icon image', 'hello-tools' ) }
                      </Button>
                    ) }
                  />
                </MediaUploadCheck>
              </div>
            ) }
            <ToggleControl
              label={ __( 'Show super heading?', 'hello-tools' ) }
              checked={ hasSuperHeading }
              onChange={ value => setAttributes( { hasSuperHeading: value } ) }
            />
          </PanelBody>
        </InspectorControls>
        <div className={ flexClasses }>
          { renderWithoutImageBg && imageURL && (
          <div className={ `hello-custom-cta__image-wrap ${imageRatio} no-padding hello-flex align-self-stretch align-items-center` }>
            <div className="objectfit__container w-100 h-100">
              <img className="hello-custom-cta__image objectfit__image w-100 h-100" src={ imageURL }  alt={ imageALT } />
            </div>
          </div>
          ) }
          { !renderWithoutImageBg && imageURL && (
          <div className={ `hello-custom-cta__image-wrap ${imageRatio} hello-bg--${imageBgColor} hello-flex align-self-stretch align-items-center p-sm-4 p-lg-5` }>
            <img className="hello-custom-cta__image" src={ imageURL } alt={ imageALT } />
          </div>
          ) }
          { !renderWithoutImageBg && !imageID && (
            <MediaUploadCheck>
              <MediaUpload
                onSelect={ onImageSelect }
                allowedTypes="image"
                value={ imageID }
                render={ ( { open } ) => (
                  <Button onClick={ open }>
                    { __( 'Choose Image', 'hello-tools' ) }
                  </Button>
                ) }
              />
            </MediaUploadCheck>
          ) }
          <div className={ `${textClasses} hello-bg--${textBgColor}` }>
            <div>
              { hasIcon && iconID && (
                <div className="flex-item--fullwidth">
                  <img className="hello-custom-cta__icon circle d-block mx-auto" src={ iconURL } alt={ iconALT } />
                </div>
              ) }
              { hasSuperHeading && (
                <TextControl
                  className="hello-custom-cta__superheading hello-interactive-input"
                  value={ superHeading }
                  onChange={ value => setAttributes( { superHeading: value } ) }
                  placeholder={ __( 'Add super heading here (optional)', 'hello-tools' ) }
                  allowedFormats={ [] }
                />
              ) }
              <TextareaControl
                className="hello-custom-cta__headline w-100 hello-interactive-input font-weight-bold"
                value={ headline }
                onChange={ value => setAttributes( { headline: value } ) }
                placeholder={ __( 'Add CTA headline here', 'hello-tools' ) }
                allowedFormats={ [] }
                rows="2"
              />
              { ( isSelected || ( blurb && blurb != '<p></p>' ) ) && ( 
                <div className="w-100">
                  <RichText
                    tagName="div"
                    multiline="p"
                    className="hello-custom-cta__blurb font-weight-light mt-0 w-100"
                    translate-name="blurb"
                    onChange={ value => setAttributes( { blurb: value } ) }
                    placeholder={ __( 'Subtext goes here (optional)', 'hello-tools' ) }
                    value={ blurb }
                    allowedFormats={ [ 'core/bold', 'core/italic' ] }
                    focusOnInsert={ false }
                  />
                </div>
              ) }
              <div className="hello-tools-editable-btn-text-wrapper">
                <div className="hello-inline-flex">
                  <RichText
                    tagName="div"
                    placeholder={ ctaButtonPlaceholderText }
                    onFocus={ (e) => e.target.placeholder = "" } 
                    value={ ctaButtonText }
                    onChange={ value => setAttributes( { ctaButtonText: value } ) }
                    className="hello-tools-editable-btn-text mt-4 hello-btn hello-btn--blue"
                    withoutInteractiveFormatting
                    allowedFormats={ [] }
                  />
                </div>
              </div>
            </div>
          </div>
        </div>
        { isSelected && (
          <div className="hello-block-post-selector">  
            <form
              key={ "form-link" }
              onSubmit={ ( event ) => event.preventDefault() }
              className="hello-flex hello-bg--white">
              <URLInput
                value={ ctaLinkURL }
                onChange={ value => setAttributes( { ctaLinkURL: value } ) }
                autoFocus={ false }
              />
              <IconButton
                className="hello-bg--white"
                icon={ "editor-break" }
                label={ __( "Apply", "hello-tools" ) }
                type={ "submit" }
              />
            </form>
          </div>
        ) }
      </div>
    );

  },

  save() {
    return null; // Data is rendered via PHP callback
  },

  deprecated: [
    {
      attributes: { ...blockAttributes },

      save( { attributes } ) {

        const { switchOrientation, imageID, imageURL, imageALT, imageBgColor, imageRatio, hideCTAImageOnMobile, textBgColor, hasIcon, iconID, iconURL, iconALT, hasSuperHeading, superHeading, headline, blurb, ctaButtonText, ctaLinkURL, blockClasses, textClasses, renderWithoutImageBg } = attributes;
        const flexClasses = `hello-flex hello-wrap--content align-items-center ${switchOrientation && 'switch-orientation'}`;
        const superHeadingExtraClasses = ( hasIcon && iconID ) ? 'mt-2 ' : '';
        const hideImageOnPhones = ( hideCTAImageOnMobile ) ? ' d-upto-md-none' : '';

        return (
          <div className={ blockClasses }>
            <div className="hello-wrap--narrow">
              <div className={ flexClasses }
                >
                { renderWithoutImageBg && imageURL && (
                <div className={ `hello-custom-cta__image-wrap ${imageRatio} hello-flex align-self-stretch align-items-center${hideImageOnPhones}` }>
                  <div className="objectfit__container w-100 h-100">
                    <img className="hello-custom-cta__image objectfit__image w-100 h-100" src={ imageURL }  alt={ imageALT } />
                  </div>
                </div>
                ) }
                { !renderWithoutImageBg && imageURL && (
                <div className={ `hello-custom-cta__image-wrap ${imageRatio} hello-bg--${imageBgColor} hello-flex align-self-stretch align-items-center p-sm-4 p-lg-5${hideImageOnPhones}` }>
                  <img className="hello-custom-cta__image" src={ imageURL } alt={ imageALT } />
                </div>
                ) }
                <div className={ `${textClasses} hello-bg--${textBgColor}` }>
                  <div>
                    { iconID && (
                      <div className="flex-item--fullwidth">
                        <img className="hello-custom-cta__icon circle d-block mx-auto" src={ iconURL } alt={ iconALT } />
                      </div>
                    ) }
                    { hasSuperHeading && superHeading && (
                      <div translate-name="custom-cta__superheading" className={`${superHeadingExtraClasses}hello-custom-cta__superheading hello-1rem-text font-weight-bold text-uppercase hello-text--orange`}>
                        <span>{ superHeading }</span>
                      </div>
                    ) }
                    <div translate-name="custom-cta__headline" className="hello-custom-cta__headline h2 font-weight-bold my-2 my-md-3">
                      { headline }
                    </div>
                    { ( blurb && blurb != '<p></p>' ) && ( 
                      <RichText.Content 
                        className="hello-custom-cta__blurb" 
                        tagName="div" 
                        value={ blurb } 
                      />
                    ) }
                    { ctaButtonText && ctaLinkURL && (
                      <a href={ ctaLinkURL } translate-name="custom-cta__btn-link" className="hello-custom-cta__btn-link mb-3 mb-md-0 btn hello-btn hello-btn--blue">
                        { ctaButtonText }
                      </a>
                    ) }
                  </div>
                </div>
              </div>
            </div>          
          </div>
        )

      }

    },
    {
      attributes: { 
        ...blockAttributes, 
        blockClasses: {
          type: 'string',
          default: 'hello-block--fullwidth px-sm-3 mb-7',
        },
      },

      save( { attributes } ) {

        const { switchOrientation, imageID, imageURL, imageALT, imageBgColor, imageRatio, hideCTAImageOnMobile, textBgColor, hasIcon, iconID, iconURL, iconALT, hasSuperHeading, superHeading, headline, blurb, ctaButtonText, ctaLinkURL, blockClasses, textClasses, renderWithoutImageBg } = attributes;
        const flexClasses = `hello-flex hello-wrap--content align-items-center ${switchOrientation && 'switch-orientation'}`;
        const superHeadingExtraClasses = ( hasIcon && iconID ) ? 'mt-2 ' : '';
        const hideImageOnPhones = ( hideCTAImageOnMobile ) ? ' d-upto-md-none' : '';

        return (
          <div className={ blockClasses }>
            <div className="hello-wrap--narrow">
              <div className={ flexClasses }
                >
                { renderWithoutImageBg && imageURL && (
                <div className={ `hello-custom-cta__image-wrap ${imageRatio} hello-flex align-self-stretch align-items-center${hideImageOnPhones}` }>
                  <div className="objectfit__container w-100 h-100">
                    <img className="hello-custom-cta__image objectfit__image w-100 h-100" src={ imageURL }  alt={ imageALT } />
                  </div>
                </div>
                ) }
                { !renderWithoutImageBg && imageURL && (
                <div className={ `hello-custom-cta__image-wrap ${imageRatio} hello-bg--${imageBgColor} hello-flex align-self-stretch align-items-center p-sm-4 p-lg-5${hideImageOnPhones}` }>
                  <img className="hello-custom-cta__image" src={ imageURL } alt={ imageALT } />
                </div>
                ) }
                <div className={ `${textClasses} hello-bg--${textBgColor}` }>
                  <div>
                    { iconID && (
                      <div className="flex-item--fullwidth">
                        <img className="hello-custom-cta__icon circle d-block mx-auto" src={ iconURL } alt={ iconALT } />
                      </div>
                    ) }
                    { hasSuperHeading && superHeading && (
                      <div translate-name="custom-cta__superheading" className={`${superHeadingExtraClasses}hello-custom-cta__superheading hello-1rem-text font-weight-bold text-uppercase hello-text--orange`}>
                        <span>{ superHeading }</span>
                      </div>
                    ) }
                    <div translate-name="custom-cta__headline" className="hello-custom-cta__headline h2 font-weight-bold my-2 my-md-3">
                      { headline }
                    </div>
                    { ( blurb && blurb != '<p></p>' ) && ( 
                      <RichText.Content 
                        className="hello-custom-cta__blurb" 
                        tagName="div" 
                        value={ blurb } 
                      />
                    ) }
                    { ctaButtonText && ctaLinkURL && (
                      <a href={ ctaLinkURL } translate-name="custom-cta__btn-link" className="hello-custom-cta__btn-link mb-3 mb-md-0 btn hello-btn hello-btn--blue no-external-icon same-window">
                        { ctaButtonText }
                      </a>
                    ) }
                  </div>
                </div>
              </div>
            </div>          
          </div>
        )

      }

    }
  ],

} );

hello-custom-cta-callback.php(处理实际的 PHP 渲染,在回调函数中引用)

<?php
global $post;

$plugin_slug = hello_get_plugin_slug();
$is_admin = ( is_admin() ) ? true : false;

$switchOrientation = ( array_key_exists( 'switchOrientation', $attributes ) ) ? $attributes['switchOrientation'] : false;
$imageID = ( array_key_exists( 'imageID', $attributes ) ) ? $attributes['imageID'] : '';
$imageURL = ( array_key_exists( 'imageURL', $attributes ) ) ? $attributes['imageURL'] : '';
$imageALT = ( array_key_exists( 'imageALT', $attributes ) ) ? $attributes['imageALT'] : '';
$imageBgColor = ( array_key_exists( 'imageBgColor', $attributes ) ) ? $attributes['imageBgColor'] : 'orange';
$hideCTAImageOnMobile = ( array_key_exists( 'hideCTAImageOnMobile', $attributes ) ) ? $attributes['hideCTAImageOnMobile'] : false;
$renderWithoutImageBg = ( array_key_exists( 'renderWithoutImageBg', $attributes ) ) ? $attributes['renderWithoutImageBg'] : false;
$imageRatio = ( array_key_exists( 'imageRatio', $attributes ) ) ? $attributes['imageRatio'] : 'golden';
$textBgColor = ( array_key_exists( 'textBgColor', $attributes ) ) ? $attributes['textBgColor'] : 'faint-gray';
$hasIcon = ( array_key_exists( 'hasIcon', $attributes ) ) ? $attributes['hasIcon'] : false;
$iconID = ( array_key_exists( 'iconID', $attributes ) ) ? $attributes['iconID'] : '';
$iconURL = ( array_key_exists( 'iconURL', $attributes ) ) ? $attributes['iconURL'] : '';
$iconALT = ( array_key_exists( 'iconALT', $attributes ) ) ? $attributes['iconALT'] : '';
$hasSuperHeading = ( array_key_exists( 'hasSuperHeading', $attributes ) ) ? $attributes['hasSuperHeading'] : false;
$superHeading = ( array_key_exists( 'superHeading', $attributes ) ) ? $attributes['superHeading'] : '';
$headline = ( array_key_exists( 'headline', $attributes ) ) ? $attributes['headline'] : '';
$blurb = ( array_key_exists( 'blurb', $attributes ) ) ? $attributes['blurb'] : '';
$ctaButtonText = ( array_key_exists( 'ctaButtonText', $attributes ) ) ? $attributes['ctaButtonText'] : '';
$ctaLinkURL = ( array_key_exists( 'ctaLinkURL', $attributes ) ) ? $attributes['ctaLinkURL'] : '';
$textClasses = ( array_key_exists( 'textClasses', $attributes ) ) ? $attributes['textClasses'] : 'hello-custom-cta__description flex-fill hello-flex hello-flex--fixed-size align-self-stretch align-items-center p-3 p-sm-4 p-lg-5';
$blockClasses = ( array_key_exists( 'blockClasses', $attributes ) ) ? $attributes['blockClasses'] : 'hello-block--fullwidth px-sm-3 mb-5 mb-md-6 mb-lg-7 mb-7';
$flexClasses = 'hello-flex hello-wrap--content align-items-center';
$flexClasses = ($switchOrientation) ? $flexClasses . ' switch-orientation' : $flexClasses;
$superHeadingExtraClasses = ( $hasIcon && $iconID ) ? 'mt-2 ' : '';
$hideImageOnPhones = ( $hideCTAImageOnMobile ) ? ' d-upto-md-none' : '';

$is_rtl = ( apply_filters( 'wpml_is_rtl', NULL) ) ? true : false;
if ( is_object( $post ) && get_post_meta( $post->ID, '_icl_lang_duplicate_of', true ) ) { 
    $is_rtl = false; // if this is on a duplicate page, keep the content LTR
}

echo '<pre>'.print_r($attributes,true).'</pre>';
?>

<div class="<?= $blockClasses; ?>">
    <div class="hello-wrap--narrow">
        <div class="<?= $flexClasses; ?>">
            <?php if ($renderWithoutImageBg && $imageURL) : ?>
                <div class="hello-custom-cta__image-wrap <?= $imageRatio; ?> hello-flex align-self-stretch align-items-center<?= $hideImageOnPhones; ?>">
                    <div class="objectfit__container w-100 h-100">
                        <img class="hello-custom-cta__image objectfit__image w-100 h-100" src="<?= $imageURL; ?>"  alt="<?= $imageALT; ?>" />
                    </div>
                </div>
            <?php elseif ( !$renderWithoutImageBg && $imageURL ) : ?>
                <div class="hello-custom-cta__image-wrap <?= $imageRatio; ?> hello-bg--<?= $imageBgColor; ?> hello-flex align-self-stretch align-items-center p-sm-4 p-lg-5<?= $hideImageOnPhones; ?>">
                    <img class="hello-custom-cta__image" src="<?= $imageURL; ?>" alt="<?= $imageALT; ?>" />
                </div>
            <?php endif; ?>
            <div class="<?= $textClasses; ?> hello-bg--<?= $textBgColor; ?>">
              <div>
                <?php if ($iconID) : ?>
                <div class="flex-item--fullwidth">
                    <img class="hello-custom-cta__icon circle d-block mx-auto" src="<?= $iconURL; ?>" alt="<?= $iconALT; ?>" />
                </div>
                <?php endif; ?>
                <?php if ($hasSuperHeading && $superHeading) : ?>
                <div translate-name="custom-cta__superheading" class="<?= $superHeadingExtraClasses; ?>hello-custom-cta__superheading hello-1rem-text font-weight-bold text-uppercase hello-text--orange">
                    <span><?= $superHeading; ?></span>
                </div>
                <?php endif; ?>
                <div translate-name="custom-cta__headline" class="hello-custom-cta__headline h2 font-weight-bold my-2 my-md-3">
                    <?= $headline; ?>
                </div>
                <?php if ($blurb && $blurb !== '<p></p>') : ?>
                <div class="hello-custom-cta__blurb"><?= $blurb; ?></div>
                <?php endif; ?>
                <?php if ($ctaButtonText && $ctaLinkURL) : ?>
                <a href="<?= $ctaLinkURL; ?>" translate-name="custom-cta__btn-link" class="hello-custom-cta__btn-link mb-3 mb-md-0 btn hello-btn hello-btn--blue"><?= $ctaButtonText; ?></a>
                <?php endif; ?>
              </div>
            </div>
        </div>
    </div>
</div>

我注意到在 JavaScript 中无法完成的渲染回调中的主要 function 正在检查wpml_is_rtl_icl_lang_duplicate_of 为此,使用 PHP/动态渲染来获取此值是有意义的。 虽然,将您原来的save() function 重写为 PHP,弃用前一个块然后重置 PHP 中属性的所有变量似乎并不理想。 最终目标是相同的 output:呈现 HTML。我在将现有插件迁移到 Gutenberg 块时遇到了类似的问题,您实际上只需要一点点 PHP 功能来在最终标记中获得正确的逻辑。

替代方法:

注册您的块后,可以使用wp_localize_script对块 JavaScript 进行本地化。 这种方法的优点是您可以将值从 PHP 传递到 JavaScript save() ,而不必为了访问 PHP function 而重写所有标记。

class-hello-tools-custom-blocks.php

// Revert to original static block
register_block_type( 'hello-tools/custom-cta', array(
    'style' => $this->plugin_slug . '-public',
    'editor_style' => 'hello-gutenberg-admin',
    'editor_script' => $this->plugin_slug . '-custom-blocks',
) );

// Localize script with an array (data) containing the values of PHP functions as needed
function hello_tools_localize_scripts()
{
    $id = get_the_ID(); // Changed from $post->ID in this context

    $is_rtl = (apply_filters('wpml_is_rtl', NULL)) ? true : false;

    if (is_object($post) && get_post_meta($id, '_icl_lang_duplicate_of', true)) {
        $is_rtl = false; // if this is on a duplicate page, keep the content LTR
    }

    // Name of script is santized name from block.json
    wp_localize_script('hello-tools-custom-cta', 'data', array(
        'is_rtl' => $is_rtl,
        'is_admin' => is_admin()
    ));
}
add_action('wp_enqueue_scripts', 'hello_tools_localize_scripts');

自定义cta.js

块 JavaScript 现在可以访问data并使用其内容来保存所需的标记,例如:

save({ attributes }) {
   ...
   return (
       <div className={blockClasses}>
           {data.is_rtl && (
              // save something different for RTL
           )}
        ...
       </div>
   )
}
...

如果这是最初导致您切换到使用 PHP 进行渲染的原因,那么希望您可以实施上述建议,完全删除hello-custom-cta-callback.php ,并使用附加变量重用现有的save() function。

还要检查您的custom-cta-block.json的先前版本,以了解您的属性先前是如何定义的。 对于可编辑的属性<RichText../> ,值可以来自保存的标记 - 您可以使用 class 选择器设置来源,例如:

"attributes" :{
    ...
    "blurb": {
        "type": "string",
        "source": "text",
        "selector": ".hello-custom-cta__blurb",
        "default": ""
    },
...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM