作為主題的制作者, 除了實現功能, 展示界面, 還有責任使主題靈活多變, 以滿足更多人不同的需求.
可能一些朋友曾為選用雙欄主題 (單側邊欄) 還是三欄主題 (雙側邊欄) 而煩惱過. 下面我們以 classic 主題為例, 談談如何在主題中方便地切換單側邊欄和雙側邊欄. 最后我會提供修改后的主題.
添加管理選項
后臺處理
首先, 我們要修改 function.php, 主要的處理工作都在這個文件里面, 如果主題沒有這個文件, 就創建一個吧. (沒有 function.php 說明主題不支持 widget, 可不是一個好習慣哦, 還是趕緊新建一個吧)
我的處理包括 3 大塊: 獲取選項, 初始化, 標簽頁操作界面. 這里只創建一個公告欄, 包括兩個選項 (是否顯示公告欄和公告欄內容). 如果要添加更多選項, 也只需要代碼中 3 個 todo 的位置上追加一些代碼而已. 當然, 你還需要改一下選項名稱, 將 classic 和 classic 全部之換掉.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
<?php /** * 選項組類型 */ class classicoptions { /* -- 獲取選項組 -- */ function getoptions() { // 在數據庫中獲取選項組 $options = get_option( 'classic_options' ); // 如果數據庫中不存在該選項組, 設定這些選項的默認值, 并將它們插入數據庫 if (! is_array ( $options )) { $options [ 'notice' ] = false; $options [ 'notice_content' ] = '' ; // todo: 在這里追加其他選項 update_option( 'classic_options' , $options ); } // 返回選項組 return $options ; } /* -- 初始化 -- */ function init() { // 如果是 post 提交數據, 對數據進行限制, 并更新到數據庫 if (isset( $_post [ 'classic_save' ])) { // 獲取選項組, 因為有可能只修改部分選項, 所以先整個拿下來再進行更改 $options = classicoptions::getoptions(); // 數據限制 if ( $_post [ 'notice' ]) { $options [ 'notice' ] = (bool)true; } else { $options [ 'notice' ] = (bool)false; } $options [ 'notice_content' ] = stripslashes ( $_post [ 'notice_content' ]); // todo: 在這追加其他選項的限制處理 // 更新數據 update_option( 'classic_options' , $options ); // 否則, 重新獲取選項組, 也就是對數據進行初始化 } else { classicoptions::getoptions(); } // 在后臺 design 頁面追加一個標簽頁, 叫 current theme options add_theme_page( "current theme options" , "current theme options" , 'edit_themes' , basename ( __file__ ), array ( 'classicoptions' , 'display' )); } /* -- 標簽頁 -- */ function display() { $options = classicoptions::getoptions(); ?> <form action= "#" method= "post" enctype= "multipart/form-data" name= "classic_form" id= "classic_form" > <div class = "wrap" > <h2><?php _e( 'current theme options' , 'classic' ); ?></h2> <!-- 公告欄 --> <table class = "form-table" > <tbody> <tr valign= "top" > <th scope= "row" > <?php _e( 'notice' , 'classic' ); ?> <br/> <small style= "font-weight:normal;" ><?php _e( 'html enabled' , 'classic' ) ?></small> </th> <td> <!-- 是否顯示公告欄 --> <label> <input name= "notice" type= "checkbox" value= "checkbox" <?php if ( $options [ 'notice' ]) echo "checked='checked'" ; ?> /> <?php _e( 'show notice.' , 'classic' ); ?> </label> <br/> <!-- 公告欄內容 --> <label> <textarea name= "notice_content" cols= "50" rows= "10" id= "notice_content" style= "width:98%;font-size:12px;" class = "code" ><?php echo ( $options [ 'notice_content' ]); ?></textarea> </label> </td> </tr> </tbody> </table> <!-- todo: 在這里追加其他選項內容 --> <!-- 提交按鈕 --> <p class = "submit" > <input type= "submit" name= "classic_save" value= "<?php _e('update options »', 'classic'); ?>" /> </p> </div> </form> <?php } } /** * 登記初始化方法 */ add_action( 'admin_menu' , array ( 'classicoptions' , 'init' )); ?> |
前臺處理
要公告欄在首頁上顯示, 需要修改一下 index.php, 這個比較簡單, 只是通過一些判斷語句決定東西要不要顯示出來而已. 當然, 你可以進行其他操作, 關鍵是獲取到選項的值, 并對它們進行處理.
其實可以分為兩步:
獲取選項 (對每個 php 文件, 獲取一次就行了, 可以在文件頂部執行)
對選項進行處理 (這里判斷成立的話就將公告內容顯示出來)
1
2
3
4
5
6
7
8
9
|
<!-- 獲取選項 --> <?php $options = get_option( 'classic_options' ); ?> <!-- 如果用戶選擇顯示公告欄, 并且公告欄有內容, 則顯示出來 --> <?php if ( $options [ 'notice' ] && $options [ 'notice_content' ]) : ?> <div id= "notice" > <div class = "content" ><?php echo ( $options [ 'notice_content' ]); ?></div> </div> <?php endif ; ?> |
可以使用管理項來控制側邊欄的數量, 在主題文件中獲取側邊欄的數量, 對不同的數量作出不同的處理, 以達到在不同數量側邊欄之間切換的目的.
1
2
3
4
5
6
7
8
9
10
11
|
// 側邊欄數量, 默認為單側邊欄 $options [ 'sidebar' ] = 1; // 獲得最新提交的值 $options [ 'sidebar' ] = $_post [ 'sidebar' ]; <select name= "sidebar" size= "1" > <!-- 單側邊欄 --> <option value= "1" <?php if ( $options [ 'sidebar' ] != 2) echo ' selected ' ; ?>><?php _e( 'single' , 'classic' ); ?></option> <!-- 雙側邊欄 --> <option value= "2" <?php if ( $options [ 'sidebar' ] == 2) echo ' selected ' ; ?>><?php _e( 'double' , 'classic' ); ?></option> </select> <?php _e( 'sidebar(s)' , 'classic' ); ?>. |
添加 widget 支持
因為要在單側邊欄和雙側邊欄中切換, 所以我們需要對不同的兩種模式定義兩個 widget 初始化的分支.
這里比較特殊, 為了在代碼中正確獲取 widget 信息, 就算是單側邊欄也需要起一個別名. 就像代碼中的 sidebar_single. 當側邊欄個數為 1 時, 登記 sidebar_single. 當側邊欄個數為 2 時, 登記 sidebar_top 和 sidebar_bottom.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
// widgets $options = get_option( 'classic_options' ); // 單側邊欄 if (function_exists( 'register_sidebar' ) && $options [ 'sidebar' ] == 1) { register_sidebar( array ( 'name' => 'sidebar_single' , 'before_widget' => '<li id="%1$s" class="widget %2$s">' , 'after_widget' => '</li>' , 'before_title' => '<h3>' , 'after_title' => '</h3>' )); // 雙側邊欄 } else if (function_exists( 'register_sidebar' ) && $options [ 'sidebar' ] == 2) { register_sidebar( array ( 'name' => 'sidebar_bottom' , 'before_widget' => '<li id="%1$s" class="widget %2$s">' , 'after_widget' => '</li>' , 'before_title' => '<h3>' , 'after_title' => '</h3>' )); register_sidebar( array ( 'name' => 'sidebar_top' , 'before_widget' => '<li id="%1$s" class="widget %2$s">' , 'after_widget' => '</li>' , 'before_title' => '<h3>' , 'after_title' => '</h3>' )); } |
修改側邊欄結構
首先要明確, 我們現在需要雙側邊欄結構. 怎樣將雙側邊欄變為單側邊欄呢? 只要將前一個側邊欄的結束標簽和后一個側邊欄的開始標簽刪除, 兩個側邊欄就合并為一個側邊欄了. 單純的文字很難將我的想法和實現表達出來, 你可以接著看下面的代碼和示例圖片.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<ul class = "sidebar_1" > <?php if ( !function_exists( 'dynamic_sidebar' ) || !dynamic_sidebar( 'sidebar_single' ) ) : // single ?> <?php if ( !function_exists( 'dynamic_sidebar' ) || !dynamic_sidebar( 'sidebar_top' ) ) : // top ?> <!-- todo: 頂部側邊欄內容 --> <?php endif ; // top ?> <?php if ( $options [ 'sidebar' ] >= 2) : ?> </ul> <ul class = "sidebar_2" > <?php endif ; ?> <?php if ( !function_exists( 'dynamic_sidebar' ) || !dynamic_sidebar( 'sidebar_bottom' ) ) : // bottom ?> <!-- todo: 底部側邊欄內容 --> <?php endif ; // bottom ?> <?php endif ; // single ?> </ul> |
ok, 這就是側邊欄代碼結構了. 它可以完美得實現單雙側邊欄間的切換. 但它是怎么工作的呢? 我將在后面用圖片列出它的 6 種可能出現的狀態.
因為主題已經支持 widget 了, 所以代碼中 function_exists('dynamic_sidebar') === true, 則 !function_exists('dynamic_sidebar') === false.
記得添加 widget 支持時寫的代碼嗎? 側邊欄為 1 時 sidebar_single 有效, 側邊欄為 2 時, sidebar_top 和 sidebar_bottom 有效. 這是貫穿整個思路的關鍵.
備注:
- 紅色: 表示選中代碼的值是 false, 不通過
- 綠色: 表示選中代碼的值是 true, 通過
- 藍色: 表示選中部分將被選用的 widgets 所取代
- 灰色: 表示選中部分代碼將會失效
狀態一: 單側邊欄, 沒使用 widget
狀態二:雙側邊欄, 沒使用 widget
狀態三: 單側邊欄, 使用 widget
狀態四: 雙側邊欄, 頂部側邊欄使用 widget
狀態五: 雙側邊欄, 底部側邊欄使用 widget
狀態六: 雙側邊欄, 頂部和底部側邊欄都使用 widget