Codex

Interested in functions, hooks, classes, or methods? Check out the new WordPress Code Reference!

zh-tw:主題開發

本文將介紹如何開發、設計 WordPress 主題。如果您先了解更多關於安裝與使用主題的部分,,請參閱使用佈景主題。本文的內容與使用佈景主題不同,因為這裡所討論的是透過編寫程式碼來建立專屬您的主題這樣的技術內容,而非如何去開啟主題或者是告訴您哪裡可以獲得新主題。

為什麼要開發 WordPress 主題

WordPress 布景主題是由一系列的檔案互相配合,構成一個富有美感以及實用性的 WordPress 網站。每個主題不盡相同,這也提供了站長能立即變更網站樣式的多樣化選擇。

您可能也想試著製作一個布景主題給自己用、給客戶的案子用,或是提交到WordPress佈景主題目錄。那麼為什麼您要自己動手做布景主題呢?


WordPress 主題也有很多優點。

  • WordPress 主題將 CSS 樣式表與範本檔與系統檔獨立出來,因此在升級部落格時就不會搞壞了您的主題。
  • 您可以自由地定制主題風格以及功能。
  • 您可以迅速地改變 WordPress 網站的版面配置以及樣式設計。
  • 您甚至不必深入理解 HTML、CSS 以及 PHP 等等就可以製作一個美麗的主題。

為什麼要自己製作主題呢?這個問題比較重要。

  • 這是一個學習 CSS、HTML 以及 PHP 的好機會。
  • 如此一來可以累積您的 CSS、HTML 以及 PHP 經驗。
  • 極具創意。
  • 有趣(大多數情況下)。
  • 如果您 公開主題給大眾使用,我相信您會非常愉快,因為您 為 WordPress 社群做出了貢獻(好吧,可以去炫耀一下了。)

主題開發標準

WordPress 主題應該按照如下標準開發:

剖析主題

WordPress 主題放在 wp-content/themes/ 。主題的子資料夾中包含了主題的樣式表檔案、範本檔,以及選擇性功能檔案(functions.php) 、JavaScript 檔案以及圖片。例如:一個名叫「taiwan」的主題會放在 wp-content/themes/taiwan/ 資料夾中。請避免使用數字來為主題命名,因為這可能會導致該主題不在可用主題列表中顯示。

新安裝的 WordPress 包含了預設的主題。請仔細看一下預設主題中檔案,這樣您才會更加瞭解如何建立您自己的主題。

關於視覺指南的部分,請參考infographic on WordPress Theme Anatomy(英文)

除了圖片和 JavaScript 之外,WordPress 主題通常會由三種類型的檔案構成。

  1. style.css ,也就是樣式表,控制著整個網站網頁的呈現方式(視覺設計以及版面配置)。
  2. WordPress 範本檔(英文)控制著網站要如何將 WordPress 資料庫中的資訊顯示在您的網頁中。
  3. 選擇性功能檔案(functions.php) 為 WordPress 主題檔案中的一部分。

接著,讓我們一個個瞭解這些檔案。

子主題

子主題可能是最簡單的主題,只包含了一個 style.css 檔案,加上任一圖片。這是可行的,因為它是另一個上級主題的「子」主題。

關於子主題的詳細指南,請參考子主題(英文)

主題CSS

CSS 樣式表中除了提供主題的樣式設計,style.css 中也會以註釋的方式寫出該主題的詳細資訊。 樣式表必須以註釋的方式提供該主題的詳細資訊。 兩個主題的檔案標頭不可以有相同的資訊,因為這會導致主題選擇出問題。 如果您是透過複製一個現有的主題來製作的,您必須先更改這些資訊。

下面是一個範例主題「Twenty Thirteen」的樣式表中開始的幾行,叫做樣式表標頭:

/*
Theme Name: Twenty Thirteen
Theme URI: http://wordpress.org/themes/twentythirteen
Author: the WordPress team
Author URI: http://wordpress.org/
Description: The 2013 theme for WordPress takes us back to the blog, featuring a full range of post formats, each displayed beautifully in their own unique way. Design details abound, starting with a vibrant color scheme and matching header images, beautiful typography and icons, and a flexible layout that looks great on any device, big or small.
Version: 1.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Tags: black, brown, orange, tan, white, yellow, light, one-column, two-columns, right-sidebar, flexible-width, custom-header, custom-menu, editor-style, featured-images, microformats, post-formats, rtl-language-support, sticky-post, translation-ready
Text Domain: twentythirteen

This theme, like WordPress, is licensed under the GPL.
Use it to make something cool, have fun, and share what you've learned with others.
*/

註:作者名稱建議與 wordpress.org 的使用者名稱相同,但您也可以使用真實姓名。這是由主題作者自己選擇的。

請注意以可用標籤列表中的項目來描述該主題。這可以讓使用者通過標籤篩選器來找到您的主題。這個是完整的可用標籤列表

style.css 的標頭必須要註釋掉,這樣才能使 WordPress 知道這是一個主題,並在管理面板中的 設計>主題 中將其與其它已安裝的主題一起顯示為可用的選項。

樣式表指南

  • 揮灑創意地撰寫 CSS 的時候請不要忘了CSS 程式碼標準(英文)
  • 盡可能使用有效的 CSS 。作為例外,也可以使用一些遵守 CSS3 標準的首碼。
  • 儘量不要用 CSS hack。但是通常一些特定的瀏覽器例外,這發生在 IE 身上,可以的話最好將使用 CSS hack 的部分區分出來甚至獨立成單一檔案。
  • 所有可能的 HTML 元素都應該由主題來指定樣式,文章、頁面的內容還有評論的內容都一樣。
    • Tables, captions, images, lists, block quotes, et cetera。
  • 在這裡強烈地建議新增一些列印模式*的樣式。
    • 您可以包含列印用的樣式表 media="print" 或者將您的主樣式表新增到列印媒體區塊。

(譯者註:原文Print-friendly 就是指在列印的時候能夠只列印出必要資訊,而忽略掉其它不必要的元素,例如我們列印您現在看的這個文件,右邊的Views ,Toolbox 這類的以及網頁頂部導航列的部分都不印出,這就叫Print-friendly 。)

函數檔

一個主題可以使用 functions 檔,位於主題的子目錄,檔名為 functions.php。該檔案就如同擴充套件一般,如果其位於您現在使用的主題中,主題初始化時就會自動將其加載(無論管理頁面或外部頁面)。這個檔案有這些作用:


預設的 WordPress 主題包含一個 functions.php 檔案,其定義了眾多這樣的功能,所以您可能會想參考它。既然基本上我們可以把 functions.php 看作一個擴充套件,因此函數參考可以讓您更瞭解該函數以及如何使用。


Note for deciding when to add functions to functions.php or to a specific plugin: You may find that you need the same function to be available to more than one parent theme. If that is the case, the function should be created in a plugin instead of a functions.php for the specific theme. This can include template tags and other specific functions. Functions contained in plugins will be seen by all themes.

範本檔

範本 是一些PHP檔,他可以輸出HTML代碼呈獻給流覽器,決定著主題的外觀.下麵讓我們來看一下主題的範本.

WordPress允許為你的網站定義不同的範本.他雖然不是必需的,但是這些不同的範本為你的網站添上一筆. 範本是根據Template Hierarchy的,由一個具體的主題決定.

作為一個主題開發者,你可以自由決定如何定制你的範本.比如說,極端情況下, 你甚至可以僅僅使用一個檔index.php作為範本檔,所有 頁面都會使用這個範本.更多的情況是,使用不同的範本檔產生不同的結果,以達到最大定制.

範本檔列表

這裏是被 WordPress 確認的佈景主題檔列表。當然,你的佈景主題可以包含任何樣式表、圖像或者檔案。記住,下面列出的檔案對 WordPress 具有特殊的意義 -- 點擊Template Hierarchy 查看具體情況.

style.css
主樣式表,這個檔 必須 位於你的主題裏面,而且必須在頭部注釋處寫清楚你的主題的資訊。
rtl.css
rtl stylesheet. 如果網站的閱讀方向是自右向左的,他會自動被包含進來. 你可以使用一個插件來生成這個檔the RTLer.
index.php
主範本。如果你的主題使用自己的範本, index.php 是必須要有的。
comments.php
評論(讀者回應)範本。
front-page.php
The front page template, it is only used if you use a static front page.
home.php
主頁範本, which is the front page by default. If you use a static front page this is the template for the page with the latest posts.
single.php
The single post template. Used when a single post is queried. For this and all other query templates, index.php is used if the query template is not present.
single-<post-type>.php
The single post template used when a single post from a custom post type is queried. For example, single-books.php would be used for displaying single posts from the custom post type books. index.php is used if the query template for the custom post type is not present.
page.php
The page template. Used when an individual Page is queried.
category.php
The category template. Used when a category is queried.
tag.php
The tag template. Used when a tag is queried.
taxonomy.php
The term template. Used when a term in a custom taxonomy is queried.
author.php
The author template. Used when an author is queried.
date.php
The date/time template. Used when a date or time is queried. Year, month, day, hour, minute, second.
archive.php
The archive template. Used when a category, author, or date is queried. Note that this template will be overridden by category.phpauthor.php, and date.php for their respective query types.
search.php
The search results template. Used when a search is performed.
attachment.php
Attachment template. Used when viewing a single attachment.
image.php
Image attachment template. Used when viewing a single image attachment. If not present, attachment.php will be used.
404.php
404 未找到 範本。當WordPress 無法查找到匹配查詢的日誌或頁面時,使用 404.php 檔。

這些檔在 WordPress 中有特殊的意義,他們在合適的情況下代替index.php Template Hierarchy, and when the corresponding Conditional Tag returns true. For example, if only a single post is being displayed, the is_single() function returns 'true', and, if there is a single.php file in the active Theme, that template is used to generate the page.

基本範本

在最簡單的情況下,一個WordPress主題由兩個檔構成:

  • style.css
  • index.php

這些檔都位於主題目錄. 這index.php 範本 是非常靈活的.他可以用來包含所有的引用 header, sidebar, footer, content, categories, archives, search, error, 和其他在WordPress產生的檔.

或者,他也可以模組化,使用單獨的檔分擔工作.如果你沒有提供其他的範本檔,WordPress 會使用默認檔.比如說,如果你沒有提供comments.php 檔, WordPress會自動使用 wp-comments.php 範本檔 Template Hierarchy. (Note: As of version 3.0, the default files aren't guaranteed to be present or to be the same as they have been. It's much safer to supply your own template files.)

典型的範本檔包括:

  • comments.php
  • footer.php
  • header.php
  • sidebar.php

使用這些範本檔,你可以把這些檔嵌入到index.php 中,最後生成的檔裏.

include 用法:

<?php get_sidebar(); ?>

<?php get_footer(); ?>

關於更多的如何利用各種範本,如何產生不同的資訊, 請閱讀 Templates 文檔.

Query-based Template Files

WordPress can load different Templates for different query types. There are two ways to do this: as part of the built-in Template Hierarchy, and through the use of Conditional Tags within The Loop of a template file.

To use the Template Hierarchy, you basically need to provide special-purpose Template files, which will automatically be used to override index.php. For instance, if your Theme provides a template called category.php and a category is being queried, category.php will be loaded instead of index.php. If category.php is not present, index.php is used as usual.

You can get even more specific in the Template Hierarchy by providing a file called, for instance, category-6.php -- this file will be used rather than category.php when generating the page for the category whose ID number is 6. (You can find category ID numbers in Manage > Categories if you are logged in as the site administrator in WordPress version 2.3 and below. In WordPress 2.5 the ID column was removed from the Admin panels. You can locate the category id by clicking 'Edit Category' and looking on the URL address bar for the cat_ID value. It will look '...categories.php?action=edit&cat_ID=3' where '3' is the category id). For a more detailed look at how this process works, see Category Templates.

If your Theme needs to have even more control over which Template files are used than what is provided in the Template Hierarchy, you can use Conditional Tags. The Conditional Tag basically checks to see if some particular condition is true, within the WordPress Loop, and then you can load a particular template, or put some particular text on the screen, based on that condition.

For example, to generate a distinctive stylesheet in a post only found within a specific category, the code might look like this:

<?php
if ( is_category( '9' ) ) {
    get_template_part( 'single2' ); // looking for posts in category with ID of '9'
} else {
    get_template_part( 'single1' ); // put this on every other category post
}
?>

Or, using a query, it might look like this:

<?php
$post = $wp_query->post;
if ( in_category( '9' ) ) {
    get_template_part( 'single2' );
} else {
    get_template_part( 'single1' );
}
?>

In either case, this example code will cause different templates to be used depending on the category of the particular post being displayed. Query conditions are not limited to categories, however, see the Conditional Tags article to look at all the options.

定義範本

It is possible to use the WordPress plugin system to define additional templates that are shown based on your own custom criteria. This advanced feature can be accomplished using the template_redirect action hook. More information about creating plugins can be found in the Plugin API reference.

Including Template Files

To load another template (other than header, sidebar, footer, which have predefined included commands like get_header()) into a template, you can use get_template_part(). This makes it easy for a Theme to reuse sections of code.

Referencing Files From a Template

When referencing other files within the same Theme, avoid hard-coded URIs and file paths. Instead reference the URIs and file paths with bloginfo(): see Referencing Files From a Template.

Note that URIs that are used in the stylesheet are relative to the stylesheet, not the page that references the stylesheet. For example, if you include an images/ directory in your Theme, you need only specify this relative directory in the CSS, like so:

h1 {
    background-image: url(images/my-background.jpg);
}

Plugin API Hooks

When developing Themes, it's good to keep in mind that your Theme should be set up so that it can work well with any WordPress plugins users might decide to install. Plugins add functionality to WordPress via "Action Hooks" (see Plugin API for more information).

Most Action Hooks are within the core PHP code of WordPress, so your Theme does not have to have any special tags for them to work. But a few Action Hooks do need to be present in your Theme, in order for Plugins to display information directly in your header, footer, sidebar, or in the page body. Here is a list of the special Action Hook Template Tags you need to include:

wp_head()
Goes in the <head> element of a theme, in header.php. Example plugin use: add JavaScript code.
wp_footer()
Goes in footer.php, just before the closing </body> tag. Example plugin use: insert PHP code that needs to run after everything else, at the bottom of the footer. Very commonly used to insert web statistics code, such as Google Analytics.
wp_meta()
Typically goes in the <li>Meta</li> section of a Theme's menu or sidebar; sidebar.php template. Example plugin use: include a rotating advertisement or a tag cloud.
comment_form()
Goes in comments.php directly before the comment form's closing tag (<tt</form></tt>). Example plugin use: display a comment preview. As of WordPress 3.0, you should use the default comment form instead, see comment_form().

For a real world usage example, you'll find these plugin hooks included in the default Theme's templates.

Untrusted Data

You should escape dynamically generated content in your Theme, especially content that is output in HTML attributes. As noted in WordPress Coding Standards, text that goes into attributes should be run through esc_attr so that single or double quotes do not end the attribute value and invalidate the XHTML and cause a security issue. Common places to check are titlealt, and value attributes.

In a few cases there might already be a template tag for common cases where safe output is needed. One such case involves the "title" attribute when used with the_title() for post and page titles. To avoid a security vulnerability, use the_title_attribute() instead. Here's an example of correct escaping for the title attribute in a post title link when using translatable text:

<?php echo esc_attr( sprintf( __( 'Permanent Link to %s', 'theme-name' ), the_title_attribute( 'echo=0' ) ) ); ?>

Replace deprecated escape calls with the correct calls: wp_specialcharshtmlspecialchar with esc_htmlclean_url with esc_url, and attribute_escape with esc_attr. See Data_Validation for more.

翻譯 / i18n 支援

為了確保本地化翻譯能順利進行,請使用 gettext 函式包裹範本檔中需要翻譯的文字。這使翻譯檔可以更容易介接,並且更容易將標籤、標題與其他佈景主題內的文字翻譯成網站當前語言。更多資料請參閱 WordPress_Localization i18n for WordPress Developers.

主題的 class

使用以下標籤標籤增加 WordPress系統產生的 class 屬性, body,post 和 comment 標籤。 關於post class,只能位於The Loop.

範本檔清單

當開發一個主題的時候,檢查你的範本檔是不是遵守了這些標準。

Head 檔(header.php)

  • 使用合適的 DOCTYPE 聲明。
  • 開始的 <html> 標籤應該包含 language_attributes().
  • "content-type" meta 元素應該位於最前面,包括 title 標籤。
  • 使用 bloginfo() 獲得標題和博客描述。
  • 使用 automatic feed links 增加 FEED 輸出。
  • 增加 wp_head(). 插件會使用這個鉤子增加他們的腳本樣式表和一些其他的功能。

這裏是一份格式正確的 HTML5 頭部:

<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>" />
<title><?php wp_title(); ?> <?php bloginfo( 'name' ); ?></title>
<link rel="profile" href="http://gmpg.org/xfn/11" />
<link rel="stylesheet" href="<?php bloginfo( 'stylesheet_url' ); ?>" type="text/css" media="screen" />
<link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>" />
<?php if ( is_singular() && get_option( 'thread_comments' ) ) wp_enqueue_script( 'comment-reply' ); ?>
<?php wp_head(); ?>
</head>

導航菜單 (header.php)

  • 主題得主導航菜單應該支持自定義菜單wp_nav_menu().
    • 菜單應該支持長的菜單名和大量的列表。這些不應該破壞主題的外觀。
    • 次級菜單應該正確的顯示。如果可能的話,使二級菜單支持下拉。下拉菜單允許顯示菜單的深度而不只是頂級菜單。

小工具 (sidebar.php)

  • 主題應該盡可能的支持小工具的使用。 所有看起來像是一個小工具的地方(標籤雲,鏈接表,分類目錄)或者可以放置小工具的地方(sidebar)應該允許使用小工具。
  • 當有小工具從外觀>小工具啟動時,小工具區域默認顯示的內容應該消失。

頁面底部 (footer.php)

  • body 前面,緊緊挨著body 調用 wp_footer()

比如:

<?php wp_footer(); ?>
</body>
</html>

索引 (index.php)

  • 以全文或者摘要的形式顯示一列文章。根據情況選用使用或者其他的。
  • 包含 wp_link_pages() 來支持文章內部分頁。

歸檔 (archive.php)

  • 顯示歸檔標題(標籤,分類,作者歸檔)。
  • 以摘要的形式或者全文顯示文章。
  • 包含 wp_link_pages() 來支持文章內部分頁。

頁面 (page.php)

  • 顯示標題和內容。
  • 顯示評論列表和評論框(除非關閉了評論)。
  • 包含 wp_link_pages() 來內部分頁。
  • 元數據,必然標籤,分類目錄,日期,作者不應該被顯示出來。

日誌單獨頁面 (single.php)

  • 包含 wp_link_pages() 在文章內部產生分頁效果。
  • 顯示標題和內容。
    • 標題應該使用純文本代替指向自己的鏈接。
  • 顯示發表日期。
    • 尊重時間和日期的默認格式,沒必要就別自己設置。(用戶自己設置的是最合適的。)
    • 使用 the_time( get_option( 'date_format' ) )獲得輸出的日期和時間格式。
  • 顯示作者名字(如果有的話)。
  • 顯示分類目錄和標籤。
  • 為登陸用戶顯示“編輯”。
  • 顯示評論列表和評論框。

評論 (comments.php)

  • 作者的評論應該高亮顯示區分。
  • 如果有頭像的話顯示頭像。
  • 支持嵌套評論。
  • 顯示trackbacks/pingbacks。

搜索 (search.php)

  • 顯示一系列文章的摘要或者全文顯示, 選擇一種合適的方式。
  • 搜索結果頁面顯示搜索輸入的內容。非常簡單但是非常有用,這可以提醒用戶剛才搜索了什麼--尤其是在沒有結果的時候。使用 the_search_query 或者 get_search_query 顯示或者返回結果。例:
    <h2><?php printf( __( 'Search Results for: %s' ), '<span>' . get_search_query() . '</span>'); ?></h2>
  • 在搜索結果頁面再一次包含搜索框是對用戶非常友好的。使用 get_search_form()調用搜索框。

JavaScript

  • JavaScript 代碼應該外部引用。
  • 使用 wp_enqueue_script 引入你的腳本。
  • 直接寫入 HTML 的 JavaScript 應該使用 CDATA 來阻止在老版本的流覽器出錯。
<script type="text/javascript">
/* <![CDATA[ */
// content of your Javascript goes here
/* ]]> */
</script>

預覽

為你的主題做一個預覽,並且名字命名為screenshot.png,放在主題目錄下。預覽一定是真實的預覽效果,而且是 PNG 或者 JPG 格式的。

主題選項

主題可以自由的包含是否有選項設置頁面。參考 [1].

當增加選項頁面的時候使用 edit_theme_options 而不是 switch_themes 選項面板, unless the user actually should be able to switch Themes to be able to use your options panel. WordPress itself uses the edit_theme_options capability for menus, background, header, widgets, et cetera. See more at Roles and Capabilities and Adding Administration Menus.

A note about network mode and Theme options:

If you are using the edit_themes capability anywhere in your Theme, and the Theme is running on a network-enabled WordPress install (previously WordPress MU), be aware that the edit_themes capability used for accessing Theme options pages will prevent site admins in a network from seeing the options menu. Use edit_theme_options instead.

主題測試過程

  1. 修正 PHP 和 WordPress 錯誤。在你的 wp-config.php 檔裏添加下面程式碼來增加調試功能,檢查已廢棄的函式呼叫以及其他 WorePress 相關的錯誤:define('WP_DEBUG', true);

參考Deprecated Functions Hook 以獲得夠多的資訊。

  1. Check template files against Template File Checklist (see above).
  2. Do a run-through using the Theme Unit Test.
  3. Validate HTML and CSS. See Validating a Website.
  4. Check for JavaScript errors.
  5. Test in all your target browsers. For example, IE6, IE7, IE8, Safari, Chrome, Opera, and Firefox.
  6. Clean up any extraneous comments, debug settings, or TODO items.
  7. See Theme Review if you are publicly releasing the Theme by submitting it to the Themes Directory.

資源和參考書

編碼標準

主題設計

CSS

範本

測試

發行與提交

教學資源

以下是有關WordPress主題和範本檔的推薦文章清單:

主題製作全教程 By Ludou
wordpress主題製作教程 By 站長百科
WordPress 主題教程:從零開始製作 WordPress 主題 By 我愛水煮魚