Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Yii advanced url rewrite

Tags:

yii

pay attention to that ANYTHING_ELSE So, I have my controllers and actions that I want to behave as normal in response to examples like this:

// for UserContoller with actionList and actionEdit
user/list
user/edit/25

But for everything that doesn't fall under specific controllers and actions i want them to fall under one default controller and action like: BlogController and actionView. That is where ANYTHING_ELSE comes.

// ANYTHING_ELSE can be:
this-is-a-test-page
this/is/another/page/with/lots/of/slashes
this-has-extension.html


'urlManager' => array(
  'urlFormat' => 'path',
  'showScriptName' => false,
  'rules' => array(
    '<controller:\w+>/<id:\d+>' => '<controller>/view',
    '<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
    '<controller:\w+>/<action:\w+>' => '<controller>/<action>',
    'ANYTHING_ELSE' => 'blog/view',
   ),
),
like image 686
Marian Zburlea Avatar asked Aug 22 '12 22:08

Marian Zburlea


2 Answers

I shall explain step by step how to get this working.

Step 1 - Create an Yii web app

Navigate to your Yii framework path in your console and create a new webapp. In my case I used this in my console:

cd c:\zeus\yii-1.1.10.r3566\framework
yiic webapp c:\zeus\www\yiiblog

where c:\zeus\yii-1.1.10.r3566\framework is my path to Yii php framework and c:\zeus\www\yiiblog is the path to my Yii webapp test folder

Stept 2 - fake my domain to dev.yiiblog.com

Go to C:\Windows\System32\drivers\etc and edit your hosts file by adding this line:

127.0.0.1 dev.yiiblog.com

Step 3 - alter apache httpd.conf file

<VirtualHost *:80>
    DocumentRoot "c:/zeus/www/yiiblog"
    ServerName dev.yiiblog.com
    ErrorLog "logs/dev.yiiblog.com-error.log"
    CustomLog "logs/dev.yiiblog.com-access.log" common
</VirtualHost>

and restart apache service. I used in my windows console:

net stop apache
net start apache

where my Apache 2 service is named "apache" not "apache2.2" like the default one.

Step 4 - create a database and configure a database connection into Yii

I've created a database yiitest and a user yiitest. Then I opened my Yii configuration file located ad /protected/config/main.php and edited the connection to MySQL:

'db'=>array(
  'connectionString' => 'mysql:host=localhost;dbname=yiitest',
  'emulatePrepare' => true,
  'username' => 'yiitest',
  'password' => 'password',
  'charset' => 'utf8',
),

Step 5 - download dburlmanager Yii extension

Go to Yii dburlmanager, download the Yii dburlmanager extension http://www.yiiframework.com/extension/dburlmanager/ and extract it to your /protected/extensions folder

Step 6 - Create MySQL database tables and add dummy data

CREATE TABLE IF NOT EXISTS `articles` (
  `seoURL` varchar(100) NOT NULL
) ENGINE=InnoDB;

INSERT INTO `articles` (`seoURL`) VALUES
('first-post'),
('another-post'),
('post/value'),
('website/page1');

CREATE TABLE IF NOT EXISTS `pages` (
  `seoURL` varchar(100) NOT NULL
) ENGINE=InnoDB;

INSERT INTO `pages` (`seoURL`) VALUES
('page-first-post'),
('page-another-post'),
('page/post/value.html'),
('page-website/page1');

Step 7 - Create your Yii custom Controllers

Create under /protected/controllers folder two php files named ArticleController.php and PageController.php:

ArticleController.php content:

<?php
/**
 * @filename ArticleController.php
 */

class ArticleController extends CController {
  public function actionView() {
    $this->render('view', array(
      'article' => isset($_GET['article'])?$_GET['article']:'',
    ));
  }
}

PageController.php content:

<?php
/**
 * @filename PageController.php
 */
class PageController extends CController {
  public function actionView() {
    $this->render('view', array(
      'page' => isset($_GET['page'])?$_GET['page']:'',
    ));
  }
}

Step 8 - create your custom Yii views

Create your view files corresponding to those controllers above with the path /protected/views/article/view.php and /protected/views/page/view.php:

Article view content:

<h1>Article View Test</h1>
<br />
<?php
    if (isset ($article)) echo "article: $article";
?>

Page view content:

<h1>Page View Test</h1>
<br />
<?php
    if (isset ($page)) echo "page: $page";
?>

Step 9 - add custom Yii url rules

Open again your main.php Yii config file and set your urlManager to something similar to:

'urlManager'=>array(
  'urlFormat'=>'path',
  'class'=>'ext.DbUrlManager.EDbUrlManager',
  'connectionID'=>'db',
  'rules'=>array(
    '<article:[\w\/.-]+>'=>array(
      'article/view',
      'type'=>'db',
      'fields'=>array(
        'article'=>array(
          'table'=>'articles',
          'field'=>'seoURL'
        ),
      ),
    ),

    '<page:[\w\/.-]+>'=>array(
      'page/view',
      'type'=>'db',
      'fields'=>array(
        'page'=>array(
          'table'=>'pages',
          'field'=>'seoURL'
        ),
      ),
    ),

    '<controller:\w+>/<id:\d+>' => '<controller>/view',
    '<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
    '<controller:\w+>/<action:\w+>' => '<controller>/<action>',
  ),
  'showScriptName'=>false,
),

Step 10 - create .htaccess file

Create a .htaccess file under your web app root and etid its content to:

Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on

# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# otherwise forward it to index.php
RewriteRule . index.php

Step 11 - test your SEO Friendly URLs

dev.yiiblog.com/first-post
dev.yiiblog.com/page-first-post

etc

Have fun creating awesome blogs or other web apps with complete url managing power.

like image 116
Marian Zburlea Avatar answered Jan 17 '23 22:01

Marian Zburlea


If I've realized you correctly, you may use something like this:

  'rules' => array(
    //You should define all the controllers exactly:
    '<controller:user|archive|office>/<action:\w+>' => '<controller>/<action>',
    //Or more complicated rule:
    '<lang:(es|it|en)>/(turismo|visita|travel)/<slug:>' => array('visit/page', 'urlSuffix' => '.html'),

    //After that you can process all remaining urls as you want:
    '<alias:[\w\d\-_\/]+>' => array('blog/view', 'urlSuffix' => '.html'),
  ),

And the controller:

class BlogController extends Controller
{
    public function actionView($alias)
    {
        echo $alias;
    }
}
like image 41
Alexander Palamarchuk Avatar answered Jan 18 '23 00:01

Alexander Palamarchuk