WordPress外掛提交流程

  1. 前往 https://wordpress.org/plugins/developers/
  2. 點選 Submit your plugin for review

3.上傳你開發好的外掛zip檔
※外掛除了可運行的程式還會要求在根目錄要有readme.txt※
如果不清楚格式可到 https://generatewp.com/plugin-readme/ 自動生成
若要在描述的部分新增可點選的網址請按照此格式,不然會被當成純文字處理:
[要顯示的名稱](網址)
example: [Google](https://www.google.com/)

提交之後就等待wordpress他們的人員幫你審查,審查完後他們會寄信跟你說有那些問題,修改完後你再以github或是google雲端的方式告知他們程式碼已修正就好,反正就是能讓他們載的到你的程式就OK,接下來就是修正->審核->修正->審核的過程

以下講講我自己外掛被審出的需要修改的地方,有些真的是沒碰過不會發現有問題,但我覺的wordpress方也蠻用心地都有明確指出哪邊有哪個類型的錯誤,也有說明錯誤在哪支程式哪一行

插件名稱問題

大意是說你一開始取的外掛名稱不符合規範,他們會給你一個他們建議的名稱,照著改就好,記得要改readme.txt跟你外掛主代碼的外掛描述(如下圖)

插件包含多餘資料夾

開發的時候如果我們有引用第三方套件,常常都會將整包檔案放進程式裡,但這接第三方套件裡常常都包含如demo,example,doc等外掛並不需要使用到的部分,wordpress會要求您將這些非必要的部分移除外掛

插件呼叫遠程文件

開發外掛的時候為求方便有時候會直接call CDN , wordpress會要求可以下載到本地端做呼叫的檔案盡量下載到本地端,真的沒辦法本地呼叫的(如:googlemap相關的套件),可以允許遠端呼叫

插件必須驗證數據

我猜是因為安全性的考量,wordpress會要求您的後端程式碼在接收前端的數據時要做過驗證,這部分一開始我搞不太懂,想說我有對數據做檢查他怎麼還是回信說有問題
https://developer.wordpress.org/plugins/security/securing-input/
wordpress有提供蠻多現成的函式來讓開發者做數據驗證及清理,如果你接收的資料想要自定義(簡單來講不是像email這種有標準格式的),使用GET或POST接收前端數據的時候建議就使用sanitize_text_field這個函式,他主要是可以過濾使用者惡意插入的html tag

有興趣的可以自行搜尋: XSS攻擊

插件中含有通用的函式名稱

簡單來說就是你外掛中的function取的名字太通用了不夠有區別性,因wordpress上會同時掛載多個外掛,所以官方要確保你function的名字獨特才不會跟別的外掛相互影響

全部修正完之後官方就會給你一個svn網址讓你更新跟管理你的外掛,要進行第一次上傳之後你的外掛才會變為公開,這點請注意,至於如何使用svn就留待下一篇詳解吧!

wordpress本機基礎測試環境架設

開發外掛的過程一定會遇到很多不可預期的狀況,如果是接案的狀況再更改設定或外掛不小心玩壞了要修復也是件挺令人擔心的事情,所以這篇主要教大家如何在本地端架出wordpress的環境,出了問題也能夠比較好理解問題在哪哦!

首先先下載XAMPP

https://www.apachefriends.org/zh_tw/download.html

下載完之後進行安裝,預設安裝完的路徑會在C:\xampp

xampp下有個資料夾叫做htdocs是網站的根目錄

在htdocs下放一包wordprss(記得解壓縮)

https://drive.google.com/file/d/1XxxI75FTbDfuiOiX-cYWnnMu0emns3TY/view?usp=sharing

放好之後打開xampp程式

打開Apache跟MySQL

按下MySQL右邊的Admin
先建一個要給wordpress用的資料庫

打開網頁,輸入 http://localhost/wordpress/ ,會出現這個畫面

點擊開始安裝

資料庫名稱填上剛剛建的資料庫名稱,然後設定使用者名稱跟密碼,xampp的mysql預設的帳號密碼是root跟空白,基本上主機位置跟資料表前置詞可以用預設就好,輸入無誤後按傳送

點選執行安裝程式

輸入完畢後點選安裝Wordpress

完成啦!!!可以開始盡情的玩囉~

如果真的遇到玩壞了不知道該怎麼修復的情況,只要把wordpress刪掉重新安裝一次就可以了

wordpress外掛開發 讓外掛自動新建所需資料表

寫一個外掛的重點其中之一,讓外掛能自動建立本身所需的資料表是很重要的,如果是要在複數個網站安裝自己寫的外掛這個部分就更加重要
下面就讓我們來看看要如何做到讓外掛自動建立資料表

主要步驟如下:

首先在class的function __construct內加入

if(!defined('ABSPATH'))exit;
$this->CreateTable();
//自動新增所需資料表

CreateTable就是待會我們要建立資料表的function,將上述語法放在 function __construct 內是為了要讓其自動執行,達到自動建立的效果

接下來讓我們看CreateTable()內的內容

function CreateTable(){
	global $wpdb;

	require_once(ABSPATH.'wp-admin/includes/upgrade.php');
    //要更新資料表就得require這支wp程式
	$charset_collate=$wpdb->get_charset_collate();//取得資料表的預設編碼
	//如果有中文就設成utf8避免亂碼

	/*begin of 有多個table就要寫多個區塊*/
	$table_name=$wpdb->prefix.'_user_register';
	if($wpdb->get_var("SHOW TABLES LIKE '$table_name'")!=$table_name){
		$sql="CREATE TABLE `{$wpdb->prefix}_user_register` (
		  `ID` int(11) NOT NULL AUTO_INCREMENT,
		  `名字` varchar(10) NOT NULL,
		  `密碼` varchar(100) NOT NULL,
		  `信箱` varchar(50) NOT NULL,
		  `手機` varchar(10) NOT NULL PRIMARY KEY
		 )$charset_collate;";
		 //如果要限制一人只能註冊一個帳號,建議把手機設為primary key並且在註冊流程加上手機認證
		 dbDelta($sql);
		/*end of 有多個table就要寫多個區塊*/
	}
}

邏輯上簡單來說是先用 SHOW TABLES LIKE ‘$table_name’ 來確認是否已存在同名稱的資料表,若不存在就使用dbDelta這個函式來建立該資料表

以簡易框架教學那篇的架構來說的話,如果資料表少我就會放在main.php內

wordpress外掛開發 簡易設定頁面

建議如果還沒看過這篇的可以先去看一下還有載一下範例程式碼

本篇主要是介紹用結合外掛的方式撰寫配合外掛的設定頁面,變數的儲存機制則使用wp本身提供的方式,不需要再額外建立資料表

首先先附上程式碼:
只要把框架那篇提供的同名程式碼換掉即可

https://drive.google.com/file/d/1hKarpGikxe3EdYH8pEFqN9Xwh5JChqTa/view?usp=sharing

接下來進入正題:

<?php
add_action('admin_menu', 'add_setting_menu');

function add_setting_menu() {
	add_submenu_page('my-plugin_main', __('設定'), __('設定'), __('manage_options'), 'pm-extend_setting','add_settings_page');
	add_action( 'admin_init', 'register_plugin_settings' );
}
//先加上設定的頁面

function register_plugin_settings() {
	register_setting( 'myplugin-group', 'plugin_date' );
	register_setting( 'myplugin-group', 'plugin_flag' );
}
//記得表格中有新的設定時要在這邊註冊變數名稱,否則變數不會記錄進options.php

function add_settings_page() {
?>
<!--以下是頁面的範例內容,可依據設定頁面需求自己做更改 -->
<div class="wrap">
	<h2>範例系統設定</h2>
	<br><br>
	<!-- option.php是固定的,wordpress會自動記錄所有設定值 -->
	<form method="post" action="options.php">
		<?php settings_fields('myplugin-group'); ?>
		<!-- 要先宣告這句下面才有辦法使用上面註冊的變數 -->
		<input type="checkbox" name="plugin_flag" value="1"
			   <?php if (get_option('plugin_flag')==1) echo "checked" ; ?> />
		測試勾選框<br/>
		<br>
		測試input框  :
		<input type="text" id="plugin_date" name="plugin_date" value="<?php echo get_option('plugin_date'); ?>"/>
		<p class="submit">
			<input type="submit" class="button-primary" value="儲存" />
			<!-- 這邊就submit表單所有欄位的值就會做紀錄了,不需要另外自己寫js處理,如果要debug就去wp後台首頁,去掉index.php改成options.php-->
			<!--  網址會變成類似 worpress根目錄網址/wp-admin/options.php 可在這個頁面查詢變數是否有被記錄-->
		</p>
	</form>
</div>
<?php
}
?>

設定頁面寫好之後,如果之後要在本外掛任意地方的程式碼or甚至別支外掛的程式碼(比較不建議),使用設定值都輕鬆容易,只要在php代碼的地方寫上get_option(‘註冊的變數名稱’)就抓的到值囉!

wordpress外掛開發 簡易框架教學

當初自學wordpress外掛的時候遇到不少瓶頸,因為不熟悉wordpress的框架與運作模式,所以在外掛的開發上遇到不少問題,所以才有了撰寫這篇教學的想法,希望可以幫助到想撰寫wordpress外掛卻又不知從何下手的新手們 ,本篇教學是依據我本身開發經驗撰寫而成,觀念上可能有些許錯誤,還請各位多多包涵!

相信大家看教學最在意的就是範例程式碼,畢竟辛辛苦苦地跟著教學做了半天,如果最後弄出來無法執行,應該會很挫折吧!

下面的範例程式碼是經過實測過的,建議小夥伴們先下載下來配合著教學服用

範例程式碼:

https://drive.google.com/file/d/14Awz8BMIZdwPPRxUe1kUflViS6VSN2tL/view?usp=sharing

首先,建立一個外掛的根目錄下一定會有一個php檔,是用來載入這個外掛其他程式碼的切入點,以範例程式碼來說我將它取名為myplugin.php,讓我們先來看這支程式的內容

/*
 * Plugin Name: 外掛名稱
 * Description:外掛名稱 by 開發者名稱
 * Author: 開發者名稱
 * Plugin URI: 網址 不重要
 * Version: 版本(EX:1.0)
 */

//此區域是描述外掛的區域(必填)

//假設我的外掛名稱叫myplugin,我將其簡稱為MP(可依個人喜好)
if(!defined('MP_DIR')){
	define('MP_DIR', dirname(__FILE__));
}
//把MP_DIR定義為本外掛的根目錄,後面要呼叫相對路徑時會方便很多
define('MP_URL', plugin_dir_url(__FILE__));

//這邊要include主要是'後端處理'的php,我習慣將這些放在include資料夾內
function LoadMyplugin_Class(){
	include MP_DIR.'/includes/class_myplugin-main.php';
	include MP_DIR.'/includes/class_myplugin-cofunction.php';
	include MP_DIR.'/includes/class_myplugin-setting.php';
	$GLOBALS['MP']=MP();
}
//我自己會建議至少有這三支程式
//cofunction用來寫共用函式,setting則用來撰寫此外掛的設定頁面,會在之後的教學詳細說明
function MP(){
	return My_Plugin::instance();
}
add_action('plugins_loaded', 'LoadMyplugin_Class');
//綁定action讓wordpress載入本外掛

到這邊外掛的切入點主要就已經完成了,接下來讓我們看include資料夾內主要的class_myplugin-main.php這支程式

if(!class_exists('My_Plugin')):

class My_Plugin{
	public static $_instance=NULL;

	//我的理解是建構子
	function __construct(){
		global $wpdb;//讓外掛可以呼叫wp資料庫函式

		//這邊是判斷當前頁面是不是wp的後台,所以後台所需的東西要在這裡引入
		if(is_admin()){
			add_action('admin_menu', array($this, 'AdminMenu'), 1);
			//在後台頁面的左側加上自己設定的頁面的函式,如果外掛不需要做後台頁面就不用加
		}
		else{
			add_shortcode('mp-extend', array($this, 'RenderShortCode'));
			add_action('wp_head', array($this, 'AddScripts'));
			add_action('wp_head', array($this, 'AddStyles'));
			//這邊我習慣預設這三個
			//RenderShortCode是用來產生短代碼,在用elementor建構頁面時可以把外掛的頁面嵌入在適當的地方
			//AddScripts是用來引入全域會用到的js
			//AddStyles用來引入全域會用到的css
		}

		add_action('wp_ajax_nopriv_MPexecAjax', array($this, 'MPexecAjax'));
		add_action('wp_ajax_MPexecAjax', array($this, 'MPexecAjax'));
		//這邊先簡單說明一下,這兩行是前端用到ajax時url設為 admin_url('admin-ajax.php') 這個位置然後傳送到後端的data內action設為A
		//後端的add_action('wp_ajax_nopriv_A', array($this, 'Afunction'));只要在Afunction內做好對ajax送來的資料的處理就好
		//有興趣的之後會再開文章詳細說明
		//wp_ajax_MPexecAjax跟wp_ajax_nopriv_MPexecAjax的差別是前者是操作者有登入wordpress的情況才有權限
		//後者是沒有登入wordpress的操作者才有權限
		//所以如果是自製的外掛沒有要結合wp的會員機制的話,建議兩個都加比較保險
	}

	function AddScripts(){
		wp_register_script('my-plugin_script', MP_URL.'/js/my-plugin.js');
		wp_enqueue_script('my-plugin_script');

		wp_localize_script(	
			'my-plugin_script', 
			'MP_vars',
			array(
				'imgroot'		=>MP_URL.'/images/', 
				'templateroot'		=>MP_URL.'/templates/', 
				'ajaxurl'		=>admin_url('admin-ajax.php'),
			));
		//這是wordpress傳php值供前端js使用的方式
		//js的呼叫方式是 EX:MP_vars.ajaxurl,MP_vars.imgroot
		//imgroot跟templateroot建議可以先預設好,js在呼叫圖片或是跳轉頁面的時候比較方便
	}

	function AddStyles(){
		wp_register_style('my-plugin_style', MP_URL.'/css/my-plugin.css');
		wp_enqueue_style('my-plugin_style');
	}
    
    //設定後端管理頁面的時候用
	function AdminMenu(){	
		add_menu_page('我的外掛', __('我的外掛'), __('manage_options'), 'my-plugin_main', create_function('', 'require_once \''.MP_DIR.'/templates/my-plugin_admin.php\';'), 'dashicons-nametag', 56);
		// Add to admin_menu
		//是選單旁邊的符號,可以自己更換
		add_submenu_page('my-plugin_main', __('我的外掛功能一'), __('我的外掛功能一'), __('manage_options'), 'my-plugin_func1', create_function('', 'require_once \''.MP_DIR.'/templates/my-plugin_admin_func1.php\';'));
		//若要在主選單下面加上子選單可以使用此語法
		//這邊不是重點先簡易帶過,有興趣可以google add_menu_page跟add_submenu_page會有更詳細的介紹
	}

	public function RenderShortCode($args){
		if(!is_array($args))return;
		switch($args['type']){
			case 'example_page':
				$this->ExamplePage();
				break;
		}
	}
	//[mp-extend type='example_page'] 可在elementor以shortcode的方式直接插入自製頁面或功能
	//這是我目前覺得最好結合elementor的開發方式

	function ExamplePage(){
		include MP_DIR.'/templates/example_page.php';
	}
        //引入該頁面
	//這邊有需求還可引入只有該功能或頁面需要的特定css跟js

	//讓myplugin.php呼叫用
	public static function instance(){
		if(is_null(self::$_instance))self::$_instance=new self();
		return self::$_instance;
	}
}

endif;

這邊其實我多加了很多一般外掛教學沒有的部分,當初開發的時候照著別的外掛教學做完,雖然外掛是可以執行的,但還有許多常用的功能不知道要如何結合,所以這邊就把一些外掛基本上都會使用到的功能結合進來,建議大家可以稍微做修改拿來當作自己開發外掛的基礎模板

細心的小夥伴應該會發現範例程式碼有幾支引用的程式我都先留空,那是因為要在這篇內全部說明完可能會過於複雜,有興趣的人可以關注一下,之後會不定時更新剩餘部分的範例,當然如果對php及前端語言原本就有些底子的人就可以開始用這個框架玩玩看啦!