Условные выражения в Hiccup, я могу сделать это более идиоматичным?

Clojure новичок здесь! Я добавил поддержку флеш-сообщений в мой код Hiccup в проекте Noir.

То, что я пытаюсь сделать, это проверить, была ли задана строка сообщения для каждого конкретного или нет. Если сообщения нет, я не хочу отображать конкретный флэш-элемент, содержащий это сообщение.

(defpartial success-flash [msg]
            [:div.alert.notice.alert-success
             [:a.close {:data-dismiss "alert"} "x"]
             [:div#flash_notice msg]])

(defpartial error-flash [msg]
            [:div.alert.notice.alert-error
             [:a.close {:data-dismiss "alert"} "x"]
             [:div#flash_notice msg]])

[..]

(defpartial layout [& content]
            (html5
              [:head
                [...]
              [:body
               (list
                [...]
                [:div.container
                 (let [error-msg (session/flash-get :error-message)
                       error-div (if (nil? error-msg) () (error-flash error-msg))
                       success-msg (session/flash-get :success-message)
                       success-div (if (nil? success-msg) () (success-flash success-msg))]
                       warning-msg (session/flash-get :warning-message)
                       warning-div (if (nil? warning-msg) () (warning-flash warning-msg))]

                   (list error-div success-div warning-div content))])]))

Отказ от ответственности: я полностью согласен с тем, что вы вряд ли когда-либо окажетесь в ситуации, когда вам понадобится более одной из этих специальных вспышек одновременно, но побалуйте меня в моей попытке найти лучший и более функциональный способ реализации этого,

Я уверен, что есть способ справиться с подобными ситуациями. По сути, я проверяю значение нескольких выражений, делаю кучу вещей с этими значениями, а затем действую на основе результатов. Вы можете осуществить это все более и более чудовищно (cond), но мое решение, по крайней мере, несколько чище.

Подсказки?

2 ответа

Решение

Вы также можете использовать when-let,

(defpartial layout
  [& contents]
  (html5
    [:body
     (when-let [msg (session/flash-get :error-message)]
       (error-flash msg))
     (when-let [msg (session/flash-get :warning-message)]
       (warning-flash msg))
     (when-let [msg (session/flash-get :success-message)]
       (success-flash msg))
     contents))

Я не эксперт по сбоям, но я думаю, что это должно сработать. Я нахожу это немного более ясным о том, что происходит, хотя это немного более многословно.

Шаблон называется значением отображения. Ниже приведен пример, который использует keep функция для применения шаблона сопоставления значений, а затем их фильтрации

(use 'clojure.contrib.core)


(def flash-message
[[:error-message error-flash]
 [:success-message success-flash]
 [:warning-message warning-flash]])

(keep (fn [m f] (-?>> m (session/flash-get) (f))) flash-message)
Другие вопросы по тегам