Yii2 give us the opportunity to customize URL rules as we want. This can be done using the rules
property in urlManager
, an array where keys are patterns and values are corresponding routes. Patterns are common regular expression patterns, so it is necessary to have some familiarity with regular expression.
Patterns can contain parameters that will be passed to the route. In the next example, we will display a list of news that can be filtered through year or category parameter, based on parameters passed to the URL.
In this example, we will create a new Controller named News
in controllers/NewsController.php
. In this new controller, we will insert a data()
function containing an array with test data, and a function named actionItemsList
.
The first thing to do is to configure the rules
property under the urlManager
component under config/web.php
:
'rules' => [ news/<year:d{4}>/items-list' => ' news/items-list', 'news/<category:w+>/items-list' => 'test-rules/items-list', ],
Here, we have two patterns:
news/<year:d{4}>/items-list
news/<category:w+>/items-list
The first pattern catches requests with a numeric parameter with four digits, passed to the news /items-list
route as the year
GET parameter. We can request 'news/2014/items-list' or 'news/2015/items-list'.
The second pattern catches requests with the word parameter, passed to the news/items-list
route as the category
GET parameter. We can request news/business/items-list
or news/shopping/items-list
.
Then, we create NewsController
where to define the data()
function, to return static data to be used as data source, and the actionItemsList()
function to handle requests to news/year/or/category/itemsList
:
<?php namespace appcontrollers; use Yii; use yiiwebController; class NewsController extends Controller { public function data() { return [ [ "id" => 1, "date" => "2015-04-19", "category" => "business", "title" => "Test news of 2015-04-19" ], [ "id" => 2, "date" => "2015-05-20", "category" => "shopping", "title" => "Test news of 2015-05-20" ], [ "id" => 3, "date" => "2015-06-21", "category" => "business", "title" => "Test news of 2015-06-21" ], [ "id" => 4, "date" => "2016-04-19", "category" => "shopping", "title" => "Test news of 2016-04-19" ], [ "id" => 5, "date" => "2017-05-19", "category" => "business", "title" => "Test news of 2017-05-19" ], [ "id" => 6, "date" => "2018-06-19", "category" => "shopping", "title" => "Test news of 2018-06-19" ] ]; } public function actionItemsList() { // if missing, value will be null $year = Yii::$app->request->get('year'); // if missing, value will be null $category = Yii::$app->request->get('category'); $data = $this->data(); $filteredData = []; foreach($data as $d) { if(($year != null)&&(date('Y', strtotime($d['date'])) == $year)) $filteredData[] = $d; if(($category != null)&&($d['category'] == $category)) $filteredData[] = $d; } return $this->render('itemsList', ['year' => $year, 'category' => $category, 'filteredData' => $filteredData] ); }
Finally, we create a view in views/news/itemsList.php
, displaying the parameter used, year or category, and a list of results:
<?php if($year != null) { ?> <b>List for year <?php echo $year ?></b> <?php } ?> <?php if($category != null) { ?> <b>List for category <?php echo $category ?></b> <?php } ?> <br /><br /> <table border="1"> <tr> <th>Date</th> <th>Category</th> <th>Title</th> </tr> <?php foreach($filteredData as $fd) { ?> <tr> <td><?php echo $fd['date'] ?></td> <td><?php echo $fd['category'] ?></td> <td><?php echo $fd['title'] ?></td> </tr> <?php } ?> </table>
Now, let's point to http://hostname/basic/web/news/2015/items-list
to display the items list filtered out by year:
Try to change the year between news and items list to see how the data result changes in the list. The rules that are created allow us to display the items list filtered by category. Point to http://hostname/basic/web/news/business/items-list
to see the list filtered by business category:
We can also point to http://hostname/basic/web/news/shopping/items-list
to see the list filtered by shopping category.
18.119.133.228