Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Yii PHP Framework url routing

Posted on 2015-01-22
21
Medium Priority
?
456 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 43

Expert Comment

by:Rob
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 43

Expert Comment

by:Rob
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

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 43

Expert Comment

by:Rob
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 43

Expert Comment

by:Rob
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
 
LVL 43

Expert Comment

by:Rob
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 43

Expert Comment

by:Rob
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 43

Expert Comment

by:Rob
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 43

Expert Comment

by:Rob
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 43

Accepted Solution

by:
Rob earned 1500 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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I have written articles previously comparing SARDU and YUMI.  I also included a couple of lines about Easy2boot (easy2boot.com).  I have now been using, and enjoying easy2boot as my sole multiboot utility for some years and realize that it deserves …
The first step to building an amazing About page is to figure out what you want the page to say about your company. You then must grab the attention of the reader, boast a bit, tell a story and let others brag about you. With a little bit of thought…
This tutorial demonstrates how to identify and create boundary or building outlines in Google Maps. In this example, I outline the boundaries of an enclosed skatepark within a community park.  Login to your Google Account, then  Google for "Google M…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
Suggested Courses

580 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