23 mins read2022/08/03

在網頁前台上添加一個HTML輸入框


前言

如果你會一些 HTML,你可能已經知道如何添加常規的輸入框、例如:

  1. 一般輸入框 input
    1. 文字 type="text"
    2. 電子信箱 type="email"
    3. 網址 type="url"
    4. 日期 type="date"
    5. 單選 type="radio"
    6. 多選 type="checkbox"
  2. 區塊輸入框 textarea

最近開發上遇到一個常見的需求,就是要做前端的提交表單

其實更簡單的方式用 ACFMetabox 都能做同樣的需求

好了,這篇講完了 😂😂😂

 

為什麼我不用套件實現

其實是可以用套件的,我自己也蠻常使用 Metabox ,而且 Metabox 還能產生 php code 去修改

通常是很簡單的需求,或者很需要高度客製化的需求,要考慮到未來擴充或者自訂邏輯時,才會選擇自己做

在你繼續往下看之前,我們假設你已經具備基礎的 php 知識,以及知道如何運用版型覆寫機制去新增修改 php

既然講到 HTML 的輸入框!?是不覺得很熟悉?

不就是跟後台的 傳統編輯器 ( Classic Editor ) 一樣嗎?

 

關於傳統編輯器 ( Classic Editor )

傳統編輯器 ( Classic Editor ) ,的正確名稱其實是 TinyMCE

TinyMCE 是一款功能極其豐富、客製化程度也超級高、也有豐富生態系的開源編輯器

因為其開源的特性,TinyMCE 也有非常多的套件可以安裝 ( 第 4 版套件列表 ) ,但是 ⭐ 要注意你的 TinyMCE 版本 ⭐

⭐ WordPress 預設是整合它的第 4 版,想要用第 5 版的朋友們可以安裝 Advanced Editor Tools 由 WordPress 母公司 Automattic 開發

( 挖,一下子沒注意, TinyMCE  居然出到第 6 版了,跟上 WordPress 更新的節奏,但 WordPress 還是只有整合第 4 版 😂 )

如果想知道怎麼在後台啟用傳統編輯器 ( Classic Editor ) 的話,可以參考這篇

怎麼去安裝 TinyMCE  的套件,還有客製化你順手的編輯器,這個未來有機會再做一篇,有興趣的朋友們可以先去看第 4 版的文件

 

添加傳統編輯器 ( Classic Editor ) / TinyMCE 在畫面上

TinyMCE 官方有提供好幾種添加方式,對應不同的套件管理工具和框架等… npm, composer 等…會用這些管理工具的自己看就好了

這邊主要挑一個最基本的 HTML 講就好

1. 官方引入方式 ( 最新版 第6版 )

可以參考 TinyMCE 官方文件,或者直接看官網的 Codepen 範例

tinyMCE
用法也是相當的簡單

 

2. WordPress 整合的 TinyMCE ( 舊版 第 4 版 )

這邊我們會用到  wp_editor() 這隻函式


wp_editor( string $content, string $editor_id, array $settings = array() )
變數 說明
$content string (必填)

輸入框的內容

$editor_id string  (必填)

輸入框的 id ,之後你要取得輸入框內容就要靠這 id 來識別了

$settings array (選填)

TinyMCE 的 config 參數可以填在這裡

例如:限制這個 HTML 編輯器有哪些按鈕,比如說,你不想要用戶上傳圖片,可以把新增圖片的按鈕移除,或者不想要使用者編輯顏色,也可以把顏色按鈕移除,又或者,要讓使用者只能使用限定的顏色,這些細部都可以控制

這些選項,在上述的 1. 官方引入方式 ( 最新版 第6版 ) 也同樣可以使用

可以參考 TinyMCE 的官方文件設置,或下方程式碼範例

 


// 初始內容為空
$content = ''; 

// 設定輸入框 id = html_input
$editor_id = 'html_input';

// TinyMCE 的設定參數
$args = array(
    'tinymce'       => array(
        // 定義各個工具列要放什麼
        'toolbar1'      => 'bold,italic,underline,separator,alignleft,aligncenter,alignright,separator,link,unlink,undo,redo',
        'toolbar2'      => '', // 第二工具列不放東西
        'toolbar3'      => '', // 第三工具列不放東西
    ),
);
wp_editor( $content, $editor_id, $args );
例如像這樣,我用這方法讓用戶可以在 WCMP 的會員介面修改自己的商店資訊

 

3.再更進階的用法 – TinyMCE in Ajax

使用場景是這樣的

比如說我要對某套件,例如 WCMP 去做後台/前台欄位的修改

而這套件又沒有 Hook又沒有支援版型覆寫

那你只剩下兩條路

  1. 硬改套件原始碼:極度不推薦,因為套件只要一更新,你的客製化代碼會消失,除非你永遠不更新
  2. 透過 Javascript 來客製:在特定的套件頁面,引入你自己的 Javascript 文件,透過 Javascript 來做 DOM 修改和 Ajax 表單存值

此時的你,如果你又要新增一個 HTML 編輯器

回到前面講到的2種引入方式

1. 官方引入方式 ( 最新版 第6版 )  – 可以用,直接透過 Javascript 創造一個 textarea 的 DOM,再初始化就好

2. WordPress 整合的 TinyMCE  – 依然可以用,步驟如下:

  1. 在 php 上先用 wp_editor() 產生,TinyMCE 的 DOM
  2. 運用 ob_start()ob_get_clean() 將 TinyMCE 的 DOM 塞到變數裡面
  3. 透過 wp_localize_script 將變數丟到前端瀏覽器
  4. 只要輸出這個變數,就可以得到一個 TinyMCE 編輯器

 

在你的 functions.php 裡面


// 1. 在 php 上先用 wp_editor() 產生,TinyMCE 的 DOM
// 2. 運用 ob_start() 與 ob_get_clean() 將 TinyMCE 的 DOM 塞到變數裡面
function get_wp_editor( $content = '', $editor_id, $options = array() ) {
    ob_start();
    
    wp_editor( $content, $editor_id, $options );
 
    // 這一步會把 TinyMCE 的 DOM 傳入到 $temp
    $temp = ob_get_clean(); 

    // 下面是會載入 TinyMCE 的 初始化 Javascript 代碼
    $temp .= \_WP_Editors::enqueue_scripts();
    $temp .= print_footer_scripts();
    $temp .= \_WP_Editors::editor_js();
 
    return $temp;
}

 


// 透過 wp_localize_script 將變數丟到前端瀏覽器
add_action('admin_enqueue_scripts', 'custom_wcmp_field_enqueue');

function custom_wcmp_field_enqueue($hook)
{
    // 這邊是限制,只有在 WCMP 後台才可以繼續,不然就退出函式
    if ('wcmp_page_vendors' !== $hook) {
        return;
    }

    // 引入你的客製化 Javascript
    wp_enqueue_script('custom_wcmp_field', get_stylesheet_directory_uri() . '/assets/js/wcmp-custom-field.js', array(), '1.0.0', true);


    // 將 php 的變數傳到前台去
    wp_localize_script('custom_wcmp_field', 'ajax_object', array(
        'ajaxurl' => admin_url('admin-ajax.php'),
        'ajaxnonce' => wp_create_nonce('ajax_post_validation'), // 安全性考量,這個蠻重要的
        'vendor_id' => $_GET['ID'],
        'vendor' => get_user_meta($_GET['ID']),
        // 下面這兩個就是兩個 HTML 編輯器
        'vendor_other_editor' => get_wp_editor(wpautop(get_user_meta($_GET['ID'], '_vendor_other', true)), 'vendor_other'),
        'vendor_charge_editor' => get_wp_editor(wpautop(get_user_meta($_GET['ID'], '_vendor_charge', true)), 'vendor_charge'),

        /*
         * 補充說明:
         * wpautop() - 自動補 <p> 標籤的函式,幫你自動斷行,不然你內容會連在一起
         * get_user_meta() - 取得用戶資料 ( user_meta )
        */
    ));
}

在你剛剛引入的 /assets/js/wcmp-custom-field.js 裡面


// 4. 輸出這個變數,就可以得到一個 TinyMCE 編輯器
let html = '';

// 這邊用的是 Javascript 的模板字符串 `` ,是可以換行的
html += `
<fieldset class="vendor_other_wrapper">
    <p class="vendor_other" style="vertical-align: top;"><strong>其他詳情</strong></p>
    <label class="screen-reader-text" for="vendor_other">其他詳情</label>
    ${ajax_object.vendor_other_editor}
</fieldset>
`;

結果會像這樣 – 客製化WCMP後台的欄位與輸入框

 

 

結語

今天講了這麼多,都是針對,怎麼把一個 HTML 編輯器,放到頁面上去

還沒有講到儲存資料的部分

 

覺得不錯的話,請給我點個推薦

您的支持與鼓勵是我們前進的最大動力!