Shirakumo / radiance

A Common Lisp web application environment
https://shirakumo.github.io/radiance/
zlib License
311 stars 19 forks source link

define new pages programmatically #15

Closed hjudt closed 7 years ago

hjudt commented 7 years ago

I can use (define-page name "/name" () (....)). but when I try to create pages like this I get "URI fell through ETYPECASE expression. Wanted one of (URI STRING)":

(let ((name (item-name some-item))
      (uri (item-uri some-item)))
 (define-page name uri () (....)))

Of course, I also cannot simply use (define-page name (item-uri some-item) () (....)). My goal is to create pages for all available items automatically, so i can access them via /item-name/attribute etc.

hjudt commented 7 years ago

Ok, I guess i need to define api endpoints instead of this. I have stumbled over the tutorial pages at https://github.com/Shirakumo/radiance-tutorial/blob/master/Part%201.md only a minute ago.

Shinmera commented 7 years ago

define-page is a macro and you thus can't do what you're trying to do. While there are ways to programmatically create pages, usually when you think you need to do that, you're going the wrong way about your problem.

What you should do instead is something like this:

(defun ensure-item (item-name)
  (or (find-item item-name)
      (error 'request-not-found)))

(define-page item "/([^/]*)" (:uri-groups (item))
  (let ((item (ensure-item item)))
    #| display item or whatever |#))

(define-page item-attribute "/([^/]*)/([^/]*)" (:uri-groups (item attribute))
  (let ((item (ensure-item item)))
    #| display attribute or whatever |#))
Shinmera commented 7 years ago

API endpoints are for when you want to present raw data or data manipulation pages, rather than content for the user to see. Defining API endpoints will land you in the exact same boat as pages, anyway.

hjudt commented 7 years ago

Thanks, that is indeed a good solution and the exact thing I need. Your response was very helpful.