Yii PHP Framework url routing

Hi,

Using the Yii framework, is it possible to map this type of url -following Google guidance to index a single page application:

http;//somedomain.com/?_escaped_fragment=page/contact

Where page is my controller. The action is generic and in this case takes the contact value and retrieves that page from the database (this is not important to this discussion).

I'm not an expert on .htaccess - these are the rewrite rules I currently have in place

<IfModule mod_rewrite.c>
  RewriteCond %{HTTPS} !=on
  RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
  RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]

  RewriteCond %{SCRIPT_FILENAME} -f [OR]
  RewriteCond %{SCRIPT_FILENAME} -d
  RewriteRule .* - [L]
  RewriteRule ^search/(.+)/([0-9]+)/?$ search/search?search=$1&page=$2 [QSA,L]
  RewriteRule ^(.+)/([0-9]+)/?$ index.php?name=$1&page=$2 [QSA,L]
  RewriteRule ^(.+)$            index.php?name=$1         [QSA,L]

</IfModule>

Any help much appreciated !
daisydoosAsked:
Who is Participating?
 
RobConnect With a Mentor Owner (Aidellio)Commented:
Would you mind sharing some of the latest code you've got so far regarding the routing? Something might jump out at me.
0
 
RobOwner (Aidellio)Commented:
Typically the only configuration you need for your URL rewrite is:

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

Open in new window


Then you control the routing from within your app by following what's described here: http://www.yiiframework.com/doc-2.0/guide-runtime-routing.html

So in your case: http://somedomain.com/?_escaped_fragment=page/contact.  Are you forced to use this URL or believe you have to so that Yii works for you?  

Specifically look at Creating URLs that map to the relevant View or Controller action.  http://www.yiiframework.com/doc-2.0/guide-runtime-routing.html#creating-urls
0
 
daisydoosAuthor Commented:
Hi,

I have no problem creating standard routing urls in Yii - have built many sites using the framework.

I want to use this type of scheme to include the "?_escaped_fragment=" portion because I have a single page application which I want to make crawlable using Google's advice on such topics ...

The docs don't help on this.

Do you know how I would create a route to allow for this inclusion?
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

 
RobOwner (Aidellio)Commented:
I haven't used Yii but I have used CakePHP, Slim, NodeJS that all use rewriting so forgive me if I don't get the syntax correct.

What URL Rules have you currently got?  What have you tried that hasn't worked (but you expect it to)?

http;//somedomain.com/?_escaped_fragment=page/contact

should map as the following with a URL Rule, with page as your controller
[
'\?_escaped_fragment=page/<category>' => 'page/view'
]
0
 
daisydoosAuthor Commented:
Hi,

People on stack overflow have been asking a similiar question (not related to Yii tho!)

http://stackoverflow.com/questions/8063287/crawlable-ajax-with-escaped-fragment-in-htaccess
0
 
daisydoosAuthor Commented:
HI,

Sorry didnt see your message before my last one..

I want http;//somedomain.com/?_escaped_fragment=controller/action to redirect to http;//somedomain.com/controller/action - the way to do this is surely through htaccess??

My current htaccess is listed above.

I am trying a route of

<fragment:.*>/<controller:\w+>/<action:\w+>=><controller>/<action>

or

\?_escaped_fragment_\=/<controller:\w+>/<action:\w+>=><controller><action>

But neither work - it's got to be down to htaccess surely?
0
 
RobOwner (Aidellio)Commented:
My experience with these systems is that you set up what they need to run with htaccess and then leave it alone.

Given you are routing essentially within the app, I would be trying to do this in Yii.  Start trying to use htaccess and you could break something else.

As for the route, did the following not work?

[
'\?_escaped_fragment\=<controller:\w+>/<category:\w+>' => 'page/view'
]

Force it to a specific controller function and see if it works
0
 
daisydoosAuthor Commented:
Hi,

No tried all of this - it needs to be

'\?_escaped_fragment_\=<controller:\w+>/<action:.*>'=>'<controller>/<action>',

but this doesnt work
0
 
RobOwner (Aidellio)Commented:
Seeing the parametized example
'<controller:(post|comment)>/<id:\d+>/<action:(create|update|delete)>' => '<controller>/<action>'

Have you tried not escaping the ? and = as there doesn't seem to be any regex going on outside of the < >

'?_escaped_fragment_=<controller:\w+>/<action:.*>' => '<controller>/<action>'

Other than that, I'm not sure how much more I can help.  What is the error your getting? 404?
0
 
daisydoosAuthor Commented:
Hi,

You have to escape the ? and = as I've done otherwise Yii barfs that it's not a valid regular expression !
0
 
daisydoosAuthor Commented:
Hi,

To recap

Assuming I want to work with http://domain.com/?_escaped_fragment=/site/index

I've tried

'<fragment:.*>/<controller:site>/<action:.*>'=>'<controller>/<action>'
'\?_escaped_fragment_\=/<controller:site>/<action:.*>'=>'<controller>/<action>' (you have escape otherwise Yii will throw an error it's not a valid regular expression)

Both generate a 404 error...
0
 
RobOwner (Aidellio)Commented:
Apologies for not replying sooner. Understand about the route being a regular expression but had to rule it out.

Have you tried breaking up the route into simpler routes to determine what part of the string is causing the issue?

E.g. Do the routes posted in your last comment work for the following (underscores and question marks removed) http://domain.com/fragment=/site/index

Another thing to consider is that Yii will ignore anything after the ? And parse those terms as the querystring. In Slim for instance the route would be on the siteroot (/) for http://domain.com/?_escaped_fragment=/site/index and the query string parsed in the second stage:

$app->get('/', function() use ($app) {
    $frag=$app-request->get('_escaped_fragment'); // this now contains "/site/index"
    $app->redirect($frag);
}
0
 
daisydoosAuthor Commented:
Hi Rob,

Many thanks for getting - appreciate your efforts.

Have been advised to use additional configuration values for the Yii urlManager, which partly improves the situation but not completely which is very frustrating !!!!!
0
 
RobOwner (Aidellio)Commented:
Hi
So where does that leave you? does the url manager at least parse the querystring?
0
 
daisydoosAuthor Commented:
Hi Rob,

I can (almost) get things to work when using $_GET in urls and not a (pretty) path, and the routeVar variable in the urlManager ... I won't go into the almost bit for brevity sake, but you can read an action from the controller eg page/contact us. Hurrah!

However.

This then completely breaks my RESTful API upon which the entire single page application as been built......
0
 
RobOwner (Aidellio)Commented:
So you changed to having the route on the top level directory but you're detecting a GET variable in the middle there somewhere and redirect to the controller/function?

I gather that your RESTful API uses the top level directory as well eh?  Guessing that would be a lot harder to change....
How does what you've done interfer with the API?  Can you not just detect if "_escaped_fragment" is present and if not continue with the normal API call?


As an example, can the fragment be changed to http://somedomain.com/vars/?_escaped_fragment=page/contact so that you can perform the routing on /vars/ ?
0
 
daisydoosAuthor Commented:
Hi Rob,

When I use routeVar in the urlManager it completely overwrites any of my normal routes - I have absolutely no idea why and have failed to get an answer on the Yii forum. No one seems to know what to do to help - perhaps they've never tried to build a single page application which has to be indexable by search engines!
0
 
RobOwner (Aidellio)Commented:
How hard is it to change frameworks, thinking outside the square here...
I've built two single page apps in the last couple of months using slim and the other with cakephp...
0
 
Bernard S.CTOCommented:
Hmmm... not sure that the target url you want to build is Google-safe, since handling what comes after the ? is not guaranteed... so you should try to eliminate it one way or the other (no "=", no "?" and no "&" would be the safest). I would probably rather use '#', which also makes sens for a single page

For your single page app: you know it is a single page, but the bots will not know (although their indexer will discover), so nothing prevents you from creating an alias for each subpage

Then your rewrite could transform   /page1 into /page0#page1 etc
0
 
daisydoosAuthor Commented:
Hi Rob and Fibo,

Many thanks for getting back. Rob - appreciate your efforts, but I'm currently into Yii2 , which will give me more flexibility on my routes and create a more robust REST API.

Fibo, not sure what you mean - I'm just following the guidance from Google on making single page apps crawlable.
0
 
daisydoosAuthor Commented:
Very much appreciate Rob's help - it's difficult when people are using different frameworks!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.