Merge: doc: fixed some typos and other misc. corrections
[nit.git] / lib / nitcorn / vararg_routes.nit
index 9099284..3ec5dc1 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# Routes with uri parameters.
+# Routes with parameters.
 #
-# Using `vararg_routes`, a `Route` can contain variable parts
-# that will be matched against a `HttpRequest` path.
+# Using `vararg_routes`, a `Route` path can contain variable parts
+# that will be matched against a `HttpRequest` URL.
 #
-# Variable parts of path can be specified using the `:` prefix.
+# Variable parameters of a route path can be specified using the `:` prefix:
+#
+# ~~~nitish
+# var iface = "http://localhost:3000"
+# var vh = new VirtualHost(iface)
+# vh.routes.add new Route("/blog/articles/:articleId", new BlogArticleAction)
+# ~~~
+#
+# Route arguments can be accessed from the `HttpRequest` within a nitcorn `Action`:
+#
+# ~~~nitish
+# class BlogArticleAction
+#      super Action
+#
+#      redef fun answer(request, url) do
+#              var param = request.param("articleId")
+#              if param == null then
+#                      return new HttpResponse(400)
+#              end
+#
+#              print url # let's say "/blog/articles/12"
+#              print param # 12
+#
+#              return new HttpResponse(200)
+#      end
+# end
+# ~~~
 #
 # ## Route matching
 #
 # assert req.param("id") == "1234"
 # assert req.param("foo") == null
 # ~~~
-#
-# Note that normally, all this work is done by nitcorn.
-# Params can then be accessed in the `HttpRequest` given to `Action::answer`.
 module vararg_routes
 
 import server_config
@@ -108,6 +131,20 @@ redef class Route
                parse_pattern(path)
        end
 
+       # Replace `self.path` parameters with concrete values from the `request` URI.
+       fun resolve_path(request: HttpRequest): nullable String do
+               if pattern_parts.is_empty then return self.path
+               var path = "/"
+               for part in pattern_parts do
+                       if part isa UriString then
+                               path /= part.string
+                       else if part isa UriParam then
+                               path /= request.param(part.name) or else part.name
+                       end
+               end
+               return path
+       end
+
        # Cut `path` into `UriParts`.
        private fun parse_pattern(path: nullable String) do
                if path == null then return
@@ -189,6 +226,8 @@ private class UriParam
 
        # Parameters match everything.
        redef fun match(part) do return true
+
+       redef fun to_s do return name
 end
 
 # A static uri string like `users`.
@@ -200,6 +239,8 @@ private class UriString
 
        # Empty strings match everything otherwise matching is based on string equality.
        redef fun match(part) do return string.is_empty or string == part
+
+       redef fun to_s do return string
 end
 
 redef class Routes