How to do good custom routing with CakePHP? - cakephp

I am planning to rewrite my site into CakePHP and after having spent a full week on learning it, I am still not sure how to do good custom routing in CakePHP.
This is what I want:
Keep the current url structure in www.domain.tld/en/dragons.html, or use a www.domain.tld/en/dragons, but not www.domain.tld/en/nodes/dragons.html. And also be able to use controllers on a similar path structure.
There are about 100 static pages on the entire site. I have read into multi-language routing and I think I can do it. I can also make /en/* or /en/:slug route via a PagesControler or a self-written NodesController.
My problem is that I would like to be able to mix and match url's with and without controllers, so actually what I want is that it checks if a :slug is part of the slug-list, there should still be the option to use that url with a controller.
I have created routes for both /en/contact and /en/:slugid, but it seems all queries were routed to my NodesController, even while I explicitly said that /en/contact should be routed to the ContactsController.
How can I instruct Cakephp to keep my current dictorary structure? I read the routes part of the Cakephp book, but it was extremely short and made me a little unsure about the possibility of such routing. If necessary, I'll just write a php-code that prints all routes for all slugs, so I can still write controller-routes with a similar path structure.

If a file exists in webroot (ie. app/webroot/static.html), the .htaccess file will tell Apache to serve that file before loading the CakePHP framework for requests to www.example.com/static.html.
Cake loads routes in a top-down order and will use the first matching route to handle a request. In your case, /en/contact should be above /en/:slugid, else the slugid rule will always win.
If CakePHP's routing does not accomplish what you are after, you can always implement a custom route class (book / example).

Related

MVC Routing vs Angular Routing: Is not enough with just MVC Routing?

As far as I know the hash symbol(#) is the key when implementing routing in Angular. The web server only takes care about the part of the URL which is before the hash, and Angular takes care of the rest.
I´ve read some articles that explain how to remove the hash from URL. But if I remove the hash(#) from URL: Which routing works first?
OK, it is MVC. In that case we have to edit the MVC Route in order the server to understand the URL. But we are at the beginning again. Does it make any sense to use Angular Routing and MVC together ? Is not enough with MVC Routing?
Maybe I´m missing something. I hope you can help me.
Does it make any sense to use Angular Routing and MVC together ? Is
not enough with MVC Routing?
TL;DR;
I've rarely use both. The only time I use both is when I need to authenticate the user for some routes.
Long answer
1. Authentication
As you already figured out, Angular routing is great when you want to navigate to another page without the roundtrip to the server. It's usually a SPA. But there might be a scenario when you need to authenticate the user before sending the HTML, then MVC routing will be handy. I wrote an answer about it here. Note the difference between sending HTML and sending DATA to to the client. If you have no server routes the html-pages (or templates) will be fully accessible (unless you limit access in web.config or some other way). Some times the HTML-pages can contain some sensitive information as well...
The most common scenario is if you have a public site with an admin-part. But in my experience you can handle this on client side with client-side-routing only. It's usually the data that is sensitive, not the templates.
2. Server-side logging
The other scenario is when you want to do some logging on server side. For example if you want to log every page request. This can often be done on the client as well... Look at Google Analytics. But you might want to log the request even if the browser has javascript turned off.
3. SEO
There might be some SEO-issues when using client-side-routing. But this is only when we render the html with client side templates and if we compare to completely rendered views with MVC.Net. Do not confuse me posting the link with me actually agreeing with the content...
4. WCAG
In my country all government sites need to follow WCAG. One of the rules are - no javascript. Or at least that the site should be fully accessible without javascript. Without javascript client-side-routes are simply very difficult. ;)
These are some examples when you might need both server-side and client-side routes. But to sum up, in most cases client-side is enough.

How do I reverse an AngularJS route from a Django template?

I have a Django application with an AngularJS frontend. The application sends notification emails, which it renders using Django templates.
ITEM: {{article.title}}
DATE: {{article.date}}
SOURCE: {{article.link}}
{{article.body}}
The issue is article.link. The previous version of the application didn't use Angular, so it was simple to find the link. In urls.py we had
url(r'article/(?P<article>\d+)/$', views.ArticleView.as_view(), name='show-article')
which meant that we could reverse a URL to a particular article with
django.core.urlresolvers.reverse('show-article', kwargs={'article':article_id})
Now, on the Angular-based revamp of the site, the display URL for an article looks like /mysite/#/article/1234 and is determined by routes.js:
$routeProvider.when('/article/:articleId', { ... } )
Bottom line, I don't have a way to grab an AngularJS route from Python. I could hard-code the all the routes from routes.js into something the backend sees, but it wouldn't be very DRY. I could generate routes.js dynamically with Django, but right now none of our other JS source is touched by Django -- that doesn't seem very clean either. Maybe I should continue to support the old-style URLs (/article/1234) as a redirect to the Angular-style URLs (/#/article/1234)? That still requires logical duplication, I think.
Is there a better pattern I should be using here?
Decoupling clients and servers is often a goal so duplication should not be considered a bad thing in this case. Depending on your needs however there are solutions which provide a reverse method which behaves like in Django. There is django-js-reverse and django-angular for angular specificaly.

CakePHP: Is it safe to write queries in route.php file

I am using cakephp. And i have written some cakephp find queries inside routes file. The requirement was to create dynamic url. But i have doubts whether it is safe to write queries in route file or is there any chances of SQL injection for this. If it is unsafe then what are the threats that will affect my website and what should i do to prevent these web threats.
No this sounds like terrible code smell.
What you want sounds as well like you want to use slugs or resolve URLs to something in the DB. Here is how to do it right:
Create a custom route class (SlugRoute, DbLookupRoute...)
Create a model method (MyUrLModel::lookup($url) for example) that does the actual lookup
Load that model in the Route class
Use the custom route class in your routes.php
Optional but a good idea to implement: Caching of the route lookup.
All of the above is described on book.cakephp.org, pay attention to the chapter about the router.

Recommended nginx setup for AngularJS as front end and Symfony2 as back end

I want to use Symfony2 as back end to create a REST API and use AngularJS as front end. The 2 are completely separated ie Symfony 2 will not render anything, it'll just send json data to AngularJS.
I'm not sure on how to configure my web server (nginx).
The Symfony documentation gives the configuration but it's intended for a site that only uses Symfony, and so everything outside of the /web/ folder is not accessible.
I can see several possibilities:
Create 2 different directories (eg /path/frontend and /path/backend) and a corresponding website for both. I would then have 2 different addresses to access the front end and the back end (eg http://myfrontend.com and http://mybackend.com). The problem I see is that I probably won't be able to directly use AJAX calls in AngularJS.
Create 2 different directories (eg /website/frontend and /website/backend) and only one website. I would then probably need to access the front end and back end with something like http://example.com/frontend and http://example.com/backend. I'm not sure how to configure the web server though (issue with root /website/backend/web).
Put the AngularJS directory inside the web folder of Symfony, but then I'd need to also change the configuration so that nginx doesn't only server app.php, app_dev.php and config.php.
Put the AngularJS directory in the src folder of Symfony, and have Symfony handle the routing. I don't know if it will mess with AngularJS' one routing. Also I will probably have a few other php that should be accessible, so I'd need to route them through Symfony also.
What would you suggest and why? Maybe I'm missing something obivous?
I guess you could accomplish your task using any of those methods. It would come down to how you want to structure you application and what it's objectives are. For large scale projects the first method (having the API separate from the AngularJS) would serve you well. Twitter really made that software model big.
So I would suggest going with method one. All you would have to do is specify an Nginx header in your server block that allows cross domain access to another domain. So you would specify the following directive in your frontendangular.com site:
add_header Access-Control-Allow-Origin backendsymfony.com;
This way every time a page request comes in on your front end app Nginx tells the browser that it is safe to access another domain (your symfony setup).
These are 2 frameworks that both have powerful routing capabilities, and it looks like you are going for a best of both worlds. There are many pros and cons to any setup, so I'll list a few that come to mind:
Angular routing / templating is great but it will leave you with SEO and meta issues to solve . It's probably better to manage your major pages with symfony2 and any routing within each page with angular. This would allow you to still make dynamic pages w/out compromising your meta and SEO control. Access Control seems flexible but probably not necessary, I would just put all calls to REST API under http://www.thesite.com/api and if I need another setup something like https://api.thesite.com, nginx can route or proxypass this without leaving the domain.
Locating partials gets a little wonky but that's probably fine for a large application. Just note that you will probably need to search the js location object for [host] / [path] /web/bundles/someBundle/public/blah.... Or you can setup a '/partials' path in nginx.
Twig and Angular tpl may end up a confusing mix as they both use {{foo}}. This alone would make me reconsider mixing the 2, and I might look to go with a frontend server, like node with ejs where I could also benefit from the streaming transfer of the data sent from the API.
You can get around it easy enough with but it's still concerning:
angular.module('myApp', []).config(function($interpolateProvider){
$interpolateProvider.startSymbol('[[').endSymbol(']]');
}
);
You do get the benefit of angular partials as symfony twig, which can be good or bad depending on how you see the flexibility being used. I have seen guys making examples of forms that fill out values with symfony data, but they are just undermining the power of angulars binding.
Don't get me wrong, I actually do really like the idea of the two harmonizing.
Just food for thought - cheers

FrontController implementation for JSP pages

I am developing a simple website with few JSP pages. Each jsp does have a dynamic data that needs be read from XML before they redered on to the browser. Though MVC pattern such as Struts2 is more appropriate here, I don't want to implement it for a simple web application.
For this purpose I just want to implement FrontController Pattern which is sufficient for managing the jsp pages with few Helper Classes.
What I want is to have a Centralized Controller for all JSP pages. if user try to acccess any jsp page, then it should first go to the Controller. So I tried to implement a servlet with URL pattern "/pages/*.jsp" where /pages contains all jsp pages in webcontent.
The problem is, the controller is being invoked each time when there is a call for .jsp file, but when I try to disatch it to the jsp page(ex /pages/homepage.jsp) it goes into indefinite loop. It is obvious that each jsp page call will always comes to controler again.
So is there any other way that we can implement the centralized controller for this situation.
Thanks in advance.
I guess your only problem is that you need to read a XML file before each and request is processed.
If this is only the case than Filters are best suited.
But in case there are more that needs to be done and you really need a centralized control on all request than you can do anyone of the following: -
Struts (it doesn't matter that your
project is small or big, but using a
predefined and proven pattern is
always useful).
In your Controller put a mapping of
logical URL's with Physical URL's
and now put your mapping to Logical
URL's and not the physical URL's.

Resources