Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CakePHP and AngularJs in routing harmony: htaccess rules to send user to index.html or bootstrap index.php

I'm building an app with CakePHP as my backend and AngularJS as my front-end framework.

I need to have CakePHP on the same server as my front-end code so it can serve the JSON I need.

Typically in CakePHP, one has the webroot folder, and besides the js/css/less/*, there is an index.php that hooks to CakePHP. Adding AngularJS, though, adds some complexity because I also want an index.html.

Here is the control flow I'd like to have:

  • If the user goes to domain.com/, display index.html (but the route stays '*.com/'!)
  • If the user goes to domain.com/#/home, display index.html and let Angular take care of the hash route
  • If the user goes to domain.com/about (assuming the about page, html and all, is served by CakePHP), send them to index.php.
  • If I make a AJAX call with domain.com/users/list.json, use index.php so that CakePHP can serve the JSON.

So my thought was I could have .htaccess rules take care of this. But I'm not quite sure what to write.

Right now I have:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d #if it's not an existing directory
    RewriteCond %{REQUEST_FILENAME} !-f #if it's not an existing file
    RewriteRule ^(.*)$ index.php?/$1 [QSA,L] #everything else, send to CakePHP
</IfModule>

Any ideas?

Would it be as simple as adding a line after the last condition like RewriteRule / index.html [L]?

Also, please feel free to suggest alternative setups with CakePHP and AngularJS.

Thanks!


EDIT: I want to give more information on the build system I'm using for AngularJS and why it poses issues with just serving from the 'home.ctp' view.

I'm using ng-boilerplate which uses karma for testing and grunt for concatenation, uglifying, and including scripts in index.html.

I think the build system is truly beautiful since it allows me to keep a modular structure.

Here is the directory structure for a typical ng-boilerplate front-end:

ng-boilerplate/
  |- build/                    # Development build
  |  | index.html
  |  | assets/
  |  | 
  |  |- angular/
  |- grunt-tasks/
  |- karma/
  |- src/                      # Actual source code I'm editing
  |  |- app/
  |  |  |- <app logic>
  |  |- assets/
  |  |  |- <static files>
  |  |- common/
  |  |  |- <reusable code>
  |  |- less/
  |  |  |- main.less
  |- vendor/
  |  |- angular-bootstrap/
  |  |- bootstrap/
  |  |- placeholders/
  |- build.config.js           # Build configuration specific to app
  |- Gruntfile.js
  |- module.prefix
  |- module.suffix
  |- package.json

(More info on each of these directories and folders here: https://github.com/joshdmiller/ng-boilerplate)

This makes for a difficult workflow, since I have to take the most recent 'build' (during development) and place the index.html file manually in home.ctp every time I edit index.html.

This is why my mind first went to .htaccess. Though, I understand that this idea has its own limitations if I ever do want to serve a page from CakePHP directly rather than bringing AngularJS into the picture.

Maybe I could configure the build system to place the index.html in the CakePHP's home.ctp view. Any ideas on this solution?

like image 291
Will M Avatar asked Jan 12 '23 23:01

Will M


1 Answers

Keep it simple

One of Cake's main principles is KISS ("Keep it Simple (Stupid)").

You don't need any rewrite rule changes if the response for the url / is that of your index.html file

i.e. do the equivalent of this:

cd app
mv webroot/index.html View/Pages/home.ctp
<edit View/Pages/home.ctp>

If you put the following at the top of the view file:

<?php $this->layout = false; ?>

You can also leave the contents as the complete raw html file.

Doing this would remove the need for any .htaccess modifications.

A specific note about one of the bullet points:

If the user goes to domain.com/#/home, display index.html and let Angular take care of the hash route

Nothing needs doing for that, as a url fragment is not sent by browsers with requests - the url received on the server is domain.com/.

But if you really want to do it with mod rewrite only

Then all that's required is to add a rule for the url / - which is the only exception:

<IfModule mod_rewrite.c>
    RewriteEngine On

    RewriteRule  ^$ /index.html [L]

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

Be sure to use the .htaccess rules for the exact version of cake you're using as they changed over the years and can cause odd behavior using an older version of the rewrite rule with a newer version of Cake.

Note that the directory-exclusion condition isn't required and is probably not desired (it allows a directory listing with e.g. /css).

like image 176
AD7six Avatar answered Jan 30 '23 07:01

AD7six