Warning: Creating default object from empty value in /www/wwwroot/sc35.com/blog/wp-content/plugins/paged-comments/paged-comments.php on line 31
Dissect WordPress Themes - Wang
FV.Zone Project Code

Dissect WordPress Themes

还是想用Nat在OOS上的一段话来作为开头:

You have to give people work to do.
Create an “architecture of participation” as Tim O’Reilly says.

要想真正成功,必须能够提供一个可以供人参与的架构,Eclipse如此,Firefox亦如此。与Plugin一样,WordPress中的Theme机制也非常灵活和强大,社区贡献出的一个个漂亮的Theme都是这个良好架构下的杰作。

1)读取系统中所有可用Themes

 function get_themes()
?>

这个函数用来从文件系统得到所有的Themes。首先列出’wp-content/themes’的文件夹,然后跳过’’.’、’..’、’CVS’(跳过CVS目录,这个在Xerdoc DSearch的Theme中也遇到过,因为都是采用CVS进行源码管理 ):

 if ($theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS') {
continue;
}
?>

然后会判断每个目录中是否有Stylesheet ’style.css’文件,如果有,列为Theme候选目录,否则加入到’$wp_broken_themes’中。

接下来,就利用函数

 function get_theme_data($theme_file);
?>

来从’style.css’中提取Theme的描述信息,包括’Theme Name’、’Version’、’Author’等等。同WordPress中的插件类似,这些描述信息是存在’style.css’中的。

 Theme Name: WordPress Default
Theme URI: http://wordpress.org/
Description: The default WordPress theme based on the famous Kubrick.
Version: 1.5
Author: Michael Heilemann
Author URI: http://binarybonsai.com/
?>

第三步,需要判断命名冲突。这种情况发生的原因是:将一个Theme拷贝,然后做修改,可是Theme的Descriptor并没有修改。可见,WordPress在人性化上真是做足了功夫,值得学习。

这样,合格的Theme就读取完毕了。不合格的Theme会被放到”Broken Theme”这个Section中,需要重新进行修改才能使用。

2)更换Theme

更换Theme很简单,先来看看当Active一个Theme的时候我们所Access的URL:

http://localhost/blog/wp-admin/themes.php?action
=activate&template=sixties-datetitle&stylesheet=sixties-datetitle

同Plugin一样,Active Theme的信息(其实就是目录名称)也保存在数据库中。但是需要存两项,分别是”template”和”stylesheet”。这是为了处理Style的CSS文件与模板文件(比如index.php)放在不同目录的情况。

 if (isset($_GET['template'])) {
update_option('template', $_GET['template']);
}

if (isset($_GET['stylesheet'])) {
update_option('stylesheet', $_GET['stylesheet']);
}
?>

3)Theme的加载

首先看看我们访问WordPress的过程。当我们访问’http://yoursite/blog/’的时候,访问的是’index.php’文件:

 define('WP_USE_THEMES', true);
require('./wp-blog-header.php');
?>

在’wp-blog-header.php’文件中,可以看到下面的重定向过程:

 // Template redirection
if ( defined('WP_USE_THEMES') && constant('WP_USE_THEMES') ) {
do_action('template_redirect');
if ( is_feed() && empty($doing_rss) ) {
include(ABSPATH . '/wp-feed.php');
exit;
} else if ( is_trackback() && empty($doing_trackback) ) {
include(ABSPATH . '/wp-trackback.php');
exit;
} else if ( is_404() && get_404_template() ) {
include(get_404_template());
exit;
} else if ( is_search() && get_search_template() ) {
include(get_search_template());
exit;
} else if ( is_home() && get_home_template() ) {
include(get_home_template());
exit;
} else if ( is_single() && get_single_template() ) {
include(get_single_template());
exit;
} else if ( is_page() && get_page_template() ) {
include(get_page_template());
exit;
} else if ( is_category() && get_category_template()) {
include(get_category_template());
exit;
} else if ( is_author() && get_author_template() ) {
include(get_author_template());
exit;
} else if ( is_date() && get_date_template() ) {
include(get_date_template());
exit;
} else if ( is_archive() && get_archive_template() ) {
include(get_archive_template());
exit;
} else if ( is_comments_popup() && get_comments_popup_template() ) {
include(get_comments_popup_template());
exit;
} else if ( is_paged() && get_paged_template() ) {
include(get_paged_template());
exit;
} else if ( file_exists(TEMPLATEPATH . "/index.php") ) {
include(TEMPLATEPATH . "/index.php");
exit;
}
} else {
// Process feeds and trackbacks even if not using themes.
if ( is_feed() && empty($doing_rss) ) {
include(ABSPATH . '/wp-feed.php');
exit;
} else if ( is_trackback() && empty($doing_trackback) ) {
include(ABSPATH . '/wp-trackback.php');
exit;
}
}
?>

可以看到,根据访问的不同,会定向到不同的页面。比如访问首页的时候,’is_home’返回为true,这样,将会利用get_home_template(),重定向到home template。

 function get_home_template() {
$template = '';

if ( file_exists(TEMPLATEPATH . "/home.php") )
$template = TEMPLATEPATH . "/home.php";
else if ( file_exists(TEMPLATEPATH . "/index.php") )
$template = TEMPLATEPATH . "/index.php";

return apply_filters('home_template', $template);
}
?>

在’wp-setting.php’中,可以找到’TEMPLATEPATH’的定义:

 define('TEMPLATEPATH', get_template_directory());
?>

get_template_directory()的定义为:

 function get_template_directory() {
$template = get_template();
$template_dir = get_theme_root() . "/$template";
return apply_filters('template_directory', $template_dir, $template);
}
?>

get_template则是从数据库中取出现在使用的Theme,再加上Theme Root的路径,即可得到我们选择的Theme的路径。

 function get_template() {
return apply_filters('template', get_settings('template'));
}
?>

因此,这样就定位到所选择Theme的目录,并访问相应的文件。

4)Template的模式

其实对于一个能够提供Theme的程序而言,在程序的构架上必须要实现数据和表现的分离。通常我们所说的MVC(Model、View、Controller)架构就是这个意思。

在WordPress中,是这样来实现数据和实现的分离的。

XHTML。用Div等用来表现数据,CSS来描述这些数据的表现形式,用这种方式来实现数据和表现的分离;
在程序内部,采用Template来进行数据展现。
以 ‘Default’ Theme为例:


<p id="content" class="narrowcolumn">
<p class="post" id="post-&lt;?php the_ID(); ?&gt;&lt;p&gt;">
<h2><a href="http://blog.raidybor.com/wp-admin/%3C?php%20the_permalink%28%29%20?%3E" rel="bookmark" title="Permanent Link to &lt;?php the_title(); ?&gt;"></a></h2>
<small> <!-- by <?php the_author() ?> --></small>
<p class="entry"></p>
<p class="postmetadata">Posted in  <strong>|</strong> |'); ?&gt;</p>


<p class="navigation">
<p class="alignleft"></p>
<p class="alignright"></p>

<h2 class="center">Not Found</h2>
<p class="center">Sorry, but you are looking for something that isn't here.</p>

?&gt;

“get_header”和”get_footer”分别用来得到该页的Header和Footer,其实就是两个DIV块儿。Post的主体同样是一个大的Div(

<di d=" content " class="narrowcolumn">

),在该Theme的CSS中即可以看到对这个DIV的表现定义,包括字体、背景颜色、边距等等。

.narrowcolumn {
float: left;
padding: 0 0 20px 45px;
margin: 0px 0 0;
width: 450px;
}

Post的内容由”have_posts()”, “the_post()”, “the_ID()”得到,具体见此,风格同样定义在CSS文件中。

Leave a Reply

You must be logged in to post a comment.