Allow for variables as a path for the routes
alejandrogallo opened this issue · comments
I went ahead and created a patch, you can consider adding it, I think
this makes sense
diff -u --label /home/gallo/quicklisp/dists/quicklisp/software/easy-routes-20220707-git/easy-routes.lisp --label \#\<buffer\ easy-routes.lisp\> /home/gallo/quicklisp/dists/quicklisp/software/easy-routes-20220707-git/easy-routes.lisp /tmp/buffer-content-nm8tpn
--- /home/gallo/quicklisp/dists/quicklisp/software/easy-routes-20220707-git/easy-routes.lisp
+++ #<buffer easy-routes.lisp>
@@ -167,7 +167,8 @@
with:
-* path: A string with an url path that can contain arguments prefixed with a colon.
+* path: A string or a symbol evaluating to a string with an url path
+ that can contain arguments prefixed with a colon.
Like \"/foo/:x/:y\", where :x and :y are bound into x and y variables in the context of the route body.
* route-options: possible options are
* :method - The HTTP method to dispatch, as a keyword. Default is :get.
@@ -198,9 +199,12 @@
&path (x 'integer))
(format nil \"~A\" (+ x y)))"
- (let* ((template (if (listp template-and-options)
- (first template-and-options)
- template-and-options))
+ (let* ((template (let ((template (if (listp template-and-options)
+ (first template-and-options)
+ template-and-options)))
+ (etypecase template
+ (string template)
+ (symbol (eval template)))))
(variables (routes:template-variables
(routes:parse-template template)))
(arglist (mapcar (alexandria:compose #'intern #'symbol-name)
Diff finished. Tue Aug 15 17:18:41 2023
Ok. What do you need this for? More flexibility in the routes? You have an example?
I would also consider using (funcall (symbol-function template))
instead of eval.
Sorry for not explaining
I have something like
(defvar *home-path* "/home")
(easy-routes:defroute index (*home-path*
:decorators (@login))
(q)
....)
How do you do this normally?
Like this it does not work because the function to trim
the path does an implicit conversion with symbol-name
,
i.ep
(string-left-trim "/" '*lalala*) ;; => "*LALALA*"
gracias a ti!
This is a related issue: #3
This was accepted as a solution, but I'm not sure it applies in your case: #3 (comment)
Do you have an opinion?
It uses a read-time "trick". So perhaps a patch like yours is better, but I'm not sure.
ah, yes with the reader.
That works actually, because the important thing is to have
somewhere the paths parametrized.
I agree that evaling is not maybe the best thing,
I tried with a symbol-macro but it did not work,
but I guess the reader is fair enough, maybe
one can add a comment in the defroute docstring
for future reference.
This is a common need, for example Hunchentoot allows URL as function-designator: http://edicl.github.io/hunchentoot/#define-easy-handler
If uri (which is evaluated) is provided, then it must be a string or a [function designator](http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#function_designator) for a unary function. In this case, the handler will be returned by [DISPATCH-EASY-HANDLERS](http://edicl.github.io/hunchentoot/#dispatch-easy-handlers), if uri is a string and the [script name](http://edicl.github.io/hunchentoot/#script-name) of the current request is uri, or if uri designates a function and applying this function to the [current REQUEST object](http://edicl.github.io/hunchentoot/#*request*) returns a true value.
So perhaps it would be better to have it other than as just a reader trick. I'll see ...
I tried with a symbol-macro but it did not work,
It may work with symbol-value. I'll try.
@alejandrogallo Pushed a slightly different version of your patch. Please close the issue if you think it is correct.
oh yes, this looks completely fine! Thank you very much for the quick fix!