Simple page app routes to same view or controller SailsJS - sails.js

How can I route multiple urls to the same controller or view to work with angular single page app?!
I can do this but i think is ugly..
'/': {
view: 'homepage'
},
'/login': {
view: 'homepage'
},
'/register': {
view: 'homepage'
},
'/troller': {
view: 'homepage'
},
............
I want somethink like
['/','/login','/register','/troller'] -> view: 'homepage'
And other question, Can I use regular expressions for routing?
Thx!! and sorry for my english.

You can't currently use real regular expressions for routing. You can however use a wildcard route to do what you want (aim multiple routes at one view).
Put this at the end of your /config/routes.js object:
'/*': function(req, res, next) {
if (req.path.match(/\..*/g)) {
return next();
} else {
return res.view('homepage');
}
}
and everything that isn't matched by one of the routes above it will execute that function. The function first checks if you're trying to access a static asset (something with a file extension, like .js or .css), and if so, continues matching the route so that the Express static middleware can server the file. Otherwise, it will server your view.
Update
As of Sails v0.10.0-rc5, regular expressions can be used to define routes. From the docs:
The syntax for a regular expression route is:
"r|<regular expression string>|<comma-delimited list of param names>"
That's the letter "r", followed by a pipe, a regular expression string without delimiters, another pipe, and a list of parameter names that should be mapped to parenthesized groups in the regular expression. For example:
"r|^/\d+/(\w+)/(\w+)$|foo,bar": "MessageController.myaction"
will match /123/abc/def, running the myaction action of MessageController and supplying the values abc and def as req.param('foo') and req.param('bar'), respectively.

You can also route them simultaneously using | operator
'/' | '/login' | '/register' | '/troller': {
view: 'homepage'
}

I don't know if your approach succeded but in my head mapping angular routes clientside to node routes serverside is misleading. My approach to an single page application with these two libraries would be:
having the default sails view deliver your index and angular.js
having the angular routes working your clientside routes together with controllers, etc
managing the complete ui and page flow in angular
using the default sails api's with angular ressource to work on the node models (dont forget to use promises)
using the node / sails routes to add specials on top of that if needed (e.g. login management)
using css framework to compile css (e.g. sass with compass or less)

Related

Problem with plugin routes and multilanguage in a Cakephp4

I've built a multilanguage NewsManager plugin that has a NewsController
I'm try to write routes in this plugin to be able to access to routes like /en/news-manager/news/, /en/news-manager/news/my-lastest-news, ...
Here is my code :
// in /plugins/NewsManager/config/routes.php
$routes->scope('/{lang}', function (RouteBuilder $routes) {
$routes->plugin('NewsManager', function (RouteBuilder $routes) {
$routes->connect('/news', ['controller' => 'News', 'action' => 'index'])
->setPatterns([
'lang' => 'en|fr'
])
->setPersist(['lang']);
$routes->connect('/news/{slug}', ['controller' => 'News', 'action' => 'view'])
->setPass(['slug'])
->setPatterns([
'lang' => 'en|fr'
])
->setPersist(['lang']);
});
});
When I try to access to /en/news-manager/news/ I have a Missing Controller error with the message NewsManagerController could not be found.
What am I doing wrong ?
(Note that when I write exactly the same code that the code above but in my App routes it works...)
For parsing requests, routes are being ordered by their template's static path portion, which is the porition of the template before the first routing element.
So in your case the static portion would be / for all the language routes, as they immediately start with the {lang} routing element. This will result in a first comes first served order, meaning since your fallback routes are being connected before the plugin routes, they will be processed and matched first, making your plugin routes inaccessible.
As mentioned in the comments, one solution would obviously be to remove the fallback routes. This isn't an uncommon thing to do, as bailing out early at routes lookup will avoid unneccsary processing until the code runs into a problem at controller lookup later on.
Another way would be to connect the fallback routes after the plugin routes. Plugin route loading will always be invokved after application routes loading, so the pretty much only way to achieve this, is to move connecting the respective application routes into the plugin routes loading mechanism, which has a slight workaround smell.
Basically, move those routes into Application::pluginRoutes() to after invoking the parent method:
// in src/Application.php
public function pluginRoutes(\Cake\Routing\RouteBuilder $routes): \Cake\Routing\RouteBuilder
{
// connect plugin routes
$routes = parent::pluginRoutes($routes);
// connect fallback routes
$routes->scope('/{lang}', function (\Cake\Routing\RouteBuilder $routes) {
$routes->fallbacks();
});
return $routes;
}

How to call a Scala function from Play html template

I am new to Scala/Play Framework.
Currently, I am trying to call a Scala function from my html page: test.scala.html and pass the hash parameters to the Scala function.
I added the following lines to routes:
GET /hello controllers.Application.test
POST /hello controllers.Application.hello
In my test.scala.html I have:
#params = { window.location.hash }
#helper.form(action = routes.Application.hello) {
}
And my hello function is defined as:
def hello() = Action {
Ok("Hello !")
}
I am completely confused by the concept of routing and # so I am not too sure which part I did right and which part I did wrong. Please point out my mistakes.
Thanks in advance.
If the function is returning an action, not content to be displayed formatted inside view (HTML), you may want to route request to this action, from a link click or a form submit, to url configured in routing (aka /hello).
To add a parameter you need to either add it as url query string (e.g. for a link → /hello?p=1), or with an input/field for a form (e.g. <input type="text" name="p" value="1" />).
You can use reverse routing to get URL to call configured action. For example for a form POST to hello: <form action="#routes.MyController.hello()" method="POST">.... In this case you will need to look at form mapping, to extract parameters from request.
1) Concept of routing
The main purpose of this routing is simply to translate each incoming HTTP request to an Action in any of your Controller. By Reverse Routing its simply let you use the right part, controllers.Application.hello, in your HTML/Controller/else.
So, for your 2 URLs above, it's likely to say that if there is a request /hello with method GET then it will go to Application controller and test method. If you don't understand the role of each Routing method, please read this documentation..
2) the magic # character
# is a character that you can use in your HTML file if you need to use the Scala code or variables. It's like you can combine PHP code in your HTML file, if you're a PHP developer.
Here is the full-documentation of what you can do with this # character.
3) pass the hash to the controller
To this specific case the simplest way would be passing the value trough a form:
#helper.form(action = routes.Application.hello) {
#helper.inputText(myForm("username"), 'id -> "username", 'size -> 30, 'value -> 'value here' )
}
However, if you're a new Play developer, then I'm afraid you need to read about Form Submission and Form Helper in Play Framework..

Is it possible to have a parameter as the first node of a route?

I'd like to have the following type of route in ASP.NET MVC.
{a}/{b} -> SiteController.Search(a, b) (where a and b are arbitrary strings)
While still having a HomeController
home/index -> HomeController.Index()
Is this possible? Is it possible if the home controllers routes are hardcoded?
ie:
routes.MapRoute(
"Home", // Route name
"Home/{action}", // URL with parameters
new { action = "Index" } // Parameter defaults
);
No this is not possible without removing the default route because the routing engine cannot disambiguate between those two urls:
foo/bar
home/index
Assuming you want the first to match {a}/{b} and the second {controller}/{action}. Even if you hardcode the route as in your example home/index will always match the first route which is {a}/{b}.
Also if a and b can be arbitrary strings it would be better if they were passed as query string parameters.

How to route lower-case URLs ('questions/add_to_favorites/123') with underscores in ASP.NET MVC2?

ASP.NET MVC 2 controllers and actions use UpperCamelCase.
For some reasons many big sites, including SO, use lowercase (with underscore) for controllers and actions in the urls. Examples:
https://stackoverflow.com/questions
https://stackoverflow.com/users/377920/randomguy
http://www.reddit.com/ad_inq/
http://www.wired.com/special_multimedia/mobile/
etc.
I would like to know how this is accomplished.
The default router seems to be case-insensitive, ie. stackoverflow.com/questions/ask will be directed to Questions-controller's Ask() method without a problem.
However, say we want to direct questions/add_to_favorites to Questions-controller's AddToFavorites() action.
How is this accomplished?
Is it now required to use Html.ActionLink("add_to_favorites")
instead of Html.ActionLink("AddToFavorites") to make the links in the HTML point as questions/add_to_favorites instead of Questions/AddToFavorites?
Edit:
Similar posts
How can I have lowercase routes in ASP.NET MVC?
ASP.NET MVC: Get lowercase links (instead of Camel Case)
One way to support underscores is to use the ActionName attribute:
[ActionName("add_to_favorites")]
public ActionResult AddToFavorites() {
// ...
}
However, this doesn't work for controllers. Perhaps if we could somehow remove all the underscores from the request before it gets to the routing mechanism, then it would work.
You can add custom routes manually. This is not an universal solution and must be added for every controller and action separately.
routes.MapRoute(
"Web2.0 RoR style lowercase URLs with underscores",
"questions-foo/add_to_favorites",
new { controller = "Questions", action = "AddToFavorites" }
);
The cool thing is that the URL generating Html-helper methods don't need to be modified. The routing table is used to route incoming requests and to generate URLs. So,
Html.ActionLink("Add to favorites", "Questions", "AddToFavorites"); maps to /questions-foo/add_to_favorites.
Note that the original /Question/AddToFavorites still works as does /qUeStIoN/aDdtOfAvOrItEs as well as /qUeStIoNs-FOO/ADD_TO_FAVORITES because the default routing mechanism is case-insensitive.

How would I configure the global.config to allow for root path to actionMethod in MVC2?

specifically, the default directory naming structure is [Controller]/[ActionMethod] resulting in a rendered url like www.mysite.com/home/actionMethodName.
What if I want to simply imply the Controller (in this example, 'home') so that I can get a url that looks like this: www.mysite.com/actionMethodName.
I haven't seen many requests for this kind of configuration. I can see how it breaks convention, but I would imagine that there are lots of people who need root pathing.
Because you are planning to remove the {controller} element of the url, you may need to get a bit more specific with your other urls, e.g.:
routes.MapRoute("MyOtherControllerRoute", "Account/{action}", new { controller = "Account", action = "Index" });
routes.MapRoute("MyDefaultRoute", "{action}", new { controller = "Home", action = "Index" });
When the route table is interrogated, if the url such as www.mysite.com/Account is used, it will match the first route, because we have been specific about the pattern used to match the url. If we then do something like www.mysite.com/DoSomething it will use the default route we've selected last, trying to invoke the DoSomething action on the HomeController type.
Something which I've noticed is that a lot of MVC developers seems to assume that the url is strictly {something}/{something}/{something}, whereas it can essentially be anything you like, e.g, I can have a route that does: www.mysite.com/my-weird-and-wonderful-url which I could map specifically:
routes.MapRoute("Somewhere", "my-weird-and-wonderful-url", new { controller = "Whatever", action = "Whenever" });
Hope that helps.
Easy as apple pie - you just specify a route of your own! =)
An example:
routes.MapRoute(
"RootPathing",
"{action}",
new { controller = "Default", action = "Index" });
This will register a route that catches all paths, and try to map them to the DefaultController with an action name corresponding to the path. However, note that if you place this route above the included default route, you will not be able to reach any other controller than the DefaultController - hence, place this route below the default route in the chain. It will then be matched by all paths that don't match a controller name.
When debugging routes, Phil Haack's Routing Debugger is really worth taking a look at.