To extend further static pages as shown by Qiang http://www.yiiframework.com/wiki/22/how-to-display-static-pages-in-yii/ here're the steps to take:
- Create a table
spage
(static page) in the databse with fields (id, url, title, content) - Create model and CRUD for it via Gii
- Add method in the model Spage.php
public function findByUrl($url) {
return $this->find('url=:url',array(':url'=>$url));
}
4.. In protected/components/SiteController.php add
public function actionPage() {
if(empty($_GET['view']))
$this->actionIndex();
$model = Spage::model()->findByUrl($_GET['view']);
// if page is not found, then run a controller with that name
if ($model === NULL)
Yii::app()->runController($_GET['view']);
else
$this->render('pages/spage', array('model'=>$model));
}
5.. Create a view file: protected/views/site/spages/spage.php with content
<h1><?php echo $model->title?></h1>
<?php echo $model->content?>
6.. Create a page via the admin, e.g. with a url
= "test" and sample data for title
and content
and navigate to it http://example.com/page/test - assuming that friendly URLs are turned on and index.php is hidden with config urlManager(array('urlFormat'=>'path','showScriptName'=>false,))
Hint: To remove "page" from the URL a line could be added at the start of the URL rules array:
'<view:\w+>' => 'site/page',
so the address could simply be http://example.com/test
'<view:[\w\-]+>'=>'site/page', now have priority over '<controller:[\w\-]+>'=>'/index' and the other rules with controller so if the static page is not found in the database, we will run a controller with that name Yii::app()->runController($controller);
7.. Now if you use the CMenu widget, you will notice that the static pages do not get highlighted on select. Here's a fix for that too. Create Menu.php file in /protected/components/ with:
class Menu extends CMenu{
protected function isItemActive($item,$route)
{
$pos=strpos(ltrim(Yii::app()->getRequest()->pathInfo,'/'),'/');
$route = $pos===false ? $pathInfo : substr($pathInfo,0,$pos);
return parent::isItemActive($item, $route);
}
}
Replace widgets.CMenu with widgets.Menu in your layout file/s.
That's about it. Hope it's clear enough. Will update the article further to make it better. Happy coding.
Update: Added controller execution on missing static page. Extended CMenu widget to highlight active static pages in the menu.
This what I needed
This is what I needed. I had implemented is but not the way you have done it.
Thanks.
Consistent method names
It is good to have consistent method names, so when your app gets bigger you will not be wondering if you should use find or maybe get to get model instance(s). So method
getSpageByUrl
should have namefindSpageByUrl
, as it really is predefinedfind
method. This could be even shorter, because we already know that we want to find instance of Spage by usingSpage
model, so final method name could befindByUrl
.Re: Consistent method names
@peter.m, good point. Updated the article. Thanks.
problem
it seems there is a probleme with your how to ....
What about throwing exception 404?
If view is empty, isn't it be better to throw 404 exception?
if (empty($_GET['view'])) { throw new CHttpException(404,'The requested page does not exist.'); } else { $model = Spage::model()->findByUrl($_GET['view']); // if page is not found, then run a controller with that name if ($model === NULL) Yii::app()->runController($_GET['view']); else $this->render('pages/spage', array('model'=>$model)); }
hypen(-) in url
If there is url like contact-us, about-us etc.
Route should be :
'<view:[\w\-]+>' => 'site/page',
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.