性价比最高的香港ASP、PHP主机提供商
做网站,就上凡科建站

WordPress中文文档:WordPress主题开发

Loading
0
Comodo SLL证书促销 - 免费ssl证书申请_ssl证书购买_ev ssl证书_https证书购买 - GDCA_数安时代

本文介绍如何开发设计你自己的 WordPress 主题,所讨论的是编写代码去构建你自己的主题的技术内容。

为什么要使用 WordPress 主题

WordPress 主题由一系列文件和 CSS 样式表构成,构成了一个美丽的 WordPress 网站。每个主题都是不同的, 这样WordPress用户就可以随时更改 WordPress 网站的外观。

你也许想为自己开发 WordPress 主题,或者制作公开发行的的主题。但是除了这个为什么要自己制作主题呢?

  • 创建自己独特的 WordPress 主题外观.
  • 利用模板模板标签, 和 WordPress循环 来产生不同的效果.
  • 为了产生不同的效果,比如在category pages页面和搜索结果页面产生个性的效果.
  • 为了迅速从两个主题改变你的博客外观,可以充分利用 Theme or style switcher 这个插件迅速改变外观.
  • 设计 WordPress 主题,这样大家就可以通过网络更好的使用你的作品.

WordPress 主题有很多优点

  • WordPress 主题把CSS样式表和 模板文件 从系统中独立出来,所以这样升级博客的时候就不会破坏你的主题样式。
  • 允许你自由的定制主题样式。
  • 允许你迅速改变主题。
  • 你甚至都不需要学习HTML,CSS,PHP等,即可拥有一个美观的主题。

为什么要自己制作主题呢?这才是问题的关键.

  • 这是一个学习 CSS,HTML,和PHP的好机会.
  • 这是一个积累你的 CSS,HTML,PHP实践经验的的机会.
  • 制作主题的过程中充满创造力.
  • 这非常的有趣(大多数情况下).
  • 如果你 设计公共主题, 你会感觉非常好,因为你为 WordPress 社区做出了自己的贡献 (好吧,可以吹牛了~)

主题开发标准

WordPress 主题应该按照如下标准开发:

主题的剖析

WordPress主题目录位于 wp-content/themes/。主题的子目录拥有所有样式文件、模板文件、可选的函数文件 (functions.php)、JavaScript 文件、图片等。比如说一个叫做 "test" 的主题就会放在 wp-content/themes/test/目录里。请避免使用数字名字,这会导致无法在主题列表中正常显示出来。

WordPress每一个发行版都会有一个默认的主题。请认真查看默认的主题,这样可能会对制作你自己的主题有帮助。

WordPress 主题除了图片和JavaScript,经常由三种文件构成。

  1. 样式表文件 style.css, 控制着页面的外观
  2. 函数文件 (functions.php)。
  3. 模板文件,它控制着从数据库中调出的数据所呈现的外观。

让我们单独看一下。

主题样式表

CSS文件不仅列出了一些主题的样式设计, style.css 必须 以注释的形式列出主题的详细信息 两个不同的主题是不允许拥有相同的表述的 , 因为这样会导致主题选择出错。如果你通过拷贝一个你已经制作的主题来制作你新的主题,请确保先更改这些头部注释.

下面是样式表头部注释的例子,被称作样式表头注释。比如主题叫做 "Twenty Ten":

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
Theme Name: Twenty Ten
Theme URI: http://wordpress.org/
Description: The 2010 default theme for WordPress.
Author: wordpressdotorg
Author URI: http://wordpress.org/
Version: 1.0
Tags: black, blue, white, two-columns, fixed-width, custom-header, custom-background, threaded-comments, sticky-post, translation-ready, microformats, rtl-language-support, editor-style, custom-menu (optional)
 
License:
License URI:
 
General comments (optional).
*/

这些位于style.css里的文件是必须要写的,这是用来区分安装的主题。

注意使用不同的标签来描述你的主题,如果你的主题提交到WordPress官方主题库,这允许用户使用标记过滤器找到你的主题。下面是完整的允许的标签列表

样式表指南

  • 当创作你的CSS的时候请参考CSS 编码标准
  • 尽可能使用有效地 CSS。作为例外,也可以使用一些前缀,遵循CSS3标准。
  • 尽量减少使用CSS hacks。明显浏览器支持(如IE)是个例外,如果可能的话,将CSS hack文件区分开来或者使用独立的文件。
  • 所有的 HTML 元素应该有样式声明,无论是文章页面还是评论部分。
    • Tables, captions, images, lists, block quotes,等等。
  • 强烈建议添加打印友好的字体
    • 你能通过使用media="print"属性来包含一个适用于打印的样式表文件,或者在你的主样式表文件中增加一部分专为打印提供的设置。

子主题

最简单的主题可能是子主题,其仅仅包含一个style.css文件,也可以加上一些图片。之所以它能工作是因为它是以另一个主题为基础进行工作的。

更多关于子主题的信息,请看Child Themes

函数文件

一个主题可以使用一个函数文件,位于主题的子目录,叫做 functions.php。这个文件就像一个插件, 如果它位于你正在使用的主题里的话, 他在你的主题初始化的时候就会自动加载(后台和前台都一样加载)。对于这个文件的建议:

  • 定义你的模板使用的函数.
  • 启用缩略图功能,如职位,自定义标题和背景,和导航菜单.
  • 设置一个选项菜单,让网站拥有者可以自定义颜色,样式,和你的主题的其他特性.

默认的WordPress的主题包含一个functions.php文件,它定义这些功能很多,所以你可能会把它当做参考.既然functions.php基本上可以作为一个插件,所以Function_Reference可以让你更多的了解这个函数,以及你可以怎么利用这些函数.

需要注意的是,如果你要在不同的主题使用同一个功能时,那么请将函数应建立在一个插件上,而不是一个特定主题的functions.php。这样一来,及时你更换主题,你还是可以通过这个插件实现你想要的功能。

模板文件

模板 是一些PHP文件,他可以输出HTML代码呈献给浏览器,决定着主题的外观。下面让我们来看一下主题的模板。

WordPress允许为你的网站定义不同的模板。他虽然不是必需的,但是这些不同的模板为你的网站添上一笔。模板是根据模板层次(Template Hierarchy)的,由一个具体的主题决定。

作为一个主题开发者,你可以自由决定如何定制你的模板。比如说,极端情况下, 你甚至可以仅仅使用一个文件index.php作为模板文件,所有 页面都会使用这个模板.更多的情况是,使用不同的模板文件产生不同的结果,以达到最大定制。

模板文件列表

这里是被WordPress确认的主题文件列表.当然,你的主题可以包含任何样式表,图像或者文件。记住 下面列出的文件对WordPress有特殊的意义——点击模板层次(Template Hierarchy) 查看具体情况。

style.css
主样式表,这个文件 必须 位于你的主题里面,而且必须在头部注释处写清楚你的主题的信息.
rtl.css
rtl 样式表。如果网站的阅读方向是自右向左的,他会自动被包含进来。你可以使用 the RTLer 插件来生成这个文件.
index.php
主模板.如果你的主题使用自己的模板,index.php 是必须要有的.
comments.php
评论模板.
front-page.php
首页模板,仅用于开启 静态首页 时。
home.php
主页模板,默认的首页。如果你开启了 静态首页 这是展现最新的文章的模板页面。
single.php
单独页面模板。显示单独的一篇文章时被调用。对于这个以及其他的请求模板,如果模板不存在会使用 index.php
single-<post-type>.php
自定义单独页面模板。例如, single-books.php 展示自定义文章类型为 books的文章. 如果文章类型未被设置则使用index.php
page.php
页面模板. 独立页面调用。
category.php
分类模板。 分类页面调用。
tag.php
标签模板。标签页面调用。
taxonomy.php
术语模板。请求自定义分类法的术语时使用。
author.php
作者模板。作者页面调用。
date.php
日期/时间模板,按时间查询时使用的模板。
archive.php
存档模板。查询分类,作者或日期时使用的模板。需要注意的是,该模板将会分别被category.phpauthor.phpdate.php所覆盖(如果存在的话)。
search.php
搜索结果模板,显示搜索结果时使用的模板。
attachment.php
附件模板,查看单个附件时使用的模板。
image.php
图片附件模板。当在wordpress中查看单个图片时将调用此模板,如果不存在此模板,则调用attachment.php 模板。
404.php
404 错误页面 模板。当WordPress无法查找到匹配查询的日志或页面时,使用404.php文件。

按照Template Hierarchy,这些文件在 WordPress 中有特殊的意义,即当对应的 条件标签 返回 true 的时候,他们将在这种情况下代替index.php ,例如,如果当前显示的是单一的一篇博文,那么is_single() 这个函数将返回’true’,并且,如果有一个single.php文件存在于当前主题中,该文件模板就将起作用.

基本模板

在最简单的情况下,一个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). (注:从 3.0 版本开始,默认的文件不能保证是现成的或者相同的。为了安全起见,请使用自己的模板文件。)

典型的模板文件包括:

  • comments.php
  • comments-popup.php
  • footer.php
  • header.php
  • sidebar.php

使用这些模板文件,你可以把这些文件嵌入到index.php 中,最后生成的文件里.

include 用法:

1
2
3
<?php get_sidebar(); ?>
 
<?php get_footer(); ?>

一些模板函数的默认文件可能被废弃或不存在,在你的主题,你应该提供这些文件。至于3.0版本以上,不推荐使用位于 wp-includes/theme-compat 的默认文件。例如,你应该提供 header.php 文件让  get_header() 函数更好地安全工作,以及为 comments_template() 函数提供  comments.php 文件。

关于更多的如何利用各种模板,如何产生不同的信息, 请阅读 Templates 文档.

自定义页面模板

在你的主题目录中,你可以定义每个页面的模板。要创建一个新的自定义页面模板,你必须创建一个文件,比如我们创建一个  snarfer.php 文件,然后将下面的内容添加到这个文件中:

1
2
3
4
5
<?php
/*
Template Name: Snarfer
*/
?>

上面的代码定义了这个 snarfer.php 文件作为“Snarfer”模板。当然,你可以使用其他名称替换“Snarfer”。此模板的名称将出现在“主题编辑器”(即:外观 – 编辑)中,作为编辑这个文件的链接。

需要注意的是,你不能使用WordPress默认保留的名字来命名这个文件,因为那些名字是有特殊用途的。你可以查看 WordPress保留的文件名

上面的代码只是用来声明这个模板的,至于这个模板要显示什么,如何显示,就要靠你自己添加代码了。要了解WordPress模板的各种功能,你可以通过 模板标签 查看介绍。你可能会发现,通过复制一些其他的模板(比如 page.php 或 index.php)的代码到 snarfer.php,然后添加上面的5行代码,就可以拥有和其他模板一样的功能。你就可以在此基础上对代码进行二次修改,而不必从头开始了。一旦你创建好这个模板,请将它添加到你的主题目录中,这样,你就可以在创建或编辑页面的时候,通过“页面属性”这个模块下的“模板”选择这个模板啦。(注:如果你的主题不存在任何页面模板,就没办法在“页面属性”中看到“模板”这个选项)

基于查询的模板文件

WordPress可以根据不同查询类型加载不同的模板。你可以通过两种方法做到这一点:作为内置模板层次(Template Hierarchy)的一部分,并通过使用 条件标签(Conditional Tag) 在模板文件的 循环 (loop)中加载。

要使用 模板层次,你基本上需要提供特殊用途的模板文件,它会自动覆盖原来的 index.php 。例如,如果你的主题中提供了一个名为 category.php  的模板文件,但一个分类被查询时,就会优先加载 category.php 文件取代 index.php ;如果category.php 不存在,就会使用 index.php。

你还可以通过文件的命名获得一个更具体的模板层次,比如一个名为 category-6.php 的文件,如果查询的分类ID为 6 ,那么就会优先加载这个 category-6.php 文件取代 category.php 。(要获得分类的ID,你只需访问后台 文章 – 分类目录,然后点击编辑任何一个分类下的“编辑”,就可以在URL中看到“categories.php?action=edit&cat_ID=3”这样的字样,3 就是ID号)。你可以阅读 分类模板 了解更多详情。

如果你的主题需要更好地控制哪些模板文件中提供的 模板层次,你可以使用 条件标签。通过使用 条件标签 ,判断在WordPress循环中哪些条件为真,就加在对应的特定模板,或者显示对应的内容。

例如,要为一个特定的类别加载一个独特的样式表,可以使用类似的代码:

1
2
3
4
5
6
7
<?php
if ( is_category( '9' ) ) {
    get_template_part( 'single2' ); // 将这个模板样式应用于分类ID为 9 的文章
} else {
    get_template_part( 'single1' ); // 其他分类的文章使用这个模板样式
}
?>

或者使用一个查询,例如:

1
2
3
4
5
6
7
8
<?php
$post = $wp_query->post;
if ( in_category( '9' ) ) {
    get_template_part( 'single2' );
} else {
    get_template_part( 'single1' );
}
?>

上面例子的2种代码,都可以根据判断不同的分类,将不同的模板应用在特定的分类上。查询条件 不限分类,不过,建议你阅读 条件标签 这篇文章查看所有的可用选项。

定义自定义模板

你可以通过使用 WordPress 插件系统来根据自己的标准定义不同的自定义模板。可以通过使用“template_redirect”这个行动钩子来实现这个先进的功能。你可以在 插件API 参考 了解过多创建创建的信息。

包括模板文件

要在模板中加载另一个模板(除了 header、sidebar、footer,其中包括有预定义的命令,如 get_header()),你可以使用 get_template_part() 。通过这种方式,可以在主题中重复利用一个代码片段。

从模板中引用文件

在同一个模板中引用其他文件,避免 硬编码(hard-coded) 的 URIs 或文件路径。而应该使用 bloginfo() 引用URIs 或文件路径:请看 从模板中引用文件

请注意,在样式表中的 URIs 是相对于样式表,而不是相对于引用样式表的页面。例如,如果要包含一个 images/ 目录到你的主题中,你只需要指定相对目录中的CSS,像这样:

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

插件 API 钩子

开发主题的时候,需要注意的是你的主题最好能和用户可能安装的任何插件共存。插件可以通过“动作钩子(Action Hooks, 查看Plugin API)”为wordpress增加功能。

大部分Action Hooks存在于wp的php核心中,所以你的主题不需要任何多余的特殊标签来让它可以正常运转。但是少数的Action Hooks需要在你的主题中做特殊处理,以使插件能够将头,尾,侧边栏等信息输出到页面中。如下是你需要包含到主题 中的Action Hooks列表:

wp_head()
放在<head>标签之内,在 header.php文件中. 大部分插件常在这里导入javascript文件。
wp_footer()
footer.php,在</body>标签之前 . 使用举例:一些插件会在这里插入要在文档最后执行的PHP代码。更常见的用法是插入网页静态代码,比如Google Analytics。
wp_meta()
通常用在主题菜单或侧边栏 sidebar.php 模板文件的 <li>Meta</li> 中。使用举例:包括一个旋转的广告或标签云。
comment_form()
放在 comments.php ,在文件的结束标签(</div>)之前。 使用举例:显示评论预览。

主题定制API

在 WordPress 3.4开始,添加了一个新的主题自定义功能,几乎适用于所有WordPress主题。通过在主题中提供一个支持声明 add_theme_support() 或者使用 设置API ,就可以自动填充一些选项到主题的定制管理页面中,同时允许管理员在线实时预览主题的效果。

主题和插件开发者,如果有兴趣添加一些新的选项到主题定制页面中,可以查看 主题定制API 文档 和 Ottopress.com 网站的教程。

不可信的数据

你应该避免在你的主题中动态生成内容,尤其是在HTML属性中输出的内容。正如 WordPress标准编码文档 所提及的,在属性中加载的本文应该使用 esc_attr() 包括,以避免单引号或双引号结束属性值和产生无效的XHTML,从而导致安全问题。

常见的安全输出情况下,需要有一些特殊的模板标签。在这种情况下,输出一个标题属性,应该使用 the_title_attribute() 而不是 the_title() ,这样才能避免安全问题。下面来看一个例子,正确转义一篇文章标题链接的标题属性:

1
<a href="<?php the_permalink(); ?>" title="<?php sprintf( __( 'Permanent Link to %s', 'theme-name' ), the_title_attribute( 'echo=0' ) ); ?>"><?php the_title(); ?></a>

使用正确的响应函数替换已经弃用的应该避免的函数:使用 esc_html() 替换 wp_specialchars()htmlspecialchars(),使用 esc_url() 替换 clean_url(),使用 esc_attr() 替换 attribute_escape()。查看 Data_Validation 了解更多。

翻译支持/ I18N

为了确保本地语言的平稳过渡,请在主题文件中,使用基于 WordPress  gettext-based i18n 的功能来包装所有需要翻译的文本。这样更有利于将语言包的翻译挂载到当前网站中。请阅读 WordPress 本地化I18n for WordPress Developers 了解更多信息。

主题类(Theme Classes)

使用下面的模板标签来添加WordPress的 body、post、和 comment 的元素属性。其中 post 类,只适用于在循环(Loop)中的元素。

模板文件清单

开发你的主题时,请按照下面的标准检查你的主题模板文件:

头部文档(header.php)

下面是一个格式正确的HTML5兼容的头部区域的例子:

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
    <head>
        <meta charset="<?php bloginfo( 'charset' ); ?>" />
        <title><?php wp_title(); ?></title>
        <meta name="description" content="<?php bloginfo( 'description' ); ?>">
        <link rel="profile" href="http://gmpg.org/xfn/11" />
        <link rel="stylesheet" href="<?php echo get_stylesheet_uri(); ?>" 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() 的自定义菜单功能:

  • 菜单应该支持长链接的标题和大量的列表项。不应该打破这些项目的设计或布局。
  • 应该正确支持子菜单的显示。可以的话,建议通过下来菜单来显示子菜单,并且支持多级子菜单。

Widgets小工具(sidebar.php)

  • 主题应该支持小工具(Widgets),允许一些布局区域(比如侧边栏)挂载小工具(比如标签云、友情链接、分类类表 等)。
  • 小工具的应该是可以从 外观 – 小工具 中进行设置,并且当添加小工具时,原来硬性写定到小工具区域的默认内容应该被替换。

页脚(footer.php)

1
2
3
<?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’ ) )
  • 显示作者的名字(如果适用)
  • 显示文章分类和标签
  • 为已登录的具有编辑权限的用户显示一个“编辑”链接
  • 显示评论列表和评论表单
  • 使用 previous_post_link()next_post_link()  显示上一篇和下一篇文章

评论(comments.php)

  • 作者的评论应该高亮显示,以便区分。
  • 显示用户的 gravatars 头像(如果适用)
  • 支持嵌套评论
  • 显示 引用通告(trackbacks/pingbacks)
  • 该文件不应该包含函数的定义,除非使用  function_exist() 来检查,以避免再次声明中指定的错误。理想情况下,所有的函数应该在 functions.php 文件中。

搜索结果(search.php)

  • 通过摘要或全文输出的方式显示文章列表。可以根据自己的需要选择适合的方式。
  • 搜索结果页面显示的搜索字词产生的结果。这是一个简单而有效的方式来提醒别人,他们只是在搜索——特别是在结果为零的情况下。使用  the_search_query()get_search_query() (显示或返回值,分别)。例如:

    1
    
    <h2><?php printf( __( 'Search Results for: %s' ), '<span>' . get_search_query() . '</span>'); ?></h2>
  • 这是一个好的做法,在搜索结果页面中再次包含搜索表单,可以使用 get_search_form()

JavaScript

  • JavaScript代码应该尽可能放在外部文件中。
  • 使用 wp_enqueue_script() 加载你的脚本。
  • Javascript的直接加载到HTML文件(模板文件)应该是CDATA编码,以防止旧版本的浏览器出现错误。

    1
    2
    3
    4
    5
    
    <script type="text/javascript">
    /* <![CDATA[ */
    // content of your Javascript goes here
    /* ]]> */
    </script>

截图

为你的主题添加一个截图。截图应该命名为 screenshot.png ,并且放在你的主题的根目录下。截图应该能直接展示你的主题设计和保存为 PNG 格式。推荐的图像大小为600×450,截图将显示为300×225,但双尺寸的图像,用来给HIDPI显示器上更好的显示效果。

主题选项

主题可以有选择地支持 主题选项屏幕 。举个简单的代码例子,查看 A Sample WordPress Theme Options Page

如果要给用户使用 主题选项屏幕 的权限,应该使用“edit_theme_options”来设置用户的权限,而不是使用 “switch_themes”,除非这个用户角色可以直接切换主题。需要了解更多,你可以阅读 Roles and Capabilities 和  Adding Administration Menus

如果你正在主题中使用 “edit_themes”能力来为管理员添加访问 主题选项屏幕 (或其他自定义屏幕)的权限,要知道,自 3.0 版以来,这个能力默认并没有分配给WordPress多站点的管理员。查看 说明。 在这种情况下,如果你希望管理员访问“主题选项”菜单,请使用 “edit_theme_options”能力。查看WordPress多站点的管理员的附加能力

主题测试过程

  1. 修复PHP和WordPress错误。添加下面的调试设置到你的wp-config.php,以便看到废弃的函数调用和其他WordPress相关的错误:define(‘WP_DEBUG’, true); 。查看 Deprecated Functions Hook 了解更多。
  2. 对照上面提到的 模板文件清单 检查模板文件。
  3. 使用 Theme Unit Test 做一个运行测试。
  4. 验证HTML和CSS。请参阅验证一个网站
  5. 检查 JavaScript 错误。
  6. 测试在所有目标浏览器。例如,IE7,IE8,IE9,Safari,Chrome,Opera,和 Firefox。
  7. 清理任何多余的意见,调试设置,或待办项目。
  8. 请查阅 Theme Review 如果你希望将主题公开发布到WordPress官方主题库。

资源和参考

请访问 原文 阅读这个部分的内容。

注:本文由 倡萌@WordPress大学 翻译自“ Theme Development ”,前半部分译文参考WordPress官方中文翻译。

支付宝扫码打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者

MetInfo | 最适合企业网站建设的cms系统

关于 倡萌

一个疯狂的 WordPress 爱好者,喜欢折腾 WordPress 主题,分享 WordPress 资源。如果你也喜欢 WordPress,欢迎和我一起交流!

7 条评论

  1. 写的不错,加油支持

  2. 请问我的网站404页面不能加载模板里的404页面咋办?只是nginx404

  3. 怪不得呢, 后半部分读起来感觉很不对, 原来后半部分是自己翻译的…….

  4. 楼主,你好,我会常来看你的_________________________________________________博客的

发表评论