= Html::encode($username) ?>
= Html::encode($tagline) ?>
Views ===== Views are part of the [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) architecture. They are code responsible for presenting data to end users. In a Web application, views are usually created in terms of *view templates* which are PHP script files containing mainly HTML code and presentational PHP code. They are managed by the [[yii\web\View|view]] application component which provides commonly used methods to facilitate view composition and rendering. For simplicity, we often call view templates or view template files as views. ## Creating Views As aforementioned, a view is simply a PHP script mixed with HTML and PHP code. The following is the view that presents a login form. As you can see, PHP code is used to generate the dynamic content, such as the page title and the form, while HTML code organizes them into a presentable HTML page. ```php title = 'Login'; ?>
Please fill out the following fields to login:
= $form->field($model, 'username') ?> = $form->field($model, 'password')->passwordInput() ?> = Html::submitButton('Login') ?> ``` Within a view, you can access `$this` which refers to the [[yii\web\View|view component]] managing and rendering this view template. Besides `$this`, there may be other predefined variables in a view, such as `$form` and `$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 practice to document your views. TODO: features in creating views ## Organizing Views Like [controllers](structure-controllers.md) and [models](structure-models.md), there are conventions to organize views. * For views rendered in a controller, they should be put under the directory `@app/views/ControllerID` by default, where `ControllerID` refers to [the ID of the controller](structure-controllers.md#routes). For example, if the controller class is `PostController`, the directory would be `@app/views/post`; If the class is `PostCommentController`, the directory would be `@app/views/post-comment`. In case the controller belongs to a module, the directory would be `views/ControllerID` under the [[yii\base\Module::basePath|module directory]]. * For views rendered in a [widget](structure-widgets.md), they should be put under the `WidgetPath/views` directory by default, where `WidgetPath` stands for the directory containing the widget class file. * For views rendered by other objects, it is recommended that you follow the similar convention as that for widgets. You may customize these default view directories by overriding the [[yii\base\ViewContextInterface::getViewPath()]] method of controllers or widgets. ## Rendering Views You can render views in [controllers](structure-controllers.md), [widgets](structure-widgets.md), or any other places by calling view rendering methods. These methods share a similar signature shown as follows, ``` /** * @param string $view view name or file path, depending on the actual rendering method * @param array $params the data to be passed to the view * @return string rendering result */ methodName($view, $params = []) ``` ### Rendering in Controllers Within [controllers](structure-controllers.md), you may call the following controller methods to render views: * [[yii\base\Controller::render()|render()]]: renders a [named view](#named-views) and applies a [layout](#layouts) to the rendering result. * [[yii\base\Controller::renderPartial()|renderPartial()]]: renders a [named view](#named-views) without any layout. * [[yii\web\Controller::renderAjax()|renderAjax()]]: renders a [named view](#named-views) without any layout, and injects all registered JS/CSS scripts and files. It is usually used in response to AJAX Web requests. * [[yii\base\Controller::renderFile()|renderFile()]]: renders a view specified in terms of a view file path or [alias](concept-aliases.md). For example, ```php namespace app\controllers; use Yii; use app\models\Post; use yii\web\Controller; use yii\web\NotFoundHttpException; class PostController extends Controller { public function actionView($id) { $model = Post::findOne($id); if ($model === null) { throw new NotFoundHttpException; } // renders a view named "view" and applies a layout to it return $this->render('view', [ 'model' => $model, ]); } } ``` ### Rendering in Widgets Within [widgets](structure-widgets.md), you may call the following widget methods to render views. * [[yii\base\Widget::render()|render()]]: renders a [named view](#named-views). * [[yii\base\Widget::renderFile()|renderFile()]]: renders a view specified in terms of a view file path or [alias](concept-aliases.md). For example, ```php namespace app\components; use yii\base\Widget; use yii\helpers\Html; class ListWidget extends Widget { public $items = []; public function run() { // renders a view named "list" return $this->render('list', [ 'items' => $this->items, ]); } } ``` ### Rendering in Other Places In any place, you can render views with the help of the [[yii\base\View|view]] application component by calling its following methods: * [[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, ```php // displays the view file "@app/views/site/license.php" echo \Yii::$app->view->renderFile('@app/views/site/license.php'); ``` If you are rendering a view within another view, you can use the following code, because `$this` in a view refers to the [[yii\base\View|view]] component: ```php = $this->renderFile('@app/views/site/license.php') ?> ``` ## Named Views When you render a view, you can specify the view using either a view name or a view file path/alias. In most cases, you would use the former because it is more concise and flexible. We call views specified using names as *named views*. A view name is resolved into the corresponding view file path according to the following rules: * A view name may omit the file extension name. In this case, `.php` will be used as the extension. For example, the view name `about` corresponds to the file name `about.php`. * If the view name starts with double slashes `//`, the corresponding view file path would be `@app/views/ViewName`. That is, the view is looked for under the [[yii\base\Application::viewPath|application's view path]]. For example, `//site/about` will be resolved into `@app/views/site/about.php`. * If the view name starts with a single slash `/`, the view file path is formed by prefixing the view name with the [[yii\base\Module::viewPath|view path]] of the currently active [module](structure-modules.md). If there is no active module, `@app/views/ViewName` will be used. For example, `/user/create` will be resolved into `@app/modules/user/views/user/create.php`, if the currently active module is `user`. If there is no active module, the view file path would be `@app/views/user/create.php`. * If the view is rendered with a [[yii\base\View::context|context]] and the context implements [[yii\base\ViewContextInterface]], the view file path is formed by prefixing the [[yii\base\ViewContextInterface::getViewPath()|view path]] of the context to the view name. This mainly applies to the views rendered within controllers and widgets. For example, `site/about` will be resolved into `@app/views/site/about.php` if the context is the controller `SiteController`. * If a view is rendered within another view, the directory containing the other view file will be prefixed to the new view name to form the actual view file path. For example, `item` will be resolved into `@app/views/post/item` if it is being rendered in the view `@app/views/post/index.php`. According to the above rules, the following code in a controller is actually rendering the view file `@app/views/post/view.php` ```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, ]); } } ``` And the following code in the view `@app/views/post/view.php` is actually rendering the view file `@app/views/post/_overview.php`: ```php = $this->render('_overview', ['model' => $model]) ?> ``` ### Accessing Data in Views There are two approaches to access data within a view: push and pull. By passing the data as the second parameter to the view rendering methods, you are using the push approach. The data should be represented be 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::context|view context object]]. Using the above code as an example, within the view you can get the controller object by the expression `$this->context`. As a result, it is possible for you to access any properties or methods of the controller in the `report` view. For example, in the `report` view you may pull the `id` data like the following: ```php The controller ID is: = $this->context->id ?> ?> ``` The pull 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 becomes tedious and error prone if a view is shared and rendered in different places. ## Layouts Layouts are a special type of views that represent the common parts of multiple views. For example, the pages for most Web applications share the same page header and footer. While you can repeat the same page header and footer in every view, a better way is to do this once in a layout and embed the rendering result of a content view at an appropriate place in the layout. ### Creating Layouts Because layouts are also views, they can be created in the similar way as normal views. The following example shows how a layout looks like: ```php beginPage() ?>= Html::encode($tagline) ?>