3

I have a module that is named article. It exists in the collowing folder:

- protected
      - modules
           - article
                 - controllers
                   ArticleController.php
                 - views
                       -article
             articleModule.php

Since I am making a CMS. I have chosen not to use direct links to controllers or actions. This means a call to example.com/article/article/index. Would not work. Since the CMS treats an url request as a page. (So it looks for a page called 'index' with a parents 'article' and 'article'. Such a page does not exist.

The CMS loads blocks for a valid page and for one of this blocks I want to execute the article module. I tried using

Yii::app()->runController($route). 

However for this you need a route.

Is it possible to run a module like this so that the module works the same as going to the url example.com/article/article ?

Or if that is not possible. How do I setup the Url Manager so that it can handle pages?. With Clean Urls. Here are some examples:

example.com/join_us  
example.com/join_us/contact 
example.com/news/ 
example.com/countries/us/healthcare 

The above are pages that the user can create and change. I have wrestled with this for a long time. Normally it would be an easy thing. But Yii makes it very hard. Mostly because a controller or module is linked to going to a route.

Minahalmon
  • 131
  • 2
  • 11
  • It's not really clear what you want. Should all URLs be served from one action only (in `modules/article`)? If not, which URLs should be excluded? – Michael Härtl Mar 22 '13 at 11:58
  • Show us your urlManager rules – soju Mar 22 '13 at 12:24
  • @MichaelHärtl Harti standard index action and all other actions by using get params – Minahalmon Mar 23 '13 at 08:09
  • @Soju, Currently I have written everything to a pageController that handles all clean url. `code` 'urlManager'=>array( 'urlFormat'=>'path', 'showScriptName'=>false, 'rules'=>array( '(.*)'=>'page/index', ), ), Otherwise if I fill in a self made clean url it will be treated as a type. But such a module or controller doesn't exist. – Minahalmon Mar 23 '13 at 08:12

2 Answers2

1

Put this in your main configuration:

'urlManager'=>array(
    'urlFormat'=>'path',
        'showScriptName'=>false,
        'caseSensitive'=>false,
    'rules'=>array(
        'gii'=>'gii',
        '<controller:\w+>/<id:\d+>'=>'<controller>/view',
        '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>', 
        '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
        '<action>'=>'site/<action>',
    ),
),

And this in your .htaccess file:

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
Daniel A.A. Pelsmaeker
  • 47,471
  • 20
  • 111
  • 157
Gunnit
  • 1,064
  • 5
  • 22
  • 45
  • @Virtlink why did you rate down my answer – Gunnit Mar 22 '13 at 14:31
  • Yes, why would I? I don't know, must be someone else. I only edited it. – Daniel A.A. Pelsmaeker Mar 22 '13 at 14:34
  • @Virtlink Thanks for the suggestion. A link like about_us however now goes to an action in the siteController. And for every page I need to make an action in siteController now. Also subpages don't work like join_us/contact. Could you explain abit about the idea of this. Again thanks for the reply. What i try to achieve is to run module if they exists in that folder. Otherwise send a url and sub url to a standard controller let's say siteController. That checks if it's a valid page. That is the idea I currently have. – Minahalmon Mar 23 '13 at 08:33
  • update: I changed the last line to `''=>'page/index'`. It seems to work for all first level parent urls, but not for any 2nd, 3th and onwards. Interesting is that the 3 standard Yii controller action rule `'/'=>'/'` seems to be invocated first and then the last 4th action rule. The third one is important but it does seem to conflict with my previous single rule of `'(.*)'=>'page/index'`. If I place this single rule after the 3th controller action rule. – Minahalmon Mar 23 '13 at 09:24
  • @Minahalmon You'll have to ask Gunnit, the writer of the post. I only clarified it. – Daniel A.A. Pelsmaeker Mar 23 '13 at 15:51
  • @gunnit thanks for the reply. Sorry, I am new to stackoverflow. And thanks Virtlink for the explanation tips. So far I have come far. But I can't say it's sovled yet. This worked well `''=>'page/index',` But the 2nd and 3th sub level links don't work. Like `example.com/about_us/countries/us`. As you can see it has at least 3 levels. I tried adding the following: `''=>'page/index',` In an attempt to see if it worked but it gives an error. I am not completely new to url rewriting but I am not sure how to tags and terms with Yii Url Manager. – Minahalmon Mar 23 '13 at 16:47
1

You could route everything to article controller. Yii uses rules from in order from top to bottom, so first define some specific rules, and in the end something like catch-all rule. This should work:

// Url manager rules
// Some of example non-article rules
'login' => 'userModule/user/login'
'logout' => 'userModule/user/login'
// Below regex rule catch any string and pass it to $_GET['ariticlePath'] 
// and executes action `article` of controller `article` of module `article` 
'<ariticlePath:.+>' => 'article/article/article'

In article action you can do whatever you want with passed $_GET['ariticlePath'].

SIDE NOTE: To avoid double indexing of content i recommend using meta canonical, so some possibly bogus urls with query string or whatever some users might enter, will not be treated as duplicated content by google.

EDIT: As soju sugested, articlePath can also be bound as action param:

...
public function actionArticle($articlePath)
...
  • 1
    +1, but don't use `$_GET['articlePath']`, you just have to add `$articlePath` param to your controller action function – soju Mar 22 '13 at 15:51
  • Nice, seem to be a new feature since i was reading fundamentals:) –  Mar 22 '13 at 17:55
  • Still truggling to get his to work. I have put in the 3 above write rules. And removed my (.*) rule to pageController. But it goes to the login page now. Since that is the first rules it comes by. I tried filling in index.php/?articlepath=get. But now it goes to standard Yii welcome view handled by siteController – Minahalmon Mar 23 '13 at 08:18