During website creation, most of the page structures are similar. If both have the same header and bottom. Each page is just a different part in the middle.
The layout file in yii is used to implement such a function. For example:
Layout file: @ APP/views/layouts/Main. php
<! -- The front and back HTML, Head, and body code are omitted, read only the most important part -->
Background action:
public function actionIndex(){ $this->layout=‘@app/views/layouts/main.php‘; return $this->render(‘index‘);}
The execution sequence is as follows:
- First look for the index View File,
- Rendering the index View File as the variable $ output
- Find the layout file @ APP/views/layouts/Main. php
- If this parameter is found, the $ output value is passed to the layout file as the variable $ content.
- Returns the rendered layout file as a result.
- If no layout file is found, $ output is directly returned as the result.
The above layout is a column layout page. Now we add another layout: The page displays two columns, the main content on the left, and the statistics on the right. What should I do at this time? Should I write another code that is basically the same as above?
Layout file nesting (Widget: contentdecorator)
This widget is designed for this purpose.
Its function is to take the content between begin and end as the value of the variable $ content, and then render the specified View File.
Two-column layout file: @ APP/views/layouts/column_2.php
<! -- First reference the layout file main. php, --> <? PHP $ this-> begincontent ('@ APP/views/layouts/Main. php');?> <Div class = "left_column"> <? = $ Content?> </Div> <Div class = "right_column"> <! -- Unified data shared on the right --> </div> <? PHP $ this-> endcontent ();?>
Change the preceding action:
public function actionIndex(){ $this->layout=‘@app/views/layouts/column_2.php‘; return $this->render(‘index‘);}
The execution sequence is as follows:
- First, pass the rendered View index result as the variable $ content to the layout file column_2.
- Then, the content between begincontent and endcontent in the layout file column_2 is passed as the variable $ content to the layout file @ APP/views/layouts/Main. php.
- Finally, output the result of the Main. php file.
Note: In the preceding layout file column_2
Endcontent
Other content is not displayed.
Therefore, layout files in yii can be infinitely nested through the contentdecorator widget. Of course, be careful not to create an endless loop. For example, ayout1 references layout2 and layout2 references the layout1 file.
Do you think this article is over now? The ultimate decryption technique is just getting started !!!!!
Multi-variable inheritance
Let me show you an example:
Layout file maiin: APP/views/layouts/Main. php
We can see that there are two variables: $ content and
$ Footer
.
Layout file columns_2: @ APP/views/layouts/columns_2.php
<?php AreaDecorator::begin([‘viewFile‘=>‘@app/views/layouts/main.php‘])?> <?php Block::begin([‘id‘ =>‘content‘]);?> <div class="main_column"> <?= $mainData ?> </div> <div class="side_column"> <?= $sideData ?> </div> <?php Block::end();?> <?php Block::begin([‘id‘ =>‘footer‘]);?> <div>footer data </div> <?php Block::end();?><?php AreaDecorator::end();?>
The layout file columns_2 references main and uses the block
ID
Specify the content of two variables in main
Layout file columns_3: @ APP/views/layouts/columns_3.php
<?php AreaDecorator::begin([‘viewFile‘=>‘@app/views/layouts/columns_2.php‘])?> <?php Block::begin([‘id‘ =>‘mainData‘]);?> <div class="main_column_left"> <div>main column left data</div> </div> <div class="main_column_right"> <div><?= $content ?></div> </div> <?php Block::end();?> <?php Block::begin([‘id‘ =>‘sideData‘]);?> <div class="side_column"> side data </div> <?php Block::end();?><?php AreaDecorator::end();?>
This is similar to the above
Action usage:
public function actionIndex() { $this->layout=‘@app/views/layouts/columns_3.php‘; return $this->render(‘index‘); }
You can define multiple point operators in the layout and specify the content used in each sub-layout.
Now, you no longer have to worry that only one
$ Content
Variable
The following is a widget class that implements this function.
Areadecorator widget class:
class AreaDecorator extends Widget{ public $viewFile; public $params = []; public $ids=[]; public function init() { if ($this->viewFile === null) { throw new InvalidConfigException(‘ContentDecorator::viewFile must be set.‘); } ob_start(); ob_implicit_flush(false); } public function run() { $params = $this->params; $params[‘content‘] = ob_get_clean(); $blocks = $this->view->blocks; if(count($this->ids)>0) { foreach ($blocks as $id=>$block) { if(in_array($id,$this->ids)) { $params[$id]=$block; unset($this->view->blocks[$id]); } } } else { foreach ($blocks as $id=>$block) { $params[$id]=$block; unset($this->view->blocks[$id]); } } echo $this->view->renderFile($this->viewFile, $params); }}