Yii 1.1: How to display static pages in Yii with database content?

15 followers

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.

Total 5 comments

#17962 report it
jonghwa at 2014/08/18 01:14pm
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));
            }
#10303 report it
fouss at 2012/10/18 07:27am
problem

it seems there is a probleme with your how to ....

#10245 report it
yasen at 2012/10/13 02:01pm
Re: Consistent method names

@peter.m, good point. Updated the article. Thanks.

#10238 report it
pmaselkowski at 2012/10/13 06:18am
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 name findSpageByUrl, as it really is predefined find method. This could be even shorter, because we already know that we want to find instance of Spage by using Spage model, so final method name could be findByUrl.

#10216 report it
bonnie at 2012/10/11 07:16pm
This what I needed

This is what I needed. I had implemented is but not the way you have done it. Thanks.

Leave a comment

Please to leave your comment.

Write new article