iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 14
0
自我挑戰組

Wordpress 外掛開發系列 第 14

「Wordpress 外掛開發」shortCode 給你的館員將貢獻表移入shortcode之中

當我們想要使用php的內容,基本上在wordpress上編輯是會被直接轉化成esc_html的,我們這邊定義的wordpress編輯係指在wordpress的後台加入的內容,而如我們要讓動態資料載入到我們的wordpress 編輯內容之中,我們可以使用shortcode來達成,藉由輸入參數來讓它出現多采多姿得樣子。

基礎shortCode有什麼

在原生的系統上,我們可以使用的就有六種(不包含外掛提供的),而以下是個部分,單一使用都很基礎,可以在節錄的介紹中看見,我們就快速的展示:

  • [caption]
  • [gallery]
  • [audio]
  • [video]
  • [playlist]
  • [embed]

add_shortcode / remove_shortcode

使用add_shortcode其實非常容易,與其他更加簡潔,只需要加入有唯一性的$tag,然後帶入你要回傳的template,這樣即可以顯示,而另外的刪除shortcode則是與先前無異,找到地方及可以刪除,而如果我們的shortcode需要加入更多的參數,只需要在回傳的函式中加入即可,add_shortcode是不用加入的,可以看見shortcode的handler中間三個是如何處理,來做相對應的條件顯示。

我們使用woocommerce來當範例,請大家去安裝一下,學好電商不吃虧XD我們建立一個產品的項目(card),woocommerce有提供[products]可以直接顯示,可是如果我們只是想要簡單的顯示,圖片、標題以及價錢呢?

add_action( 'init', 'go_ranger_shortcode' );

function go_ranger_shortcode(){
  add_shortcode('ranger_shoot','ranger_shoot_template');
}

function ranger_shoot_template($atts = [], $content = null, $tag = ''){
  $user_parms = shortcode_atts( array(
		'product_id' => '0'
	), $atts );
  get_search_content($user_parms['product_id']);
}

function get_search_content($product_id){
  $product = wc_get_product( $product_id );
  $image = wp_get_attachment_image_src( get_post_thumbnail_id( $product_id ), 'single-post-thumbnail' );?>
  <img src="<?php  echo $image[0]; ?>" >
  <span> <?php echo $product->get_name(); ?></span>
  <span> <?php echo $product->get_price(); ?></span>
  <?php
}

來,你的貢獻表

如此我們就可以做一個簡單的產品顯示卡片,而想要加入的可以有更多的彈性,而在woocommerce中的global $product這些取得,因為不太熟悉所以都是使用wc_get_product來代替,除非是進到特定頁面才有辦法取得那些get_title的資料,所以在使用還是明確點較為恰當,那我們就來做我們員工的貢獻表了。


add_action( 'init', 'go_ranger_shortcode' );

function go_ranger_shortcode(){
  add_shortcode('ranger_shoot','ranger_milestone_template');
}

function ranger_milestone_template($atts = [], $content = null, $tag = ''){
  global $current_user; 

  if($current_user){
    go_ranger_user_collaborate(get_current_user_id());
  } else go_ranger_default_template();
}

function go_ranger_user_collaborate($user__ID ) {
  // $level也可以用來檢查權限
  $level = get_user_meta( $user__ID, 'user_level', true );

  if (  empty( $level ) ) {
        go_ranger_default_template();
        return;
  }

  $posts = get_posts( [ 'numberposts' => -1 ] ); 
  $posts_count = count_user_posts( $user->ID );?>
  <h2>貢獻里程碑</h2>
  <table class="form-table">
    <tr>
      <th><label for="go_ranger-favorite-post">等級</label></th>
      <td><?php echo esc_html($level) ?></td>
    </tr>
		<tr>
			<th><label for="go_ranger-favorite-post">Favorite Post</label></th>
      <td>
        <ol>
					<?php foreach ( $posts as $post ) {
						printf(
							'<li>%s</li>',
							esc_html( $post->post_title )
						);
					} ?>
        <ol/>
        </br>
				<span class="description">你已經完成了<?php echo esc_html($posts_count) ?>書本上傳了!</span>
			</td>
		</tr>
	</table>
 <?php }

 function go_ranger_default_template(){
   echo "看來你不是屬於我們的一員。";
 }

現在我們就可以使用[ranger_shoot]就可以顯示我們的貢獻表了,當時還在朦朧時看到了shortcode寫作,不過讓人為之一亮的shortcode寫法,當時很迷這個東西,我幾乎所有的東西都用shortcode來代替,不過在更深入了解content post之後,對於模板的切換有著更深入的理解,回頭看來,shortcode真的是方便,但不要將使用的情境搞混才是最好的。

而shortcode唯一的問題就是比較慢,然而我們不可能因為效能的關係,就放棄這個動態增加的用法,在wordpress的開發之中,最大的問題就是評估,才不會讓你的網站效率慢又ux糟糕,而另外有個其他的應用,是將shortcode加入widget之中,這其實非常容易,只需要在你的程式碼中加入add_filter( 'widget_text', 'do_shortcode' );,這樣即可在點選custom HTML的widget之中加入加入你要的內容,比如說像無名小站人氣累積(以暴漏年齡)之類的,或是建成class來加入register_widget,也是非常好用的啦,下面節錄簡單的使用來做應用!

class Level_system_Widgets extends WP_Widget {

    public function __construct(){
        $widget_ops = array( 
            'classname' => 'level_system_widget',
            'description' => 'Level System Widget',
        );
        parent::__construct( 'level_system_widget', 'Level System Widget', $widget_ops );
    }

    public function widget( $args, $instance ) {
        echo $args['before_widget'];
        if ( ! empty( $instance['title'] ) ) {
            echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
        }
        echo esc_html__( 'Hello, World!', 'text_domain' );
        echo $args['after_widget'];
    }   

    public function form( $instance ) {
        $title = ! empty( $instance['title'] ) ? $instance['title'] : esc_html__( 'New title', 'text_domain' );
    ?>
    <p>
    <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php esc_attr_e( 'Title:', 'text_domain' ); ?></label> 
    <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
    </p>
    <?php 
    }

    public function update( $new_instance, $old_instance ) {
        $instance = array();
    $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? sanitize_text_field( $new_instance['title'] ) : '';

    return $instance;
    }

}
add_action('widgets_init', create_function('', 'return register_widget("Level_system_Widgets");'));

shortcode就到此告一段落,雖然寫這個是寫了就可以在看到改變,但我覺得外掛開發的核心,還是得先著重在後台中,option設定及編排,以系統資料的設定複雜度,是足以應付前端的一些基礎需求的,在wordpress中最困難的不是寫程式,而是你不知道寫了一個功能後,是不是原生就已經有提供這一項了,做白工是不舒服的。

reference

wordpress - shortcode
wordpress - do_shortcode
How to Add Audio Files and Create Playlists in WordPress
Using WP_Query to pull and display WooCommerce Products
in woocommerce, is there a shortcode/page to view all orders?
How to make my custom widget appear within WordPress widgets? Plugin development


上一篇
「Wordpress 外掛開發」建構我們的館員權限 - 以user data來更深入探討role與capability的應用
下一篇
「Wordpress 外掛開發」設計排程,定時清理不智言論 - wp-cron
系列文
Wordpress 外掛開發30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言