diff --git a/docs/guide-zh-CN/README.md b/docs/guide-zh-CN/README.md
index d405671..9d2f4e7 100644
--- a/docs/guide-zh-CN/README.md
+++ b/docs/guide-zh-CN/README.md
@@ -28,7 +28,7 @@ Yii 2.0 权威指南
应用结构
--------
-* **已定稿** [结构总览](structure-overview.md)
+* **已定稿** [结构概述](structure-overview.md)
* **已定稿** [入口脚本](structure-entry-scripts.md)
* **已定稿** [应用](structure-applications.md)
* **已定稿** [应用组件](structure-application-components.md)
@@ -44,11 +44,12 @@ Yii 2.0 权威指南
请求处理
--------
-* **待定中** [引导(Bootstrapping)](runtime-bootstrapping.md)
-* **待定中** [路由(Routing)](runtime-routing.md)
-* **待定中** [请求(Request)](runtime-requests.md)
-* **待定中** [响应(Response)](runtime-responses.md)
-* **待定中** [Sessions(会话)和 Cookies](runtime-sessions-cookies.md)
+* **已定稿** [运行概述](runtime-overview.md)
+* **已定稿** [引导(Bootstrapping)](runtime-bootstrapping.md)
+* **已定稿** [路由(Routing)](runtime-routing.md)
+* **已定稿** [请求(Request)](runtime-requests.md)
+* **已定稿** [响应(Response)](runtime-responses.md)
+* **已定稿** [Sessions(会话)和 Cookies](runtime-sessions-cookies.md)
* **编撰中** [URL 解析和生成](runtime-url-handling.md)
* **编撰中** [错误处理](runtime-handling-errors.md)
* **编撰中** [日志](runtime-logging.md)
@@ -89,7 +90,7 @@ Yii 2.0 权威指南
显示数据
--------
-* **待定中** [格式化输出数据](output-formatting.md)
+* **待定中** [格式化输出数据](output-formatter.md)
* **待定中** [分页(Pagination)](output-pagination.md)
* **待定中** [排序(Sorting)](output-sorting.md)
* **编撰中** [数据提供器](output-data-providers.md)
diff --git a/docs/guide-zh-CN/intro-upgrade-from-v1.md b/docs/guide-zh-CN/intro-upgrade-from-v1.md
index 82d42ab..a2bab42 100644
--- a/docs/guide-zh-CN/intro-upgrade-from-v1.md
+++ b/docs/guide-zh-CN/intro-upgrade-from-v1.md
@@ -11,7 +11,7 @@
安装
------------
-Yii 2.0 完全拥抱 [Composer](https://getcomposer.org/),它是PHP中的一个依赖管理工具。核心框架以及扩展的安装都通过 Composer 来处理。想要了解更多如何安装 Yii 2.0 请参阅本指南的 [安装 Yii](start-installation.md) 章节。如果你想创建新扩展,或者把你已有的 Yii 1.1 的扩展改写成兼容 2.0 的版本,你可以参考 [创建扩展](extend-creating-extensions.md) 章节。
+Yii 2.0 完全拥抱 [Composer](https://getcomposer.org/),它是事实上的 PHP 依赖管理工具。核心框架以及扩展的安装都通过 Composer 来处理。想要了解更多如何安装 Yii 2.0 请参阅本指南的 [安装 Yii](start-installation.md) 章节。如果你想创建新扩展,或者把你已有的 Yii 1.1 的扩展改写成兼容 2.0 的版本,你可以参考 [创建扩展](extend-creating-extensions.md) 章节。
PHP 需求
@@ -33,17 +33,17 @@ Yii 2.0 需要 PHP 5.4 或更高版本,该版本相对于 Yii 1.1 所需求的
命名空间
---------
-Yii 2.0 里最明显的改动就数命名空间的使用了。几乎每一个核心类都引入了命名空间,比如 `yii\web\Request`。1.1 版用于类名前的字母 “C” 已经不再使用。当前的命名规范与目录结构相吻合。例如,`yii\web\Request` 就表明对应的类文件是 Yii 框架文件夹下的 `web/Request.php` 文件。
+Yii 2.0 里最明显的改动就数命名空间的使用了。几乎每一个核心类都引入了命名空间,比如 `yii\web\Request`。1.1 版类名前缀 “C” 已经不再使用。当前的命名方案与目录结构相吻合。例如,`yii\web\Request` 就表明对应的类文件是 Yii 框架文件夹下的 `web/Request.php` 文件。
-(有了 Yii 的类自动加载器,你可以直接使用全部核心类而不需要显式包含具体文件。)
+有了 Yii 的类自动加载器,你可以直接使用全部核心类而不需要显式包含具体文件。
组件(Component)与对象(Object)
--------------------
-Yii 2.0 把 1.1 里的 `CComponent` 类拆分成了两个类:[[yii\base\Object]] 和 [[yii\base\Component]]。[[yii\base\Object|Object]] 类是一个轻量级的基类,你可以通过 getters 和 setters 来定义 [object 的属性](concept-properties.md)。[[yii\base\Component|Component]] 类继承自 [[yii\base\Object|Object]],同时进一步支持 [事件](concept-events.md) 和 [行为](concept-behaviors.md)。
+Yii 2.0 把 1.1 中的 `CComponent` 类拆分成了两个类:[[yii\base\Object]] 和 [[yii\base\Component]]。[[yii\base\Object|Object]] 类是一个轻量级的基类,你可以通过 getters 和 setters 来定义[对象的属性](concept-properties.md)。[[yii\base\Component|Component]] 类继承自 [[yii\base\Object|Object]],同时进一步支持 [事件](concept-events.md) 和 [行为](concept-behaviors.md)。
-如果你不需要用到事件或行为,应该考虑使用 [[yii\base\Object|Object]] 类作为基类。这通常是表示基本数据结构的类。
+如果你不需要用到事件或行为,应该考虑使用 [[yii\base\Object|Object]] 类作为基类。这种类通常用来表示基本的数据结构。
对象的配置
@@ -65,12 +65,12 @@ class MyClass extends \yii\base\Object
{
parent::init();
- // ...配置生效后的初始化过程
+ // ... 配置生效后的初始化过程
}
}
```
-在上面的例子里,构造方法的最后一个参数必须输入一个配置数组,包含一系列用于在方法结尾初始化相关属性的键值对。你可以重写 [[yii\base\Object::init()|init()]] 方法来执行一些需要在配置生效后进行的初始化工作。
+在上面的例子里,构造方法的最后一个参数必须传入一个配置数组,包含一系列用于在方法结尾初始化相关属性的键值对。你可以重写 [[yii\base\Object::init()|init()]] 方法来执行一些需要在配置生效后进行的初始化工作。
你可以通过遵循以下约定俗成的编码习惯,来使用配置数组创建并配置新的对象:
@@ -95,11 +95,11 @@ $event = new \yii\base\Event;
$component->trigger($eventName, $event);
```
-要给事件附加一个事件句柄(Event Handler 或者叫事件处理器),需要使用 [[yii\base\Component::on()|on()]] 方法:
+要给事件附加一个事件事件处理器,需要使用 [[yii\base\Component::on()|on()]] 方法:
```php
$component->on($eventName, $handler);
-// 要解除相关句柄,使用 off 方法:
+// 解除事件处理器,使用 off 方法:
// $component->off($eventName, $handler);
```
@@ -174,7 +174,7 @@ public function actionView($id)
}
```
-请查看 [控制器(Controller)](structure-controllers.md) 章节了解有关控制器的更多细节。
+请查看[控制器(Controller)](structure-controllers.md)章节了解有关控制器的更多细节。
小部件(Widget)
@@ -283,7 +283,7 @@ Yii 2.0 很多常用的静态助手类,包括:
表单
-----
-Yii 2.0 引进了**表单栏(field)**的概念,用来创建一个基于 [[yii\widgets\ActiveForm]]的表单。一个表单栏是一个由标签、输入框、错误消息(可能还有提示文字)组成的容器,被表示为 [[yii\widgets\ActiveField|ActiveField]] 对象。使用表单栏建立表单的过程比以前更整洁利落:
+Yii 2.0 引进了**表单栏(field)**的概念,用来创建一个基于 [[yii\widgets\ActiveForm]] 的表单。一个表单栏是一个由标签、输入框、错误消息(可能还有提示文字)组成的容器,被表示为一个 [[yii\widgets\ActiveField|ActiveField]] 对象。使用表单栏建立表单的过程比以前更整洁利落:
```php
@@ -327,14 +327,14 @@ Yii 2.0 的[活动记录](db-active-record.md)改动了很多。两个最显而
1.1 中的 `CDbCriteria` 类在 Yii 2 中被 [[yii\db\ActiveQuery]] 所替代。这个类是继承自 [[yii\db\Query]],因此也继承了所有查询生成方法。开始拼装一个查询可以调用 [[yii\db\ActiveRecord::find()]] 方法进行:
```php
-// 检索所有 *活动的* 客户和订单,并以 ID 排序:
+// 检索所有“活动的”客户和订单,并以 ID 排序:
$customers = Customer::find()
->where(['status' => $active])
->orderBy('id')
->all();
```
-要声明一个关联关系,只需简单地定义一个 getter 方法来返回一个 [[yii\db\ActiveQuery|ActiveQuery]] 对象。getter 方法定义的属性名(译者注:即 getOrders() 中的 orders)表示关联关系名。如,以下代码声明了一个名为 `orders` 的关系(1.1 中必须在 `relations()` 方法内声明关系):
+要声明一个关联关系,只需简单地定义一个 getter 方法来返回一个 [[yii\db\ActiveQuery|ActiveQuery]] 对象。getter 方法定义的属性名代表关联表名称。如,以下代码声明了一个名为 `orders` 的关系(1.1 中必须在 `relations()` 方法内声明关系):
```php
class Customer extends \yii\db\ActiveRecord
@@ -360,7 +360,7 @@ $orders = $customer->getOrders()->andWhere('status=1')->all();
$customers = Customer::find()->asArray()->all();
```
-另一个改变是你不能再通过公共数据定属性(Attribute)的默认值了。如果你需要这么做的话,可以在你的记录类的 `init` 方法中设置它们。
+另一个改变是你不能再通过公共变量定义属性(Attribute)的默认值了。如果你需要这么做的话,可以在你的记录类的 `init` 方法中设置它们。
```php
public function init()
@@ -370,11 +370,41 @@ public function init()
}
```
-曾几何时,在 1.1 中重写一个活动记录类的构造方法(Constructor)会导致一些问题。它们不会在 2.0 中出现了。需要注意的是,如果你需要在构造方法中添加一些参数,恐怕必须重写 [[yii\db\ActiveRecord::instantiate()]] 方法。
+曾几何时,在 1.1 中重写一个活动记录类的构造方法会导致一些问题。它们不会在 2.0 中出现了。需要注意的是,如果你需要在构造方法中添加一些参数,恐怕必须重写 [[yii\db\ActiveRecord::instantiate()]] 方法。
活动记录方面还有很多其他的变化与改进,请参考[活动记录](db-active-record.md)章节以了解更多细节。
+活动记录行为(Active Record Behaviors)
+------------------------------------
+
+在 2.0 中遗弃了活动记录行为基类 `CActiveRecordBehavior`。如果你想创建活动记录行为,需要直接继承 `yii\base\Behavior`。如果行为类中需要表示一些事件,需要像这样覆写 `events()` 方法:
+
+```php
+namespace app\components;
+
+use yii\db\ActiveRecord;
+use yii\base\Behavior;
+
+class MyBehavior extends Behavior
+{
+ // ...
+
+ public function events()
+ {
+ return [
+ ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate',
+ ];
+ }
+
+ public function beforeValidate($event)
+ {
+ // ...
+ }
+}
+```
+
+
用户及身份验证接口(IdentityInterface)
-------------------------------------
@@ -401,4 +431,4 @@ Yii 2.0 的 URL 管理跟 1.1 中很像。一个主要的改进是现在的 URL
同时使用 Yii 1.1 和 2.x
----------------------
-如果你有一些遗留的 Yii 1.1 代码,需要跟 Yii 2.0 一起使用,可以参考 [1.1 和 2.0 共用](extend-using-v1-v2.md)章节。
+如果你有一些遗留的 Yii 1.1 代码,需要跟 Yii 2.0 一起使用,可以参考 [1.1 和 2.0 共用](tutorial-yii-integration.md)章节。
diff --git a/docs/guide-zh-CN/intro-yii.md b/docs/guide-zh-CN/intro-yii.md
index 0843e2a..db28804 100644
--- a/docs/guide-zh-CN/intro-yii.md
+++ b/docs/guide-zh-CN/intro-yii.md
@@ -1,30 +1,32 @@
Yii 是什么
===========
-Yii 是一个高性能,基于组件的 PHP 框架,用于快速开发现代 Web 应用程序。名字 Yii (读作 `易`)在中文里有 “极致简单与不断演变” 两重含义,也可看作 **Yes It Is**! 的缩写。
+Yii 是一个高性能,基于组件的 PHP 框架,用于快速开发现代 Web 应用程序。名字 Yii (读作 `易`)在中文里有“极致简单与不断演变”两重含义,也可看作 **Yes It Is**! 的缩写。
Yii 最适合做什么?
---------------------
-Yii 是一个通用的 Web 编程框架,即可以用于开发各种基于 PHP 的 Web 应用。因为基于组件的框架结构和设计精巧的缓存支持,Yii 特别适合开发大型应用,如门户网站、论坛、内容管理系统(CMS)、电子商务项目和 RESTful Web 服务等。
+Yii 是一个通用的 Web 编程框架,即可以用于开发各种基于 PHP 的 Web 应用。因为基于组件的框架结构和设计精巧的缓存支持,它特别适合开发大型应用,如门户网站、社区、内容管理系统(CMS)、电子商务项目和 RESTful Web 服务等。
Yii 和其他框架相比呢?
-------------------------------------------
+如果你有其它框架使用经验,那么你会很开心看到 Yii 所做的努力:
+
- 和其他 PHP 框架类似,Yii 实现了 MVC(Model-View-Controller)设计模式并基于该模式组织代码。
-- Yii 的代码简洁优雅,这是 Yii 的编程哲学。它永远不会为了要迎合某个设计模式而对代码进行过度的设计。
-- Yii 是一个全栈框架,提供了大量久经考验,开箱即用的特性,例如:对关系型和 NoSQL 数据库都提供了查询生成器(QueryBuilders)和 ActiveRecord;RESTful API 的开发支持;多层缓存支持,等等。
+- Yii 的代码简洁优雅,这是它的编程哲学。它永远不会为了严格遵照某种设计模式而对代码进行过度的设计。
+- Yii 是一个全栈框架,提供了大量久经考验,开箱即用的特性:对关系型和 NoSQL 数据库都提供了查询生成器和 ActiveRecord;RESTful API 的开发支持;多层缓存支持,等等。
- Yii 非常易于扩展。你可以自定义或替换几乎任何一处核心代码。你还会受益于它坚实可靠的扩展架构,使用、再开发或再发布扩展。
- 高性能始终是 Yii 的首要目标之一。
-Yii 不是一场独角戏,它由一个[强大的开发者团队](http://www.yiiframework.com/about/)提供支持,也有一个庞大的专家社区,持续不断地对 Yii 的开发作出贡献。Yii 开发者团队始终对 Web 开发最新潮流和其他框架及项目中的最佳实践和特性保持密切关注,那些有意义的最佳实践及特性会被不定期的整合进核心框架中,并提供简单优雅的接口。
+Yii 不是一场独角戏,它由一个[强大的开发者团队](http://www.yiiframework.com/about/)提供支持,也有一个庞大的专家社区,持续不断地对 Yii 的开发作出贡献。Yii 开发者团队始终对 Web 开发趋势和其他框架及项目中的最佳实践和特性保持密切关注,那些有意义的最佳实践及特性会被不定期的整合进核心框架中,并提供简单优雅的接口。
Yii 版本
------------
-Yii 当前有两个主要版本:1.1 和 2.0。 1.1 版是上代的老版本,现在处于维护状态。2.0 版是一个完全重写的版本,采用了最新的技术和协议,包括依赖包管理器(Composer)、PHP 代码规范(PSR)、命名空间、Traits(特质)等等。 2.0 版代表了最新一代框架,是未来几年中我们的主要开发版本。本指南主要基于 2.0 版编写。
+Yii 当前有两个主要版本:1.1 和 2.0。 1.1 版是上代的老版本,现在处于维护状态。2.0 版是一个完全重写的版本,采用了最新的技术和协议,包括依赖包管理器 Composer、PHP 代码规范 PSR、命名空间、Traits(特质)等等。 2.0 版代表新一代框架,是未来几年中我们的主要开发版本。本指南主要基于 2.0 版编写。
系统要求和先决条件
@@ -32,5 +34,5 @@ Yii 当前有两个主要版本:1.1 和 2.0。 1.1 版是上代的老版本,
Yii 2.0 需要 PHP 5.4.0 或以上版本支持。你可以通过运行任何 Yii 发行包中附带的系统要求检查器查看每个具体特性所需的 PHP 配置。
-使用 Yii 需要对面向对象编程(OOP)有基本了解,因为 Yii 是一个纯面向对象的框架。Yii 2.0 还使用了 PHP 的最新特性,例如 [命名空间](http://www.php.net/manual/en/language.namespaces.php) 和 [Trait(特质)](http://www.php.net/manual/en/language.oop5.traits.php)。理解这些概念将有助于你更快地掌握 Yii 2.0。
+使用 Yii 需要对面向对象编程(OOP)有基本了解,因为 Yii 是一个纯面向对象的框架。Yii 2.0 还使用了 PHP 的最新特性,例如[命名空间](http://www.php.net/manual/en/language.namespaces.php)和[Trait(特质)](http://www.php.net/manual/en/language.oop5.traits.php)。理解这些概念将有助于你更快地掌握 Yii 2.0。
diff --git a/docs/guide-zh-CN/start-databases.md b/docs/guide-zh-CN/start-databases.md
index 178de25..113c922 100644
--- a/docs/guide-zh-CN/start-databases.md
+++ b/docs/guide-zh-CN/start-databases.md
@@ -1,7 +1,7 @@
使用数据库
======================
-本章节将介绍如何如何创建一个从数据表 `country` 中获取国家数据并显示出来的页面。为了实现这个目标,你将会配置一个数据库连接,创建一个[活动记录](db-active-record.md)类,并且创建一个[操作](structure-controllers.md)及一个[视图](structure-views.md)。
+本章节将介绍如何如何创建一个从数据表 `country` 中读取国家数据并显示出来的页面。为了实现这个目标,你将会配置一个数据库连接,创建一个[活动记录](db-active-record.md)类,并且创建一个[操作](structure-controllers.md)及一个[视图](structure-views.md)。
贯穿整个章节,你将会学到:
@@ -16,7 +16,7 @@
准备数据库
--------------------
-首先创建一个名为 `yii2basic` 的数据库,应用将从这个数据库中获取数据。你可以创建 SQLite,MySQL,PostregSQL,MSSQL 或 Oracle 数据库,Yii 内置多种数据库支持。简单起见后面的内容将以 MySQL 为例做演示。
+首先创建一个名为 `yii2basic` 的数据库,应用将从这个数据库中读取数据。你可以创建 SQLite,MySQL,PostregSQL,MSSQL 或 Oracle 数据库,Yii 内置多种数据库支持。简单起见,后面的内容将以 MySQL 为例做演示。
然后在数据库中创建一个名为 `country` 的表并插入简单的数据。可以执行下面的语句:
@@ -39,7 +39,7 @@ INSERT INTO `country` VALUES ('RU','Russia',146934000);
INSERT INTO `country` VALUES ('US','United States',278357000);
```
-于是便有了一个名为 `yii2basic` 的数据库,在这个数据库中有一个包含三个字段的数据表 `country`,表中有十行数据。
+此时便有了一个名为 `yii2basic` 的数据库,在这个数据库中有一个包含三个字段的数据表 `country`,表中有十行数据。
配置数据库连接
---------------------------
@@ -62,7 +62,7 @@ return [
`config/db/php` 是一个典型的基于文件的[配置](concept-configurations.md)工具。这个文件配置了数据库连接 [[yii\db\Connection]] 的创建和初始化参数,应用的 SQL 查询正是基于这个数据库。
-上面配置的数据库连接可以在应用中通过 `Yii::$app->db` 访问。
+上面配置的数据库连接可以在应用中通过 `Yii::$app->db` 表达式访问。
> 补充:`config/db.php` 将被包含在应用配置文件 `config/web.php` 中,后者指定了整个[应用](structure-applications.md)如何初始化。请参考[配置](concept-configurations.md)章节了解更多信息。
@@ -70,7 +70,7 @@ return [
创建活动记录
-------------------------
-创建一个继承自[活动记录](db-active-record.md)类的类 `Country`,把它放在 `models/Country.php`,去表示和获取 `country` 表的数据。
+创建一个继承自[活动记录](db-active-record.md)类的类 `Country`,把它放在 `models/Country.php` 文件,去代表和读取 `country` 表的数据。
```php
补充:如果类名和数据表名不能直接对应,可以重写 [[yii\db\ActiveRecord::tableName()|tableName()]] 方法去显式指定相关表名。
+> 补充:如果类名和数据表名不能直接对应,可以覆写 [[yii\db\ActiveRecord::tableName()|tableName()]] 方法去显式指定相关表名。
使用 `Country` 类可以很容易地操作 `country` 表数据,就像这段代码:
@@ -107,7 +107,7 @@ $country->name = 'U.S.A.';
$country->save();
```
-> 补充:活动记录是面向对象、功能强大的访问和操作数据库数据的方式。你可以在[活动记录](db-active-record.md)章节了解更多信息。除此之外你还可以使用另一种更原生的称做[数据访问对象](db-dao)的方法操作数据库数据。
+> 补充:活动记录是面向对象、功能强大的访问和操作数据库数据的方式。你可以在[活动记录](db-active-record.md)章节了解更多信息。除此之外你还可以使用另一种更原生的被称做[数据访问对象](db-dao)的方法操作数据库数据。
创建操作
@@ -148,7 +148,7 @@ class CountryController extends Controller
}
```
-把上面的代码保存在 `controllers/CountryController.php`。
+把上面的代码保存在 `controllers/CountryController.php` 文件中。
`index` 操作调用了活动记录 `Country::find()` 方法,去生成查询语句并从 `country` 表中取回所有数据。为了限定每个请求所返回的国家数量,查询在 [[yii\data\Pagination]] 对象的帮助下进行分页。 `Pagination` 对象的使命主要有两点:
@@ -184,7 +184,7 @@ use yii\widgets\LinkPager;
这个视图包含两部分用以显示国家数据。第一部分遍历国家数据并以无序 HTML 列表渲染出来。第二部分使用 [[yii\widgets\LinkPager]] 去渲染从操作中传来的分页信息。小部件 `LinkPager` 显示一个分页按钮的列表。点击任何一个按钮都会跳转到对应的分页。
-尝试下
+试运行
-------------
浏览器访问下面的 URL 看看能否工作:
diff --git a/docs/guide-zh-CN/start-forms.md b/docs/guide-zh-CN/start-forms.md
index f633e51..f87666c 100644
--- a/docs/guide-zh-CN/start-forms.md
+++ b/docs/guide-zh-CN/start-forms.md
@@ -1,7 +1,7 @@
使用表单
==================
-本章节将介绍如何创建一个从用户那搜集数据的表单页。该页将显示一个包含 name 输入框和 email 输入框的表单。当搜集完这两部分信息后,页面将会显示用户输入的信息。
+本章将介绍如何创建一个从用户那搜集数据的表单页。该页将显示一个包含 name 输入框和 email 输入框的表单。当搜集完这两部分信息后,页面将会显示用户输入的信息。
为了实现这个目标,除了创建一个[操作](structure-controllers.md)和两个[视图](structure-views)外,还需要创建一个[模型](structure-models.md)。
@@ -39,11 +39,11 @@ class EntryForm extends Model
}
```
-该类继承自 [[yii\base\Model]],Yii 提供的一个基类,通常用来表示数据。
+该类继承自 [[yii\base\Model]],Yii 提供的一个基类,通常用来代表表单数据。
-> 补充:[[yii\base\Model]] 被用于普通模型类的父类并与数据表**无关**。[[yii\db\ActiveRecord]] 通常是普通模型类的父类但与数据表有关联(译者注:[[yii\db\ActiveRecord]] 类其实也是继承自 [[yii\base\Model]],增加了数据库处理)。
+> 补充:[[yii\base\Model]] 被用于普通模型类的父类并与数据表**无关**。[[yii\db\ActiveRecord]] 通常是普通模型类的父类但与数据表有关联。
-`EntryForm` 类包含 `name` 和 `email` 两个公共成员,用来储存用户输入的数据。它还包含一个名为 `rules()` 的方法,用来返回数据验证规则的集合。上面声明的验证规则表示:
+`EntryForm` 类包含 `name` 和 `email` 两个公共变量,用来储存用户输入的数据。它还包含一个名为 `rules()` 的方法,用来返回数据验证规则的集合。上面声明的验证规则表示:
* `name` 和 `email` 值都是必须的
* `mail` 的值必须满足 email 地址验证
@@ -67,7 +67,7 @@ if ($model->validate()) {
创建操作
------------------
-下面你得在 `site` 控制器中创建一个 `entry` 操作用于新建的模型。操作的创建和使用已经在[说一声你好](start-hello.md)小节中解释了。
+接下来你需要在 `site` 控制器中创建一个 `entry` 操作用于新建的模型。操作的创建和使用已经在[说一声你好](start-hello.md)小节中解释了。
```php
补充:表达式 `Yii::$app` 代表[应用](structure-applications.md)实例,它是一个全局可访问的单例。同时它也是一个[服务定位器](concept-service-locator.md),能提供 `request`,`response`,`db` 等等特定功能的组件。在上面的代码里就是使用 `request` 组件来访问应用实例收到的 `$_POST` 数据。
-用户提交表单后,操作将会渲染一个名为 `entry-confirm` 的视图去确认用户输入的数据。如果没填表单就提交,或数据包含错误(译者:如 email 格式不对),`entry` 视图将会渲染输出,连同表单一起输出的还有验证错误的详细信息。
+用户提交表单后,操作将会渲染一个名为 `entry-confirm` 的视图去确认用户输入的数据。如果没填表单就提交,或数据包含错误,`entry` 视图将会渲染输出,连同表单一起输出的还有验证错误的详细信息。
> 注意:在这个简单例子里我们只是呈现了有效数据的确认页面。实践中你应该考虑使用 [[yii\web\Controller::refresh()|refresh()]] 或 [[yii\web\Controller::redirect()|redirect()]] 去避免[表单重复提交问题](http://en.wikipedia.org/wiki/Post/Redirect/Get)。
@@ -148,10 +148,10 @@ use yii\widgets\ActiveForm;
```
-视图使用了一个功能强大的[小部件](structure-widgets.md) [[yii\widgets\ActiveForm|ActiveForm]] 去生成 HTML 表单。其中的 `begin()` 和 `end()` 分别用来渲染表单的开始和关闭标签。在这两个方法之间使用了 [[yii\widgets\ActiveForm::field()|field()]] 方法去创建输入框。第一个输入框用于 “name”,第二个输入框用于 “email”。之后使用 [[yii\helpers\Html::submitButton()]] 方法生成提交按钮。
+视图使用了一个功能强大的[小部件](structure-widgets.md) [[yii\widgets\ActiveForm|ActiveForm]] 去生成 HTML 表单。其中的 `begin()` 和 `end()` 分别用来渲染表单的开始和关闭标签。在这两个方法之间使用了 [[yii\widgets\ActiveForm::field()|field()]] 方法去创建表单栏。第一个表单栏用于 “name”,第二个表单栏用于 “email”。之后使用 [[yii\helpers\Html::submitButton()]] 方法生成提交按钮。
-尝试下
+试运行
-------------
用浏览器访问下面的 URL 看它能否工作:
@@ -160,7 +160,7 @@ use yii\widgets\ActiveForm;
http://hostname/index.php?r=site/entry
```
-你会看到一个包含两个输入框的表单的页面。每个输入框的前面都有一个标签指明应该输入的数据类型。如果什么都不填就点击提交按钮,或填入格式不正确的 email 地址,将会看到在对应的输入框下显示错误信息。
+你会看到一个包含两个表单栏的页面。每个表单栏的前面都有一个标签指明应该输入的数据类型。如果什么都不填就点击提交按钮,或填入格式不正确的 email 地址,将会看到在对应的表单栏下显示错误信息。
![验证错误的表单](images/start-form-validation.png)
@@ -172,13 +172,13 @@ http://hostname/index.php?r=site/entry
### 效果说明
-你可能会好奇 HTML 表单暗地里是如何工作的呢,看起来它可以为每个输入框显示文字标签,而当你没输入正确的信息时又不需要刷新页面就能给出错误提示,似乎有些神奇。
+你可能会好奇 HTML 表单暗地里是如何工作的,看起来它可以为每个表单栏显示文字标签,而当你没输入正确的信息时又不需要刷新页面就能给出错误提示,似乎有些神奇。
是的,其实数据首先由客户端 JavaScript 脚本验证,然后才会提交给服务器通过 PHP 验证。[[yii\widgets\ActiveForm]] 足够智能到把你在 `EntryForm` 模型中声明的验证规则转化成客户端 JavaScript 脚本去执行验证。如果用户浏览器禁用了 JavaScript, 服务器端仍然会像 `actionEntry()` 方法里这样验证一遍数据。这保证了任何情况下用户提交的数据都是有效的。
-> 警告:客户端验证是提高用户体验的手段。无论它是否正常启用,服务端验证则都是必须的,请不要忽略它。
+> 警告:客户端验证只是提高用户体验的手段。无论它是否正常启用,服务端验证则都是必须的,请不要忽略它。
-输入框的文字标签是 `field()` 方法生成的,内容就是模型中该数据的属性名。例如模型中的 `name` 属性生成的标签就是 `Name`。
+表单栏的文字标签是 `field()` 方法生成的,内容就是模型中该数据的属性名。例如模型中的 `name` 属性生成的标签就是 `Name`。
你可以在视图中自定义标签:
@@ -193,7 +193,7 @@ http://hostname/index.php?r=site/entry
总结
-------
-本章节指南中你接触了 MVC 设计模式的每个部分。学到了如何创建一个模型代表用户数据并验证它的有效性。
+本章指南中你接触了 MVC 设计模式的每个部分。学到了如何创建一个模型代表用户数据并验证它的有效性。
你还学到了如何从用户那获取数据并在浏览器上回显给用户。这本来是开发应用的过程中比较耗时的任务,好在 Yii 提供了强大的小部件让它变得如此简单。
diff --git a/docs/guide-zh-CN/start-gii.md b/docs/guide-zh-CN/start-gii.md
index 9be3c7d..fb2397e 100644
--- a/docs/guide-zh-CN/start-gii.md
+++ b/docs/guide-zh-CN/start-gii.md
@@ -1,7 +1,7 @@
使用 Gii 生成代码
========================
-本章节将介绍如何使用 [Gii](tool-gii.md) 去自动生成 Web 站点常用功能的代码。使用 Gii 生成代码非常简单,只要按照 Gii 页面上的介绍输入正确的信息即可。
+本章将介绍如何使用 [Gii](tool-gii.md) 去自动生成 Web 站点常用功能的代码。使用 Gii 生成代码非常简单,只要按照 Gii 页面上的介绍输入正确的信息即可。
贯穿本章节,你将会学到:
@@ -25,7 +25,7 @@ if (YII_ENV_DEV) {
}
```
-这段配置的意思是如果当前是[开发环境](concept-configurations.md#environment-constants),应用会包含 `gii` 模块,模块类是 [[yii\gii\Module]]。
+这段配置表明,如果当前是[开发环境](concept-configurations.md#environment-constants),应用会包含 `gii` 模块,模块类是 [[yii\gii\Module]]。
如果你检查应用的[入口脚本](structure-entry-scripts.md) `web/index.php`,将看到这行代码将 `YII_ENV_DEV` 设为 true:
@@ -33,16 +33,18 @@ if (YII_ENV_DEV) {
defined('YII_ENV') or define('YII_ENV', 'dev');
```
-代码设置应用处于开发模式下,按照上面的配置会打开 Gii 模块。你可以直接通过 URL 访问 Gii:
+鉴于这行代码的定义,应用处于开发模式下,按照上面的配置会打开 Gii 模块。你可以直接通过 URL 访问 Gii:
```
http://hostname/index.php?r=gii
```
-> 提示:如果不是通过localhost而是通过IP地址访问Gii,出于安全考虑系统默认禁止,按照如下在配置文件的gii部分添加允许IP地址访问。
+
+> 补充: 如果你通过本机以外的机器访问 Gii,请求会被出于安全原因拒绝。你可以配置 Gii 为其添加允许访问的 IP 地址:
+>
```php
'gii' => [
'class' => 'yii\gii\Module',
- 'allowedIPs' => ['127.0.0.1', '::1', '192.168.0.*', '192.168.178.20'] // 根据你自己的需要调整
+ 'allowedIPs' => ['127.0.0.1', '::1', '192.168.0.*', '192.168.178.20'] // 按需调整这里
],
```
@@ -61,7 +63,7 @@ http://hostname/index.php?r=gii
然后点击 “Preview” 按钮。你会看到 `models/Country.php` 被列在将要生成的文件列表中。可以点击文件名预览内容。
-如果你已经创建过同样的文件,使用 Gii 可以覆写它,点击文件名旁边的 `diff` 能查看现有文件与将要生成的文件的内容区别。
+如果你已经创建过同样的文件,使用 Gii 会覆写它,点击文件名旁边的 `diff` 能查看现有文件与将要生成的文件的内容区别。
![模型生成器预览](images/start-gii-model-preview.png)
@@ -73,7 +75,7 @@ http://hostname/index.php?r=gii
生成 CRUD 代码
--------------------
-CRUD 代表增,查,改,删操作,这是绝大多数 Web 站点常用的数据处理方式。选择 Gii 中的 “CRUD Generator” (点击 Gii 首页的链接)去创建 CRUD 功能。之前的 “country” 例子需要像这样填写表单:
+CRUD 代表增,查,改,删操作,这是绝大多数 Web 站点常用的数据处理方式。选择 Gii 中的 “CRUD Generator” (点击 Gii 首页的链接)去创建 CRUD 功能。本例 “country” 中需要这样填写表单:
* Model Class: `app\models\Country`
* Search Model Class: `app\models\CountrySearch`
@@ -83,12 +85,12 @@ CRUD 代表增,查,改,删操作,这是绝大多数 Web 站点常用的
然后点击 “Preview” 按钮。你会看到下述将要生成的文件列表。
-![CRUD 生成器预览](images/start-gii-crud-preview.png)
+[[NEED THE IMAGE HERE / 等待官方补充图片]]
-如果你之前创建过 `controllers/CountryController.php` 和 `views/country/index.php` 文件(在指南的使用数据库小节),选中 “overwrite” 下的复选框覆写它们(之前的文件没能全部支持 CRUD)。
+如果你之前创建过 `controllers/CountryController.php` 和 `views/country/index.php` 文件(在指南的使用数据库章节),选中 “overwrite” 下的复选框覆写它们(之前的文件没能全部支持 CRUD)。
-尝试下
+试运行
-------------
用浏览器访问下面的 URL 查看生成代码的运行:
@@ -97,7 +99,7 @@ CRUD 代表增,查,改,删操作,这是绝大多数 Web 站点常用的
http://hostname/index.php?r=country/index
```
-可以看到一个栅格显示着从数据表中获取的国家数据。支持在列头对数据进行排序,输入筛选条件进行筛选。
+可以看到一个栅格显示着从数据表中读取的国家数据。支持在列头对数据进行排序,输入筛选条件进行筛选。
可以浏览详情,编辑,或删除栅格中的每个国家。还可以点击栅格上方的 “Create Country” 按钮通过表单创建新国家。
@@ -111,7 +113,7 @@ http://hostname/index.php?r=country/index
* 模型:`models/Country.php` 和 `models/CountrySearch.php`
* 视图:`views/country/*.php`
-> 补充:Gii 被设计成高度可定制和可扩展的代码生成工具。使用它可以大幅提高应用开发速度。请参考 [Gii](tool-gii.md) 小节了解更多内容。
+> 补充:Gii 被设计成高度可定制和可扩展的代码生成工具。使用它可以大幅提高应用开发速度。请参考 [Gii](tool-gii.md) 章节了解更多内容。
总结
diff --git a/docs/guide-zh-CN/start-hello.md b/docs/guide-zh-CN/start-hello.md
index 6fc664a..59c2519 100644
--- a/docs/guide-zh-CN/start-hello.md
+++ b/docs/guide-zh-CN/start-hello.md
@@ -1,7 +1,7 @@
说声 Hello
============
-本章节描述了如何在你的应用中创建一个新的 “Hello” 页面。为了做到这点,将会创建一个[操作](structure-controllers.md#creating-actions)和一个[视图](structure-views.md):
+本章描述了如何在你的应用中创建一个新的 “Hello” 页面。为了实现这一目标,将会创建一个[操作](structure-controllers.md#creating-actions)和一个[视图](structure-views.md):
* 应用将会分派页面请求给操作
* 操作将会依次渲染视图呈现 “Hello” 给最终用户
@@ -16,7 +16,7 @@
创建操作
------------------
-为了说 “Hello”,需要创建一个 `say` [操作](structure-controllers.md#creating-actions),从请求中接收 `message` 参数并显示给最终用户。如果请求没有提供 `message` 参数,操作将显示默认参数 “Hello”。
+为了 “Hello”,需要创建一个 `say` [操作](structure-controllers.md#creating-actions),从请求中接收 `message` 参数并显示给最终用户。如果请求没有提供 `message` 参数,操作将显示默认参数 “Hello”。
> 补充:[操作](structure-controllers.md#creating-actions)是最终用户可以直接访问并执行的对象。操作被组织在[控制器](structure-controllers.md)中。一个操作的执行结果就是最终用户收到的响应内容。
@@ -33,7 +33,7 @@ class SiteController extends Controller
{
// ...其它代码...
- public function actionSay($message = '你好')
+ public function actionSay($message = 'Hello')
{
return $this->render('say', ['message' => $message]);
}
@@ -68,7 +68,7 @@ use yii\helpers\Html;
当然了,你大概会在 `say` 视图里放入更多内容。内容可以由 HTML 标签,纯文本,甚至 PHP 语句组成。实际上 `say` 视图就是一个由 [[yii\web\Controller::render()|render()]] 执行的 PHP 脚本。视图脚本输出的内容将会作为响应结果返回给应用。应用将依次输出结果给最终用户。
-尝试下
+试运行
-------------
创建完操作和视图后,你就可以通过下面的 URL 访问新页面了:
diff --git a/docs/guide-zh-CN/start-installation.md b/docs/guide-zh-CN/start-installation.md
index b007e43..395e22a 100644
--- a/docs/guide-zh-CN/start-installation.md
+++ b/docs/guide-zh-CN/start-installation.md
@@ -90,9 +90,9 @@ http://localhost/basic/web/index.php
>补充:如果你现在只是要试用 Yii 而不是将其部署到生产环境中,本小节可以跳过。
-通过上述方法安装的应用程序在 Windows,Max OS X,Linux 中的 [Apache HTTP 服务器](http://httpd.apache.org/)或 [Nginx HTTP 服务器](http://nginx.org/) 且PHP版本为5.4或更高都可以直接运行。Yii 2.0 也兼容 Facebook 公司的 [HHVM](http://hhvm.com/),由于 HHVM 和标准 PHP 在边界案例上有些地方略有不同,在使用 HHVM 时需稍作处理。
+通过上述方法安装的应用程序在 Windows,Max OS X,Linux 中的 [Apache HTTP 服务器](http://httpd.apache.org/)或 [Nginx HTTP 服务器](http://nginx.org/)且PHP版本为5.4或更高都可以直接运行。Yii 2.0 也兼容 Facebook 公司的 [HHVM](http://hhvm.com/),由于 HHVM 和标准 PHP 在边界案例上有些地方略有不同,在使用 HHVM 时需稍作处理。
-在生产环境的服务器上,你可能会想配置服务器让应用程序可以通过 URL `http://www.example.com/index.php` 访问而不是 `http://www.example.com/basic/web/index.php`。这种配置需要将 Web 服务器的文档根目录指向 `basic/web` 目录。可能你还会想隐藏掉 URL 中的 `index.php`,具体细节在 [URL 解析和生成](runtime-url-handling.md) 一章中有介绍,你将学到如何配置 Apache 或 Nginx 服务器实现这些目标。
+在生产环境的服务器上,你可能会想配置服务器让应用程序可以通过 URL `http://www.example.com/index.php` 访问而不是 `http://www.example.com/basic/web/index.php`。这种配置需要将 Web 服务器的文档根目录指向 `basic/web` 目录。可能你还会想隐藏掉 URL 中的 `index.php`,具体细节在 [URL 解析和生成](runtime-url-handling.md)一章中有介绍,你将学到如何配置 Apache 或 Nginx 服务器实现这些目标。
>补充:将 `basic/web` 设置为文档根目录,可以防止终端用户访问 `basic/web` 相邻目录中的私有应用代码和敏感数据文件。禁止对其他目录的访问是一个不错的安全改进。
@@ -141,7 +141,7 @@ server {
error_log /path/to/basic/log/error.log;
location / {
- # 如果找不到真实存在的文件,把请求重定向给 index.php
+ # 如果找不到真实存在的文件,把请求分发至 index.php
try_files $uri $uri/ /index.php?$args;
}
diff --git a/docs/guide-zh-CN/start-looking-ahead.md b/docs/guide-zh-CN/start-looking-ahead.md
index 6109fb4..03bad82 100644
--- a/docs/guide-zh-CN/start-looking-ahead.md
+++ b/docs/guide-zh-CN/start-looking-ahead.md
@@ -1,20 +1,16 @@
更上一层楼
=============
-通篇阅读完整个“入门”板块,你就完成了一个完整 Yii 应用的创建。在此过程中你学到了如何实现一些常用功能,例如通过 HTML 表单从用户那获取数据,从数据库中获取数据并以分页形式显示。你还学到了如何通过 [Gii](tool-gii.md) 去自动生成代码。使用 Gii 生成代码把 Web 开发中多数繁杂的过程转化为仅仅填写几个表单就行。
+通篇阅读完整个“入门”部分,你就完成了一个完整 Yii 应用的创建。在此过程中你学到了如何实现一些常用功能,例如通过 HTML 表单从用户那获取数据,从数据库中获取数据并以分页形式显示。你还学到了如何通过 [Gii](tool-gii.md) 去自动生成代码。使用 Gii 生成代码把 Web 开发中多数繁杂的过程转化为仅仅填写几个表单就行。
-本章节将介绍一些有助于更好使用 Yii 的资源:
+本章将介绍一些有助于更好使用 Yii 的资源:
* 文档
- - 权威指南:
- 顾名思义,指南详细描述了 Yii 的工作原理并提供了如何使用它的常规引导。这是最重要的 Yii 辅助资料,强烈建议在开始写 Yii 代码之前阅读。
- - 类参考手册:
- 描述了 Yii 中每个类的用法。在编码过程中这极为有用,能够帮你理清某个特定类,方法,和属性的用法。类参考手册最好在整个框架的语境下去理解。
- - Wiki 文章:
- Wiki 文章是 Yii 用户在其自身经验基础上分享出来的。大多数是使用教程或如何使用 Yii 解决特定问题。虽然这些文章质量可能并不如权威指南,但它们往往覆盖了更广泛的话题,并常常提供解决方案,所以它们也很有用。
+ - 权威指南:顾名思义,指南详细描述了 Yii 的工作原理并提供了如何使用它的常规引导。这是最重要的 Yii 辅助资料,强烈建议在开始写 Yii 代码之前阅读。
+ - 类参考手册:描述了 Yii 中每个类的用法。在编码过程中这极为有用,能够帮你理清某个特定类,方法,和属性的用法。类参考手册最好在整个框架的语境下去理解。
+ - Wiki 文章:Wiki 文章是 Yii 用户在其自身经验基础上分享出来的。大多数是使用教程或如何使用 Yii 解决特定问题。虽然这些文章质量可能并不如权威指南,但它们往往覆盖了更广泛的话题,并常常提供解决方案,所以它们也很有用。
- 书籍
-* [扩展](http://www.yiiframework.com/extensions/):
- Yii 拥有数以千计用户提供的扩展,这些扩展能非常方便的插入到应用中,使你的应用开发过程更加方便快捷。
+* [扩展](http://www.yiiframework.com/extensions/):Yii 拥有数以千计用户提供的扩展,这些扩展能非常方便的插入到应用中,使你的应用开发过程更加方便快捷。
* 社区
- [官方论坛](http://www.yiiframework.com/forum/)
- [GitHub](https://github.com/yiisoft/yii2)
diff --git a/docs/guide-zh-CN/structure-application-components.md b/docs/guide-zh-CN/structure-application-components.md
new file mode 100644
index 0000000..e5142fa
--- /dev/null
+++ b/docs/guide-zh-CN/structure-application-components.md
@@ -0,0 +1,101 @@
+应用组件
+======================
+
+应用主体是[服务定位器](concept-service-locator.md),它部署一组提供各种不同功能的 *应用组件* 来处理请求。
+例如,`urlManager`组件负责处理网页请求路由到对应的控制器。`db`组件提供数据库相关服务等等。
+
+在同一个应用中,每个应用组件都有一个独一无二的 ID 用来区分其他应用组件,你可以通过如下表达式访问应用组件。
+
+```php
+\Yii::$app->componentID
+```
+
+例如,可以使用 `\Yii::$app->db` 来获取到已注册到应用的 [[yii\db\Connection|DB connection]],
+使用 `\Yii::$app->cache` 来获取到已注册到应用的 [[yii\caching\Cache|primary cache]]。
+
+第一次使用以上表达式时候会创建应用组件实例,后续再访问会返回此实例,无需再次创建。
+
+应用组件可以是任意对象,可以在 [应用主体配置](structure-applications.md#application-configurations)配置 [[yii\base\Application::components]] 属性 .
+例如:
+
+```php
+[
+ 'components' => [
+ // 使用类名注册 "cache" 组件
+ 'cache' => 'yii\caching\ApcCache',
+
+ // 使用配置数组注册 "db" 组件
+ 'db' => [
+ 'class' => 'yii\db\Connection',
+ 'dsn' => 'mysql:host=localhost;dbname=demo',
+ 'username' => 'root',
+ 'password' => '',
+ ],
+
+ // 使用函数注册"search" 组件
+ 'search' => function () {
+ return new app\components\SolrService;
+ },
+ ],
+]
+```
+
+> 补充:请谨慎注册太多应用组件,应用组件就像全局变量,使用太多可能加大测试和维护的难度。
+ 一般情况下可以在需要时再创建本地组件。
+
+
+## 引导启动组件
+
+上面提到一个应用组件只会在第一次访问时实例化,如果处理请求过程没有访问的话就不实例化。
+有时你想在每个请求处理过程都实例化某个组件即便它不会被访问,
+可以将该组件ID加入到应用主体的 [[yii\base\Application::bootstrap|bootstrap]] 属性中。
+
+例如, 如下的应用主体配置保证了 `log` 组件一直被加载。
+
+```php
+[
+ 'bootstrap' => [
+ // 将 log 组件 ID 加入引导让它始终载入
+ 'log',
+ ],
+ 'components' => [
+ 'log' => [
+ // "log" 组件的配置
+ ],
+ ],
+]
+```
+
+
+## 核心应用组件
+
+Yii 定义了一组固定ID和默认配置的 *核心* 组件,例如 [[yii\web\Application::request|request]] 组件
+用来收集用户请求并解析 [路由](runtime-routing.md);
+[[yii\base\Application::db|db]] 代表一个可以执行数据库操作的数据库连接。
+通过这些组件,Yii应用主体能处理用户请求。
+
+下面是预定义的核心应用组件列表,可以和普通应用组件一样配置和自定义它们。
+当你配置一个核心组件,不指定它的类名的话就会使用Yii默认指定的类。
+
+* [[yii\web\AssetManager|assetManager]]: 管理资源包和资源发布,详情请参考 [管理资源](output-assets.md) 一节。
+* [[yii\db\Connection|db]]: 代表一个可以执行数据库操作的数据库连接,
+ 注意配置该组件时必须指定组件类名和其他相关组件属性,如[[yii\db\Connection::dsn]]。
+ 详情请参考 [数据访问对象](db-dao.md) 一节。
+* [[yii\base\Application::errorHandler|errorHandler]]: 处理 PHP 错误和异常,
+ 详情请参考 [错误处理](tutorial-handling-errors.md) 一节。
+* [[yii\i18n\Formatter|formatter]]: 格式化输出显示给终端用户的数据,例如数字可能要带分隔符,
+ 日期使用长格式。详情请参考 [格式化输出数据](output-formatting.md) 一节。
+* [[yii\i18n\I18N|i18n]]: 支持信息翻译和格式化。详情请参考 [国际化](tutorial-i18n.md) 一节。
+* [[yii\log\Dispatcher|log]]: 管理日志对象。详情请参考 [日志](tutorial-logging.md) 一节。
+* [[yii\swiftmailer\Mailer|mail]]: 支持生成邮件结构并发送,详情请参考 [邮件](tutorial-mailing.md) 一节。
+* [[yii\base\Application::response|response]]: 代表发送给用户的响应,
+ 详情请参考 [响应](runtime-responses.md) 一节。
+* [[yii\base\Application::request|request]]: 代表从终端用户处接收到的请求,
+ 详情请参考 [请求](runtime-requests.md) 一节。
+* [[yii\web\Session|session]]: 代表会话信息,仅在[[yii\web\Application|Web applications]] 网页应用中可用,
+ 详情请参考 [Sessions (会话) and Cookies](runtime-sessions-cookies.md) 一节。
+* [[yii\web\UrlManager|urlManager]]: 支持URL地址解析和创建,
+ 详情请参考 [URL 解析和生成](runtime-url-handling.md) 一节。
+* [[yii\web\User|user]]: 代表认证登录用户信息,仅在[[yii\web\Application|Web applications]] 网页应用中可用,
+ 详情请参考 [认证](security-authentication.md) 一节。
+* [[yii\web\View|view]]: 支持渲染视图,详情请参考 [Views](structure-views.md) 一节。
diff --git a/docs/guide-zh-CN/structure-applications.md b/docs/guide-zh-CN/structure-applications.md
new file mode 100644
index 0000000..452467d
--- /dev/null
+++ b/docs/guide-zh-CN/structure-applications.md
@@ -0,0 +1,524 @@
+应用主体
+============
+
+应用主体是管理 Yii 应用系统整体结构和生命周期的对象。
+每个Yii应用系统只能包含一个应用主体,应用主体在 [入口脚本](structure-entry-scripts.md) 中创建并能通过表达式 `\Yii::$app` 全局范围内访问。
+
+> 补充: 当我们说"一个应用",它可能是一个应用主体对象,也可能是一个应用系统,是根据上下文来决定[译:中文为避免歧义,Application翻译为应用主体]。
+
+Yii有两种应用主体: [[yii\web\Application|网页应用主体]] and
+[[yii\console\Application|控制台应用主体]], 如名称所示,前者主要处理网页请求,后者处理控制台请求。
+
+
+## 应用主体配置
+
+如下所示,当 [入口脚本](structure-entry-scripts.md) 创建了一个应用主体,它会加载一个 [配置](concept-configurations.md) 文件并传给应用主体。
+
+```php
+require(__DIR__ . '/../vendor/autoload.php');
+require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
+
+// 加载应用主体配置
+$config = require(__DIR__ . '/../config/web.php');
+
+// 实例化应用主体、配置应用主体
+(new yii\web\Application($config))->run();
+```
+
+类似其他 [配置](concept-configurations.md) 文件, 应用主体配置文件标明如何设置应用对象初始属性。
+由于应用主体配置比较复杂,一般保存在多个类似如上web.php的 [配置文件](concept-configurations.md#configuration-files) 当中。
+
+## 应用主体属性
+
+应用主体配置文件中有许多重要的属性要配置,这些属性指定应用主体的运行环境。
+比如,应用主体需要知道如何加载 [控制器](structure-controllers.md) ,临时文件保存到哪儿等等。
+以下我们简述这些属性。
+
+### 必要属性
+
+在一个应用中,至少要配置2个属性: [[yii\base\Application::id|id]] 和 [[yii\base\Application::basePath|basePath]]。
+
+
+#### [[yii\base\Application::id|id]]
+
+[[yii\base\Application::id|id]] 属性用来区分其他应用的唯一标识ID。主要给程序使用。
+为了方便协作,最好使用数字作为应用主体ID,但不强制要求为数字。
+
+
+#### [[yii\base\Application::basePath|basePath]]
+
+
+[[yii\base\Application::basePath|basePath]] 指定该应用的根目录。根目录包含应用系统所有受保护的源代码。
+在根目录下可以看到对应MVC设计模式的`models`, `views`, `controllers`等子目录。
+
+可以使用路径或 [路径别名](concept-aliases.md) 来在配置 [[yii\base\Application::basePath|basePath]] 属性。
+两种格式所对应的目录都必须存在,否则系统会抛出一个异常。 系统会使用 `realpath()` 函数规范化配置的路径.
+
+[[yii\base\Application::basePath|basePath]] 属性经常用于派生一些其他重要路径(如runtime路径),因此,系统预定义 `@app` 代表这个路径。
+派生路径可以通过这个别名组成(如`@app/runtime`代表runtime的路径)。
+
+
+### 重要属性
+
+本小节所描述的属性通常需要设置,因为不用的应用属性不同。
+
+
+#### [[yii\base\Application::aliases|aliases]]
+
+该属性允许你用一个数组定义多个 [别名](concept-aliases.md)。数组的key为别名名称,值为对应的路径。例如:
+
+```php
+[
+ 'aliases' => [
+ '@name1' => 'path/to/path1',
+ '@name2' => 'path/to/path2',
+ ],
+]
+```
+
+使用这个属性来定义别名,代替 [[Yii::setAlias()]] 方法来设置。
+
+
+#### [[yii\base\Application::bootstrap|bootstrap]]
+
+这个属性很实用,它允许你用数组指定启动阶段[[yii\base\Application::bootstrap()|bootstrapping process]]需要运行的组件。
+比如,如果你希望一个 [模块](structure-modules.md) 自定义 [URL 规则](runtime-url-handling.md),你可以将模块ID加入到bootstrap数组中。
+
+属性中的每个组件需要指定以下一项:
+
+- 应用 [组件](#components) ID.
+- [模块](#modules) ID.
+- 类名.
+- 配置数组.
+- 创建并返回一个组件的无名称函数.
+
+例如:
+
+```php
+[
+ 'bootstrap' => [
+ // 应用组件ID或模块ID
+ 'demo',
+
+ // 类名
+ 'app\components\Profiler',
+
+ // 配置数组
+ [
+ 'class' => 'app\components\Profiler',
+ 'level' => 3,
+ ],
+
+ // 无名称函数
+ function () {
+ return new app\components\Profiler();
+ }
+ ],
+]
+```
+
+> 补充: 如果模块ID和应用组件ID同名,优先使用应用组件ID,如果你想用模块ID,可以使用如下无名称函数返回模块ID。
+>```php
+[
+ function () {
+ return Yii::$app->getModule('user');
+ },
+]
+```
+
+
+在启动阶段,每个组件都会实例化。如果组件类实现接口 [[yii\base\BootstrapInterface]],也会调用 [[yii\base\BootstrapInterface::bootstrap()|bootstrap()]] 方法。
+
+举一个实际的例子,[Basic Application Template](start-installation.md) 应用主体配置中,
+开发环境下会在启动阶段运行 `debug` 和 `gii` 模块。
+
+```php
+if (YII_ENV_DEV) {
+ // configuration adjustments for 'dev' environment
+ $config['bootstrap'][] = 'debug';
+ $config['modules']['debug'] = 'yii\debug\Module';
+
+ $config['bootstrap'][] = 'gii';
+ $config['modules']['gii'] = 'yii\gii\Module';
+}
+```
+
+> 注: 启动太多的组件会降低系统性能,因为每次请求都需要重新运行启动组件,因此谨慎配置启动组件。
+
+
+#### [[yii\web\Application::catchAll|catchAll]]
+
+该属性仅 [[yii\web\Application|Web applications]] 网页应用支持。
+它指定一个要处理所有用户请求的 [控制器方法](structure-controllers.md),通常在维护模式下使用,同一个方法处理所有用户请求。
+
+该配置为一个数组,第一项指定动作的路由,剩下的数组项(key-value 成对)指定传递给动作的参数,例如:
+
+```php
+[
+ 'catchAll' => [
+ 'offline/notice',
+ 'param1' => 'value1',
+ 'param2' => 'value2',
+ ],
+]
+```
+
+
+#### [[yii\base\Application::components|components]]
+
+这是最重要的属性,它允许你注册多个在其他地方使用的[应用组件](#structure-application-components.md). 例如
+
+```php
+[
+ 'components' => [
+ 'cache' => [
+ 'class' => 'yii\caching\FileCache',
+ ],
+ 'user' => [
+ 'identityClass' => 'app\models\User',
+ 'enableAutoLogin' => true,
+ ],
+ ],
+]
+```
+
+每一个应用组件指定一个key-value对的数组,key代表组件ID,value代表组件类名或 [配置](concept-configurations.md)。
+
+在应用中可以任意注册组件,并可以通过表达式 `\Yii::$app->ComponentID` 全局访问。
+
+详情请阅读 [应用组件](structure-application-components.md) 一节.
+
+
+#### [[yii\base\Application::controllerMap|controllerMap]]
+
+该属性允许你指定一个控制器ID到任意控制器类。Yii遵循一个默认的 [规则](#controllerNamespace)指定控制器ID到任意控制器类(如`post`对应`app\controllers\PostController`)。
+通过配置这个属性,可以打破这个默认规则,在下面的例子中,`account`对应到`app\controllers\UserController`,
+`article` 对应到 `app\controllers\PostController`。
+
+```php
+[
+ 'controllerMap' => [
+ [
+ 'account' => 'app\controllers\UserController',
+ 'article' => [
+ 'class' => 'app\controllers\PostController',
+ 'enableCsrfValidation' => false,
+ ],
+ ],
+ ],
+]
+```
+
+数组的键代表控制器ID,数组的值代表对应的类名。
+
+
+#### [[yii\base\Application::controllerNamespace|controllerNamespace]]
+
+该属性指定控制器类默认的命名空间,默认为`app\controllers`。比如控制器ID为 `post` 默认对应 `PostController` (不带命名空间),
+类全名为 `app\controllers\PostController`。
+
+控制器类文件可能放在这个命名空间对应目录的子目录下,
+例如,控制器ID `admin/post` 对应的控制器类全名为 `app\controllers\admin\PostController`。
+
+控制器类全面能被 [自动加载](concept-autoloading.md),这点是非常重要的,控制器类的实际命名空间对应这个属性,
+否则,访问时你会收到"Page Not Found"[译:页面找不到]。
+
+如果你想打破上述的规则,可以配置 [controllerMap](#controllerMap) 属性。
+
+
+#### [[yii\base\Application::language|language]]
+
+该属性指定应用展示给终端用户的语言,默认为 `en` 标识英文。如果需要之前其他语言可以配置该属性。
+
+该属性影响各种 [国际化](tutorial-i18n.md) ,包括信息翻译、日期格式、数字格式等。
+例如 [[yii\jui\DatePicker]] 小部件会根据该属性展示对应语言的日历以及日期格式。
+
+推荐遵循 [IETF language tag](http://en.wikipedia.org/wiki/IETF_language_tag) 来设置语言,例如 `en` 代表英文, `en-US` 代表英文(美国).
+
+该属性的更多信息可参考 [国际化](tutorial-i18n.md) 一节.
+
+
+#### [[yii\base\Application::modules|modules]]
+
+该属性指定应用所包含的 [模块](structure-modules.md)。
+
+该属性使用数组包含多个模块类 [配置](concept-configurations.md),数组的键为模块ID,例:
+
+```php
+[
+ 'modules' => [
+ // "booking" 模块以及对应的类
+ 'booking' => 'app\modules\booking\BookingModule',
+
+ // "comment" 模块以及对应的配置数组
+ 'comment' => [
+ 'class' => 'app\modules\comment\CommentModule',
+ 'db' => 'db',
+ ],
+ ],
+]
+```
+
+更多详情请参考 [模块](structure-modules.md) 一节。
+
+
+#### [[yii\base\Application::name|name]]
+
+该属性指定你可能想展示给终端用户的应用名称,不同于需要唯一性的 [[yii\base\Application::id|id]] 属性,
+该属性可以不唯一,该属性用于显示应用的用途。
+
+如果其他地方的代码没有用到,可以不配置该属性。
+
+
+#### [[yii\base\Application::params|params]]
+
+该属性为一个数组,指定可以全局访问的参数,代替程序中硬编码的数字和字符,应用中的参数定义到一个单独的文件并随时可以访问是一个好习惯。
+例如用参数定义缩略图的长宽如下:
+
+```php
+[
+ 'params' => [
+ 'thumbnail.size' => [128, 128],
+ ],
+]
+```
+
+然后简单的使用如下代码即可获取到你需要的长宽参数:
+
+```php
+$size = \Yii::$app->params['thumbnail.size'];
+$width = \Yii::$app->params['thumbnail.size'][0];
+```
+
+以后想修改缩略图长宽,只需要修改该参数而不需要相关的代码。
+
+
+#### [[yii\base\Application::sourceLanguage|sourceLanguage]]
+
+该属性指定应用代码的语言,默认为 `'en-US'` 标识英文(美国),如果应用不是英文请修改该属性。
+
+和 [语言](#language) 属性类似,配置该属性需遵循 [IETF language tag](http://en.wikipedia.org/wiki/IETF_language_tag).
+例如 `en` 代表英文, `en-US` 代表英文(美国)。
+
+该属性的更多信息可参考 [国际化](tutorial-i18n.md) 一节.
+
+
+#### [[yii\base\Application::timeZone|timeZone]]
+
+该属性提供一种方式修改PHP运行环境中的默认时区,配置该属性本质上就是调用PHP函数
+[date_default_timezone_set()](http://php.net/manual/en/function.date-default-timezone-set.php),例如:
+
+```php
+[
+ 'timeZone' => 'America/Los_Angeles',
+]
+```
+
+
+#### [[yii\base\Application::version|version]]
+
+该属性指定应用的版本,默认为`'1.0'`,其他代码不使用的话可以不配置。
+
+
+### 实用属性
+
+本小节描述的属性不经常设置,通常使用系统默认值。如果你想改变默认值,可以配置这些属性。
+
+
+#### [[yii\base\Application::charset|charset]]
+
+该属性指定应用使用的字符集,默认值为 `'UTF-8'`,绝大部分应用都在使用,除非已有的系统大量使用非unicode数据才需要更改该属性。
+
+
+#### [[yii\base\Application::defaultRoute|defaultRoute]]
+
+该属性指定未配置的请求的响应 [路由](runtime-routing.md) 规则,路由规则可能包含模块ID,控制器ID,动作ID。
+例如`help`, `post/create`, `admin/post/create`,如果动作ID没有指定,会使用[[yii\base\Controller::defaultAction]]中指定的默认值。
+
+对于 [[yii\web\Application|Web applications]] 网页应用,默认值为 `'site'` 对应 `SiteController` 控制器,并使用默认的动作。
+因此你不带路由的访问应用,默认会显示 `app\controllers\SiteController::actionIndex()` 的结果。
+
+对于 [[yii\console\Application|console applications]] 控制台应用,
+默认值为 `'help'` 对应 [[yii\console\controllers\HelpController::actionIndex()]]。
+因此,如果执行的命令不带参数,默认会显示帮助信息。
+
+
+#### [[yii\base\Application::extensions|extensions]]
+
+该属性用数组列表指定应用安装和使用的 [扩展](structure-extensions.md),默认使用`@vendor/yiisoft/extensions.php`文件返回的数组。
+当你使用 [Composer](http://getcomposer.org) 安装扩展,`extensions.php` 会被自动生成和维护更新。
+所以大多数情况下,不需要配置该属性。
+
+特殊情况下你想自己手动维护扩展,可以参照如下配置该属性:
+
+```php
+[
+ 'extensions' => [
+ [
+ 'name' => 'extension name',
+ 'version' => 'version number',
+ 'bootstrap' => 'BootstrapClassName', // 可选配,可为配置数组
+ 'alias' => [ // 可选配
+ '@alias1' => 'to/path1',
+ '@alias2' => 'to/path2',
+ ],
+ ],
+
+ // ... 更多像上面的扩展 ...
+
+ ],
+]
+```
+
+如上所示,该属性包含一个扩展定义数组,每个扩展为一个包含 `name` 和 `version` 项的数组。
+如果扩展要在 [引导启动](runtime-bootstrapping.md) 阶段运行,需要配置 `bootstrap`以及对应的引导启动类名或 [configuration](concept-configurations.md) 数组。
+扩展也可以定义 [别名](concept-aliases.md)
+
+
+#### [[yii\base\Application::layout|layout]]
+
+该属性指定渲染 [视图](structure-views.md) 默认使用的布局名字,默认值为 `'main'` 对应[布局路径](#layoutPath)下的 `main.php` 文件,
+如果 [布局路径](#layoutPath) 和 [视图路径](#viewPath) 都是默认值,默认布局文件可以使用路径别名`@app/views/layouts/main.php`
+
+如果不想设置默认布局文件,可以设置该属性为 `false`,这种做法比较罕见。
+
+
+#### [[yii\base\Application::layoutPath|layoutPath]]
+
+该属性指定查找布局文件的路径,默认值为 [视图路径](#viewPath) 下的 `layouts` 子目录。
+如果 [视图路径](#viewPath) 使用默认值,默认的布局路径别名为`@app/views/layouts`。
+
+该属性需要配置成一个目录或 路径 [别名](concept-aliases.md)。
+You may configure it as a directory or a path [alias](concept-aliases.md).
+
+
+#### [[yii\base\Application::runtimePath|runtimePath]]
+
+该属性指定临时文件如日志文件、缓存文件等保存路径,默认值为带别名的 `@app/runtime`。
+
+可以配置该属性为一个目录或者路径 [别名](concept-aliases.md),注意应用运行时有对该路径的写入权限,
+以及终端用户不能访问改路径因为临时文件可能包含一些敏感信息。
+
+为了简化访问该路径,Yii预定义别名 `@runtime` 代表该路径。
+
+
+#### [[yii\base\Application::viewPath|viewPath]]
+
+该路径指定视图文件的根目录,默认值为带别名的 `@app/views`,可以配置它为一个目录或者路径 [别名](concept-aliases.md).
+
+
+#### [[yii\base\Application::vendorPath|vendorPath]]
+
+该属性指定 [Composer](http://getcomposer.org) 管理的供应商路径,该路径包含应用使用的包括Yii框架在内的所有第三方库。
+默认值为带别名的 `@app/vendor` 。
+
+可以配置它为一个目录或者路径 [别名](concept-aliases.md),当你修改时,务必修改对应的 Composer 配置。
+
+为了简化访问该路径,Yii预定义别名 `@vendor` 代表该路径。
+
+
+#### [[yii\console\Application::enableCoreCommands|enableCoreCommands]]
+
+该属性仅 [[yii\console\Application|console applications]] 控制台应用支持, 用来指定是否启用Yii中的核心命令,默认值为 `true`。
+
+
+## 应用事件
+
+应用在处理请求过程中会触发事件,可以在配置文件配置事件处理代码,如下所示:
+
+```php
+[
+ 'on beforeRequest' => function ($event) {
+ // ...
+ },
+]
+```
+
+`on eventName` 语法的用法在 [Configurations](concept-configurations.md#configuration-format) 一节有详细描述.
+
+另外,在应用主体实例化后,你可以在[引导启动](runtime-bootstrapping.md) 阶段附加事件处理代码,例如:
+
+```php
+\Yii::$app->on(\yii\base\Application::EVENT_BEFORE_REQUEST, function ($event) {
+ // ...
+});
+```
+
+### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_REQUEST]]
+
+该事件在应用处理请求*before*之前,实际的事件名为 `beforeRequest`。
+
+在事件触发前,应用主体已经实例化并配置好了,所以通过事件机制将你的代码嵌入到请求处理过程中非常不错。
+例如在事件处理中根据某些参数动态设置[[yii\base\Application::language]]语言属性。
+
+
+### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_AFTER_REQUEST]]
+
+该事件在应用处理请求*after*之后但在返回响应*before*之前触发,实际的事件名为`afterRequest`。
+
+该事件触发时,请求已经被处理完,可以做一些请求后处理或自定义响应。
+
+注意 [[yii\web\Response|response]] 组件在发送响应给终端用户时也会触发一些事件,这些事件都在本事件*after*之后触发。
+
+
+### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_ACTION]]
+
+该事件在每个 [控制器动作](structure-controllers.md) 运行*before*之前会被触发,实际的事件名为 `beforeAction`.
+
+事件的参数为一个 [[yii\base\ActionEvent]] 实例,
+事件处理中可以设置[[yii\base\ActionEvent::isValid]] 为 `false` 停止运行后续动作,例如:
+
+```php
+[
+ 'on beforeAction' => function ($event) {
+ if (some condition) {
+ $event->isValid = false;
+ } else {
+ }
+ },
+]
+```
+
+注意 [模块](structure-modules.md) 和 [控制器](structure-controllers.md) 都会触发 `beforeAction` 事件。
+应用主体对象首先触发该事件,然后模块触发(如果存在模块),最后控制器触发。
+任何一个事件处理中设置 [[yii\base\ActionEvent::isValid]] 设置为 `false` 会停止触发后面的事件。
+
+
+### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_AFTER_ACTION]]
+
+该事件在每个 [控制器动作](structure-controllers.md) 运行*after*之后会被触发,实际的事件名为 `afterAction`.
+
+该事件的参数为 [[yii\base\ActionEvent]] 实例,通过[[yii\base\ActionEvent::result]]属性,
+事件处理可以访问和修改动作的结果。例如:
+
+```php
+[
+ 'on afterAction' => function ($event) {
+ if (some condition) {
+ // 修改 $event->result
+ } else {
+ }
+ },
+]
+```
+
+注意 [模块](structure-modules.md) 和 [控制器](structure-controllers.md) 都会触发 `afterAction` 事件。
+这些对象的触发顺序和 `beforeAction` 相反,也就是说,控制器最先触发,然后是模块(如果有模块),最后为应用主体。
+
+
+## 应用主体生命周期
+
+当运行 [入口脚本](structure-entry-scripts.md) 处理请求时,应用主体会经历以下生命周期:
+
+1. 入口脚本加载应用主体配置数组。
+2. 入口脚本创建一个应用主体实例:
+ * 调用 [[yii\base\Application::preInit()|preInit()]] 配置几个高级别应用主体属性,比如[[yii\base\Application::basePath|basePath]]。
+ * 注册 [[yii\base\Application::errorHandler|error handler]] 错误处理方法.
+ * 配置应用主体属性.
+ * 调用 [[yii\base\Application::init()|init()]] 初始化,该函数会调用 [[yii\base\Application::bootstrap()|bootstrap()]] 运行引导启动组件.
+3. 入口脚本调用 [[yii\base\Application::run()]] 运行应用主体:
+ * 触发 [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_REQUEST]] 事件。
+ * 处理请求:解析请求 [路由](runtime-routing.md) 和相关参数;创建路由指定的模块、控制器和动作对应的类,并运行动作。
+ * 触发 [[yii\base\Application::EVENT_AFTER_REQUEST|EVENT_AFTER_REQUEST]] 事件。
+ * 发送响应到终端用户.
+4. 入口脚本接收应用主体传来的退出状态并完成请求的处理。
diff --git a/docs/guide-zh-CN/structure-controllers.md b/docs/guide-zh-CN/structure-controllers.md
new file mode 100644
index 0000000..79737be
--- /dev/null
+++ b/docs/guide-zh-CN/structure-controllers.md
@@ -0,0 +1,449 @@
+Controllers
+===========
+
+Controllers are part of the [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) architecture.
+They are objects of classes extending from [[yii\base\Controller]] and are responsible for processing requests and
+generating responses. In particular, after taking over the control from [applications](structure-applications.md),
+controllers will analyze incoming request data, pass them to [models](structure-models.md), inject model results
+into [views](structure-views.md), and finally generate outgoing responses.
+
+
+## Actions
+
+Controllers are composed by *actions* which are the most basic units that end users can address and request for
+execution. A controller can have one or multiple actions.
+
+The following example shows a `post` controller with two actions: `view` and `create`:
+
+```php
+namespace app\controllers;
+
+use Yii;
+use app\models\Post;
+use yii\web\Controller;
+use yii\web\NotFoundHttpException;
+
+class PostController extends Controller
+{
+ public function actionView($id)
+ {
+ $model = Post::findOne($id);
+ if ($model === null) {
+ throw new NotFoundHttpException;
+ }
+
+ return $this->render('view', [
+ 'model' => $model,
+ ]);
+ }
+
+ public function actionCreate()
+ {
+ $model = new Post;
+
+ if ($model->load(Yii::$app->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ } else {
+ return $this->render('create', [
+ 'model' => $model,
+ ]);
+ }
+ }
+}
+```
+
+In the `view` action (defined by the `actionView()` method), the code first loads the [model](structure-models.md)
+according to the requested model ID; If the model is loaded successfully, it will display it using
+a [view](structure-views.md) named `view`. Otherwise, it will throw an exception.
+
+In the `create` action (defined by the `actionCreate()` method), the code is similar. It first tries to populate
+the [model](structure-models.md) using the request data and save the model. If both succeed it will redirect
+the browser to the `view` action with the ID of the newly created model. Otherwise it will display
+the `create` view through which users can provide the needed input.
+
+
+## Routes
+
+End users address actions through the so-called *routes*. A route is a string that consists of the following parts:
+
+* a module ID: this exists only if the controller belongs to a non-application [module](structure-modules.md);
+* a controller ID: a string that uniquely identifies the controller among all controllers within the same application
+ (or the same module if the controller belongs to a module);
+* an action ID: a string that uniquely identifies the action among all actions within the same controller.
+
+Routes take the following format:
+
+```
+ControllerID/ActionID
+```
+
+or the following format if the controller belongs to a module:
+
+```php
+ModuleID/ControllerID/ActionID
+```
+
+So if a user requests with the URL `http://hostname/index.php?r=site/index`, the `index` action in the `site` controller
+will be executed. For more details how routes are resolved into actions, please refer to
+the [Routing](runtime-routing.md) section.
+
+
+## Creating Controllers
+
+In [[yii\web\Application|Web applications]], controllers should extend from [[yii\web\Controller]] or its
+child classes. Similarly in [[yii\console\Application|console applications]], controllers should extend from
+[[yii\console\Controller]] or its child classes. The following code defines a `site` controller:
+
+```php
+namespace app\controllers;
+
+use yii\web\Controller;
+
+class SiteController extends Controller
+{
+}
+```
+
+
+### Controller IDs
+
+Usually, a controller is designed to handle the requests regarding a particular type of resource.
+For this reason, controller IDs are often nouns referring to the types of the resources that they are handling.
+For example, you may use `article` as the ID of a controller that handles article data.
+
+By default, controller IDs should contain these characters only: English letters in lower case, digits,
+underscores, dashes and forward slashes. For example, `article` and `post-comment` are both valid controller IDs,
+while `article?`, `PostComment`, `admin\post` are not.
+
+A controller ID may also contain a subdirectory prefix. For example, `admin/article` stands for an `article` controller
+in the `admin` subdirectory under the [[yii\base\Application::controllerNamespace|controller namespace]].
+Valid characters for subdirectory prefixes include: English letters in lower and upper cases, digits, underscores and
+forward slashes, where forward slashes are used as separators for multi-level subdirectories (e.g. `panels/admin`).
+
+
+### Controller Class Naming
+
+Controller class names can be derived from controller IDs according to the following rules:
+
+* Turn the first letter in each word separated by dashes into upper case. Note that if the controller ID
+ contains slashes, this rule only applies to the part after the last slash in the ID.
+* Remove dashes and replace any forward slashes with backward slashes.
+* Append the suffix `Controller`.
+* And prepend the [[yii\base\Application::controllerNamespace|controller namespace]].
+
+The followings are some examples, assuming the [[yii\base\Application::controllerNamespace|controller namespace]]
+takes the default value `app\controllers`:
+
+* `article` derives `app\controllers\ArticleController`;
+* `post-comment` derives `app\controllers\PostCommentController`;
+* `admin/post-comment` derives `app\controllers\admin\PostCommentController`;
+* `adminPanels/post-comment` derives `app\controllers\adminPanels\PostCommentController`.
+
+Controller classes must be [autoloadable](concept-autoloading.md). For this reason, in the above examples,
+the `article` controller class should be saved in the file whose [alias](concept-aliases.md)
+is `@app/controllers/ArticleController.php`; while the `admin/post2-comment` controller should be
+in `@app/controllers/admin/Post2CommentController.php`.
+
+> Info: The last example `admin/post2-comment` shows how you can put a controller under a sub-directory
+ of the [[yii\base\Application::controllerNamespace|controller namespace]]. This is useful when you want
+ to organize your controllers into several categories and you do not want to use [modules](structure-modules.md).
+
+
+### Controller Map
+
+You can configure [[yii\base\Application::controllerMap|controller map]] to overcome the constraints
+of the controller IDs and class names described above. This is mainly useful when you are using some
+third-party controllers which you do not control over their class names.
+
+You may configure [[yii\base\Application::controllerMap|controller map]] in the
+[application configuration](structure-applications.md#application-configurations) like the following:
+
+```php
+[
+ 'controllerMap' => [
+ // declares "account" controller using a class name
+ 'account' => 'app\controllers\UserController',
+
+ // declares "article" controller using a configuration array
+ 'article' => [
+ 'class' => 'app\controllers\PostController',
+ 'enableCsrfValidation' => false,
+ ],
+ ],
+]
+```
+
+
+### Default Controller
+
+Each application has a default controller specified via the [[yii\base\Application::defaultRoute]] property.
+When a request does not specify a [route](#ids-routes), the route specified by this property will be used.
+For [[yii\web\Application|Web applications]], its value is `'site'`, while for [[yii\console\Application|console applications]],
+it is `help`. Therefore, if a URL is `http://hostname/index.php`, it means the `site` controller will handle the request.
+
+You may change the default controller with the following [application configuration](structure-applications.md#application-configurations):
+
+```php
+[
+ 'defaultRoute' => 'main',
+]
+```
+
+
+## Creating Actions
+
+Creating actions can be as simple as defining the so-called *action methods* in a controller class. An action method is
+a *public* method whose name starts with the word `action`. The return value of an action method represents
+the response data to be sent to end users. The following code defines two actions `index` and `hello-world`:
+
+```php
+namespace app\controllers;
+
+use yii\web\Controller;
+
+class SiteController extends Controller
+{
+ public function actionIndex()
+ {
+ return $this->render('index');
+ }
+
+ public function actionHelloWorld()
+ {
+ return 'Hello World';
+ }
+}
+```
+
+
+### Action IDs
+
+An action is often designed to perform a particular manipulation about a resource. For this reason,
+action IDs are usually verbs, such as `view`, `update`, etc.
+
+By default, action IDs should contain these characters only: English letters in lower case, digits,
+underscores and dashes. The dashes in an actionID are used to separate words. For example,
+`view`, `update2`, `comment-post` are all valid action IDs, while `view?`, `Update` are not.
+
+You can create actions in two ways: inline actions and standalone actions. An inline action is
+defined as a method in the controller class, while a standalone action is a class extending
+[[yii\base\Action]] or its child class. Inline actions take less effort to create and are often preferred
+if you have no intention to reuse these actions. Standalone actions, on the other hand, are mainly
+created to be used in different controllers or be redistributed as [extensions](structure-extensions.md).
+
+
+### Inline Actions
+
+Inline actions refer to the actions that are defined in terms of action methods as we just described.
+
+The names of the action methods are derived from action IDs according to the following criteria:
+
+* Turn the first letter in each word of the action ID into upper case;
+* Remove dashes;
+* Prepend the prefix `action`.
+
+For example, `index` becomes `actionIndex`, and `hello-world` becomes `actionHelloWorld`.
+
+> Note: The names of the action methods are *case-sensitive*. If you have a method named `ActionIndex`,
+ it will not be considered as an action method, and as a result, the request for the `index` action
+ will result in an exception. Also note that action methods must be public. A private or protected
+ method does NOT define an inline action.
+
+
+Inline actions are the most commonly defined actions because they take little effort to create. However,
+if you plan to reuse the same action in different places, or if you want to redistribute an action,
+you should consider defining it as a *standalone action*.
+
+
+### Standalone Actions
+
+Standalone actions are defined in terms of action classes extending [[yii\base\Action]] or its child classes.
+For example, in the Yii releases, there are [[yii\web\ViewAction]] and [[yii\web\ErrorAction]], both of which
+are standalone actions.
+
+To use a standalone action, you should declare it in the *action map* by overriding the
+[[yii\base\Controller::actions()]] method in your controller classes like the following:
+
+```php
+public function actions()
+{
+ return [
+ // declares "error" action using a class name
+ 'error' => 'yii\web\ErrorAction',
+
+ // declares "view" action using a configuration array
+ 'view' => [
+ 'class' => 'yii\web\ViewAction',
+ 'viewPrefix' => '',
+ ],
+ ];
+}
+```
+
+As you can see, the `actions()` method should return an array whose keys are action IDs and values the corresponding
+action class names or [configurations](concept-configurations.md). Unlike inline actions, action IDs for standalone
+actions can contain arbitrary characters, as long as they are declared in the `actions()` method.
+
+
+To create a standalone action class, you should extend [[yii\base\Action]] or its child class, and implement
+a public method named `run()`. The role of the `run()` method is similar to that of an action method. For example,
+
+```php
+
+
+The return value of an action method or the `run()` method of a standalone action is significant. It stands
+for the result of the corresponding action.
+
+The return value can be a [response](runtime-responses.md) object which will be sent to as the response
+to end users.
+
+* For [[yii\web\Application|Web applications]], the return value can also be some arbitrary data which will
+ be assigned to [[yii\web\Response::data]] and be further converted into a string representing the response body.
+* For [[yii\console\Application|console applications]], the return value can also be an integer representing
+ the [[yii\console\Response::exitStatus|exit status]] of the command execution.
+
+In the examples shown above, the action results are all strings which will be treated as the response body
+to be sent to end users. The following example shows how an action can redirect the user browser to a new URL
+by returning a response object (because the [[yii\web\Controller::redirect()|redirect()]] method returns
+a response object):
+
+```php
+public function actionForward()
+{
+ // redirect the user browser to http://example.com
+ return $this->redirect('http://example.com');
+}
+```
+
+
+### Action Parameters
+
+The action methods for inline actions and the `run()` methods for standalone actions can take parameters,
+called *action parameters*. Their values are obtained from requests. For [[yii\web\Application|Web applications]],
+the value of each action parameter is retrieved from `$_GET` using the parameter name as the key;
+for [[yii\console\Application|console applications]], they correspond to the command line arguments.
+
+In the following example, the `view` action (an inline action) has declared two parameters: `$id` and `$version`.
+
+```php
+namespace app\controllers;
+
+use yii\web\Controller;
+
+class PostController extends Controller
+{
+ public function actionView($id, $version = null)
+ {
+ // ...
+ }
+}
+```
+
+The action parameters will be populated as follows for different requests:
+
+* `http://hostname/index.php?r=post/view&id=123`: the `$id` parameter will be filled with the value
+ `'123'`, while `$version` is still null because there is no `version` query parameter.
+* `http://hostname/index.php?r=post/view&id=123&version=2`: the `$id` and `$version` parameters will
+ be filled with `'123'` and `'2'`, respectively.
+* `http://hostname/index.php?r=post/view`: a [[yii\web\BadRequestHttpException]] exception will be thrown
+ because the required `$id` parameter is not provided in the request.
+* `http://hostname/index.php?r=post/view&id[]=123`: a [[yii\web\BadRequestHttpException]] exception will be thrown
+ because `$id` parameter is receiving an unexpected array value `['123']`.
+
+If you want an action parameter to accept array values, you should type-hint it with `array`, like the following:
+
+```php
+public function actionView(array $id, $version = null)
+{
+ // ...
+}
+```
+
+Now if the request is `http://hostname/index.php?r=post/view&id[]=123`, the `$id` parameter will take the value
+of `['123']`. If the request is `http://hostname/index.php?r=post/view&id=123`, the `$id` parameter will still
+receive the same array value because the scalar value `'123'` will be automatically turned into an array.
+
+The above examples mainly show how action parameters work for Web applications. For console applications,
+please refer to the [Console Commands](tutorial-console.md) section for more details.
+
+
+### Default Action
+
+Each controller has a default action specified via the [[yii\base\Controller::defaultAction]] property.
+When a [route](#ids-routes) contains the controller ID only, it implies that the default action of
+the specified controller is requested.
+
+By default, the default action is set as `index`. If you want to change the default value, simply override
+this property in the controller class, like the following:
+
+```php
+namespace app\controllers;
+
+use yii\web\Controller;
+
+class SiteController extends Controller
+{
+ public $defaultAction = 'home';
+
+ public function actionHome()
+ {
+ return $this->render('home');
+ }
+}
+```
+
+
+## Controller Lifecycle
+
+When processing a request, an [application](structure-applications.md) will create a controller
+based on the requested [route](#routes). The controller will then undergo the following lifecycle
+to fulfill the request:
+
+1. The [[yii\base\Controller::init()]] method is called after the controller is created and configured.
+2. The controller creates an action object based on the requested action ID:
+ * If the action ID is not specified, the [[yii\base\Controller::defaultAction|default action ID]] will be used.
+ * If the action ID is found in the [[yii\base\Controller::actions()|action map]], a standalone action
+ will be created;
+ * If the action ID is found to match an action method, an inline action will be created;
+ * Otherwise an [[yii\base\InvalidRouteException]] exception will be thrown.
+3. The controller sequentially calls the `beforeAction()` method of the application, the module (if the controller
+ belongs to a module) and the controller.
+ * If one of the calls returns false, the rest of the uncalled `beforeAction()` will be skipped and the
+ action execution will be cancelled.
+ * By default, each `beforeAction()` method call will trigger a `beforeAction` event to which you can attach a handler.
+4. The controller runs the action:
+ * The action parameters will be analyzed and populated from the request data;
+5. The controller sequentially calls the `afterAction()` method of the controller, the module (if the controller
+ belongs to a module) and the application.
+ * By default, each `afterAction()` method call will trigger an `afterAction` event to which you can attach a handler.
+6. The application will take the action result and assign it to the [response](runtime-responses.md).
+
+
+## Best Practices
+
+In a well-designed application, controllers are often very thin with each action containing only a few lines of code.
+If your controller is rather complicated, it usually indicates that you should refactor it and move some code
+to other classes.
+
+In summary, controllers
+
+* may access the [request](runtime-requests.md) data;
+* may call methods of [models](structure-models.md) and other service components with request data;
+* may use [views](structure-views.md) to compose responses;
+* should NOT process the request data - this should be done in [models](structure-models.md);
+* should avoid embedding HTML or other presentational code - this is better done in [views](structure-views.md).
diff --git a/docs/guide-zh-CN/structure-entry-scripts.md b/docs/guide-zh-CN/structure-entry-scripts.md
new file mode 100644
index 0000000..2992ccd
--- /dev/null
+++ b/docs/guide-zh-CN/structure-entry-scripts.md
@@ -0,0 +1,104 @@
+入口脚本
+=============
+
+入口脚本是应用启动流程中的第一环,一个应用(不管是网页应用还是控制台应用)只有一个入口脚本。终端用户的请求通过入口脚本实例化应用并将将请求转发到应用。
+
+Web 应用的入口脚本必须放在终端用户能够访问的目录下,通常命名为 `index.php`,也可以使用 Web 服务器能定位到的其他名称。
+
+控制台应用的入口脚本一般在应用根目录下命名为 `yii`(后缀为.php),该文件需要有执行权限,这样用户就能通过命令 `./yii [arguments] [options]` 来运行控制台应用。
+
+入口脚本主要完成以下工作:
+
+* 定义全局常量;
+* 注册 [Composer 自动加载器](http://getcomposer.org/doc/01-basic-usage.md#autoloading);
+* 包含 [[Yii]] 类文件;
+* 加载应用配置;
+* 创建一个[应用](structure-applications.md)实例并配置;
+* 调用 [[yii\base\Application::run()]] 来处理请求。
+
+
+## Web 应用
+
+以下是[基础应用模版](start-installation.md)入口脚本的代码:
+
+```php
+run();
+```
+
+
+## 控制台应用
+
+以下是一个控制台应用的入口脚本:
+
+```php
+#!/usr/bin/env php
+run();
+exit($exitCode);
+```
+
+
+## 定义常量
+
+入口脚本是定义全局常量的最好地方,Yii 支持以下三个常量:
+
+* `YII_DEBUG`:标识应用是否运行在调试模式。当在调试模式下,应用会保留更多日志信息,如果抛出异常,会显示详细的错误调用堆栈。因此,调试模式主要适合在开发阶段使用,`YII_DEBUG` 默认值为 false。
+* `YII_ENV`:标识应用运行的环境,详情请查阅[配置](concept-configurations.md#environment-constants)章节。`YII_ENV` 默认值为 `'prod'`,表示应用运行在线上产品环境。
+* `YII_ENABLE_ERROR_HANDLER`:标识是否启用 Yii 提供的错误处理,默认为 true。
+
+当定义一个常量时,通常使用类似如下代码来定义:
+
+```php
+defined('YII_DEBUG') or define('YII_DEBUG', true);
+```
+
+上面的代码等同于:
+
+```php
+if (!defined('YII_DEBUG')) {
+ define('YII_DEBUG', true);
+}
+```
+
+显然第一段代码更加简洁易懂。
+
+常量定义应该在入口脚本的开头,这样包含其他 PHP 文件时,常量就能生效。
\ No newline at end of file
diff --git a/docs/guide-zh-CN/structure-models.md b/docs/guide-zh-CN/structure-models.md
new file mode 100644
index 0000000..e483d73
--- /dev/null
+++ b/docs/guide-zh-CN/structure-models.md
@@ -0,0 +1,511 @@
+Models
+======
+
+Models are part of the [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) architecture.
+They are objects representing business data, rules and logic.
+
+You can create model classes by extending [[yii\base\Model]] or its child classes. The base class
+[[yii\base\Model]] supports many useful features:
+
+* [Attributes](#attributes): represent the business data and can be accessed like normal object properties
+ or array elements;
+* [Attribute labels](#attribute-labels): specify the display labels for attributes;
+* [Massive assignment](#massive-assignment): supports populating multiple attributes in a single step;
+* [Validation rules](#validation-rules): ensures input data based on the declared validation rules;
+* [Data Exporting](#data-exporting): allows model data to be exported in terms of arrays with customizable formats.
+
+The `Model` class is also the base class for more advanced models, such as [Active Record](db-active-record.md).
+Please refer to the relevant documentation for more details about these advanced models.
+
+> Info: You are not required to base your model classes on [[yii\base\Model]]. However, because there are many Yii
+ components built to support [[yii\base\Model]], it is usually the preferable base class for a model.
+
+
+## Attributes
+
+Models represent business data in terms of *attributes*. Each attribute is like a publicly accessible property
+of a model. The method [[yii\base\Model::attributes()]] specifies what attributes a model class has.
+
+You can access an attribute like accessing a normal object property:
+
+```php
+$model = new \app\models\ContactForm;
+
+// "name" is an attribute of ContactForm
+$model->name = 'example';
+echo $model->name;
+```
+
+You can also access attributes like accessing array elements, thanks to the support for
+[ArrayAccess](http://php.net/manual/en/class.arrayaccess.php) and [ArrayIterator](http://php.net/manual/en/class.arrayiterator.php)
+by [[yii\base\Model]]:
+
+```php
+$model = new \app\models\ContactForm;
+
+// accessing attributes like array elements
+$model['name'] = 'example';
+echo $model['name'];
+
+// iterate attributes
+foreach ($model as $name => $value) {
+ echo "$name: $value\n";
+}
+```
+
+
+### Defining Attributes
+
+By default, if your model class extends directly from [[yii\base\Model]], all its *non-static public* member
+variables are attributes. For example, the `ContactForm` model class below has four attributes: `name`, `email`,
+`subject` and `body`. The `ContactForm` model is used to represent the input data received from an HTML form.
+
+```php
+namespace app\models;
+
+use yii\base\Model;
+
+class ContactForm extends Model
+{
+ public $name;
+ public $email;
+ public $subject;
+ public $body;
+}
+```
+
+
+You may override [[yii\base\Model::attributes()]] to define attributes in a different way. The method should
+return the names of the attributes in a model. For example, [[yii\db\ActiveRecord]] does so by returning
+the column names of the associated database table as its attribute names. Note that you may also need to
+override the magic methods such as `__get()`, `__set()` so that the attributes can be accessed like
+normal object properties.
+
+
+### Attribute Labels
+
+When displaying values or getting input for attributes, you often need to display some labels associated
+with attributes. For example, given an attribute named `firstName`, you may want to display a label `First Name`
+which is more user-friendly when displayed to end users in places such as form inputs and error messages.
+
+You can get the label of an attribute by calling [[yii\base\Model::getAttributeLabel()]]. For example,
+
+```php
+$model = new \app\models\ContactForm;
+
+// displays "Name"
+echo $model->getAttributeLabel('name');
+```
+
+By default, attribute labels are automatically generated from attribute names. The generation is done by
+the method [[yii\base\Model::generateAttributeLabel()]]. It will turn camel-case variable names into
+multiple words with the first letter in each word in upper case. For example, `username` becomes `Username`,
+and `firstName` becomes `First Name`.
+
+If you do not want to use automatically generated labels, you may override [[yii\base\Model::attributeLabels()]]
+to explicitly declare attribute labels. For example,
+
+```php
+namespace app\models;
+
+use yii\base\Model;
+
+class ContactForm extends Model
+{
+ public $name;
+ public $email;
+ public $subject;
+ public $body;
+
+ public function attributeLabels()
+ {
+ return [
+ 'name' => 'Your name',
+ 'email' => 'Your email address',
+ 'subject' => 'Subject',
+ 'body' => 'Content',
+ ];
+ }
+}
+```
+
+For applications supporting multiple languages, you may want to translate attribute labels. This can be done
+in the [[yii\base\Model::attributeLabels()|attributeLabels()]] method as well, like the following:
+
+```php
+public function attributeLabels()
+{
+ return [
+ 'name' => \Yii::t('app', 'Your name'),
+ 'email' => \Yii::t('app', 'Your email address'),
+ 'subject' => \Yii::t('app', 'Subject'),
+ 'body' => \Yii::t('app', 'Content'),
+ ];
+}
+```
+
+You may even conditionally define attribute labels. For example, based on the [scenario](#scenarios) the model
+is being used in, you may return different labels for the same attribute.
+
+> Info: Strictly speaking, attribute labels are part of [views](structure-views.md). But declaring labels
+ in models is often very convenient and can result in very clean and reusable code.
+
+
+## Scenarios
+
+A model may be used in different *scenarios*. For example, a `User` model may be used to collect user login inputs,
+but it may also be used for the user registration purpose. In different scenarios, a model may use different
+business rules and logic. For example, the `email` attribute may be required during user registration,
+but not so during user login.
+
+A model uses the [[yii\base\Model::scenario]] property to keep track of the scenario it is being used in.
+By default, a model supports only a single scenario named `default`. The following code shows two ways of
+setting the scenario of a model:
+
+```php
+// scenario is set as a property
+$model = new User;
+$model->scenario = 'login';
+
+// scenario is set through configuration
+$model = new User(['scenario' => 'login']);
+```
+
+By default, the scenarios supported by a model are determined by the [validation rules](#validation-rules) declared
+in the model. However, you can customize this behavior by overriding the [[yii\base\Model::scenarios()]] method,
+like the following:
+
+```php
+namespace app\models;
+
+use yii\db\ActiveRecord;
+
+class User extends ActiveRecord
+{
+ public function scenarios()
+ {
+ return [
+ 'login' => ['username', 'password'],
+ 'register' => ['username', 'email', 'password'],
+ ];
+ }
+}
+```
+
+> Info: In the above and following examples, the model classes are extending from [[yii\db\ActiveRecord]]
+ because the usage of multiple scenarios usually happens to [Active Record](db-active-record.md) classes.
+
+The `scenarios()` method returns an array whose keys are the scenario names and values the corresponding
+*active attributes*. An active attribute can be [massively assigned](#massive-assignment) and is subject
+to [validation](#validation-rules). In the above example, the `username` and `password` attributes are active
+in the `login` scenario; while in the `register` scenario, `email` is also active besides `username` and `password`.
+
+The default implementation of `scenarios()` will return all scenarios found in the validation rule declaration
+method [[yii\base\Model::rules()]]. When overriding `scenarios()`, if you want to introduce new scenarios
+in addition to the default ones, you may write code like the following:
+
+```php
+namespace app\models;
+
+use yii\db\ActiveRecord;
+
+class User extends ActiveRecord
+{
+ public function scenarios()
+ {
+ $scenarios = parent::scenarios();
+ $scenarios['login'] = ['username', 'password'];
+ $scenarios['register'] = ['username', 'email', 'password'];
+ return $scenarios;
+ }
+}
+```
+
+The scenario feature is primarily used by [validation](#validation-rules) and [massive attribute assignment](#massive-assignment).
+You can, however, use it for other purposes. For example, you may declare [attribute labels](#attribute-labels)
+differently based on the current scenario.
+
+
+## Validation Rules
+
+When the data for a model is received from end users, it should be validated to make sure it satisfies
+certain rules (called *validation rules*, also known as *business rules*). For example, given a `ContactForm` model,
+you may want to make sure all attributes are not empty and the `email` attribute contains a valid email address.
+If the values for some attributes do not satisfy the corresponding business rules, appropriate error messages
+should be displayed to help the user to fix the errors.
+
+You may call [[yii\base\Model::validate()]] to validate the received data. The method will use
+the validation rules declared in [[yii\base\Model::rules()]] to validate every relevant attribute. If no error
+is found, it will return true. Otherwise, it will keep the errors in the [[yii\base\Model::errors]] property
+and return false. For example,
+
+```php
+$model = new \app\models\ContactForm;
+
+// populate model attributes with user inputs
+$model->attributes = \Yii::$app->request->post('ContactForm');
+
+if ($model->validate()) {
+ // all inputs are valid
+} else {
+ // validation failed: $errors is an array containing error messages
+ $errors = $model->errors;
+}
+```
+
+
+To declare validation rules associated with a model, override the [[yii\base\Model::rules()]] method by returning
+the rules that the model attributes should satisfy. The following example shows the validation rules declared
+for the `ContactForm` model:
+
+```php
+public function rules()
+{
+ return [
+ // the name, email, subject and body attributes are required
+ [['name', 'email', 'subject', 'body'], 'required'],
+
+ // the email attribute should be a valid email address
+ ['email', 'email'],
+ ];
+}
+```
+
+A rule can be used to validate one or multiple attributes, and an attribute may be validated by one or multiple rules.
+Please refer to the [Validating Input](input-validation.md) section for more details on how to declare
+validation rules.
+
+Sometimes, you may want a rule to be applied only in certain [scenarios](#scenarios). To do so, you can
+specify the `on` property of a rule, like the following:
+
+```php
+public function rules()
+{
+ return [
+ // username, email and password are all required in "register" scenario
+ [['username', 'email', 'password'], 'required', 'on' => 'register'],
+
+ // username and password are required in "login" scenario
+ [['username', 'password'], 'required', 'on' => 'login'],
+ ];
+}
+```
+
+If you do not specify the `on` property, the rule would be applied in all scenarios. A rule is called
+an *active rule* if it can be applied in the current [[yii\base\Model::scenario|scenario]].
+
+An attribute will be validated if and only if it is an active attribute declared in `scenarios()` and
+is associated with one or multiple active rules declared in `rules()`.
+
+
+## Massive Assignment
+
+Massive assignment is a convenient way of populating a model with user inputs using a single line of code.
+It populates the attributes of a model by assigning the input data directly to the [[yii\base\Model::$attributes]]
+property. The following two pieces of code are equivalent, both trying to assign the form data submitted by end users
+to the attributes of the `ContactForm` model. Clearly, the former, which uses massive assignment, is much cleaner
+and less error prone than the latter:
+
+```php
+$model = new \app\models\ContactForm;
+$model->attributes = \Yii::$app->request->post('ContactForm');
+```
+
+```php
+$model = new \app\models\ContactForm;
+$data = \Yii::$app->request->post('ContactForm', []);
+$model->name = isset($data['name']) ? $data['name'] : null;
+$model->email = isset($data['email']) ? $data['email'] : null;
+$model->subject = isset($data['subject']) ? $data['subject'] : null;
+$model->body = isset($data['body']) ? $data['body'] : null;
+```
+
+
+### Safe Attributes
+
+Massive assignment only applies to the so-called *safe attributes* which are the attributes listed in
+[[yii\base\Model::scenarios()]] for the current [[yii\base\Model::scenario|scenario]] of a model.
+For example, if the `User` model has the following scenario declaration, then when the current scenario
+is `login`, only the `username` and `password` can be massively assigned. Any other attributes will
+be kept untouched.
+
+```php
+public function scenarios()
+{
+ return [
+ 'login' => ['username', 'password'],
+ 'register' => ['username', 'email', 'password'],
+ ];
+}
+```
+
+> Info: The reason that massive assignment only applies to safe attributes is because you want to
+ control which attributes can be modified by end user data. For example, if the `User` model
+ has a `permission` attribute which determines the permission assigned to the user, you would
+ like this attribute to be modifiable by administrators through a backend interface only.
+
+Because the default implementation of [[yii\base\Model::scenarios()]] will return all scenarios and attributes
+found in [[yii\base\Model::rules()]], if you do not override this method, it means an attribute is safe as long
+as it appears in one of the active validation rules.
+
+For this reason, a special validator aliased `safe` is provided so that you can declare an attribute
+to be safe without actually validating it. For example, the following rules declare that both `title`
+and `description` are safe attributes.
+
+```php
+public function rules()
+{
+ return [
+ [['title', 'description'], 'safe'],
+ ];
+}
+```
+
+
+### Unsafe Attributes
+
+As described above, the [[yii\base\Model::scenarios()]] method serves for two purposes: determining which attributes
+should be validated, and determining which attributes are safe. In some rare cases, you may want to validate
+an attribute but do not want to mark it safe. You can do so by prefixing an exclamation mark `!` to the attribute
+name when declaring it in `scenarios()`, like the `secret` attribute in the following:
+
+```php
+public function scenarios()
+{
+ return [
+ 'login' => ['username', 'password', '!secret'],
+ ];
+}
+```
+
+When the model is in the `login` scenario, all three attributes will be validated. However, only the `username`
+and `password` attributes can be massively assigned. To assign an input value to the `secret` attribute, you
+have to do it explicitly as follows,
+
+```php
+$model->secret = $secret;
+```
+
+
+## Data Exporting
+
+Models often need to be exported in different formats. For example, you may want to convert a collection of
+models into JSON or Excel format. The exporting process can be broken down into two independent steps.
+In the first step, models are converted into arrays; in the second step, the arrays are converted into
+target formats. You may just focus on the first step, because the second step can be achieved by generic
+data formatters, such as [[yii\web\JsonResponseFormatter]].
+
+The simplest way of converting a model into an array is to use the [[yii\base\Model::$attributes]] property.
+For example,
+
+```php
+$post = \app\models\Post::findOne(100);
+$array = $post->attributes;
+```
+
+By default, the [[yii\base\Model::$attributes]] property will return the values of *all* attributes
+declared in [[yii\base\Model::attributes()]].
+
+A more flexible and powerful way of converting a model into an array is to use the [[yii\base\Model::toArray()]]
+method. Its default behavior is the same as that of [[yii\base\Model::$attributes]]. However, it allows you
+to choose which data items, called *fields*, to be put in the resulting array and how they should be formatted.
+In fact, it is the default way of exporting models in RESTful Web service development, as described in
+the [Response Formatting](rest-response-formatting.md).
+
+
+### Fields
+
+A field is simply a named element in the array that is obtained by calling the [[yii\base\Model::toArray()]] method
+of a model.
+
+By default, field names are equivalent to attribute names. However, you can change this behavior by overriding
+the [[yii\base\Model::fields()|fields()]] and/or [[yii\base\Model::extraFields()|extraFields()]] methods. Both methods
+should return a list of field definitions. The fields defined by `fields()` are default fields, meaning that
+`toArray()` will return these fields by default. The `extraFields()` method defines additionally available fields
+which can also be returned by `toArray()` as long as you specify them via the `$expand` parameter. For example,
+the following code will return all fields defined in `fields()` and the `prettyName` and `fullAddress` fields
+if they are defined in `extraFields()`.
+
+```php
+$array = $model->toArray([], ['prettyName', 'fullAddress']);
+```
+
+You can override `fields()` to add, remove, rename or redefine fields. The return value of `fields()`
+should be an array. The array keys are the field names, and the array values are the corresponding
+field definitions which can be either property/attribute names or anonymous functions returning the
+corresponding field values. In the special case when a field name is the same as its defining attribute
+name, you can omit the array key. For example,
+
+```php
+// explicitly list every field, best used when you want to make sure the changes
+// in your DB table or model attributes do not cause your field changes (to keep API backward compatibility).
+public function fields()
+{
+ return [
+ // field name is the same as the attribute name
+ 'id',
+
+ // field name is "email", the corresponding attribute name is "email_address"
+ 'email' => 'email_address',
+
+ // field name is "name", its value is defined by a PHP callback
+ 'name' => function () {
+ return $this->first_name . ' ' . $this->last_name;
+ },
+ ];
+}
+
+// filter out some fields, best used when you want to inherit the parent implementation
+// and blacklist some sensitive fields.
+public function fields()
+{
+ $fields = parent::fields();
+
+ // remove fields that contain sensitive information
+ unset($fields['auth_key'], $fields['password_hash'], $fields['password_reset_token']);
+
+ return $fields;
+}
+```
+
+> Warning: Because by default all attributes of a model will be included in the exported array, you should
+> examine your data to make sure they do not contain sensitive information. If there is such information,
+> you should override `fields()` to filter them out. In the above example, we choose
+> to filter out `auth_key`, `password_hash` and `password_reset_token`.
+
+
+## Best Practices
+
+Models are the central places to represent business data, rules and logic. They often need to be reused
+in different places. In a well-designed application, models are usually much fatter than
+[controllers](structure-controllers.md).
+
+In summary, models
+
+* may contain attributes to represent business data;
+* may contain validation rules to ensure the data validity and integrity;
+* may contain methods implementing business logic;
+* should NOT directly access request, session, or any other environmental data. These data should be injected
+ by [controllers](structure-controllers.md) into models;
+* should avoid embedding HTML or other presentational code - this is better done in [views](structure-views.md);
+* avoid having too many [scenarios](#scenarios) in a single model.
+
+You may usually consider the last recommendation above when you are developing large complex systems.
+In these systems, models could be very fat because they are used in many places and may thus contain many sets
+of rules and business logic. This often ends up in a nightmare in maintaining the model code
+because a single touch of the code could affect several different places. To make the mode code more maintainable,
+you may take the following strategy:
+
+* Define a set of base model classes that are shared by different [applications](structure-applications.md) or
+ [modules](structure-modules.md). These model classes should contain minimal sets of rules and logic that
+ are common among all their usages.
+* In each [application](structure-applications.md) or [module](structure-modules.md) that uses a model,
+ define a concrete model class by extending from the corresponding base model class. The concrete model classes
+ should contain rules and logic that are specific for that application or module.
+
+For example, in the [Advanced Application Template](tutorial-advanced-app.md), you may define a base model
+class `common\models\Post`. Then for the front end application, you define and use a concrete model class
+`frontend\models\Post` which extends from `common\models\Post`. And similarly for the back end application,
+you define `backend\models\Post`. With this strategy, you will be sure that the code in `frontend\models\Post`
+is only specific to the front end application, and if you make any change to it, you do not need to worry if
+the change may break the back end application.
diff --git a/docs/guide-zh-CN/structure-overview.md b/docs/guide-zh-CN/structure-overview.md
new file mode 100644
index 0000000..93bf583
--- /dev/null
+++ b/docs/guide-zh-CN/structure-overview.md
@@ -0,0 +1,18 @@
+总览
+========
+
+Yii 应用参照[模型-视图-控制器 (MVC)](http://wikipedia.org/wiki/Model-view-controller)
+ 设计模式来组织。 [模型](structure-models.md)代表数据、业务逻辑和规则;[视图](structure-views.md)展示模型的输出;[控制器](structure-controllers.md)接受出入并将其转换为[模型](structure-models.md)和[视图](structure-views.md)命令。
+
+除了 MVC, Yii 应用还有以下部分:
+
+* [入口脚本](structure-entry-scripts.md):终端用户能直接访问的 PHP 脚本,负责启动一个请求处理周期。
+* [应用](structure-applications.md):能全局范围内访问的对象,管理协调组件来完成请求.
+* [应用组件](structure-application-components.md):在应用中注册的对象,提供不同的功能来完成请求。
+* [模块](structure-modules.md):包含完整 MVC 结构的独立包,一个应用可以由多个模块组建。
+* [过滤器](structure-filters.md):控制器在处理请求之前或之后需要触发执行的代码。
+* [小部件](structure-widgets.md):可嵌入到[视图](structure-views.md)中的对象,可包含控制器逻辑,可被不同视图重复调用。
+
+下面的示意图展示了 Yii 应用的静态结构:
+
+![Yii应用静态结构](images/application-structure.png)
diff --git a/docs/guide-zh-CN/structure-views.md b/docs/guide-zh-CN/structure-views.md
new file mode 100644
index 0000000..1b13333
--- /dev/null
+++ b/docs/guide-zh-CN/structure-views.md
@@ -0,0 +1,722 @@
+Views
+=====
+
+Views are part of the [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) architecture.
+They are code responsible for presenting data to end users. In a Web application, views are usually created
+in terms of *view templates* which are PHP script files containing mainly HTML code and presentational PHP code.
+They are managed by the [[yii\web\View|view]] application component which provides commonly used methods
+to facilitate view composition and rendering. For simplicity, we often call view templates or view template files
+as views.
+
+
+## Creating Views
+
+As aforementioned, a view is simply a PHP script mixed with HTML and PHP code. The following is the view
+that presents a login form. As you can see, PHP code is used to generate the dynamic content, such as the
+page title and the form, while HTML code organizes them into a presentable HTML page.
+
+```php
+title = 'Login';
+?>
+
= Html::encode($this->title) ?>
+
+
Please fill out the following fields to login:
+
+
+ = $form->field($model, 'username') ?>
+ = $form->field($model, 'password')->passwordInput() ?>
+ = Html::submitButton('Login') ?>
+
+```
+
+Within a view, you can access `$this` which refers to the [[yii\web\View|view component]] managing
+and rendering this view template.
+
+Besides `$this`, there may be other predefined variables in a view, such as `$model` in the above
+example. These variables represent the data that are *pushed* into the view by [controllers](structure-controllers.md)
+or other objects whose trigger the [view rendering](#rendering-views).
+
+> Tip: The predefined variables are listed in a comment block at beginning of a view so that they can
+ be recognized by IDEs. It is also a good way of documenting your views.
+
+
+### Security
+
+When creating views that generate HTML pages, it is important that you encode and/or filter the data coming
+from end users before presenting them. Otherwise, your application may be subject to
+[cross-site scripting](http://en.wikipedia.org/wiki/Cross-site_scripting) attacks.
+
+To display a plain text, encode it first by calling [[yii\helpers\Html::encode()]]. For example, the following code
+encodes the user name before displaying it:
+
+```php
+
+
+
+ = Html::encode($user->name) ?>
+
+```
+
+To display HTML content, use [[yii\helpers\HtmlPurifier]] to filter the content first. For example, the following
+code filters the post content before displaying it:
+
+```php
+
+
+
+ = HtmlPurifier::process($post->text) ?>
+
+```
+
+> Tip: While HTMLPurifier does excellent job in making output safe, it is not fast. You should consider
+ [caching](caching-overview.md) the filtering result if your application requires high performance.
+
+
+### Organizing Views
+
+Like [controllers](structure-controllers.md) and [models](structure-models.md), there are conventions to organize views.
+
+* For views rendered by a controller, they should be put under the directory `@app/views/ControllerID` by default,
+ where `ControllerID` refers to the [controller ID](structure-controllers.md#routes). For example, if
+ the controller class is `PostController`, the directory would be `@app/views/post`; If it is `PostCommentController`,
+ the directory would be `@app/views/post-comment`. In case the controller belongs to a module, the directory
+ would be `views/ControllerID` under the [[yii\base\Module::basePath|module directory]].
+* For views rendered in a [widget](structure-widgets.md), they should be put under the `WidgetPath/views` directory by
+ default, where `WidgetPath` stands for the directory containing the widget class file.
+* For views rendered by other objects, it is recommended that you follow the similar convention as that for widgets.
+
+You may customize these default view directories by overriding the [[yii\base\ViewContextInterface::getViewPath()]]
+method of controllers or widgets.
+
+
+## Rendering Views
+
+You can render views in [controllers](structure-controllers.md), [widgets](structure-widgets.md), or any
+other places by calling view rendering methods. These methods share a similar signature shown as follows,
+
+```
+/**
+ * @param string $view view name or file path, depending on the actual rendering method
+ * @param array $params the data to be passed to the view
+ * @return string rendering result
+ */
+methodName($view, $params = [])
+```
+
+
+### Rendering in Controllers
+
+Within [controllers](structure-controllers.md), you may call the following controller methods to render views:
+
+* [[yii\base\Controller::render()|render()]]: renders a [named view](#named-views) and applies a [layout](#layouts)
+ to the rendering result.
+* [[yii\base\Controller::renderPartial()|renderPartial()]]: renders a [named view](#named-views) without any layout.
+* [[yii\web\Controller::renderAjax()|renderAjax()]]: renders a [named view](#named-views) without any layout,
+ and injects all registered JS/CSS scripts and files. It is usually used in response to AJAX Web requests.
+* [[yii\base\Controller::renderFile()|renderFile()]]: renders a view specified in terms of a view file path or
+ [alias](concept-aliases.md).
+
+For example,
+
+```php
+namespace app\controllers;
+
+use Yii;
+use app\models\Post;
+use yii\web\Controller;
+use yii\web\NotFoundHttpException;
+
+class PostController extends Controller
+{
+ public function actionView($id)
+ {
+ $model = Post::findOne($id);
+ if ($model === null) {
+ throw new NotFoundHttpException;
+ }
+
+ // renders a view named "view" and applies a layout to it
+ return $this->render('view', [
+ 'model' => $model,
+ ]);
+ }
+}
+```
+
+
+### Rendering in Widgets
+
+Within [widgets](structure-widgets.md), you may call the following widget methods to render views.
+
+* [[yii\base\Widget::render()|render()]]: renders a [named view](#named-views).
+* [[yii\base\Widget::renderFile()|renderFile()]]: renders a view specified in terms of a view file path or
+ [alias](concept-aliases.md).
+
+For example,
+
+```php
+namespace app\components;
+
+use yii\base\Widget;
+use yii\helpers\Html;
+
+class ListWidget extends Widget
+{
+ public $items = [];
+
+ public function run()
+ {
+ // renders a view named "list"
+ return $this->render('list', [
+ 'items' => $this->items,
+ ]);
+ }
+}
+```
+
+
+### Rendering in Views
+
+You can render a view within another view by calling one of the following methods provided by the [[yii\base\View|view component]]:
+
+* [[yii\base\View::render()|render()]]: renders a [named view](#named-views).
+* [[yii\web\View::renderAjax()|renderAjax()]]: renders a [named view](#named-views) and injects all registered
+ JS/CSS scripts and files. It is usually used in response to AJAX Web requests.
+* [[yii\base\View::renderFile()|renderFile()]]: renders a view specified in terms of a view file path or
+ [alias](concept-aliases.md).
+
+For example, the following code in a view renders the `_overview.php` view file which is in the same directory
+as the view being currently rendered. Remember that `$this` in a view refers to the [[yii\base\View|view]] component:
+
+```php
+= $this->render('_overview') ?>
+```
+
+
+### Rendering in Other Places
+
+In any place, you can get access to the [[yii\base\View|view]] application component by the expression
+`Yii::$app->view` and then call its aforementioned methods to render a view. For example,
+
+```php
+// displays the view file "@app/views/site/license.php"
+echo \Yii::$app->view->renderFile('@app/views/site/license.php');
+```
+
+
+### Named Views
+
+When you render a view, you can specify the view using either a view name or a view file path/alias. In most cases,
+you would use the former because it is more concise and flexible. We call views specified using names as *named views*.
+
+A view name is resolved into the corresponding view file path according to the following rules:
+
+* A view name may omit the file extension name. In this case, `.php` will be used as the extension. For example,
+ the view name `about` corresponds to the file name `about.php`.
+* If the view name starts with double slashes `//`, the corresponding view file path would be `@app/views/ViewName`.
+ That is, the view is looked for under the [[yii\base\Application::viewPath|application's view path]].
+ For example, `//site/about` will be resolved into `@app/views/site/about.php`.
+* If the view name starts with a single slash `/`, the view file path is formed by prefixing the view name
+ with the [[yii\base\Module::viewPath|view path]] of the currently active [module](structure-modules.md).
+ If there is no active module, `@app/views/ViewName` will be used. For example, `/user/create` will be resolved into
+ `@app/modules/user/views/user/create.php`, if the currently active module is `user`. If there is no active module,
+ the view file path would be `@app/views/user/create.php`.
+* If the view is rendered with a [[yii\base\View::context|context]] and the context implements [[yii\base\ViewContextInterface]],
+ the view file path is formed by prefixing the [[yii\base\ViewContextInterface::getViewPath()|view path]] of the
+ context to the view name. This mainly applies to the views rendered within controllers and widgets. For example,
+ `site/about` will be resolved into `@app/views/site/about.php` if the context is the controller `SiteController`.
+* If a view is rendered within another view, the directory containing the other view file will be prefixed to
+ the new view name to form the actual view file path. For example, `item` will be resolved into `@app/views/post/item`
+ if it is being rendered in the view `@app/views/post/index.php`.
+
+According to the above rules, calling `$this->render('view')` in a controller `app\controllers\PostController` will
+actually render the view file `@app/views/post/view.php`, while calling `$this->render('_overview')` in that view
+will render the view file `@app/views/post/_overview.php`.
+
+
+### Accessing Data in Views
+
+There are two approaches to access data within a view: push and pull.
+
+By passing the data as the second parameter to the view rendering methods, you are using the push approach.
+The data should be represented as an array of name-value pairs. When the view is being rendered, the PHP
+`extract()` function will be called on this array so that the array is extracted into variables in the view.
+For example, the following view rendering code in a controller will push two variables to the `report` view:
+`$foo = 1` and `$bar = 2`.
+
+```php
+echo $this->render('report', [
+ 'foo' => 1,
+ 'bar' => 2,
+]);
+```
+
+The pull approach actively retrieves data from the [[yii\base\View|view component]] or other objects accessible
+in views (e.g. `Yii::$app`). Using the code below as an example, within the view you can get the controller object
+by the expression `$this->context`. And as a result, it is possible for you to access any properties or methods
+of the controller in the `report` view, such as the controller ID shown in the following:
+
+```php
+The controller ID is: = $this->context->id ?>
+?>
+```
+
+The push approach is usually the preferred way of accessing data in views, because it makes views less dependent
+on context objects. Its drawback is that you need to manually build the data array all the time, which could
+become tedious and error prone if a view is shared and rendered in different places.
+
+
+### Sharing Data among Views
+
+The [[yii\base\View|view component]] provides the [[yii\base\View::params|params]] property that you can use
+to share data among views.
+
+For example, in an `about` view, you can have the following code which specifies the current segment of the
+breadcrumbs.
+
+```php
+$this->params['breadcrumbs'][] = 'About Us';
+```
+
+Then, in the [layout](#layouts) file, which is also a view, you can display the breadcrumbs using the data
+passed along [[yii\base\View::params|params]]:
+
+```php
+= yii\widgets\Breadcrumbs::widget([
+ 'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
+]) ?>
+```
+
+
+## Layouts
+
+Layouts are a special type of views that represent the common parts of multiple views. For example, the pages
+for most Web applications share the same page header and footer. While you can repeat the same page header and footer
+in every view, a better way is to do this once in a layout and embed the rendering result of a content view at
+an appropriate place in the layout.
+
+
+### Creating Layouts
+
+Because layouts are also views, they can be created in the similar way as normal views. By default, layouts
+are stored in the directory `@app/views/layouts`. For layouts used within a [module](structure-modules.md),
+they should be stored in the `views/layouts` directory under the [[yii\base\Module::basePath|module directory]].
+You may customize the default layout directory by configuring the [[yii\base\Module::layoutPath]] property of
+the application or modules.
+
+The following example shows how a layout looks like. Note that for illustrative purpose, we have greatly simplified
+the code in the layout. In practice, you may want to add more content to it, such as head tags, main menu, etc.
+
+```php
+
+beginPage() ?>
+
+
+
+
+ = Html::csrfMetaTags() ?>
+ = Html::encode($this->title) ?>
+ head() ?>
+
+
+beginBody() ?>
+ My Company
+ = $content ?>
+
+endBody() ?>
+
+
+endPage() ?>
+```
+
+As you can see, the layout generates the HTML tags that are common to all pages. Within the `` section,
+the layout echoes the `$content` variable which represents the rendering result of content views and is pushed
+into the layout when [[yii\base\Controller::render()]] is called.
+
+Most layouts should call the following methods like shown in the above code. These methods mainly trigger events
+about the rendering process so that scripts and tags registered in other places can be properly injected into
+the places where these methods are called.
+
+- [[yii\base\View::beginPage()|beginPage()]]: This method should be called at the very beginning of the layout.
+ It triggers the [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]] event which indicates the beginning of a page.
+- [[yii\base\View::endPage()|endPage()]]: This method should be called at the end of the layout.
+ It triggers the [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]] event which indicates the end of a page.
+- [[yii\web\View::head()|head()]]: This method should be called within the `` section of an HTML page.
+ It generates a placeholder which will be replaced with the registered head HTML code (e.g. link tags, meta tags)
+ when a page finishes rendering.
+- [[yii\web\View::beginBody()|beginBody()]]: This method should be called at the beginning of the `` section.
+ It triggers the [[yii\web\View::EVENT_BEGIN_BODY|EVENT_BEGIN_BODY]] event and generates a placeholder which will
+ be replaced by the registered HTML code (e.g. JavaScript) targeted at the body begin position.
+- [[yii\web\View::endBody()|endBody()]]: This method should be called at the end of the `` section.
+ It triggers the [[yii\web\View::EVENT_END_BODY|EVENT_END_BODY]] event and generates a placeholder which will
+ be replaced by the registered HTML code (e.g. JavaScript) targeted at the body end position.
+
+
+### Accessing Data in Layouts
+
+Within a layout, you have access to two predefined variables: `$this` and `$content`. The former refers to
+the [[yii\base\View|view]] component, like in normal views, while the latter contains the rendering result of a content
+view which is rendered by calling the [[yii\base\Controller::render()|render()]] method in controllers.
+
+If you want to access other data in layouts, you have to use the pull method as described in
+the [Accessing Data in Views](#accessing-data-in-views) subsection. If you want to pass data from a content view
+to a layout, you may use the method described in the [Sharing Data among Views](#sharing-data-among-views) subsection.
+
+
+### Using Layouts
+
+As described in the [Rendering in Controllers](#rendering-in-controllers) subsection, when you render a view
+by calling the [[yii\base\Controller::render()|render()]] method in a controller, a layout will be applied
+to the rendering result. By default, the layout `@app/views/layouts/main.php` will be used.
+
+You may use a different layout by configuring either [[yii\base\Application::layout]] or [[yii\base\Controller::layout]].
+The former governs the layout used by all controllers, while the latter overrides the former for individual controllers.
+For example, the following code makes the `post` controller to use `@app/views/layouts/post.php` as the layout
+when rendering its views. Other controllers, assuming their `layout` property is untouched, will still use the default
+`@app/views/layouts/main.php` as the layout.
+
+```php
+namespace app\controllers;
+
+use yii\web\Controller;
+
+class PostController extends Controller
+{
+ public $layout = 'post';
+
+ // ...
+}
+```
+
+For controllers belonging to a module, you may also configure the module's [[yii\base\Module::layout|layout]] property to
+use a particular layout for these controllers.
+
+Because the `layout` property may be configured at different levels (controllers, modules, application),
+behind the scene Yii takes two steps to determine what is the actual layout file being used for a particular controller.
+
+In the first step, it determines the layout value and the context module:
+
+- If the [[yii\base\Controller::layout]] property of the controller is not null, use it as the layout value and
+ the [[yii\base\Controller::module|module]] of the controller as the context module.
+- If [[yii\base\Controller::layout|layout]] is null, search through all ancestor modules (including the application itself) of the controller and
+ find the first module whose [[yii\base\Module::layout|layout]] property is not null. Use that module and
+ its [[yii\base\Module::layout|layout]] value as the context module and the chosen layout value.
+ If such a module cannot be found, it means no layout will be applied.
+
+In the second step, it determines the actual layout file according to the layout value and the context module
+determined in the first step. The layout value can be:
+
+- a path alias (e.g. `@app/views/layouts/main`).
+- an absolute path (e.g. `/main`): the layout value starts with a slash. The actual layout file will be
+ looked for under the application's [[yii\base\Application::layoutPath|layout path]] which defaults to
+ `@app/views/layouts`.
+- a relative path (e.g. `main`): the actual layout file will be looked for under the context module's
+ [[yii\base\Module::layoutPath|layout path]] which defaults to the `views/layouts` directory under the
+ [[yii\base\Module::basePath|module directory]].
+- the boolean value `false`: no layout will be applied.
+
+If the layout value does not contain a file extension, it will use the default one `.php`.
+
+
+### Nested Layouts
+
+Sometimes you may want to nest one layout in another. For example, in different sections of a Web site, you
+want to use different layouts, while all these layouts share the same basic layout that generates the overall
+HTML5 page structure. You can achieve this goal by calling [[yii\base\View::beginContent()|beginContent()]] and
+[[yii\base\View::endContent()|endContent()]] in the child layouts like the following:
+
+```php
+beginContent('@app/views/layouts/base.php'); ?>
+
+...child layout content here...
+
+endContent(); ?>
+```
+
+As shown above, the child layout content should be enclosed within [[yii\base\View::beginContent()|beginContent()]] and
+[[yii\base\View::endContent()|endContent()]]. The parameter passed to [[yii\base\View::beginContent()|beginContent()]]
+specifies what is the parent layout. It can be either a layout file or alias.
+
+Using the above approach, you can nest layouts in more than one levels.
+
+
+### Using Blocks
+
+Blocks allow you to specify the view content in one place while displaying it in another. They are often used together
+with layouts. For example, you can define a block in a content view and display it in the layout.
+
+You call [[yii\base\View::beginBlock()|beginBlock()]] and [[yii\base\View::endBlock()|endBlock()]] to define a block.
+The block can then be accessed via `$view->blocks[$blockID]`, where `$blockID` stands for a unique ID that you assign
+to the block when defining it.
+
+The following example shows how you can use blocks to customize specific parts of a layout in a content view.
+
+First, in a content view, define one or multiple blocks:
+
+```php
+...
+
+beginBlock('block1'); ?>
+
+...content of block1...
+
+endBlock(); ?>
+
+...
+
+beginBlock('block3'); ?>
+
+...content of block3...
+
+endBlock(); ?>
+```
+
+Then, in the layout view, render the blocks if they are available, or display some default content if a block is
+not defined.
+
+```php
+...
+blocks['block1'])): ?>
+ = $this->blocks['block1'] ?>
+
+ ... default content for block1 ...
+
+
+...
+
+blocks['block2'])): ?>
+ = $this->blocks['block2'] ?>
+
+ ... default content for block2 ...
+
+
+...
+
+blocks['block3'])): ?>
+ = $this->blocks['block3'] ?>
+
+ ... default content for block3 ...
+
+...
+```
+
+
+## Using View Components
+
+[[yii\base\View|View components]] provides many view-related features. While you can get view components
+by creating individual instances of [[yii\base\View]] or its child class, in most cases you will mainly use
+the `view` application component. You can configure this component in [application configurations](structure-applications.md#application-configurations)
+like the following:
+
+```php
+[
+ // ...
+ 'components' => [
+ 'view' => [
+ 'class' => 'app\components\View',
+ ],
+ // ...
+ ],
+]
+```
+
+View components provide the following useful view-related features, each described in more details in a separate section:
+
+* [theming](output-theming.md): allows you to develop and change the theme for your Web site.
+* [fragment caching](caching-fragment.md): allows you to cache a fragment within a Web page.
+* [client script handling](output-client-scripts.md): supports CSS and JavaScript registration and rendering.
+* [asset bundle handling](structure-assets.md): supports registering and rendering of [asset bundles](structure-assets.md).
+* [alternative template engines](tutorial-template-engines.md): allows you to use other template engines, such as
+ [Twig](http://twig.sensiolabs.org/), [Smarty](http://www.smarty.net/).
+
+You may also frequently use the following minor yet useful features when you are developing Web pages.
+
+
+### Setting Page Titles
+
+Every Web page should have a title. Normally the title tag is being displayed in a [layout](#layouts). However, in practice
+the title is often determined in content views rather than layouts. To solve this problem, [[yii\web\View]] provides
+the [[yii\web\View::title|title]] property for you to pass the title information from content views to layouts.
+
+To make use of this feature, in each content view, you can set the page title like the following:
+
+```php
+title = 'My page title';
+?>
+```
+
+Then in the layout, make sure you have the following code in the `` section:
+
+```php
+= Html::encode($this->title) ?>
+```
+
+
+### Registering Meta Tags
+
+Web pages usually need to generate various meta tags needed by different parties. Like page titles, meta tags
+appear in the `` section and are usually generated in layouts.
+
+If you want to specify what meta tags to generate in content views, you can call [[yii\web\View::registerMetaTag()]]
+in a content view, like the following:
+
+```php
+registerMetaTag(['name' => 'keywords', 'content' => 'yii, framework, php']);
+?>
+```
+
+The above code will register a "keywords" meta tag with the view component. The registered meta tag is
+rendered after the layout finishes rendering. By then, the following HTML code will be inserted
+at the place where you call [[yii\web\View::head()]] in the layout and generate the following HTML code:
+
+```php
+
+```
+
+Note that if you call [[yii\web\View::registerMetaTag()]] multiple times, it will register multiple meta tags,
+regardless whether the meta tags are the same or not.
+
+To make sure there is only a single instance of a meta tag type, you can specify a key as a second parameter when calling the method.
+For example, the following code registers two "description" meta tags. However, only the second one will be rendered.
+
+```html
+$this->registerMetaTag(['name' => 'description', 'content' => 'This is my cool website made with Yii!'], 'description');
+$this->registerMetaTag(['name' => 'description', 'content' => 'This website is about funny raccoons.'], 'description');
+```
+
+
+### Registering Link Tags
+
+Like [meta tags](#adding-meta-tags), link tags are useful in many cases, such as customizing favicon, pointing to
+RSS feed or delegating OpenID to another server. You can work with link tags in the similar way as meta tags
+by using [[yii\web\View::registerLinkTag()]]. For example, in a content view, you can register a link tag like follows,
+
+```php
+$this->registerLinkTag([
+ 'title' => 'Live News for Yii',
+ 'rel' => 'alternate',
+ 'type' => 'application/rss+xml',
+ 'href' => 'http://www.yiiframework.com/rss.xml/',
+]);
+```
+
+The code above will result in
+
+```html
+
+```
+
+Similar as [[yii\web\View::registerMetaTag()|registerMetaTags()]], you can specify a key when calling
+[[yii\web\View::registerLinkTag()|registerLinkTag()]] to avoid generated repeated link tags.
+
+
+## View Events
+
+[[yii\base\View|View components]] trigger several events during the view rendering process. You may respond
+to these events to inject content into views or process the rendering results before they are sent to end users.
+
+- [[yii\base\View::EVENT_BEFORE_RENDER|EVENT_BEFORE_RENDER]]: triggered at the beginning of rendering a file
+ in a controller. Handlers of this event may set [[yii\base\ViewEvent::isValid]] to be false to cancel the rendering process.
+- [[yii\base\View::EVENT_AFTER_RENDER|EVENT_AFTER_RENDER]]: triggered by the call of [[yii\base\View::beginPage()]] in layouts.
+ Handlers of this event may obtain the rendering result through [[yii\base\ViewEvent::output]] and may modify
+ this property to change the rendering result.
+- [[yii\base\View::EVENT_BEGIN_PAGE|EVENT_BEGIN_PAGE]]: triggered by the call of [[yii\base\View::beginPage()]] in layouts.
+- [[yii\base\View::EVENT_END_PAGE|EVENT_END_PAGE]]: triggered by the call of [[yii\base\View::endPage()]] in layouts.
+- [[yii\web\View::EVENT_BEGIN_BODY|EVENT_BEGIN_BODY]]: triggered by the call of [[yii\web\View::beginBody()]] in layouts.
+- [[yii\web\View::EVENT_END_BODY|EVENT_END_BODY]]: triggered by the call of [[yii\web\View::endBody()]] in layouts.
+
+For example, the following code injects the current date at the end of the page body:
+
+```php
+\Yii::$app->view->on(View::EVENT_END_BODY, function () {
+ echo date('Y-m-d');
+});
+```
+
+
+## Rendering Static Pages
+
+Static pages refer to those Web pages whose main content are mostly static without the need of accessing
+dynamic data pushed from controllers.
+
+You can output static pages by putting their code in the view, and then using the code like the following in a controller:
+
+```php
+public function actionAbout()
+{
+ return $this->render('about');
+}
+```
+
+If a Web site contains many static pages, it would be very tedious repeating the similar code many times.
+To solve this problem, you may introduce a [standalone action](structure-controllers.md#standalone-actions)
+called [[yii\web\ViewAction]] in a controller. For example,
+
+```php
+namespace app\controllers;
+
+use yii\web\Controller;
+
+class SiteController extends Controller
+{
+ public function actions()
+ {
+ return [
+ 'page' => [
+ 'class' => 'yii\web\ViewAction',
+ ],
+ ];
+ }
+}
+```
+
+Now if you create a view named `about` under the directory `@app/views/site/pages`, you will be able to
+display this view by the following URL:
+
+```
+http://localhost/index.php?r=site/page&view=about
+```
+
+The `GET` parameter `view` tells [[yii\web\ViewAction]] which view is requested. The action will then look
+for this view under the directory `@app/views/site/pages`. You may configure [[yii\web\ViewAction::viewPrefix]]
+to change the directory for searching these views.
+
+
+## Best Practices
+
+Views are responsible for presenting models in the format that end users desire. In general, views
+
+* should mainly contain presentational code, such as HTML, and simple PHP code to traverse, format and render data.
+* should not contain code that performs DB queries. Such code should be done in models.
+* should avoid direct access to request data, such as `$_GET`, `$_POST`. This belongs to controllers.
+ If request data is needed, they should be pushed into views by controllers.
+* may read model properties, but should not modify them.
+
+To make views more manageable, avoid creating views that are too complex or contain too much redundant code.
+You may use the following techniques to achieve this goal:
+
+* use [layouts](#layouts) to represent common presentational sections (e.g. page header, footer).
+* divide a complicated view into several smaller ones. The smaller views can be rendered and assembled into a bigger
+ one using the rendering methods that we have described.
+* create and use [widgets](structure-widgets.md) as building blocks of views.
+* create and use helper classes to transform and format data in views.
+