iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 25
1
自我挑戰組

WordPress 客製化從 0 開始系列 第 25

Day 25 WordPress 的短代碼 (shortcode) 機制與客製化

  • 分享至 

  • xImage
  •  

大家好,我是 Eric。

昨天介紹了自訂迴圈的作法,並透過 header.php 範本檔製作首頁頁首的投影片輪播。今天,我們再來進一步透過短代碼 (shortcode) 的機制,讓我們可以在區塊編輯器中,更有彈性的加入我們想要想要使用的程式碼片段,甚至直接擴展既有外掛、佈景主題的功能。

短代碼的基本語法

短代碼在 WordPress 區塊編輯器中通常會以 [短代碼] 或是 [短代碼 參數1=值1 參數2=值2] 的方式呈現,如果安裝官方的 Jetpack 外掛,便可以透過 [portfolio] 來呈現作品集,或是透過 [testimonial] 來呈現使用者證言。

除了 Jetpack 以外,我們常見的頁面編輯器,如 Elementor,或是 WordPress 的進階搜尋外掛 Ivory Search ,都會在設定完後,產生一組短代碼,讓使用者可以任意貼在頁面,藉此產生相對應的內容。也因為他們是透過短代碼來產生內容,因此我們也可以藉由短代碼,字型擴充這些外掛的功能。

首先,定義短代碼的基本語法如下:

add_shortcode( 'myshortcode', 'eric_the_shortcode' );
function eric_the_shortcode( $atts ) {
    $a = shortcode_atts( array(
            '引數 1'   =>  '引數預設值',
            '引數 2'   =>  '引數預設值',
        ),
    $atts );
    /* 定義回傳的初始值 */
    $output = '';

    /* 接下來可以用 $a 來組合要用的字串 */
    $output .= '<a href="' . $a['引數 1'] . '">';
    $output .= $a['引數 2'] . '</a>';

    /* 最後要將組合後的字串回傳 */
    return $output;
}

接著只要透過 [myshortcode],就會在頁面回傳一個連結元素 <a href="引數 1">引數 2</a>

透過短代碼在頁面插入自訂輪播

我們延續昨天的範例,讓我們可以在頁面的任何區塊,或是在小工具中,插入自訂的投影片輪播。關於自訂內容類型與自訂欄位的設定,可以直接延續昨天的設定,但我們就不需要將迴圈放入 header.php 中。

/**
 * 定義自訂投影片輪播的短代碼。
 * 
 * @param string $atts 從短代碼回傳的引數。
 */
function custom_slider( $atts ) {
    $a = shortcode_atts( array(
        'slides'     => 3, //顯示投影片的張數
        'exclude'    => '', //排除投影片 ID,以逗點區隔
        'include'    => '', //包含投影片 ID,以逗點區隔
        'size'       => 'full', //投影片使用的圖片大小
        ),
    $atts );

    /* 將短代碼的引數轉換為自訂迴圈的引數 */
    $args = array(
        'post_type'         => 'slide',
        'posts_per_page'    => $a['slides'],
        'post__in'          => explode( ',', $a['include'] ),
        'post__not_in'      => explode( ',', $a['exclude'] ),
    );
    
    $slides = new WP_Query( $args );
    
    $output = '';
    
    if ( $slides -> have_posts() ) {
        $output .= '<div class="slick-slider" id="custom-slider">';
        while ( $slides -> have_posts() ) {
            $slides -> the_post();
            $output .= '<div id="slide-' . get_the_ID() . '">';
            $output .= '<a href="' . get_field( 'url' ) . '" target="_self">';
            $output .= get_the_post_thumbnail( get_the_ID(), $a['size'] );
            $output .= '</a>';
            $output .= '</div>';
        }
        $output .= '</div>';
    }
    wp_reset_postdata();
    return $output;
}
add_shortcode( 'slider', 'custom_slider' );

接著,只要在區塊編輯器加入短代碼區塊,或是直接在文章中插入短代碼 [slider],便會在任何你想要的位置插入上述的 HTML 元素。此外,也可以透過 [slider slides=4] 來自訂想要加入的投影片數量。

擴展其他外掛的短代碼

我們以 Content Blocks 這款外掛為例,原本的外掛是透過短代碼的方式,將頁面的物件模組化,集中在 Content Block 這個自訂類型中進行管理,可以說是區塊編輯器「可重複使用區塊」的前身。

原本 Content Blocks 可接受的引數如下所示:

/* post-widget.php Line 172 */
shortcode_atts( array(
    'id' => '',
    'slug' => '',
    'class' => 'content_block',
    'suppress_content_filters' => 'no',
    'featured_image' => 'no',
    'featured_image_size' => 'medium',
    'title' => 'no',
    'title_tag' => 'h3',
    'markup' => 'div'
), $atts ) );

今天我們想要結合頁面捲動動畫 (animation on scroll) 的功能,必須要加上 data-aos 的屬性,因此必須要擴展這個外掛的引數。我們可以先複製 Content Blocks 這款外掛的原始碼,透過編輯子佈景主題的 functions.php 或 Code Snippets 來做以下的改編。

/** 
 * 擴展 content_block 短代碼。
 * 按照 WordPress 的 PHP 編碼標準,我們把原本的 extract 作法改掉。
 */
add_shortcode( 'content_block_ext', 'custom_post_widget_shortcode' );
function custom_post_widget_shortcode( $atts ) {
    $a = shortcode_atts( array(
        'id' => '',
        'slug' => '',
        'class' => 'content_block',
        'suppress_content_filters' => 'no',
        'featured_image' => 'no',
        'featured_image_size' => 'medium',
        'title' => 'no',
        'title_tag' => 'h3',
        'markup' => 'div',
        'aos'    => '',
    ), $atts );

    if ( $a['slug'] ) {
        $block = get_page_by_path( $a['slug'], OBJECT, 'content_block' );
        if ( $block ) {
            $a['id'] = $block->ID;
        }
    }

    $content = '';

    if( $a['id'] != '' ) {
        $args = array(
            'post__in' => array( $a['id'] ),
            'post_type' => 'content_block',
        );

        $content_post = get_posts( $args );

        foreach( $content_post as $post ) {
            /* 這邊幫最外圍的元素加上 data-aos 的資料屬性。 */
            $aos_attr = ''
            if ( $a['aos'] !== '' ) {
                $aos_attr = ' data-aos="' . $a['aos'] . '"';
            }
            $content .= '<' . esc_attr( $a['markup'] ) . ' class="'. esc_attr( $a['class'] ) .'" id="custom_post_widget-' . $a['id'] . '"' . $aos_attr . '>';
            /* 以上是主要的修改部分。 */
            if ( $a['title'] === 'yes' ) {
                $content .= '<' . esc_attr( $a['title_tag'] ) . '>' . $post -> post_title . '</' . esc_attr( $a['title_tag'] ) . '>';
            }
            if ( $a['featured_image'] === 'yes' ) {
                $content .= get_the_post_thumbnail( $post -> ID, $a['featured_image_size'] );
            }
            if ( $a['suppress_content_filters'] === 'no' ) {
                $content .= apply_filters( 'the_content', $post -> post_content );
            } else {
                $content .= $post -> post_content;
            }
            $content .= '</' .  esc_attr( $a['markup'] ) . '>';
        }
    }

    return $content;
}

接著,我們便可以複製 Content Blocks 在後台顯示的短代碼,並在需要加入動畫的時候,將短代碼從原本的 [content_block ...] 改為 [content_block_ext ...] 就可以了。

結語

透過短代碼,我們可以大幅的提高 WordPress 客製化的彈性。前面舉的兩個例子,其中一個是自行建立想要包裝的短代碼,後者則是奠基於外掛的短代碼,再進一步客製化。透過這種作法,只要你熟悉了特定的外掛或佈景主題後,便能夠自己根據該外掛或佈景主題進行延伸。

下一章,我們一樣將結合前面所提到的各種工具,來針對 Contact Form 7 的功能進行擴展。

延伸閱讀

【第 09 天】WordPress 的 Shortcode
Shortcodes


上一篇
Day 24 WordPress 客製化取用資料的基本手段:迴圈 (loop)
下一篇
Day 26 WordPress 客製化實務:替 Contact Form 7 加上地址欄位
系列文
WordPress 客製化從 0 開始30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言