Routes that can contains variables parts that will be resolved during the matching process.
Route parameters are marked with a colon :
var route = new AppParamRoute("/:id")
assert not route.match("/")
assert route.match("/user")
assert route.match("/user/")
assert not route.match("/user/10")
It is possible to use more than one parameter in the same route:
route = new AppParamRoute("/user/:userId/items/:itemId")
assert not route.match("/user/10/items/")
assert route.match("/user/10/items/e895346")
assert route.match("/user/USER/items/0/")
assert not route.match("/user/10/items/10/profile")
popcorn :: AppParamRoute :: defaultinit
popcorn :: AppParamRoute :: parse_path_parameters
Cutpath
into UriParts
.
popcorn :: AppParamRoute :: parse_uri_parameters
Extract parameter values fromuri
.
popcorn $ AppParamRoute :: SELF
Type of this instance, automatically specialized in every classpopcorn $ AppParamRoute :: init
popcorn $ AppParamRoute :: resolve_path
For parameterized routes, parameter names are replaced by their value in the URI.core :: Object :: class_factory
Implementation used byget_class
to create the specific class.
popcorn :: AppParamRoute :: defaultinit
core :: Object :: defaultinit
popcorn :: AppRoute :: defaultinit
core :: Object :: is_same_instance
Return true ifself
and other
are the same instance (i.e. same identity).
core :: Object :: is_same_serialized
Isself
the same as other
in a serialization context?
core :: Object :: is_same_type
Return true ifself
and other
have the same dynamic type.
core :: Object :: output_class_name
Display class name on stdout (debug only).popcorn :: AppParamRoute :: parse_path_parameters
Cutpath
into UriParts
.
popcorn :: AppParamRoute :: parse_uri_parameters
Extract parameter values fromuri
.
popcorn :: AppRoute :: resolve_path
Replace path parameters with concrete values from theuri
.
# Parameterizable routes.
#
# Routes that can contains variables parts that will be resolved during the
# matching process.
#
# Route parameters are marked with a colon `:`
# ~~~
# var route = new AppParamRoute("/:id")
# assert not route.match("/")
# assert route.match("/user")
# assert route.match("/user/")
# assert not route.match("/user/10")
# ~~~
#
# It is possible to use more than one parameter in the same route:
# ~~~
# route = new AppParamRoute("/user/:userId/items/:itemId")
# assert not route.match("/user/10/items/")
# assert route.match("/user/10/items/e895346")
# assert route.match("/user/USER/items/0/")
# assert not route.match("/user/10/items/10/profile")
# ~~~
class AppParamRoute
super AppRoute
init do parse_path_parameters(path)
# Cut `path` into `UriParts`.
fun parse_path_parameters(path: String) do
for part in path.split("/") do
if not part.is_empty and part.first == ':' then
# is an uri param
path_parts.add new UriParam(part.substring(1, part.length))
else
# is a standard string
path_parts.add new UriString(part)
end
end
end
# For parameterized routes, parameter names are replaced by their value in the URI.
# ~~~
# var route = new AppParamRoute("/user/:id")
# assert route.resolve_path("/user/10/profile") == "/user/10"
#
# route = new AppParamRoute("/user/:userId/items/:itemId")
# assert route.resolve_path("/user/Morriar/items/i156/desc") == "/user/Morriar/items/i156"
# ~~~
redef fun resolve_path(uri) do
var uri_params = parse_uri_parameters(uri)
var path = "/"
for part in path_parts do
if part isa UriString then
path /= part.string
else if part isa UriParam then
path /= uri_params.get_or_default(part.name, part.name)
end
end
return path.simplify_path
end
# Extract parameter values from `uri`.
# ~~~
# var route = new AppParamRoute("/user/:userId/items/:itemId")
# var params = route.parse_uri_parameters("/user/10/items/i125/desc")
# assert params["userId"] == "10"
# assert params["itemId"] == "i125"
# assert params.length == 2
#
# params = route.parse_uri_parameters("/")
# assert params.is_empty
# ~~~
fun parse_uri_parameters(uri: String): Map[String, String] do
var res = new HashMap[String, String]
if path_parts.is_empty then return res
var parts = uri.split("/")
for i in [0 .. path_parts.length[ do
if i >= parts.length then return res
var ppart = path_parts[i]
var part = parts[i]
if not ppart.match(part) then return res
if ppart isa UriParam then
res[ppart.name] = part
end
end
return res
end
private var path_parts = new Array[UriPart]
end
lib/popcorn/pop_routes.nit:87,1--176,3