本文介绍如何开发设计你自己的 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 主题应该按照如下标准开发:
- 使用结构化的、没有错误的PHP和有效的HTML代码。请看 WordPress Coding Standards。
- 使用简洁的、有效的CSS。参见 CSS Coding Standards。
- 遵循设计指南 Site Design and Layout。
主题的剖析
WordPress主题目录位于 wp-content/themes/。主题的子目录拥有所有样式文件、模板文件、可选的函数文件 (functions.php)、JavaScript 文件、图片等。比如说一个叫做 "test" 的主题就会放在 wp-content/themes/test/目录里。请避免使用数字名字,这会导致无法在主题列表中正常显示出来。
WordPress每一个发行版都会有一个默认的主题。请认真查看默认的主题,这样可能会对制作你自己的主题有帮助。
WordPress 主题除了图片和JavaScript,经常由三种文件构成。
- 样式表文件 style.css, 控制着页面的外观
- 函数文件 (functions.php)。
- 模板文件,它控制着从数据库中调出的数据所呈现的外观。
让我们单独看一下。
主题样式表
CSS文件不仅列出了一些主题的样式设计, style.css 必须 以注释的形式列出主题的详细信息 两个不同的主题是不允许拥有相同的表述的 , 因为这样会导致主题选择出错。如果你通过拷贝一个你已经制作的主题来制作你新的主题,请确保先更改这些头部注释.
下面是样式表头部注释的例子,被称作样式表头注释。比如主题叫做 "Twenty Ten":
/*
Theme Name: Twenty Ten
Theme URI: https://wordpress.org/
Description: The 2010 default theme for WordPress.
Author: wordpressdotorg
Author URI: https://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.php, author.php, date.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 中,最后生成的文件里.
- 包含header, 使用get_header().
- 包含sidebar, 使用 get_sidebar().
- 包含 footer, 使用 get_footer().
- 包含 search form, 使用 get_search_form().
include 用法:
<?php get_sidebar(); ?>
<?php get_footer(); ?>
一些模板函数的默认文件可能被废弃或不存在,在你的主题,你应该提供这些文件。至于3.0版本以上,不推荐使用位于 wp-includes/theme-compat 的默认文件。例如,你应该提供 header.php 文件让 get_header() 函数更好地安全工作,以及为 comments_template() 函数提供 comments.php 文件。
关于更多的如何利用各种模板,如何产生不同的信息, 请阅读 Templates 文档.
自定义页面模板
在你的主题目录中,你可以定义每个页面的模板。要创建一个新的自定义页面模板,你必须创建一个文件,比如我们创建一个 snarfer.php 文件,然后将下面的内容添加到这个文件中:
<?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循环中哪些条件为真,就加在对应的特定模板,或者显示对应的内容。
例如,要为一个特定的类别加载一个独特的样式表,可以使用类似的代码:
<?php
if ( is_category( '9' ) ) {
get_template_part( 'single2' ); // 将这个模板样式应用于分类ID为 9 的文章
} else {
get_template_part( 'single1' ); // 其他分类的文章使用这个模板样式
}
?>
或者使用一个查询,例如:
<?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,像这样:
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() ,这样才能避免安全问题。下面来看一个例子,正确转义一篇文章标题链接的标题属性:
<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)
- 使用正确的 DOCTYPE.
- <html> 开始标签应该包含 language_attributes().
- <meta> 字符集元素应该放到其他元素的上面,包括 <title> 元素。
- 使用 bloginfo() 设置 <meta> 字符集和description元素。
- 使用 wp_title() 设置 <title> 元素。 查看原因。
- 使用 get_stylesheet_uri() 来获取当前主题的样式表文件。
- 使用 Automatic Feed Links 添加 feed 链接。
- 添加声明 wp_head() 到 </head> 结束标签的前面。插件会使用这个动作钩子(action hook )来加载它们的JS、CSS 和其他功能代码。
下面是一个格式正确的HTML5兼容的头部区域的例子:
<!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)
- 在 </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’ ) )
- 显示作者的名字(如果适用)
- 显示文章分类和标签
- 为已登录的具有编辑权限的用户显示一个“编辑”链接
- 显示评论列表和评论表单
- 使用 previous_post_link() 和 next_post_link() 显示上一篇和下一篇文章
评论(comments.php)
- 作者的评论应该高亮显示,以便区分。
- 显示用户的 gravatars 头像(如果适用)
- 支持嵌套评论
- 显示 引用通告(trackbacks/pingbacks)
- 该文件不应该包含函数的定义,除非使用 function_exist() 来检查,以避免再次声明中指定的错误。理想情况下,所有的函数应该在 functions.php 文件中。
搜索结果(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() 加载你的脚本。
- Javascript的直接加载到HTML文件(模板文件)应该是CDATA编码,以防止旧版本的浏览器出现错误。
<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多站点的管理员的附加能力。
主题测试过程
- 修复PHP和WordPress错误。添加下面的调试设置到你的wp-config.php,以便看到废弃的函数调用和其他WordPress相关的错误:define(‘WP_DEBUG’, true); 。查看 Deprecated Functions Hook 了解更多。
- 对照上面提到的 模板文件清单 检查模板文件。
- 使用 Theme Unit Test 做一个运行测试。
- 验证HTML和CSS。请参阅验证一个网站。
- 检查 JavaScript 错误。
- 测试在所有目标浏览器。例如,IE7,IE8,IE9,Safari,Chrome,Opera,和 Firefox。
- 清理任何多余的意见,调试设置,或待办项目。
- 请查阅 Theme Review 如果你希望将主题公开发布到WordPress官方主题库。
资源和参考
请访问 原文 阅读这个部分的内容。
注:本文由 倡萌@WordPress大学 翻译自“ Theme Development ”,前半部分译文参考WordPress官方中文翻译。
写的不错,加油支持
多谢支持
请问我的网站404页面不能加载模板里的404页面咋办?只是nginx404
怪不得呢, 后半部分读起来感觉很不对, 原来后半部分是自己翻译的…….
现在就去试试
收藏留用
楼主,你好,我会常来看你的_________________________________________________博客的