Solved

Yii PHP Framework url routing

Posted on 2015-01-22
21
349 Views
Last Modified: 2015-02-23
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 !
0
Comment
Question by:daisydoos
  • 11
  • 9
21 Comments
 
LVL 42

Expert Comment

by:Rob Jurd, EE MVE
ID: 40583080
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
 

Author Comment

by:daisydoos
ID: 40583510
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
 
LVL 42

Expert Comment

by:Rob Jurd, EE MVE
ID: 40583522
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
 

Author Comment

by:daisydoos
ID: 40583715
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
 

Author Comment

by:daisydoos
ID: 40583719
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
 
LVL 42

Expert Comment

by:Rob Jurd, EE MVE
ID: 40583837
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
 

Author Comment

by:daisydoos
ID: 40583911
Hi,

No tried all of this - it needs to be

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

but this doesnt work
0
 
LVL 42

Expert Comment

by:Rob Jurd, EE MVE
ID: 40584895
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
 

Author Comment

by:daisydoos
ID: 40588145
Hi,

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

Author Comment

by:daisydoos
ID: 40588174
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 42

Expert Comment

by:Rob Jurd, EE MVE
ID: 40596776
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
 

Author Comment

by:daisydoos
ID: 40600497
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
 
LVL 42

Expert Comment

by:Rob Jurd, EE MVE
ID: 40602133
Hi
So where does that leave you? does the url manager at least parse the querystring?
0
 

Author Comment

by:daisydoos
ID: 40604056
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
 
LVL 42

Expert Comment

by:Rob Jurd, EE MVE
ID: 40605306
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
 

Author Comment

by:daisydoos
ID: 40607679
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
 
LVL 42

Expert Comment

by:Rob Jurd, EE MVE
ID: 40610550
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
 
LVL 42

Accepted Solution

by:
Rob Jurd, EE MVE earned 500 total points
ID: 40622912
Would you mind sharing some of the latest code you've got so far regarding the routing? Something might jump out at me.
0
 
LVL 29

Expert Comment

by:fibo
ID: 40623261
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
 

Author Comment

by:daisydoos
ID: 40625755
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
 

Author Closing Comment

by:daisydoos
ID: 40625756
Very much appreciate Rob's help - it's difficult when people are using different frameworks!
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Suggested Solutions

Envision that you are chipping away at another e-business site with a team of pundit developers and designers. Everything seems, by all accounts, to be going easily.
Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
Any person in technology especially those working for big companies should at least know about the basics of web accessibility. Believe it or not there are even laws in place that require businesses to provide such means for the disabled and aging p…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now