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..1155695
--- /dev/null
+++ b/docs/guide-zh-CN/structure-application-components.md
@@ -0,0 +1,119 @@
+Application Components
+======================
+
+Applications are [service locators](concept-service-locators.md). They host a set of the so-called
+*application components* that provide different services for processing requests. For example,
+the `urlManager` component is responsible for routing Web requests to appropriate controllers;
+the `db` component provides DB-related services; and so on.
+
+Each application component has an ID that uniquely identifies itself among other application components
+in the same application. You can access an application component through the expression
+
+```php
+\Yii::$app->componentID
+```
+
+For example, you can use `\Yii::$app->db` to get the [[yii\db\Connection|DB connection]],
+and `\Yii::$app->cache` to get the [[yii\caching\Cache|primary cache]] registered with the application.
+
+An application component is created the first time it is accessed through the above expression. Any
+further accesses will return the same component instance.
+
+Application components can be any objects. You can register them by configuring
+the [[yii\base\Application::components]] property in [application configurations](structure-applications.md#application-configurations).
+For example,
+
+```php
+[
+    'components' => [
+        // register "cache" component using a class name
+        'cache' => 'yii\caching\ApcCache',
+
+        // register "db" component using a configuration array
+        'db' => [
+            'class' => 'yii\db\Connection',
+            'dsn' => 'mysql:host=localhost;dbname=demo',
+            'username' => 'root',
+            'password' => '',
+        ],
+
+        // register "search" component using an anonymous function
+        'search' => function () {
+            return new app\components\SolrService;
+        },
+    ],
+]
+```
+
+> Info: While you can register as many application components as you want, you should do this judiciously.
+  Application components are like global variables. Using too many application components can potentially
+  make your code harder to test and maintain. In many cases, you can simply create a local component
+  and use it when needed.
+
+
+## Bootstrapping Components <a name="bootstrapping-components"></a>
+
+As mentioned above, an application component will only be instantiated when it is being accessed the first time.
+If it is not accessed at all during a request, it will not be instantiated. Sometimes, however, you may want
+to instantiate an application component for every request, even if it is not explicitly accessed.
+To do so, you may list its ID in the [[yii\base\Application::bootstrap|bootstrap]] property of the application.
+
+For example, the following application configuration makes sure the `log` component is always loaded:
+
+```php
+[
+    'bootstrap' => [
+        'log',
+    ],
+    'components' => [
+        'log' => [
+            // configuration for "log" component
+        ],
+    ],
+]
+```
+
+
+## Core Application Components <a name="core-application-components"></a>
+
+Yii defines a set of *core* application components with fixed IDs and default configurations. For example,
+the [[yii\web\Application::request|request]] component is used to collect information about
+a user request and resolve it into a [route](runtime-routing.md); the [[yii\base\Application::db|db]]
+component represents a database connection through which you can perform database queries.
+It is with help of these core application components that Yii applications are able to handle user requests.
+
+Below is the list of the predefined core application components. You may configure and customize them
+like you do with normal application components. When you are configuring a core application component,
+if you do not specify its class, the default one will be used.
+
+* [[yii\web\AssetManager|assetManager]]: manages asset bundles and asset publishing.
+  Please refer to the [Managing Assets](output-assets.md) section for more details.
+* [[yii\db\Connection|db]]: represents a database connection through which you can perform DB queries.
+  Note that when you configure this component, you must specify the component class as well as other required
+  component properties, such as [[yii\db\Connection::dsn]].
+  Please refer to the [Data Access Objects](db-dao.md) section for more details.
+* [[yii\base\Application::errorHandler|errorHandler]]: handles PHP errors and exceptions.
+  Please refer to the [Handling Errors](tutorial-handling-errors.md) section for more details.
+* [[yii\base\Formatter|formatter]]: formats data when they are displayed to end users. For example, a number
+  may be displayed with thousand separator, a date may be formatted in long format.
+  Please refer to the [Data Formatting](output-formatting.md) section for more details.
+* [[yii\i18n\I18N|i18n]]: supports message translation and formatting.
+  Please refer to the [Internationalization](tutorial-i18n.md) section for more details.
+* [[yii\log\Dispatcher|log]]: manages log targets.
+  Please refer to the [Logging](tutorial-logging.md) section for more details.
+* [[yii\swiftmailer\Mailer|mail]]: supports mail composing and sending.
+  Please refer to the [Mailing](tutorial-mailing.md) section for more details.
+* [[yii\base\Application::response|response]]: represents the response being sent to end users.
+  Please refer to the [Responses](runtime-responses.md) section for more details.
+* [[yii\base\Application::request|request]]: represents the request received from end users.
+  Please refer to the [Requests](runtime-requests.md) section for more details.
+* [[yii\web\Session|session]]: represents the session information. This component is only available
+  in [[yii\web\Application|Web applications]].
+  Please refer to the [Sessions and Cookies](runtime-sessions-cookies.md) section for more details.
+* [[yii\web\UrlManager|urlManager]]: supports URL parsing and creation.
+  Please refer to the [URL Parsing and Generation](runtime-url-handling.md) section for more details.
+* [[yii\web\User|user]]: represents the user authentication information. This component is only available
+  in [[yii\web\Application|Web applications]]
+  Please refer to the [Authentication](security-authentication.md) section for more details.
+* [[yii\web\View|view]]: supports view rendering.
+  Please refer to the [Views](structure-views.md) section for more details.
diff --git a/docs/guide-zh-CN/structure-applications.md b/docs/guide-zh-CN/structure-applications.md
new file mode 100644
index 0000000..2a1c137
--- /dev/null
+++ b/docs/guide-zh-CN/structure-applications.md
@@ -0,0 +1,609 @@
+Applications
+============
+
+Applications are objects that govern the overall structure and lifecycle of Yii application systems.
+Each Yii application system contains a single application object which is created in
+the [entry script](structure-entry-scripts.md) and is globally accessible through the expression `\Yii::$app`.
+
+> Info: Depending on the context, when we say "an application", it can mean either an application
+  object or an application system.
+
+There are two types of applications: [[yii\web\Application|Web applications]] and
+[[yii\console\Application|console applications]]. As the names indicate, the former mainly handles
+Web requests while the latter console command requests.
+
+
+## Application Configurations <a name="application-configurations"></a>
+
+When an [entry script](structure-entry-scripts.md) creates an application, it will load
+a [configuration](concept-configurations.md) and apply it to the application, like the following:
+
+```php
+require(__DIR__ . '/../vendor/autoload.php');
+require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
+
+// load application configuration
+$config = require(__DIR__ . '/../config/web.php');
+
+// instantiate and configure the application
+(new yii\web\Application($config))->run();
+```
+
+Like normal [configurations](concept-configurations.md), application configurations specify how
+to initialize properties of application objects. Because application configurations are often
+very complex, they usually are kept in [configuration files](concept-configurations.md#configuration-files),
+like the `web.php` file in the above example.
+
+
+## Application Properties <a name="application-properties"></a>
+
+There are many important application properties that you should configure in application configurations.
+These properties typically describe the environment that applications are running in.
+For example, applications need to know how to load [controllers](structure-controllers.md),
+where to store temporary files, etc. In the following, we will summarize these properties.
+
+
+### Required Properties <a name="required-properties"></a>
+
+In any application, you should at least configure two properties: [[yii\base\Application::id|id]]
+and [[yii\base\Application::basePath|basePath]].
+
+
+#### [[yii\base\Application::id|id]] <a name="id"></a>
+
+The [[yii\base\Application::id|id]] property specifies a unique ID that differentiates an application
+from others. It is mainly used programmatically. Although not a requirement, for best interoperability
+it is recommended that you use alphanumeric characters only when specifying an application ID.
+
+
+#### [[yii\base\Application::basePath|basePath]] <a name="basePath"></a>
+
+The [[yii\base\Application::basePath|basePath]] property specifies the root directory of an application.
+It is the directory that contains all protected source code of an application system. Under this directory,
+you normally will see sub-directories such as `models`, `views`, `controllers`, which contain source code
+corresponding to the MVC pattern.
+
+You may configure the [[yii\base\Application::basePath|basePath]] property using a directory path
+or a [path alias](concept-aliases.md). In both forms, the corresponding directory must exist, or an exception
+will be thrown. The path will be normalized by calling the `realpath()` function.
+
+The [[yii\base\Application::basePath|basePath]] property is often used to derive other important
+paths (e.g. the runtime path). For this reason, a path alias named `@app` is predefined to represent this
+path. Derived paths may then be formed using this alias (e.g. `@app/runtime` to refer to the runtime directory).
+
+
+### Important Properties <a name="important-properties"></a>
+
+The properties described in this subsection often need to be configured because they differ across
+different applications.
+
+
+#### [[yii\base\Application::aliases|aliases]] <a name="aliases"></a>
+
+This property allows you to define a set of [aliases](concept-aliases.md) in terms of an array.
+The array keys are alias names, and the array values are the corresponding path definitions.
+For example,
+
+```php
+[
+    'aliases' => [
+        '@name1' => 'path/to/path1',
+        '@name2' => 'path/to/path2',
+    ],
+]
+```
+
+This property is provided such that you can define aliases in terms of application configurations instead of
+the method calls [[Yii::setAlias()]].
+
+
+#### [[yii\base\Application::bootstrap|bootstrap]] <a name="bootstrap"></a>
+
+This is a very useful property. It allows you to specify an array of components that should
+be run during the application [[yii\base\Application::bootstrap()|bootstrapping process]].
+For example, if you want a [module](structure-modules.md) to customize the [URL rules](runtime-url-handling.md),
+you may list its ID as an element in this property.
+
+Each component listed in this property may be specified in one of the following formats:
+
+- an application component ID as specified via [components](#components).
+- a module ID as specified via [modules](#modules).
+- a class name.
+- a configuration array.
+- an anonymous function that creates and returns a component.
+
+For example,
+
+```php
+[
+    'bootstrap' => [
+        // an application component ID or module ID
+        'demo',
+
+        // a class name
+        'app\components\Profiler',
+
+        // a configuration array
+        [
+            'class' => 'app\components\Profiler',
+            'level' => 3,
+        ],
+
+        // an anonymous function
+        function () {
+            return new app\components\Profiler();
+        }
+    ],
+]
+```
+
+> Info: If a module ID is the same as an application component ID, the application component will be used during
+  the bootstrapping process. If you want to use the module instead, you may specify it using an anonymous function
+  like the following:
+>```php
+[
+    function () {
+        return Yii::$app->getModule('user');
+    },
+]
+```
+
+
+During the bootstrapping process, each component will be instantiated. If the component class
+implements [[yii\base\BootstrapInterface]], its [[yii\base\BootstrapInterface::bootstrap()|bootstrap()]] method
+will also be called.
+
+Another practical example is in the application configuration for the [Basic Application Template](start-installation.md),
+where the `debug` and `gii` modules are configured as bootstrapping components when the application is running
+in development environment,
+
+```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';
+}
+```
+
+> Note: Putting too many components in `bootstrap` will degrade the performance of your application because
+  for each request, the same set of components need to be run. So use bootstrapping components judiciously.
+
+
+#### [[yii\web\Application::catchAll|catchAll]] <a name="catchAll"></a>
+
+This property is supported by [[yii\web\Application|Web applications]] only. It specifies
+a [controller action](structure-controllers.md) which should handle all user requests. This is mainly
+used when the application is in maintenance mode and needs to handle all incoming requests via a single action.
+
+The configuration is an array whose first element specifies the route of the action.
+The rest of the array elements (key-value pairs) specify the parameters to be bound to the action. For example,
+
+```php
+[
+    'catchAll' => [
+        'offline/notice',
+        'param1' => 'value1',
+        'param2' => 'value2',
+    ],
+]
+```
+
+
+#### [[yii\base\Application::components|components]] <a name="components"></a>
+
+This is the single most important property. It allows you to register a list of named components
+called [application components](#structure-application-components.md) that you can use in other places. For example,
+
+```php
+[
+    'components' => [
+        'cache' => [
+            'class' => 'yii\caching\FileCache',
+        ],
+        'user' => [
+            'identityClass' => 'app\models\User',
+            'enableAutoLogin' => true,
+        ],
+    ],
+]
+```
+
+Each application component is specified as a key-value pair in the array. The key represents the component ID,
+while the value represents the component class name or [configuration](concept-configurations.md).
+
+You can register any component with an application, and the component can later be accessed globally
+using the expression `\Yii::$app->ComponentID`.
+
+Please read the [Application Components](structure-application-components.md) section for details.
+
+
+#### [[yii\base\Application::controllerMap|controllerMap]] <a name="controllerMap"></a>
+
+This property allows you to map a controller ID to an arbitrary controller class. By default, Yii maps
+controller IDs to controller classes based on a [convention](#controllerNamespace) (e.g. the ID `post` would be mapped
+to `app\controllers\PostController`). By configuring this property, you can break the convention for
+specific controllers. In the following example, `account` will be mapped to
+`app\controllers\UserController`, while `article` will be mapped to `app\controllers\PostController`.
+
+```php
+[
+    'controllerMap' => [
+        [
+            'account' => 'app\controllers\UserController',
+            'article' => [
+                'class' => 'app\controllers\PostController',
+                'enableCsrfValidation' => false,
+            ],
+        ],
+    ],
+]
+```
+
+The array keys of this property represent the controller IDs, while the array values represent the corresponding
+controller class names or [configurations](concept-configurations.md).
+
+
+#### [[yii\base\Application::controllerNamespace|controllerNamespace]] <a name="controllerNamespace"></a>
+
+This property specifies the default namespace under which controller classes should be located. It defaults to
+`app\controllers`. If a controller ID is `post`, by convention the corresponding controller class name (without
+namespace) would be `PostController`, and the fully qualified class name would be `app\controllers\PostController`.
+
+Controller classes may also be located under sub-directories of the directory corresponding to this namespace.
+For example, given a controller ID `admin/post`, the corresponding fully qualified controller class would
+be `app\controllers\admin\PostController`.
+
+It is important that the fully qualified controller classes should be [autoloadable](concept-autoloading.md)
+and the actual namespace of your controller classes match the value of this property. Otherwise,
+you will receive "Page Not Found" error when accessing the application.
+
+In case you want to break the convention as described above, you may configure the [controllerMap](#controllerMap)
+property.
+
+
+#### [[yii\base\Application::language|language]] <a name="language"></a>
+
+This property specifies the language in which the application should display content to end users.
+The default value of this property is `en`, meaning English. You should configure this property
+if your application needs to support multiple languages.
+
+The value of this property determines various [internationalization](tutorial-i18n.md) aspects,
+including message translation, date formatting, number formatting, etc. For example, the [[yii\jui\DatePicker]] widget
+will use this property value by default to determine in which language the calendar should be displayed and how
+should the date be formatted.
+
+It is recommended that you specify a language in terms of an [IETF language tag](http://en.wikipedia.org/wiki/IETF_language_tag).
+For example, `en` stands for English, while `en-US` stands for English (United States).
+
+More details about this property can be found in the [Internationalization](tutorial-i18n.md) section.
+
+
+#### [[yii\base\Application::modules|modules]] <a name="modules"></a>
+
+This property specifies the [modules](structure-modules.md) that the application contains.
+
+The property takes an array of module classes or [configurations](concept-configurations.md) with the array keys
+being the module IDs. For example,
+
+```php
+[
+    'modules' => [
+        // a "booking" module specified with the module class
+        'booking' => 'app\modules\booking\BookingModule',
+
+        // a "comment" module specified with a configuration array
+        'comment' => [
+            'class' => 'app\modules\comment\CommentModule',
+            'db' => 'db',
+        ],
+    ],
+]
+```
+
+Please refer to the [Modules](structure-modules.md) section for more details.
+
+
+#### [[yii\base\Application::name|name]] <a name="name"></a>
+
+This property specifies the application name that may be displayed to end users. Unlike the
+[[yii\base\Application::id|id]] property which should take a unique value, the value of this property is mainly for
+display purpose and does not need to be unique.
+
+You do not always need to configure this property if none of your code is using it.
+
+
+#### [[yii\base\Application::params|params]] <a name="params"></a>
+
+This property specifies an array of globally accessible application parameters. Instead of using hardcoded
+numbers and strings everywhere in your code, it is a good practice to define them as application parameters
+in a single place and use the parameters in places where needed. For example, you may define the thumbnail
+image size as a parameter like the following:
+
+```php
+[
+    'params' => [
+        'thumbnail.size' => [128, 128],
+    ],
+]
+```
+
+Then in your code where you need to use the size value, you can simply use the code like the following:
+
+```php
+$size = \Yii::$app->params['thumbnail.size'];
+$width = \Yii::$app->params['thumbnail.size'][0];
+```
+
+Later if you decide to change the thumbnail size, you only need to modify it in the application configuration
+without touching any dependent code.
+
+
+#### [[yii\base\Application::sourceLanguage|sourceLanguage]] <a name="sourceLanguage"></a>
+
+This property specifies the language that the application code is written in. The default value is `'en-US'`,
+meaning English (United States). You should configure this property if the text content in your code is not in English.
+
+Like the [language](#language) property, you should configure this property in terms of
+an [IETF language tag](http://en.wikipedia.org/wiki/IETF_language_tag). For example, `en` stands for English,
+while `en-US` stands for English (United States).
+
+More details about this property can be found in the [Internationalization](tutorial-i18n.md) section.
+
+
+#### [[yii\base\Application::timeZone|timeZone]] <a name="timeZone"></a>
+
+This property is provided as an alternative way of setting the default time zone of PHP runtime.
+By configuring this property, you are essentially calling the PHP function
+[date_default_timezone_set()](http://php.net/manual/en/function.date-default-timezone-set.php). For example,
+
+```php
+[
+    'timeZone' => 'America/Los_Angeles',
+]
+```
+
+
+#### [[yii\base\Application::version|version]] <a name="version"></a>
+
+This property specifies the version of the application. It defaults to `'1.0'`. You do not always need to configure
+this property if none of your code is using it.
+
+
+### Useful Properties <a name="useful-properties"></a>
+
+The properties described in this subsection are not commonly configured because their default values
+stipulate common conventions. However, you may still configure them in case you want to break the conventions.
+
+
+#### [[yii\base\Application::charset|charset]] <a name="charset"></a>
+
+This property specifies the charset that the application uses. The default value is `'UTF-8'` which should
+be kept as is for most applications unless you are working with some legacy systems that use a lot of non-unicode data.
+
+
+#### [[yii\base\Application::defaultRoute|defaultRoute]] <a name="defaultRoute"></a>
+
+This property specifies the [route](runtime-routing.md) that an application should use when a request
+does not specify one. The route may consist of child module ID, controller ID, and/or action ID.
+For example, `help`, `post/create`, `admin/post/create`. If action ID is not given, it will take the default
+value as specified in [[yii\base\Controller::defaultAction]].
+
+For [[yii\web\Application|Web applications]], the default value of this property is `'site'`, which means
+the `SiteController` controller and its default action should be used. As a result, if you access
+the application without specifying a route, it will show the result of `app\controllers\SiteController::actionIndex()`.
+
+For [[yii\console\Application|console applications]], the default value is `'help'`, which means the core command
+[[yii\console\controllers\HelpController::actionIndex()]] should be used. As a result, if you run the command `yii`
+without providing any arguments, it will display the help information.
+
+
+#### [[yii\base\Application::extensions|extensions]] <a name="extensions"></a>
+
+This property specifies the list of [extensions](structure-extensions.md) that are installed and used by the application.
+By default, it will take the array returned by the file `@vendor/yiisoft/extensions.php`. The `extensions.php` file
+is generated and maintained automatically when you use [Composer](http://getcomposer.org) to install extensions.
+So in most cases, you do not need to configure this property.
+
+In the special case when you want to maintain extensions manually, you may configure this property like the following:
+
+```php
+[
+    'extensions' => [
+        [
+            'name' => 'extension name',
+            'version' => 'version number',
+            'bootstrap' => 'BootstrapClassName',  // optional, may also be a configuration array
+            'alias' => [  // optional
+                '@alias1' => 'to/path1',
+                '@alias2' => 'to/path2',
+            ],
+        ],
+
+        // ... more extensions like the above ...
+
+    ],
+]
+```
+
+As you can see, the property takes an array of extension specifications. Each extension is specified with an array
+consisting of `name` and `version` elements. If an extension needs to run during the [bootstrap](runtime-bootstrapping.md)
+process, a `bootstrap` element may be specified with a bootstrapping class name or a [configuration](concept-configurations.md)
+array. An extension may also define a few [aliases](concept-aliases.md).
+
+
+#### [[yii\base\Application::layout|layout]] <a name="layout"></a>
+
+This property specifies the name of the default layout that should be used when rendering a [view](structure-views.md).
+The default value is `'main'`, meaning the layout file `main.php` under the [layout path](#layoutPath) should be used.
+If both of the [layout path](#layoutPath) and the [view path](#viewPath) are taking the default values,
+the default layout file can be represented as the path alias `@app/views/layouts/main.php`.
+
+You may configure this property to be `false` if you want to disable layout by default, although this is very rare.
+
+
+#### [[yii\base\Application::layoutPath|layoutPath]] <a name="layoutPath"></a>
+
+This property specifies the path where layout files should be looked for. The default value is
+the `layouts` sub-directory under the [view path](#viewPath). If the [view path](#viewPath) is taking
+its default value, the default layout path can be represented as the path alias `@app/views/layouts`.
+
+You may configure it as a directory or a path [alias](concept-aliases.md).
+
+
+#### [[yii\base\Application::runtimePath|runtimePath]] <a name="runtimePath"></a>
+
+This property specifies the path where temporary files, such as log files, cache files, can be generated.
+The default value is the directory represented by the alias `@app/runtime`.
+
+You may configure it as a directory or a path [alias](concept-aliases.md). Note that the runtime path must
+be writable by the process running the application. And the path should be protected from being accessed
+by end users because the temporary files under it may contain sensitive information.
+
+To simplify accessing to this path, Yii has predefined a path alias named `@runtime` for it.
+
+
+#### [[yii\base\Application::viewPath|viewPath]] <a name="viewPath"></a>
+
+This property specifies the root directory where view files are located. The default value is the directory
+represented by the alias `@app/views`. You may configure it as a directory or a path [alias](concept-aliases.md).
+
+
+#### [[yii\base\Application::vendorPath|vendorPath]] <a name="vendorPath"></a>
+
+This property specifies the vendor directory managed by [Composer](http://getcomposer.org). It contains
+all third party libraries used by your application, including the Yii framework. The default value is
+the directory represented by the alias `@app/vendor`.
+
+You may configure this property as a directory or a path [alias](concept-aliases.md). When you modify
+this property, make sure you also adjust the Composer configuration accordingly.
+
+To simplify accessing to this path, Yii has predefined a path alias named `@vendor` for it.
+
+
+#### [[yii\console\Application::enableCoreCommands|enableCoreCommands]] <a name="enableCoreCommands"></a>
+
+This property is supported by [[yii\console\Application|console applications]] only. It specifies
+whether the core commands included in the Yii release should be enabled. The default value is `true`.
+
+
+## Application Events <a name="application-events"></a>
+
+An application triggers several events during the lifecycle of handling an request. You may attach event
+handlers to these events in application configurations like the following,
+
+```php
+[
+    'on beforeRequest' => function ($event) {
+        // ...
+    },
+]
+```
+
+The use of the `on eventName` syntax is described in the [Configurations](concept-configurations.md#configuration-format)
+section.
+
+Alternatively, you may attach event handlers during the [bootstrapping process](runtime-bootstrapping.md) process
+after the application instance is created. For example,
+
+```php
+\Yii::$app->on(\yii\base\Application::EVENT_BEFORE_REQUEST, function ($event) {
+    // ...
+});
+```
+
+### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_REQUEST]] <a name="beforeRequest"></a>
+
+This event is triggered *before* an application handles a request. The actual event name is `beforeRequest`.
+
+When this event is triggered, the application instance has been configured and initialized. So it is a good place
+to insert your custom code via the event mechanism to intercept the request handling process. For example,
+in the event handler, you may dynamically set the [[yii\base\Application::language]] property based on some parameters.
+
+
+### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_AFTER_REQUEST]] <a name="afterRequest"></a>
+
+This event is triggered *after* an application finishes handling a request but *before* sending the response.
+The actual event name is `afterRequest`.
+
+When this event is triggered, the request handling is completed and you may take this chance to do some postprocessing
+of the request or customize the response.
+
+Note that the [[yii\web\Response|response]] component also triggers some events while it is sending out
+response content to end users. Those events are triggered *after* this event.
+
+
+### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_ACTION]] <a name="beforeAction"></a>
+
+This event is triggered *before* running every [controller action](structure-controllers.md).
+The actual event name is `beforeAction`.
+
+The event parameter is an instance of [[yii\base\ActionEvent]]. An event handler may set
+the [[yii\base\ActionEvent::isValid]] property to be `false` to stop running the action.
+For example,
+
+```php
+[
+    'on beforeAction' => function ($event) {
+        if (some condition) {
+            $event->isValid = false;
+        } else {
+        }
+    },
+]
+```
+
+Note that the same `beforeAction` event is also triggered by [modules](structure-modules.md)
+and [controllers](structure-controllers.md). Application objects are the first ones
+triggering this event, followed by modules (if any), and finally controllers. If an event handler
+sets [[yii\base\ActionEvent::isValid]] to be `false`, all the following events will NOT be triggered.
+
+
+### [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_AFTER_ACTION]] <a name="afterAction"></a>
+
+This event is triggered *after* running every [controller action](structure-controllers.md).
+The actual event name is `afterAction`.
+
+The event parameter is an instance of [[yii\base\ActionEvent]]. Through
+the [[yii\base\ActionEvent::result]] property, an event handler may access or modify the action result.
+For example,
+
+```php
+[
+    'on afterAction' => function ($event) {
+        if (some condition) {
+            // modify $event->result
+        } else {
+        }
+    },
+]
+```
+
+Note that the same `afterAction` event is also triggered by [modules](structure-modules.md)
+and [controllers](structure-controllers.md). These objects trigger this event in the reverse order
+as for that of `beforeAction`. That is, controllers are the first objects triggering this event,
+followed by modules (if any), and finally applications.
+
+
+## Application Lifecycle <a name="application-lifecycle"></a>
+
+When an [entry script](structure-entry-scripts.md) is being executed to handle a request,
+an application will undergo the following lifecycle:
+
+1. The entry script loads the application configuration as an array.
+2. The entry script creates a new instance of the application:
+  * [[yii\base\Application::preInit()|preInit()]] is called, which configures some high priority
+    application properties, such as [[yii\base\Application::basePath|basePath]].
+  * Register the [[yii\base\Application::errorHandler|error handler]].
+  * Configure application properties.
+  * [[yii\base\Application::init()|init()]] is called which further calls
+    [[yii\base\Application::bootstrap()|bootstrap()]] to run bootstrapping components.
+3. The entry script calls [[yii\base\Application::run()]] to run the application:
+  * Trigger the [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_REQUEST]] event.
+  * Handle the request: resolve the request into a [route](runtime-routing.md) and the associated parameters;
+    create the module, controller and action objects as specified by the route; and run the action.
+  * Trigger the [[yii\base\Application::EVENT_AFTER_REQUEST|EVENT_AFTER_REQUEST]] event.
+  * Send response to the end user.
+4. The entry script receives the exit status from the application and completes the request processing.
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 <a name="actions"></a>
+
+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 <a name="routes"></a>
+
+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 <a name="creating-controllers"></a>
+
+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 <a name="controller-ids"></a>
+
+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 <a name="controller-class-naming"></a>
+
+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 <a name="controller-map"></a>
+
+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 <a name="default-controller"></a>
+
+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 <a name="creating-actions"></a>
+
+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 <a name="action-ids"></a>
+
+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 <a name="inline-actions"></a>
+
+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 <a name="standalone-actions"></a>
+
+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
+<?php
+namespace app\components;
+
+use yii\base\Action;
+
+class HelloWorldAction extends Action
+{
+    public function run()
+    {
+        return "Hello World";
+    }
+}
+```
+
+
+### Action Results <a name="action-results"></a>
+
+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 <a name="action-parameters"></a>
+
+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 <a name="default-action"></a>
+
+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 <a name="controller-lifecycle"></a>
+
+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 <a name="best-practices"></a>
+
+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-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 <a name="attributes"></a>
+
+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 <a name="defining-attributes"></a>
+
+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 <a name="attribute-labels"></a>
+
+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 name="scenarios"></a>
+
+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 <a name="validation-rules"></a>
+
+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 <a name="massive-assignment"></a>
+
+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 <a name="safe-attributes"></a>
+
+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 <a name="unsafe-attributes"></a>
+
+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 <a name="data-exporting"></a>
+
+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 name="fields"></a>
+
+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 <a name="best-practices"></a>
+
+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-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 <a name="creating-views"></a>
+
+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
+<?php
+use yii\helpers\Html;
+use yii\widgets\ActiveForm;
+
+/* @var $this yii\web\View */
+/* @var $form yii\widgets\ActiveForm */
+/* @var $model app\models\LoginForm */
+
+$this->title = 'Login';
+?>
+<h1><?= Html::encode($this->title) ?></h1>
+
+<p>Please fill out the following fields to login:</p>
+
+<?php $form = ActiveForm::begin(); ?>
+    <?= $form->field($model, 'username') ?>
+    <?= $form->field($model, 'password')->passwordInput() ?>
+    <?= Html::submitButton('Login') ?>
+<?php ActiveForm::end(); ?>
+```
+
+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 <a name="security"></a>
+
+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
+<?php
+use yii\helpers\Html;
+?>
+
+<div class="username">
+    <?= Html::encode($user->name) ?>
+</div>
+```
+
+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
+<?php
+use yii\helpers\HtmlPurifier;
+?>
+
+<div class="post">
+    <?= HtmlPurifier::process($post->text) ?>
+</div>
+```
+
+> 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 <a name="organizing-views"></a>
+
+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 <a name="rendering-views"></a>
+
+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 <a name="rendering-in-controllers"></a>
+
+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 <a name="rendering-in-widgets"></a>
+
+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 <a name="rendering-in-views"></a>
+
+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 <a name="rendering-in-other-places"></a>
+
+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 <a name="named-views"></a>
+
+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 <a name="accessing-data-in-views"></a>
+
+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 <a name="sharing-data-among-views"></a>
+
+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 <a name="layouts"></a>
+
+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 <a name="creating-layouts"></a>
+
+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
+<?php
+use yii\helpers\Html;
+
+/* @var $this yii\web\View */
+/* @var $content string */
+?>
+<?php $this->beginPage() ?>
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8"/>
+    <?= Html::csrfMetaTags() ?>
+    <title><?= Html::encode($this->title) ?></title>
+    <?php $this->head() ?>
+</head>
+<body>
+<?php $this->beginBody() ?>
+    <header>My Company</header>
+    <?= $content ?>
+    <footer>&copy; 2014 by My Company</footer>
+<?php $this->endBody() ?>
+</body>
+</html>
+<?php $this->endPage() ?>
+```
+
+As you can see, the layout generates the HTML tags that are common to all pages. Within the `<body>` 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 `<head>` 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 `<body>` 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 `<body>` 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 <a name="accessing-data-in-layouts"></a>
+
+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 <a name="using-layouts"></a>
+
+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 <a name="nested-layouts"></a>
+
+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
+<?php $this->beginContent('@app/views/layouts/base.php'); ?>
+
+...child layout content here...
+
+<?php $this->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 <a name="using-blocks"></a>
+
+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
+...
+
+<?php $this->beginBlock('block1'); ?>
+
+...content of block1...
+
+<?php $this->endBlock(); ?>
+
+...
+
+<?php $this->beginBlock('block3'); ?>
+
+...content of block3...
+
+<?php $this->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
+...
+<?php if (isset($this->blocks['block1'])): ?>
+    <?= $this->blocks['block1'] ?>
+<?php else: ?>
+    ... default content for block1 ...
+<?php endif; ?>
+
+...
+
+<?php if (isset($this->blocks['block2'])): ?>
+    <?= $this->blocks['block2'] ?>
+<?php else: ?>
+    ... default content for block2 ...
+<?php endif; ?>
+
+...
+
+<?php if (isset($this->blocks['block3'])): ?>
+    <?= $this->blocks['block3'] ?>
+<?php else: ?>
+    ... default content for block3 ...
+<?php endif; ?>
+...
+```
+
+
+## Using View Components <a name="using-view-components"></a>
+
+[[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 <a name="setting-page-titles"></a>
+
+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
+<?php
+$this->title = 'My page title';
+?>
+```
+
+Then in the layout, make sure you have the following code in the `<head>` section:
+
+```php
+<title><?= Html::encode($this->title) ?></title>
+```
+
+
+### Registering Meta Tags <a name="registering-meta-tags"></a>
+
+Web pages usually need to generate various meta tags needed by different parties. Like page titles, meta tags
+appear in the `<head>` 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
+<?php
+$this->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
+<meta name="keywords" content="yii, framework, 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 <a name="registering-link-tags"></a>
+
+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
+<link title="Live News for Yii" rel="alternate" type="application/rss+xml" href="http://www.yiiframework.com/rss.xml/">
+```
+
+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 <a name="view-events"></a>
+
+[[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 <a name="rendering-static-pages"></a>
+
+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 <a name="best-practices"></a>
+
+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.
+