首頁 > web前端 > css教學 > 在WordPress中使用Web組件比您想像的要容易

在WordPress中使用Web組件比您想像的要容易

Joseph Gordon-Levitt
發布: 2025-03-21 11:09:11
原創
590 人瀏覽過

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( &#39;wp_footer&#39;, &#39;diy_ezwebcomp_footer&#39;);
登入後複製

接下來是註冊組件的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' );
登入後複製

這並不太難,對吧?如果你不打算讓除管理員以外的任何用戶使用它,那麼你就可以在任何你想使用它們的地方添加它們了。但這並非總是如此,所以我們將繼續前進!

不要過濾掉你的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組件應該只包含內聯元素,如果你在那裡放了一個

或其他一些塊級元素,它會將結束的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(), &#39;Age&#39;, true);
  if ($temp) { ??><?php echo $temp; ??>
    <?php }
  // 殭屍感染日期$temp = get_post_meta(the_ID(), &#39;Infection Date&#39;, true);
  if ($temp) { ??><?php echo $temp; ??>
    <?php }
  // 殭屍興趣$temp = get_post_meta(the_ID(), &#39;Interests&#39;, 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));

連接到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
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板