diff options
Diffstat (limited to 'bin')
| -rw-r--r-- | bin/serve.fnl | 91 |
1 files changed, 63 insertions, 28 deletions
diff --git a/bin/serve.fnl b/bin/serve.fnl index 5b08e55..884fb4f 100644 --- a/bin/serve.fnl +++ b/bin/serve.fnl @@ -83,20 +83,21 @@ {:query (str.trim (or (get-query-string params "query") "")) :tags (filter #(~= "" $2) (or params.tags [category])) :site (str.trim (or (get-query-string params "site") "")) + :sort (str.trim (or (get-query-string params "sort") "")) :min-price (get-query-number params "min-price") :max-price (get-query-number params "max-price") :price-per (= "on" (get-query-string params "price-per"))}) (fn form-empty? [form] (and - (= "" form.query) - (= (# form.tags) 0) - (= "" form.site) - (not form.min-price) - (not form.max-price) - ;; price-per is intentionally left out since it must not trigger search - ;; by itself - )) + (= "" form.query) + (= (# form.tags) 0) + (= "" form.site) + (not form.min-price) + (not form.max-price) + ;; price-per and sort are intentionally left out since they must not + ;; trigger search by itself + )) (fn form->path [page form] (.. "?page=" (tostring page) @@ -122,6 +123,9 @@ "") (if form.price-per "&price-per=on" + "") + (if form.sort + (.. "&sort=" form.sort) ""))) (fn teas-of-the-day [limit] @@ -173,18 +177,20 @@ ORDER BY creation_time" [])))) -(fn query-products [{: query : tags : min-price : max-price : price-per : site} page] +(fn query-products [{: query : tags : min-price : max-price : price-per : site : sort} page] (local tags (or tags [])) (var where-conds []) - (var where-vars []) + (var query-args []) + + ;; create WHERE clause from dynamic form parameters (when (< 0 (# tags)) (each [_ tag (pairs tags)] (table.insert where-conds "product_tags.tag = ?") - (table.insert where-vars tag))) + (table.insert query-args tag))) (when (and query (< 0 (# query))) (table.insert where-conds "search.title MATCH ?") - (table.insert where-vars + (table.insert query-args (array.join (map (fn [_ q] (local lower-q (must (luna.utf8.lower q))) @@ -195,21 +201,40 @@ " AND "))) (when (not (str.empty? site)) (table.insert where-conds "products.site = ?") - (table.insert where-vars site)) + (table.insert query-args site)) (when (and min-price (< 0 min-price)) (if price-per (table.insert where-conds "products.price_per >= ?") (table.insert where-conds "products.price >= ?")) - (table.insert where-vars min-price)) + (table.insert query-args min-price)) (when (and max-price (< 0 max-price)) (if price-per (table.insert where-conds "products.price_per <= ?") (table.insert where-conds "products.price <= ?")) - (table.insert where-vars max-price)) - + (table.insert query-args max-price)) (local where-sql (if (< 0 (# where-conds)) - (.. "AND " (array.join where-conds "\nAND ")) + (.. "AND " (array.join where-conds "\nAND ")) + "")) + + ;; create SORT clause from dynamic form parameters + (var sort-criteria []) + (when sort + (if (= sort "cheap-first") + (table.insert sort-criteria + ;; multiple price by 100 if we only know a price for 1 gram + "CASE WHEN products.weight = 1 THEN products.price * 100 + ELSE products.price + END ASC") + (= sort "expensive-first") + (table.insert sort-criteria + ;; multiple price by 100 if we only know a price for 1 gram + "CASE WHEN products.weight = 1 THEN products.price * 100 + ELSE products.price + END DESC"))) + (local sort-sql + (if (< 0 (# sort-criteria)) + (.. (array.join sort-criteria ",\n") ",") "")) (local total @@ -227,7 +252,7 @@ AND products.archived = false %s GROUP BY products.url)" where-sql) - where-vars))) + query-args))) {:results (must @@ -249,10 +274,11 @@ AND products.archived = false %s GROUP BY products.url - ORDER BY ROW_NUMBER() over (PARTITION BY products.site ORDER BY products.ROWID), + ORDER BY %s + ROW_NUMBER() over (PARTITION BY products.site ORDER BY products.ROWID), rank - LIMIT 48 OFFSET ?" where-sql) - (array.concat where-vars [(* (- page 1) 48)]))) + LIMIT 48 OFFSET ?" where-sql sort-sql) + (array.concat query-args [(* (- page 1) 48)]))) :total (if (< 0 (# total)) (. total 1 1) 0)}) @@ -366,6 +392,15 @@ :selected (if (= form.site val) "selected" nil)} (. (require (.. "parser." val)) :title)]) [:ozchai :clubcha :ipuer :artoftea :chaekshop]))]] + [:div {} + [:select {:name "sort"} + [:option {:value ""} "~ Порядок ~"] + [:option {:value "cheap-first" + :selected (if (= form.sort "cheap-first") "selected" nil)} + "Сначала дешевле"] + [:option {:value "expensive-first" + :selected (if (= form.sort "expensive-first") "selected" nil)} + "Сначала дороже"]]] [:button {:type :submit} "Искать"]] paginator]]) @@ -414,13 +449,13 @@ (< 0 (# items)) [:div {:class "list"} (table.unpack (map #(item-template $2) items))] - [:p {:class "text"} - (if spellfix-suggestion - [:NO-ESCAPE - (string.format texts.no-results-with-suggestion - spellfix-suggestion - spellfix-suggestion)] - [:NO-ESCAPE texts.no-results])]) + [:p {:class "text"} + (if spellfix-suggestion + [:NO-ESCAPE + (string.format texts.no-results-with-suggestion + spellfix-suggestion + spellfix-suggestion)] + [:NO-ESCAPE texts.no-results])]) [:div {} paginator] [:footer {} [:small {:class "text"} [:NO-ESCAPE texts.footer-text]]]]]]]]) |
