Gutenberg-BLOCK的快捷码:前端和条件显示上的附加文本

时间:2019-01-06 作者:Bram

我正在努力将一个自定义的短代码翻译成古腾堡积木,但在两个问题上遇到了困难。这篇文章首先讨论了当前的情况,下一个标题更详细地显示了我遇到的问题。

当前情况

我正在使用快捷码(下面的语法和代码)在我的website. 它包括标题、组织、位置、持续时间、每周小时数和/或GPA的字段,以及以下输出。有一些属性的链接。Shortcode output

Syntax of the shortcode (为了简洁起见,删除了部分说明)is as follows:

[cv-item naam=\'<a href="https://www.tudelft.nl/en/education/programmes/masters/aerospace-engineering/msc-aerospace-engineering/" target="_blank" rel="noopener">Aerospace Engineering (MSc)</a>\' organisatie=\'<a href="http://www.tudelft.nl/en/" target="_blank" rel="noopener">Delft University of Technology</a>\' locatie=\'Delft, The Netherlands\' duur=\'09/2014 - current\' status=\'open\' cijfer=\'7.7/10\' cijfer_datum=\'11/2018\'] Double-track specialisation (180 EC, three years) in the [...] on the other. [/cv-item]

Shortcode definition is as follows:

function cv_item( $atts, $content = null ) {
$atts_completed = shortcode_atts( array(
    \'naam\'         => null,
    \'organisatie\'  => null,
    \'locatie\'      => null,
    \'duur\'         => null,
    \'uren\'         => null,
    \'status\'       => \'closed\',
    \'cijfer\'       => null,
    \'cijfer_datum\' => null,
), $atts );

$naam         = $atts_completed[\'naam\'];
$organisatie  = $atts_completed[\'organisatie\'];
$locatie      = $atts_completed[\'locatie\'];
$duur         = $atts_completed[\'duur\'];
$uren         = $atts_completed[\'uren\'];
$status       = $atts_completed[\'status\'];
$cijfer       = $atts_completed[\'cijfer\'];
$cijfer_datum = $atts_completed[\'cijfer_datum\'];

static $id = 1;
$id ++;

$output = \'<div class="cv-item" id="cv-item-\' . $id . \'">\';

/* Uit-/inklap-knop */
if ( $status == \'open\' ) {
    $toggle_class = \'fa-arrow-up\';
} else {
    $toggle_class = \'fa-arrow-down\';
}

if ( $content != null ) {
    $output .= \'<i class="fa \' . $toggle_class . \' cv-item-toggle" id="cv-item-\' . $id . \'"></i>\';
}

/* Eerste regel, met naam, bedrijf en locatie */
$output .= \'<span class="cv-item-title">\';
$output .= \'<strong>\' . $naam . \'</strong>\';

if ( $organisatie != null ) {
    $output .= \', <span class="organisation">\' . $organisatie . \'</span>\';

    if ( $locatie != null ) {
        $output .= \' (\' . $locatie . \')\';
    }
}
$output .= \'</span>\';

/* Tweede regel, met duur en aantal uren per week */
if ( $duur != null || $uren != null || $cijfer != null ) {
    $output .= \'<span class="cv-item-details">\';

    if ( $duur != null ) {
        $output .= $duur;
    }

    if ( $uren != null | $cijfer != null ) {
        if ( $duur != null ) {
            $output .= \' | \';
        }

        if ( $uren != null ) {
            $output .= $uren . __( \' uur per week\', \'peerlings\' );
        }

        if ( $cijfer != null ) {
            $output .= $cijfer;

            if ( $cijfer_datum != null ) {
                $output .= \' (\' . __( \'per\', \'peerlings\', \'Cijfer XX per YY\' ) . \' \' . $cijfer_datum . \')\';
            }
        }

    }

    $output .= \'</span>\';
}

/* Omschrijving */
if ( $content != null ) {
    $output .= \'<div class="cv-item-description \' . $status . \'">\' . $content . \'</div>\';
}

/* Closing */
$output .= \'</div>\';

return $output; }
如您所见,处理短代码的函数中有一系列条件。此外,还添加了一些分隔符(如项目标题和组织之间的逗号),以及一组包装器-span用于设置样式(例如span.cv-item-titlespan.details). 我很难在古腾堡复制这个。

新情况、问题和解决方案尝试我一直在努力调整this custom profile block 来满足我的需要。到目前为止,这已经相当有效(完全有效block.js-密码here), 但我有两个问题:

复制条件句,添加分隔符和span-包装器在原始代码中,根据下面的代码(从edit- 和save-功能):

el(\'div\', {className: \'organic-profile-social\'},
    attributes.nameURL && el(\'a\', {
        className: \'social-link\',
        href: attributes.nameURL,
        target: \'_blank\'
    },
    el(\'i\', {className: \'fa fa-facebook\'})
    ),
    attributes.organisationURL && el(\'a\', {
        className: \'social-link\',
        href: attributes.organisationURL,
        target: \'_blank\'
    },
    el(\'i\', {className: \'fa fa-twitter\'})
    )
)
但是,相同的逻辑不适用于常规字段,如下所示(从save-功能):

el(\'span\', {},
    attributes.grade && el(\'span\', {
        className: \'grade\',
        value: attributes.grade
    }),
    attributes.gradeDate && el(\'span\', {
        className: \'grade-date\',
        value: attributes.gradeDate
    }
    )
)
这将输出gradegrade-date spans,而不考虑其内容。此外span 应该把这两个包起来,结果是空的span 在它们之前:

<span></span><span class="grade"></span><span class="grade-date"></span>
当然,我可以将所有条件字段移动到侧栏中的设置面板,但这(对我来说)击败了Gutenberg(据我正确理解)所说的后端方法上的所有WYSIWYG。

Question: 甚至有可能实现我心中的目标吗?我怎样才能做到?

分隔符、包装器和中间文本

我认为我可以做到这一点,通过使用帮助函数添加分隔符来设置特定分隔符,或者将其设置为null 如果周围的值为空,如下所示:

if (typeof props.attributes.grade !== \'undefined\' && typeof props.attributes.gradeDate !== \'undefined\') {
    var separatorGradeGradeDatePre = \' (\' + i18n.__(\'per\')
    var separatorGradeGradeDateSuf = \')\'
} else {
    var separatorGradeGradeDatePre = null
    var separatorGradeGradeDateSuf = null
}
然后,我将这两个添加到save-作用这种方法在某种程度上很有效,但在过去的情况下却不行。换言之:如果edit-函数用于读取post_content-HTML中没有指定的文本edit-函数并引发错误。

到目前为止,我已经想到了这个想法,以及我没有实施的原因:

将分离器包括在edit-函数,然后使用特定于编辑器的CSS隐藏这些。还没有实现,因为我认为(至少可以这么说)包含我(在所有情况下)将要使用CSS隐藏的内容是丑陋的save-函数,但使用CSS添加它们content-属性。甚至比前面的选项更难看,尤其是因为它需要一个讨厌的PHP CSS mashup来包含条件语句Question: 有没有其他的方法来实现这一点,或者我应该只使用上面发布的我的一个想法?

1 个回复
最合适的回答,由SO网友:Bram 整理而成

虽然与我最初预期的略有不同,但我已经找到/创建了两个问题的解决方案。

条件句

我选择使用InspectorControls-要素原因是我意识到,在仍然能够编辑该字段的同时,不可能隐藏一个留空的字段(在屏幕的编辑器部分)(需要显示准确的前端表示)。

例如,这是侧栏中文本字段的定义。

el(TextControl, {
    type: \'text\',
    value: attr.location,
    label: __(\'Location\', \'peerlings-blocks\'),
    onChange: function (newLocation) {
        props.setAttributes({location: newLocation})
    }
}),
这是(在edit- 和save-零件)用于显示的代码(如果已使用该字段)

attr.location && el(\'span\', {className: \'location\'}, attr.location),
我最初不想将这些细节移动到侧栏的原因是,我认为它们不会显示在编辑器预览中,但使用上面的代码,这是可以实现的。问题已解决。

分离器和包装器这需要更多的摆弄才能开始工作,对此我有一些启示:

selector (定义为任何attribute) 查看从中提取的HTMLpost_content 查找特定属性的值。如果此选择找到的HTML不是预期的HTML,则块验证失败

  • edit-part用于在Wordpress仪表板中显示块-“预览”。此外,它还从post_content, 再次编辑块时。另一方面save-零件将属性值转换为发送到(并保存在)的HTMLpost_content. 基本上,save 将块编码为HTML,edit 将HTML解码为属性(可以在前面讨论的选择器中找到)。这就解释了为什么两者之间的微小差异(在选择器找到的部分中)会立即使块无效
  • 鉴于上述情况,我将分隔符和包装器放置在选择用于检索属性的元素之外。这导致了一些额外的包装器元素,但确实如此。举例来说,该短代码具有以下HTML输出:

    <span class="cv-item-details">08/2013 - current | 6 hours per week</span>
    
    现在,这条线是这样的:

    <span class="resume-item-details">
        <span class="duration">
            08/2013 – current
        </span> 
        | 
        <span class="hours">
            <span class="data">
                6
            </span>
         hours per week
        </span>
    </span>
    
    我最初设想的问题(块级输入字段之间的分隔符)基本上是通过将多个输入字段移动到侧栏(如上所述)来解决的。保留的输入字段之间的分隔符仅包含在save-零件,并按预期工作-如下面的代码所示。

    edit-零件:

    el(\'span\', {className: \'resume-item-title\'},
        el(RichText, {
            key: \'editable\',
            tagName: \'strong\',
            className: \'name\',
            placeholder: __(\'Name\', \'peerlings-blocks\'),
            keepPlaceholderOnFocus: true,
            value: attr.name,
            onChange: function (newName) {
                props.setAttributes({name: newName})
            }
        }),
        el(RichText, {
            key: \'editable\',
            className: \'organisation\',
            placeholder: __(\'Organisation\', \'peerlings-blocks\'),
            keepPlaceholderOnFocus: true,
            value: attr.organisation,
            onChange: function (newOrganisation) {
                props.setAttributes({organisation: newOrganisation.replace(\'<br>\', \'\')})
            }
        })
    ),
    
    save-part(注意两者之间的逗号RichText-零件,有条件attr.organisation 不为空):

    el(\'span\',
        {className: \'resume-item-title\'},
        el(RichText.Content, {
            tagName: \'strong\',
            className: \'name\',
            value: attr.name
        }),
        attr.organisation && \', \',
        el(RichText.Content, {
            tagName: \'span\',
            className: \'organisation\',
            value: attr.organisation
        })
    ),
    
    您可以找到该块的完整JS文件(至少是当前版本)here.