Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
內容目錄
短代碼與勾點可以說是讓 WordPress 實現模組化的核心功臣,短代碼的出現,也使 WordPress 的專案可以將 PHP 程式希望達成的功能,呼叫到頁面編輯器當中。在說明 Code Snippets 的時候,曾經提到過直接在頁面中執行 PHP 程式碼,對於管理會十分不方便,尤其當需要進行重複指令的時候。
因此,利用 Code Snippets 集中管理短代碼的方式,可以實現「在頁面執行的 PHP 程式」的需求。這次使用的例子「延伸閱讀」就是使用了這樣的概念。
事實上,許多知名的頁面編輯器,如 Elementor、Oxygen 等,都有透過短代碼儲存頁面屬性,再加以匯出、再製的功能。而知名的聯絡表單外掛 Contact Form 7,也是用短代碼的方式將聯絡表單產出的。
短代碼的基本寫法如下:
<?php add_shortcode( 'mycode', 'my_shortcode' );//在編輯器中輸入 [mycode] 就可以呼叫代碼 function my_shortcode( $atts ){ $a = shortcode_atts( array( 'class' => '', //短代碼要使用的參數 ), $atts ); }
其中 $atts 並非要的。$atts 代表的是短代碼使用的參數,譬如 [mycode class=1] 等。
這次的延伸閱讀,主要是透過搭配 ACF Pro 的方式,實現半外掛化的功能。先看看實際上操作的結果:
這項功能的操作邏輯如下:
首先我們需要先建立一個重複器 (repeater) 欄位,因為一篇文章可能會有不只一篇的相關文章。而重複器中,我們需要再建立一個文章物件 (Post Object) 欄位,回傳格式我們選用文章物件 (Post Object),來符合後續短代碼的程式碼。
接下來,我們將自訂欄位與 [文章] 進行關聯。
/** * Relevant Posts */ /** * Use this to register custom fields and the shortcode for relevant posts. * Required: ACF Pro or ACF Repeater Extension */ if ( !function_exists( 'hyc_relevant_posts' ) ){ function hyc_relevant_posts( $atts ) { $output = ''; $arr = []; if ( ! function_exists( 'get_field' ) ) : return esc_html__( 'This shortcode requires the plugin ACF, please install it.', 'applemint' ); else : $a = shortcode_atts( array( 'key' => 0, ), $atts ); if ( have_rows( 'relevant_posts' ) ) { while( have_rows( 'relevant_posts') ) { the_row( 'relevant_posts' ); $arr[] = get_sub_field( 'relevant_post' ); } } $pid = $arr[$a['key']]->ID; $output = '<div class="relevant-post custom-loop-list">'; $output .= '<fieldset><legend>' . esc_html__( 'More to read', 'applemint' ) . '</legend>'; $output .= '<div class="flex flex-wrap"><div class="f-w-4"><a href="' . get_permalink( $pid ) . '" target="_blank">'; $output .= get_the_post_thumbnail( $pid, 'blog-loop', array( 'class' => 'post-thumbnail aligncenter lozad', 'data-src' => get_the_post_thumbnail_url( $pid, 'blog-loop' ), 'src' => '' ) ) . '</a></div>'; $output .= '<div class="f-w-8"><a href="'. get_permalink( $pid ) . '" target="_blank"><h3 class="entry-title">'. get_the_title( $pid ) . '</h3></a>'; $output .= get_post_meta( $pid, '_aioseop_description' )[0] . '</div>'; $output .= '</div><!-- .flex -->'; $output .= '</fieldset></div><!-- .relevant-post -->'; return $output; endif; //ACF check } } add_shortcode( 'hyc_relevant', 'hyc_relevant_posts' );
在這個步驟中,我們建立名為 hyc_relevant 的短代碼,其中會使用到的參數是 key。需要注意的是 PHP 當中 key 會從 0 開始計算,因此我們的預設值先設定為 0(如果今天只使用 [hyc_relevant],那就會自動帶入第一篇文章。
透過 if ( have_rows( ‘relevant_posts’ ) ) 來驗證我們的重複器欄位中是不是有任何內容,如果有的話,我們會在 $arr 這個變數裡儲存每一篇所選文章的物件。
接著我們就可以透過 $output 這個變數,將希望建立的 html 標記。
這邊注意一下 get_post_meta( $pid, ‘_aioseop_description’ )[0] ,這是因為我們公司使用了 All in One SEO Pack 這套外掛,用來擷取 description 的中繼資料用,這裡也可以改為 get_the_excerpt( $pid ); 來擷取文章的內容摘要。
以上面圖片中的例子來說,我們會透過這個短代碼得出以下的 html 標記:
<div class="relevant-post custom-loop-list"> <fieldset> <legend>More to read</legend> <div class="flex flex-wrap"> <div class="f-w-4"> <a href="https://www.applemint.tech/blog/ja-blog-kol/" target="_blank"> <img width="270" height="180" src="https://www.applemint.tech/wp-content/uploads/2017/10/influencer1024x540-270x180.jpg" class="post-thumbnail aligncenter lozad wp-post-image" alt="台湾インフルエンサー" data-src="https://www.applemint.tech/wp-content/uploads/2017/10/influencer1024x540-270x180.jpg" srcset="" data-loaded="true"> </a> </div> <div class="f-w-8"> <a href="https://www.applemint.tech/blog/ja-blog-kol/" target="_blank"> <h3 class="entry-title"> <span id="2019-KOL">【2019年版】台湾インフルエンサー裏話-台湾のブロガー/KOL の費用</span> </h3> </a> 台湾でインフルエンサーやブロガー、KOL のお探しにお困りですか? applemint ではすでにインフルエンサーやブロガーを手配した実績があり、 台湾インフルエンサーのメリットはもちろんデメリット、及び代理店の実情まで知っています。台湾でインフルエンサーをお探しの場合まずはご相談ください </div> </div><!-- .flex --> </fieldset> </div>
這邊直接附上 [相關文章] 的 SCSS 設置。
.relevant-post { h3 { margin-top: 0; } > fieldset { border: 1px solid #00c1d1; max-width: 90%; margin: 0 auto 1em auto; } > fieldset > div { padding: 8px 0 20px 0; } > fieldset legend { background: #00c1d1; border-radius: 5px; color: #fff; margin-left: 1em; padding: 8px 16px; } > fieldset legend::before { content: url('./assets/svg/post.svg'); margin-right: 0.5rem; } a::after { content: ''; } } .flex { display: flex; flex-wrap: wrap; .f-w-4 { width: 30%; flex-basis: auto; flex-grow: 0; margin-left: 0; margin-right: 0; .f-w-8 { width: 60%; flex-basis: auto; flex-grow: 0; margin-left: 0; margin-right: 0; } } @media screen and (max-width: $screen__break-point-s){ .flex { [class*="f-w"] { width: 100%; } .f-w-4:nth-child(3n+1), .f-w-4:nth-child(3n+2), .f-w-3:nth-child(4n+1), .f-w-3:nth-child(4n+2), .f-w-3:nth-child(4n+3), .f-w-6:not(.site-info):nth-child(2n+1) { margin-right: 0; } } }
post.svg 的內容如下:
<svg height="16" viewBox="0 0 512 512" width="16" xmlns="http://www.w3.org/2000/svg" fill="#fff"> <path d="m458.903 114.538c-11.106-15.146-26.587-32.85-43.589-49.852s-34.706-32.482-49.852-43.589c-25.787-18.91-38.296-21.097-45.462-21.097h-248c-22.056 0-40 17.944-40 40v432c0 22.056 17.944 40 40 40h368c22.056 0 40-17.944 40-40v-312c0-7.166-2.186-19.675-21.097-45.462zm-66.216-27.225c15.35 15.35 27.4 29.199 36.29 40.687h-76.977v-76.973c11.492 8.89 25.339 20.939 40.687 36.286zm55.313 384.687c0 4.336-3.664 8-8 8h-368c-4.336 0-8-3.664-8-8v-432c0-4.336 3.664-8 8-8 0 0 247.978-.001 248 0v112c0 8.836 7.163 16 16 16h112z"/><path d="m368 416h-224c-8.836 0-16-7.163-16-16s7.164-16 16-16h224c8.837 0 16 7.163 16 16s-7.163 16-16 16z"/><path d="m368 352h-224c-8.836 0-16-7.163-16-16s7.164-16 16-16h224c8.837 0 16 7.163 16 16s-7.163 16-16 16z"/><path d="m368 288h-224c-8.836 0-16-7.163-16-16s7.164-16 16-16h224c8.837 0 16 7.163 16 16s-7.163 16-16 16z"/> </svg>
短代碼適合用的情境,在於他可以高度客製化,同時又可以透過參數,讓使用者保有一定的操作彈性。因此在設計上,需要先設想好每個參數的預設值,以及例外狀況(學程式的時候都需要考慮的議題)。
由於 ACF Pro 從版本 5.8 開始,就開始支援註冊區塊的功能,因此未來應該也可以把這項功能改用 ACF 的自訂區塊包裝起來。
Eric 您好,
從意見回饋那邊好像郵件無法順利傳送出去