首页 > web前端 > css教程 > 在WordPress中使用Web组件比您想象的要容易

在WordPress中使用Web组件比您想象的要容易

Joseph Gordon-Levitt
发布: 2025-03-21 11:09:11
原创
587 人浏览过

Using Web Components in WordPress is Easier Than You Think

既然我们已经了解到Web组件和交互式Web组件都比你想象的更容易使用,那么让我们来看看如何将它们添加到内容管理系统,也就是WordPress中。

主要有三种方法可以添加它们。首先,通过手动输入到网站——将它们直接放入小工具或文本块中,基本上可以在任何可以放置其他HTML的地方。其次,我们可以将它们作为主题文件中的主题输出添加。最后,我们可以将它们作为自定义块的输出添加。

文章系列

    <li>Web组件比你想象的更容易 <li>交互式Web组件比你想象的更容易 <li>在WordPress中使用Web组件比你想象的更容易 (你在这里) <li>使用Web组件增强内置元素比你想象的更容易 <li>上下文感知Web组件比你想象的更容易 <li>Web组件伪类和伪元素比你想象的更容易

加载Web组件文件

无论最终采用哪种方式添加Web组件,我们都必须确保以下几点:

    <li>当我们需要自定义元素的模板时,它必须可用; <li>我们需要的任何JavaScript都已正确注册; <li>我们需要的任何未封装的样式都已注册。

我们将添加来自我之前关于交互式Web组件的文章中的<zombie-profile></zombie-profile> Web组件。请查看CodePen上的代码。

让我们来看第一点。一旦我们有了模板,将其添加到WordPress主题的footer.php文件就很容易了,但是与其直接添加到主题中,不如挂接到wp_footer,这样组件的加载就独立于footer.php文件和整个主题——假设主题使用wp_footer,大多数主题都这样做。如果在尝试时你的主题中没有出现模板,请仔细检查你的主题的footer.php模板文件中是否调用了wp_footer

<?php function diy_ezwebcomp_footer() { ?><?php }
add_action( 'wp_footer', 'diy_ezwebcomp_footer');
登录后复制

接下来是注册组件的JavaScript。我们也可以通过wp_footer添加JavaScript,但是注册是将JavaScript链接到WordPress的推荐方法。因此,让我们将JavaScript放在名为ezwebcomp.js的文件中(这个名称完全是任意的),将该文件放在主题的JavaScript目录中(如果有的话),并将其注册(在functions.php文件中)。

wp_enqueue_script( 'ezwebcomp_js', get_template_directory_uri() . '/js/ezwebcomp.js', '', '1.0', true );
登录后复制

我们需要确保最后一个参数设置为true,即它在结束的body标签之前加载JavaScript。如果我们将其加载到head中,它将找不到我们的HTML模板,并且会非常生气(抛出一堆错误)。

如果你可以完全封装你的Web组件,那么你可以跳过下一步。但是,如果你(像我一样)无法做到这一点,你需要注册那些未封装的样式,以便它们在使用Web组件的任何地方都可用。(与JavaScript类似,我们可以直接将其添加到页脚,但是注册样式是推荐的方法)。因此,我们将注册我们的CSS文件:

wp_enqueue_style( 'ezwebcomp_style', get_template_directory_uri() . '/ezwebcomp.css', '', '1.0', 'screen' );
登录后复制

这并不太难,对吧?如果你不打算让除管理员以外的任何用户使用它,那么你就可以在任何你想使用它们的地方添加它们了。但这并非总是如此,所以我们将继续前进!

<p></p>

不要过滤掉你的Web组件

WordPress有几种不同的方法可以帮助用户创建有效的HTML,并防止你的Eddie叔叔将从Shady Al那里获得的“搞笑”图片直接粘贴到编辑器中(包括用于入侵你所有访问者的脚本)。

因此,当直接将Web组件添加到块或小部件中时,我们需要小心WordPress内置的代码过滤。完全禁用它会让Eddie叔叔(以及Shady Al)为所欲为,但是我们可以修改它以允许我们的Web组件通过大门(幸运的是,它阻止了Eddie叔叔)。

首先,我们可以使用wp_kses_allowed过滤器将我们的Web组件添加到不应过滤掉的元素列表中。这有点像我们正在将组件列入白名单,我们通过将其添加到传递给过滤器函数的允许标签数组中来实现这一点。

function add_diy_ezwebcomp_to_kses_allowed( $the_allowed_tags ) {
  $the_allowed_tags['zombie-profile'] = array();
}
add_filter( 'wp_kses_allowed_html', 'add_diy_ezwebcomp_to_kses_allowed');
登录后复制

我们向<zombie-profile></zombie-profile>组件添加一个空数组,因为WordPress会过滤掉属性以及元素——这给我们带来了另一个问题:默认情况下不允许使用slot属性。因此,我们必须在预期使用它的每个元素上显式允许它,并且,相应地,用户可能决定将其添加到其中的任何元素。(等等,即使你已经与每个用户一起复习了六遍,这些元素列表也不相同……谁知道呢?)因此,在下面,我将slot设置为true,用于<span></span><img alt="在WordPress中使用Web组件比您想象的要容易" ><ul></ul>,这三个元素是我放在<zombie-profile></zombie-profile>组件的插槽中的。

function add_diy_ezwebcomp_to_kses_allowed( $the_allowed_tags ) {
  $the_allowed_tags['zombie-profile'] = array();
  $the_allowed_tags['span']['slot'] = true;
  $the_allowed_tags['ul']['slot'] = true;
  $the_allowed_tags['img']['slot'] = true;
  return $the_allowed_tags;
}
add_filter( 'wp_kses_allowed_html', 'add_diy_ezwebcomp_to_kses_allowed');
登录后复制

我们也可以使用类似以下代码的方法在所有允许的元素中启用slot属性:

function add_diy_ezwebcomp_to_kses_allowed($the_allowed_tags) {
  $the_allowed_tags['zombie-profile'] = array();
  foreach ($the_allowed_tags as &$tag) {
    $tag['slot'] = true;
  }
  return $the_allowed_tags;
}
add_filter('wp_kses_allowed_html', 'add_diy_ezwebcomp_to_kses_allowed');
登录后复制

遗憾的是,还有一个可能的问题。如果你的插槽中所有元素都是内联/短语元素,你可能不会遇到这个问题,但是如果你有一个块级元素要放入你的Web组件中,你可能会与代码编辑器中的块解析器发生冲突。你可能比我更擅长拳击,但我总是输。

由于我无法完全解释的原因,客户端解析器假设Web组件应该只包含内联元素,如果你在那里放了一个<p></p>

或其他一些块级元素,它会将结束的Web组件标签移动到最后一个内联/短语元素之后。更糟糕的是,根据WordPress开发者手册中的注释,目前“无法替换客户端解析器”。

虽然这令人沮丧,而且你必须让你的Web编辑器学习这一点,但有一个解决方法。如果我们将Web组件直接放在块编辑器中的自定义HTML块中,客户端解析器就不会让我们在人行道上哭泣、来回摇晃,并质疑我们编码的能力……当然,这种情况从未发生在任何人身上……特别是那些写文章的人……

将组件添加到主题

只要不在HTML块之外更新,在主题文件中输出我们漂亮的Web组件就非常简单。我们按照在任何其他上下文中添加它的方式添加它,并且,假设我们已经安装了模板、脚本和样式,事情就会正常工作。

但是,假设我们想在一个Web组件中输出WordPress帖子或自定义帖子类型的内容。你知道的,写一篇帖子,这篇帖子就是组件的内容。这允许我们使用WordPress编辑器来输出<zombie-profile></zombie-profile>元素的存档。这很棒,因为WordPress编辑器已经拥有我们输入其中一个<zombie-profile></zombie-profile>组件内容所需的大部分UI:

    <li> 帖子标题可以作为僵尸的名字。 <li>帖子内容中的常规段落块可以用于僵尸的陈述。 <li> 特色图片可以用于僵尸的个人资料图片。

这就是大部分内容!但是我们仍然需要僵尸的年龄、感染日期和兴趣的字段。我们将使用WordPress内置的自定义字段功能创建这些字段。

我们将使用处理打印每个帖子的模板部分(例如content.php)来输出Web组件。首先,我们将打印打开的<zombie-profile></zombie-profile>标签,然后是帖子缩略图(如果存在)。

<zombie-profile><?php // 如果存在帖子特色图片...
    if (has_post_thumbnail()) {
      $src = wp_get_attachment_image_url(get_post_thumbnail_id()); ??><img  slot="profile-image" src="<?php%20echo%20%24src;%20?>" alt="在WordPress中使用Web组件比您想象的要容易" ><?php }
  ??></zombie-profile>
登录后复制

接下来,我们将打印用于名称的标题

<?php // 如果存在帖子标题字段...
  if (get_the_title()) { ??><?php echo get_the_title(); ??>
  <?php }
?>
登录后复制

在我的代码中,我在打印这些字段之前测试了它们是否存在,原因有两个:

    <li>在大多数情况下,隐藏空字段周围的标签和元素是一种良好的编程实践。 <li>如果我们最终为名称输出一个空的<span></span>(例如,`),那么该字段将在最终的个人资料中显示为空,而不是使用我们Web组件内置的默认文本、图像等。(例如,如果你希望文本字段在没有内容时为空,你可以在自定义字段中输入空格,或者跳过代码中的if`语句)。

接下来,我们将获取自定义字段并将它们放在它们所属的插槽中。同样,这将进入输出帖子内容的主题模板。

<?php // 僵尸年龄
  $temp = get_post_meta(the_ID(), 'Age', true);
  if ($temp) { ??><?php echo $temp; ??>
    <?php }
  // 僵尸感染日期
  $temp = get_post_meta(the_ID(), 'Infection Date', true);
  if ($temp) { ??><?php echo $temp; ??>
    <?php }
  // 僵尸兴趣
  $temp = get_post_meta(the_ID(), 'Interests', true);
  if ($temp) { ??>
登录后复制

使用WordPress自定义字段的缺点之一是,你无法进行任何特殊格式化。填充此内容的非技术Web编辑器需要为列表中的每个兴趣项目编写<li>标签(例如,20.)。(你可能可以通过使用更强大的自定义字段插件(如Advanced Custom Fields、Pods或类似插件)来解决此界面限制。)最后,我们添加僵尸的陈述和结束的<zombie-profile></zombie-profile>标签。

<?php $temp = get_the_content();
      if ($temp) { ??><?php echo $temp; ??>
      <?php }
    ?>
登录后复制

因为我们使用帖子的正文作为我们的陈述,所以我们会额外获得一些代码,例如围绕内容的段落标签。将个人资料陈述放在自定义字段中可以减轻这种情况,但是根据你的目的,它也可能是预期的/所需的行为。

然后,你只需将每个帖子发布为一个帖子,就可以根据需要添加任意数量的帖子/僵尸个人资料!

块派对:自定义块中的Web组件

创建自定义块是添加Web组件的好方法。你的用户将能够填写所需的字段并获得Web组件的魔力,而无需任何代码或技术知识。此外,块完全独立于主题,因此,我们可以在一个网站上使用此块,然后将其安装到其他WordPress网站上——这有点像我们期望Web组件的工作方式!

自定义块主要有两个部分:PHP和JavaScript。我们还将添加一些CSS来改善编辑体验。

首先是PHP:

function ez_webcomp_register_block() {
  // 注册构建自定义块所需的JavaScript
  wp_register_script(
    'ez-webcomp',
    plugins_url('block.js', __FILE__),
    array('wp-blocks', 'wp-element', 'wp-editor'),
    filemtime(plugin_dir_path(__FILE__) . 'block.js')
  );

  // 注册组件的CSS文件
  wp_register_style(
    'ez-webcomp',
    plugins_url('ezwebcomp-style.css', __FILE__),
    array(),
    filemtime(plugin_dir_path(__FILE__) . 'ezwebcomp-style.css')
  );

  // 在ez-webcomp命名空间中注册自定义块
  register_block_type('ez-webcomp/zombie-profile', array(
    // 我们已经有外部样式了;这些仅在我们使用WordPress编辑器时使用
    'editor_style' => 'ez-webcomp',
    'editor_script' => 'ez-webcomp',
  ));
}
add_action('init', 'ez_webcomp_register_block');
登录后复制

CSS不是必需的,它确实有助于防止僵尸的个人资料图片与WordPress编辑器中的内容重叠。

/* 设置图像的宽度和高度。
 * 你的里程数可能会有所不同,因此请根据需要进行调整。
 * "pic" 是我们在block.js中添加到编辑器的类
*/
#editor .pic img {
  width: 300px;
  height: 300px;
}
/* 此CSS确保为图像分配了正确的空间,
 * 并同时防止按钮在选择图像之前调整大小。
*/
#editor .pic button.components-button {
  overflow: visible;
  height: auto;
}
登录后复制

我们需要的JavaScript稍微复杂一些。我已经努力尽可能简化它并使其尽可能易于访问,因此我使用ES5编写它以消除编译的需要。

显示代码

(function (blocks, editor, element, components) {
  // 创建元素的函数
  var el = element.createElement;
  // 处理块字段的文本输入
  var RichText = editor.RichText;
  // 处理上传图像/媒体
  var MediaUpload = editor.MediaUpload;

  // 回到PHP中的register_block_type
  blocks.registerBlockType('ez-webcomp/zombie-profile', {
    title: 'Zombie Profile', // 在块选择器中显示的用户友好名称
    icon: 'id-alt', // 在块选择器中使用的图标
    category: 'layout',
    // 属性是我们将使用的所有不同字段。
    // 我们正在定义它们是什么以及块编辑器如何从它们那里获取数据。
    attributes: {
      name: {
        // 内容类型
        type: 'string',
        // 可用于获取信息的位置
        source: 'text',
        // 选择器是块编辑器选择和获取内容的方式。
        // 这些在块的一个实例中应该是唯一的。
        // 如果你只有一个img或一个<p>等,你可以使用元素选择器。
        selector: '.zname',
      },
      mediaID: { type: 'number', },
      mediaURL: { type: 'string', source: 'attribute', selector: 'img', attribute: 'src', },
      age: { type: 'string', source: 'text', selector: '.age', },
      infectdate: { type: 'date', source: 'text', selector: '.infection-date' },
      interests: { type: 'array', source: 'children', selector: 'ul', },
      statement: { type: 'array', source: 'children', selector: '.statement', },
    },
    // edit函数处理在块编辑器中如何显示内容。
    edit: function (props) {
      var attributes = props.attributes;
      var onSelectImage = function (media) {
        return props.setAttributes({ mediaURL: media.url, mediaID: media.id, });
      };
      // return语句是在编辑器中显示的内容。
      // el() 创建一个元素并设置它的不同属性。
      return el(
        // 在这里使用div而不是zombie-profile Web组件是为了简单起见。
        'div',
        { className: props.className },
        // 僵尸的名字
        el(RichText, {
          tagName: 'h2',
          inline: true,
          className: 'zname',
          placeholder: 'Zombie Name…',
          value: attributes.name,
          onChange: function (value) {
            props.setAttributes({ name: value });
          },
        }),
        el(
          // 僵尸个人资料图片
          'div',
          { className: 'pic' },
          el(MediaUpload, {
            onSelect: onSelectImage,
            allowedTypes: 'image',
            value: attributes.mediaID,
            render: function (obj) {
              return el(
                components.Button,
                {
                  className: attributes.mediaID ? 'image-button' : 'button button-large',
                  onClick: obj.open,
                },
                !attributes.mediaID ? 'Upload Image' : el('img', { src: attributes.mediaURL })
              );
            },
          })
        ),
        // 我们将在块编辑器中包含僵尸年龄的标题
        el('h3', {}, 'Age'),
        // 年龄字段
        el(RichText, {
          tagName: 'div',
          className: 'age',
          placeholder: 'Zombie\'s Age…',
          value: attributes.age,
          onChange: function (value) {
            props.setAttributes({ age: value });
          },
        }),
        // 感染日期标题
        el('h3', {}, 'Infection Date'),
        // 感染日期字段
        el(RichText, {
          tagName: 'div',
          className: 'infection-date',
          placeholder: 'Zombie\'s Infection Date…',
          value: attributes.infectdate,
          onChange: function (value) {
            props.setAttributes({ infectdate: value });
          },
        }),
        // 兴趣爱好标题
        el('h3', {}, 'Interests'),
        // 兴趣爱好字段
        el(RichText, {
          tagName: 'ul',
          // 每按一次`Enter`键都会创建一个新的</p>
登录后复制
<li> multiline: 'li', placeholder: 'Write a list of interests…', value: attributes.interests, onChange: function (value) { props.setAttributes({ interests: value }); }, className: 'interests', }), // 僵尸陈述标题 el('h3', {}, 'Statement'), // 僵尸陈述字段 el(RichText, { tagName: 'div', className: "statement", placeholder: 'Write statement…', value: attributes.statement, onChange: function (value) { props.setAttributes({ statement: value }); }, }) ); }, // 将内容存储在数据库中并在前端显示。 // 在这里我们必须确保使用了Web组件。 save: function (props) { var attributes = props.attributes; return el( // 因为在WordPress中使用自定义元素需要一些额外的步骤,所以我们使用一个普通的div。 'div', { className: 'zombie-profile', ...attributes }, // 确保在打印之前验证所有字段是否存在。 attributes.name && el('h2', { className: 'zname' }, attributes.name), attributes.mediaURL && el('img', { src: attributes.mediaURL, slot: 'profile-image' }), attributes.age && el('div', { className: 'age' }, attributes.age), attributes.infectdate && el('div', { className: 'infection-date' }, attributes.infectdate), attributes.interests && el('ul', {}, attributes.interests), attributes.statement && el('div', { className: 'statement' }, attributes.statement) ); }, }); }(window.wp.blocks, window.wp.blockEditor, window.wp.element, window.wp.components)); <p></p>

连接到Web组件

现在,如果某个好心人、写文章的人和完全很棒的人创建了一个你可以将你的Web组件插入并用于你的网站的模板,那不是很棒吗?好吧,那个人没空(他去帮助慈善机构或其他什么地方了),所以我做了。它在github上:

自己动手——WordPress的简单Web组件

该插件是一个编码模板,它注册你的自定义Web组件,注册组件所需的脚本和样式,提供你可能需要的自定义块字段的示例,甚至确保在编辑器中样式精美。像手动安装任何其他WordPress插件一样,将其放在/wp-content/plugins中的新文件夹中,确保使用你的特定Web组件更新它,然后在“已安装插件”屏幕上的WordPress中激活它。

还不错,对吧?

即使看起来有很多代码,我们实际上也只是做了一些相当标准的WordPress操作来注册和渲染自定义Web组件。而且,由于我们将其打包为插件,因此我们可以将其放入任何WordPress网站并开始发布僵尸个人资料,直到我们的心满意足。

我认为平衡点是尝试使组件在WordPress块编辑器中的工作效果与前端一样好。如果没有这个考虑,我们可以用更少的代码来完成这项工作。

尽管如此,我们还是成功地将我们在之前文章中制作的完全相同的组件放入了CMS中,这允许我们在网站上放置任意数量的僵尸个人资料。我们将Web组件知识与WordPress块相结合,为可重用的Web组件开发了一个可重用的块。

你会为你的WordPress网站构建什么样的组件?我想这里有很多可能性,我很想知道你最终会制作什么。

以上是在WordPress中使用Web组件比您想象的要容易的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板