How to display static pages in Yii with database content?

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:

  1. Create a table spage (static page) in the databse with fields (id, url, title, content)
  2. Create model and CRUD for it via Gii
  3. 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.

3 0
13 followers
Viewed: 30 608 times
Version: 1.1
Category: Tutorials
Written by: yasen
Last updated by: yasen
Created on: Oct 11, 2012
Last updated: 5 years ago
Update Article

Revisions

View all history

Related Articles