iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 12
1
自我挑戰組

Wordpress 外掛開發系列 第 12

「Wordpress 外掛開發」使用post Type建立個微型圖書館 - Your Post Type

  • 分享至 

  • xImage
  •  

我們今天的目標,就是製作一個微型圖書館館藏設施,我們設定user case是要使用以建立文章的模式,並且可以在上面做處理,並且加入分類的功能,備註一個事項,我在高中時很喜歡拿人家做的小專案的實現,來做第二個二次仿作,但有些是為了魔以模仿情境為由,實際上做出來的的功能是有,但效果是否良好更得考量到UX這些,所以請大家要斟酌。

建立自己的post type

首先我們會使用到我們的register_post_type來做第一個,這個功能是會在顯示page與post這邊,你可能可以常常看見外掛在page下面有不同的名稱,像是testimonial或者是中文的顧客回饋之類的,這是用這個方式來實作的,而他可以做出什麼取決你的想像力,你可以從做一個簡單的作品集,也可以複雜的eCommerce products像是woocommerce來實作,之後你也可以把post當git tree的每個commit,不過不知道是不是會有人這樣搞就是了。

add_action( 'init', 'goranger_book_collection_post_types' );

function goranger_book_collection_post_types() {

	register_post_type( 'book', [

		// Post type 的參數們
		'public'              => true,
		'publicly_queryable'  => true,
		'show_in_rest'        => true,
		'show_in_nav_menus'   => true,
		'show_in_admin_bar'   => true,
		'exclude_from_search' => false,
		'show_ui'             => true,
		'show_in_menu'        => true,
		'menu_icon'           => 'dashicons-book',
		'hierarchical'        => false,
		'has_archive'         => 'books',
		'query_var'           => 'book',
		'map_meta_cap'        => true,

		// 對於url的形式的覆寫
		'rewrite' => [
			'slug'       => 'books',
			'with_front' => false,
			'pages'      => true,
			'feeds'      => true,
			'ep_mask'    => EP_PERMALINK,
		],

		'supports' => [
			'title',
			'editor',
			'excerpt',
			'thumbnail'
		],

		// 文字標題
		'labels'              => [
			'name'                     => 'Books',
			'singular_name'            => 'Book',
			'add_new'                  => 'Add New',
			'add_new_item'             => 'Add New Book',
			'edit_item'                => 'Edit Book',
			'new_item'                 => 'New Book',
			'view_item'                => 'View Book',
			'view_items'               => 'View Books',
			'search_items'             => 'Search Books',
			'not_found'                => 'No books found.',
			'not_found_in_trash'       => 'No books found in Trash.',
			'all_items'                => 'All Books',
			'archives'                 => 'Book Archives',
			'attributes'               => 'Book Attributes',
			'insert_into_item'         => 'Insert into book',
			'uploaded_to_this_item'    => 'Uploaded to this book',
			'featured_image'           => 'Book Image',
			'set_featured_image'       => 'Set book image',
			'remove_featured_image'    => 'Remove book image',
			'use_featured_image'       => 'Use as book image',
			'filter_items_list'        => 'Filter books list',
			'items_list_navigation'    => 'Books list navigation',
			'items_list'               => 'Books list',
			'item_published'           => 'Book published.',
			'item_published_privately' => 'Book published privately.',
			'item_reverted_to_draft'   => 'Book reverted to draft.',
			'item_scheduled'           => 'Book scheduled.',
			'item_updated'             => 'Book updated.'
		]
	] );
}

在這裡比較重要的是文字標題的部分,在此方如果沒有定義,他全部就會轉化成page,其實這並不是讓人很開心的一件事情,但願以後是有個hook能夠把關鍵字給做簡單的replace,在對於特別的參數做不同的設定。

還記得我們前幾天提到的capabilities嗎?就是那一個莫名的manage_options,如果你又自己的設定自己的cap,那麼你可以使用自己的角色權限,來制定你的頁面只有什麼權限的人可以使用,有別於加入很多條件來選擇current_user_can,cap來做的話,更加的有組織性。

使用客製化的taxonmies

如果是想加入一個簡單的tas的話,是可以在register的陣列中加入'taxonomies'=>['post_tag']來做到,不過我們希望我們的名字是不一樣的,可以換名字叫做genre,並且依照官方的文件來做那些需求的參數,我們也在後面會使用到get_taxonomythe_terms來將我們的tax可以有更多的操作性。

add_action( 'init', 'goranger_books_register_taxonomies' );

function goranger_books_register_taxonomies() {

	register_taxonomy( 'genre', 'book', [

		'public'            => true,
		'show_in_rest'      => true,
		'show_ui'           => true,
		'show_in_nav_menus' => true,
		'show_tagcloud'     => true,
		'show_admin_column' => true,
		'hierarchical'      => true,
		'query_var'         => 'genre',

		'rewrite' => [
			'slug'         => 'genre',
			'with_front'   => false,
			'hierarchical' => false,
			'ep_mask'      => EP_NONE
		],

		'labels'            => [
			'name'                       => 'Genres',
			'singular_name'              => 'Genre',
			'menu_name'                  => 'Genres',
			'name_admin_bar'             => 'Genre',
			'search_items'               => 'Search Genres',
			'popular_items'              => 'Popular Genres',
			'all_items'                  => 'All Genres',
			'edit_item'                  => 'Edit Genre',
			'view_item'                  => 'View Genre',
			'update_item'                => 'Update Genre',
			'add_new_item'               => 'Add New Genre',
			'new_item_name'              => 'New Genre Name',
			'not_found'                  => 'No genres found.',
			'no_terms'                   => 'No genres',
			'items_list_navigation'      => 'Genres list navigation',
			'items_list'                 => 'Genres list',

			// Hierarchical only.
			'select_name'                => 'Select Genre',
			'parent_item'                => 'Parent Genre',
			'parent_item_colon'          => 'Parent Genre:'
		]
	] );
}

https://ithelp.ithome.com.tw/upload/images/20200926/201045313bTURsj0GU.jpg

再增加完這段後,你可以看見在submenu之中,你會多了一個新的取代tag的選項,假如你有把我文章中的程式碼試著加進去。

加入metaData

好了,接下來就是我們所謂的更多的資訊要放進我們的post,因為我們post原始的資訊欄位有限,metadata是個對於要加上好幾十種資訊的解決方法,而他會被儲存在postmeta這個表之中,有興趣開mysql看看meta是怎麼被儲存的,我們這邊使用到的register_post_meta

add_action( 'init', 'goranger_books_register_meta' );

function goranger_books_register_meta() {

	register_post_meta( 'book', 'book_author', [
		'single'            => true,
		'show_in_rest'      => true,
		'sanitize_callback' => function( $value ) {
			return wp_strip_all_tags( $value );
		}
	] );
}

而我們在操作metadata的時候更容易些,只需要post id,就可以用add_post_meta或是get_post_meta來做到,大部分的都會是陣列回傳,所以可以在操作前先進行型態處理,而我們這邊使用註冊完後,就得加入所謂的meta_box,來做使用,將註冊的型態與之後增加的表格做連結。

建立客製化的metaboxes

說到metabox其實有分兩中,一種是在跟在編輯器下面的(如果你是5版以下,或是theme已經把guntenburg編輯器關閉),另外一種是在一旁的,而我們是做在下面的,主要是由$context來做處理,那我們緊接著就來增加我們的metaboxes,並且加入我們的表格來與meta_data連接。

add_action( 'add_meta_boxes_book', 'goranger_book_register_meta_boxes' );

function goranger_book_register_meta_boxes() {

	add_meta_box(
		'goranger-book-details',
		'Book Details',
		'goranger_book_details_meta_box',
		'book',
		'advanced',
		'high'
	);
}

function goranger_book_details_meta_box( $post ) {

	// 取得現在的作者,不過我們還沒設定值所以為空
	$author = get_post_meta( $post->ID, 'book_author', true );

	// 我們增加我們的nonce field
	wp_nonce_field( basename( __FILE__ ), 'goranger-book-details' ); ?>

	<p>
		<label>
			Book Author:
			<br />
			<input type="text" name="goranger-book-author" value="<?php echo esc_attr( $author ); ?>" />
		</label>
	</p>

<?php
}

https://ithelp.ithome.com.tw/upload/images/20200926/20104531LGkWAaUNiF.jpg

在加入這些後,我們也需要接我們的表格回傳的內容回來,我們會先驗證我們的nonce是否正確來保證安全性,以及使用者是否逾權基本的檢查,再來就是加入是否觸發了wp_autosave,這個其實是讓人很煩躁的功能,真希望他們可以只針對內容就好,目前我也還沒找出第二個不要對同一個頁面發出post觸發全部的連接的解決方式,而不只是autosave,回朔版本以及執行ajax都會觸發post,所以我們都要作防護,如果都通過就是將我們的資料做替換設定。

add_action( 'save_post_book', 'goranger_book_save_post', 10, 2 );

function goranger_book_save_post( $post_id, $post ) {

	if (
		! isset( $_POST['goranger-book-details'] ) ||
		! wp_verify_nonce( $_POST['goranger-book-details'], basename( __FILE__ ) )
	) {
		return;
	}

	if ( ! current_user_can( 'edit_post', $post_id ) ) {
		return;
	}

	if (
		wp_is_doing_ajax() ||
		wp_is_post_autosave( $post_id ) ||
		wp_is_post_revision( $post_id )
	) {
		return;
	}

	$old_author = get_post_meta( $post_id, 'book_author', true );
	$new_author = isset( $_POST['goranger-book-author'] )
	              ? wp_strip_all_tags( $_POST['goranger-book-author'] )
		      : '';

	if ( ! $new_author && $old_author ) {
		delete_post_meta( $post_id, 'book_author' );
	} elseif ( $new_value !== $old_value ) {
		update_post_meta( $post_id, 'book_author', $new_value );
	}
}

https://ithelp.ithome.com.tw/upload/images/20200926/20104531IFfgOMsF4q.jpg

這樣我們就完成了一個很簡易的加入圖書的功能了!這邊的程式碼是節錄威廉大師的範例程式碼,並且加以改來做講解,而這個基礎的運用,你也可以加工成能夠更快速的加入書本,假如你還要加入ISBN之類的,可以接上他們的API來做間接的應用,你如果覺得這個太小了,也可以去看woocommerce是怎麼實作將post做成product的,並且他在meta_box的操作是非常直得學習的,有著更複雜的表格操作,很適合新手學完基礎後去參考如何精進!

reference

post-types
resiter_post_type
get_post_type_labels
get_post_type_capabilities
add_meta_boxed
Professional WordPress Plugin Development
How to Create Custom Post Types in WordPress
https://www.smashingmagazine.com/2012/11/complete-guide-custom-post-types/


上一篇
「Wordpress 外掛開發」加入自己的靜態檔案 wp_regist_scripts/wp_enqueue_script
下一篇
「Wordpress 外掛開發」建構我們的館員權限 - 以user data來更深入探討role與capability的應用
系列文
Wordpress 外掛開發30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言