上一篇我們介紹了WordPress主題制作的基本知識,並且制作了一個簡陋的WP博客園主題。在制作的過程中發現一個問題,就是WP后台沒有設置Meta的keywords的地方。於是想自己增加一個設置界面。如果用phpmyadmin查看過WP的數據庫結構,就很容易明白后台設置的原理:只不過是在WP_Options表中增加一條記錄,當然我們是用WP提供的標准函數來操作數據庫。
機制
我們登錄后台時,WP如何將控制權交給我們呢?是去調用我們主題的哪個文件呢?約定:functions.php文件。此處有一陷阱:一旦我們的主題包含了functions.php,就在WP的請求響應處理管線中插入了一環,無論我們訪問的是哪一個頁面,都要經過functions.php,這顯然不是我們想要的。我們需要的是:登錄后台時才去執行functions.php里面的邏輯,用戶訪問前台網站不需要執行。這個“陷阱”可以通過Zend Studio的調試功能看到:
在functions.php中設置斷點,然后訪問前台index.php,卻得到了上圖的調用堆棧。這樣的結果雖然有些意外,但讓我們對WP的機制有了些了解,看來調試還是很重要的:) 下面會給出編碼,來避免這個性能陷阱。
后台實現
了解了上面的陷阱以后,為了方便增加了一個theme-options.php文件來實現主題選項的邏輯,這樣functions.php的代碼就簡化了:
<?php if(is_admin()) require ('theme-options.php'); ?>
我們用is_admin()函數判斷用戶訪問的是前台還是后台。
theme-options.php代碼:
<?php function getOptions() { $options = get_option('cnblogs_options'); if (!is_array($options)) { $options['meta_keywords'] = ''; update_option('cnblogs_options', $options); } return $options; } /* 初始化 */ function init() { if(isset($_POST['input_save'])) { $options = getOptions(); $options['meta_keywords'] = stripslashes($_POST['meta_keywords']); update_option('cnblogs_options', $options); } else { getOptions(); } add_theme_page("主題選項", "主題選項", 'edit_themes', basename(__FILE__), 'display'); } /* 界面 */ function display() { $options = getOptions(); ?> <form action="#" method="post" enctype="multipart/form-data" name="op_form" id="op_form"> <div class="wrap"> <h2>當前主題選項</h2> <table> <tbody> <tr> <td>meta keywords</td> <td> <label> <textarea name="meta_keywords" cols="50" rows="10" id="meta_keywords" style="width:98%;font-size:12px;" ><?php echo($options['meta_keywords']); ?></textarea> </label> </td> </tr> </tbody> </table> <p class="submit"> <input type="submit" name="input_save" value="保存" /> </p> </div> </form> <?php } add_action('admin_menu', 'init'); ?>
get_option函數獲取選項值;update_option更新選項。我們這里定義了一個“cnblogs_options”的選項,為了和WP自己的選項分開來,這里定義成數組形式。php的數組可以當成C#的字典集合使用,這里定義了字典項"meta_keywords“。
add_theme_page 函數在后台頁面->外觀菜單下插入一個"主題選項"的菜單。
當點擊此菜單時調用display函數,顯示設置界面。
add_action('admin_menu','init')相當於添加事件和事件處理程序。WP的常用actions參考這里。
init函數判斷如果點擊了"input_save"保存按鈕,提交form表單,就保存更改。
前台調用:
header.php中添加以下代碼
<meta name="keywords" content="<?php $cnblogsopt=get_option('cnblogs_options'); echo $cnblogsopt['meta_keywords']; ?>"/>