(import-macros {:compile-html HTML} :macros) (local templates (require :templates)) (local dicts (require :dicts)) (local lib (require :lib)) (fn text->html [text] (assert (= (type text) "string")) (var result "") (var from 1) (var to (text:find "\n%s*\n%s*" from)) (while to (set result (.. result "
" (text:sub from (- to 1)) "
\n")) (set from (+ to 2)) (set to (text:find "\n%s*\n%s*" from))) (.. result "" (text:sub from) "
")) (fn find-product [db name] (. (_G.must (luna.db.query-assoc db "SELECT products.name, products.title, products.short_description AS \"short-description\", products.description, products.price_per AS \"price-per\", products.type, products.region, products.stock, products.volume, products.packaging, products.published, products.year, products.image1, products.image2, products.image3, products.image4, products.image5 FROM products WHERE products.name = ?" [name])) 1)) (fn content [product authenticated?] (local images []) (for [i 1 5] (table.insert images (. product (.. "image" i)))) [(HTML [:div {:class "side"} (templates.header "/shop" authenticated?)]) (HTML [:div {:class "content"} [:div {:class "mb-1"} [:a {:href "/shop"} "⟵ Обратно к списку"]] [:div {:class "product-page-layout"} [:article {} [:h2 {:class "product-page-title"} product.title] (if authenticated? (HTML [:div {:class "mb-1" :style "margin-top: -0.25rem;"} [:a {:href (.. "/shop/" product.name "/edit")} "% Редактировать"]]) "") [:div {:class "mb-0-5" :style "font-style: italic;"} (or (dicts.label dicts.product-type product.type) product.type) ", " (if (not (lib.empty? product.year)) (HTML [:span {} [:NO-ESCAPE (.. product.year " год, ")]]) "") (if (not (lib.empty? product.volume)) (HTML [:span {} [:NO-ESCAPE (.. product.volume " мл., ")]]) "") (if (not (lib.empty? product.region)) (.. product.region ", ") "") (if (= product.packaging "piece") (HTML [:strong {} product.price-per "₽"]) (HTML [:span {} [:strong {} [:NO-ESCAPE (* 50 product.price-per) "₽ за 50 грамм "]] [:NO-ESCAPE "(" product.price-per "₽ за 1 грамм)"]]))] [:div {:class "mb-1" :style "font-style: italic;"} product.short-description] (let [link (.. "/static/files/" product.image1)] (HTML [:a {:href link :target "_blank"} [:img {:class "product-page-img-mobile mb-1" :src (.. link "-thumbnail.jpg")}]])) (if (not (lib.empty? product.description)) (HTML [:div {:class "mb-1"} "***"]) "") (if (not (lib.empty? product.description)) (HTML [:div {} [:NO-ESCAPE (text->html product.description)]]) "")] [:div {:class "product-page-imgs"} (table.concat (icollect [idx image (ipairs images)] (let [link (.. "/static/files/" image) video? (lib.ends-with? (_G.must (luna.utf8.lower image)) ".webm")] (HTML [:a {:href link :target "_blank"} (if video? (HTML [:video {:class "product-page-img" :autoplay true :loop true :muted true} [:source {:src (.. "/static/files/" image) :type "video/webm"}]]) (HTML [:img {:class "product-page-img" :src (.. link "-thumbnail.jpg")}]))]))))]]])]) (fn render [request db authenticated?] (let [product (find-product db request.params._product)] (if (and product (or product.published authenticated?)) (values 200 {} (templates.base (content product authenticated?))) (values 404 {} "not found")))) {: render}