Search code examples
common-lisphunchentoot

Hunchentoot List of Redirects


The URI structure of my website changed drastically recently and I need to redirect all of the old pages to their corresponding new pages. I have a dotted list of pairs of all of the old and new URIs. At the moment I am trying to define easy handlers for each in a loop:

(let ((redirects '(("/old/uri/example-1" . "/new/uri/example-1"))))
  (dolist (redirect redirects)
    (hunchentoot:define-easy-handler (???? :uri (first redirect)) ()
       (redirect (rest redirect)))
    ))

Maybe there is a better way. Assuming define-easy-handler is correct, it requires a function symbol for each easy handler. I tried the following to no avail:

  1. Placing a (gensym) where it expects a function symbol
  2. Using lists rather than dotted lists and calling (first redirect) where it expects a symbol
  3. Placing a quasiquote around the whole thing and an unquote around (first redirect)

What would be a good way to accomplish this?


Solution

  • Let's guess: DEFINE-EASY-HANDLER is a macro.

    Three typical ways to solve that:

    • call the underlying layer instead and don't use the macro - if the underlying layer is available for the programmer

    • write and use a macro which

    expands (defredirects (a . a1) (b . b1) (c . c1))) into

    (progn
      (hunchentoot:define-easy-handler (f-a ... a) () (... a1))
      (hunchentoot:define-easy-handler (f-b ... b) () (... b1))
      (hunchentoot:define-easy-handler (f-c ... c) () (... c1)))
    
    • Generate the form you want to call and use eval (or compile and funcall if possible) in the loop for each form.