I need to find a solution for the following problem:
After basic url (say "domain.org/elements") I need to have a hierarchical structure of elements following this basic url, and user if free, possibly infinitely, add another elements at any level, including element-containers, e.g. url for the example some containers and 1 element at the end of this hierarchy could look like these ones:
domain.org/elements/container-top/container-deeper/container-deeper2/element
domain.org/elements/container-top/container-deeper/container-deeper3/..../container-deeperN/element
The problem is: how to identify such routes in the Symfony2 controller, not using solutions like a Dynamic Controller (I don't want e.g. to save routes to DB)?
Well, you could easily do something like this by tweaking the regular expression to use:
/**
* #Route("/{parameters}", requirements={"parameters"="[^/]+(/[^/]+)*"})
*/
public function myAction($parameters)
{
$parameters = explode('/', $parameters);
// ...
}
The regular expression above reads like:
one or more non-forward slash character FOLLOWED BY zero or more (forward slash FOLLOWED BY one or more non-forward slash character)
Related
I am trying to create a function within my rule sets that will check that a particular document's field is null. Unfortunately one of the variables I pass in has a leading slash. For example: /mycollection/xyz123
rules_version = '1';
function hasNullStartDate(teamGuid, path) {
return get(/databases/$(database)/documents/team/$(teamGuid)/$(path)).data.startDate == null
}
match /teams/{teamid}/{subpath=**} {
allow delete: if hasNullStartDate(teamid, subpath)
}
I have tried removing the slash between my two variables $(teamGuid)$(path) but that causes a syntax error in the rules.
I have tried to do .replace() on the path, but that has ended up in a run time error. Maybe I didn't format it right or maybe it has to do with the rules version.
https://firebase.google.com/docs/reference/rules/rules.String#replace
How can I get rid of that leading slash /?
So I think you don't want to use replace at all in this specific case, since a Path object (what you're passing to get()) isn't actually a string. I think you'll be better off with a string split to get "mycollection" and "xyz123" into separate elements so you can build the path using their values individually.
Either that, or you can build the entire string the way you would expect for a normal string, and pass that string to path() to then pass to get(). Again, see the Path documentation for more on that.
I'm working on a webapp, one function of which was to list all the files under given path. I tried to map several segments of URL to one PathVariable like this :
#RequestMapping("/list/{path}")
public String listFilesUnderPath(#PathVariable String path, Model model) {
//.... add the file list to the model
return "list"; //the model name
}
It didn't work. When the request url was like /list/folder_a/folder_aa, RequestMappingHandlerMapping complained : "Did not find handler method for ..."
Since the given path could contains any number of segments, it's not practical to write a method for every possible situation.
In REST each URL is a separate resource, so I don't think you can have a generic solution. I can think of two options
One option is to change the mapping to #RequestMapping("/list/**") (path parameter no longer needed) and extract the whole path from request
Second option is to create several methods, with mappings like #RequestMapping("/list/{level1}"), #RequestMapping("/list/{level1}/{level2}"), #RequestMapping("/list/{level1}/{level2}/{level3}")... concatenate the path in method bodies and call one method that does the job. This, of course, has a downside that you can only support a limited folder depth (you can make a dozen methods with these mappings if it's not too ugly for you)
You can capture zero or more path segments by appending an asterisk to the path pattern.
From the Spring documentation on PathPattern:
{*spring} matches zero or more path segments until the end of the path and captures it as a variable named "spring"
Note that the leading slash is part of the captured path as mentioned in the example on the same page:
/resources/{*path} — matches all files underneath the /resources/, as well as /resources, and captures their relative path in a variable named "path"; /resources/image.png will match with "path" → "/image.png", and /resources/css/spring.css will match with "path" → "/css/spring.css"
For your particular problem the solution would be:
#RequestMapping("/list/{*path}") // Use *path instead of path
public String listFilesUnderPath(#PathVariable String path, Model model) {
//.... add the file list to the model
return "list"; //the model name
}
I have implemented a routing functionality successfully in my project (a news website):
Sub RegisterRoutes(ByVal routes As RouteCollection)
routes.MapPageRoute("ndetails", "news/{title}/{id}/", "~/newsdetail.aspx")
End Sub
and I set the URLs like this (databound to a repeater):
href="<%# Page.GetRouteUrl("ndetails", new with { .title= Server.UrlEncode(Eval("Title")), .id= Eval("NewsID")})%>"
The URL produced is like:
/this%20is%20a%20news%20item/89
As can be seen above, the URL part is difficult to read and I would like it to be like:
/this_is_a_news_item/89
I thought of going for a Replace function. But then, since the user creating the news might enter any string, I have to take into account all the other characters that might need to be replaced.
I just wanted to know from an experienced developer, whether going with a long replace function is the way to go, or is there another solution to format my URLs in this rouitng scenario.
Many thanks in advance
AFAIK there is no built in funcitonality in the framework to make url "pretty". You have to implement your own url fo rewriting the title.
In the save of your entities simply use a function that do the replaces that you need (' ' with '_' or example) and then use UrlEncode.
You can also use a Regular expression to do the replacement in one go.
I am dealing with this code in a Web Forms scenario:
public static void RegisterRoutes(RouteCollection routes)
{
Route r = new Route("{*url}", new MyRouteHandler());
routes.Add(r);
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{resource}.gif/{*pathInfo}");
}
Firstly, can anyone tell me where the defintion of {*pathInfo} is?
http://msdn.microsoft.com/en-us/library/cc668201.aspx#url_patterns doesn't really define it. Does:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
Match
/c/xyz.axd and
/b/c/xyz.axd and
/a/b/c/xyz.axd
Whereas
routes.IgnoreRoute("{resource}.axd");
Only matches
/xyz.axd
Secondly, in:
{*url}
What does * mean? And what does the expression as a whole mean. Is there somewhere this is clearly explained?
Thirdly, is there a particular order I need to add these expressions to correctly ignore routes? I know {*url} is some kind of catchall, should the IgnoreRoutes come before or after it eg
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{resource}.gif/{*pathInfo}");
Route r = new Route("{*url}", new MyRouteHandler());
routes.Add(r);
My 2 cents:
A route is not regex. It is simply variable and static components that make up a route, separated by segments (identified by a slash). There's one special symbol, the asterisk in the last variable, which means from here on, ignore the segment-separator -- the slash. So,
{*url}
is the simplest route, because it means take the entire URL, put it into the variable 'url', and pass that to the page associated with that route.
{controller}/{action}/{id}
puts everything in the first segment -- up to the first slash -- into the variable 'controller', puts everything between the first and second / into the variable 'action', and everything between the second and third slash (or the end) into the variable 'id'. those variables are then passed into the associated page.
{resource}.axd/{*pathInfo}
here, put the info before .axd/ (and it can't have any slashes!) into 'resource', and put everything after the first / into 'pathInfo'. Since this is typically an ignoreRoute, so instead of passing it to the page associated, it is handled by the StopHandler, which means that routing won't deal with it, and it is instead handled by the non-routing HttpHandler.
As bleevo says, routes are executed in order they're added to the collection. so IgnoreRoute s have to be added before the generic route is handled.
Here's the horse's mouth: http://msdn.microsoft.com/en-us/library/cc668201.aspx
Specific to your example, I would put the IgnoreRoute lines above your Route addition, because your route is effectively a catch-all. Also, remember that the .gif ignore will only be honoured if the gif is in the root directory.
pathinfo is just a label for a bucket. So for instance {*pathinfo} says put everything after {resource}.axd/ into pathinfo.
The routes are executing in the order you place them in the routes table, so if your very first route is a catch all the rest will never execute.
The IIS URL Rewrite Module ships with 3 built-in functions:
* ToLower - returns the input string converted to lower case.
* UrlEncode - returns the input string converted to URL-encoded format. This function can be used if the substitution URL in rewrite rule contains special characters (for example non-ASCII or URI-unsafe characters).
* UrlDecode - decodes the URL-encoded input string. This function can be used to decode a condition input before matching it against a pattern.
The functions can be invoked by using the following syntax:
{function_name:any_string}
The question is: can this list be extended by introducing a Replace function that's available for changing values within a rewrite rule action or condition?
Another way to frame the question: is there any way to do a global replace on a URL coming in using this module?
It seems that you're limited to using regular expressions and back-references to construct strings - i.e. there's no search/replace mechanism to replace every instance of X with Y in {REQUEST_URI}, without knowing how many instances there are.
I've had a quick glance at the extensibility introduced in the 2.0 RTW and don't see any 'light' means of introducing this.
Looks like you have to implement your own provider as shown here:
http://learn.iis.net/page.aspx/804/developing-a-custom-rewrite-provider-for-url-rewrite-module/