summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunwox <me@unwox.com>2024-10-16 22:40:09 +0600
committerunwox <me@unwox.com>2024-10-16 22:43:17 +0600
commitfd9a559475ac6bff7c82594dc313d762ab807592 (patch)
tree5ae19da434713cb31fe9747a2f713eb3506936f9
parentc760c798a56fb80c891f26ca932e7d182da67069 (diff)
improve site structure for seo
-rw-r--r--bin/serve.fnl134
-rw-r--r--lib/string.fnl19
-rw-r--r--spellfix.fnl2
-rw-r--r--static/favicon.pngbin0 -> 3720 bytes
-rw-r--r--static/style.css17
-rw-r--r--texts.fnl101
6 files changed, 225 insertions, 48 deletions
diff --git a/bin/serve.fnl b/bin/serve.fnl
index 4cbb905..62e3962 100644
--- a/bin/serve.fnl
+++ b/bin/serve.fnl
@@ -11,7 +11,7 @@
(local str (require :lib.string))
(local texts (require :texts))
(local spellfix (require :spellfix))
-(local {: must} (require :lib.utils))
+(local {: must : measure} (require :lib.utils))
(local ozchai (require :parser.ozchai))
(local ipuer (require :parser.ipuer))
@@ -39,6 +39,16 @@
(string.gsub "&quot;" "\"")
(string.gsub "&amp;" "&"))))
+(fn category-menu-path [category]
+ (. {"Красный чай" "red-tea"
+ "Шен пуэр" "sheng-puer"
+ "Шу пуэр" "shou-puer"
+ "Улун" "oolong"
+ "Зеленый чай" "green-tea"
+ "Белый чай" "white-tea"
+ "Желтый чай" "yellow-tea"
+ "Посуда" "teaware"} category))
+
(fn get-query-string [query key]
(if (and query
(. query key)
@@ -55,9 +65,9 @@
(tonumber (. query key 1))
nil))
-(fn collect-form [params]
+(fn collect-form [params category]
{:query (str.trim (or (get-query-string params "query") ""))
- :tags (filter #(~= "" $2) (or params.tags []))
+ :tags (filter #(~= "" $2) (or params.tags [category]))
: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"))})
@@ -140,7 +150,7 @@
(if (. query-synonyms q)
(.. "(" q "* OR " (. query-synonyms q) "*)")
(.. q "*")))
- (str.split query))
+ (str.split query " "))
" AND ")))
(when (and min-price (< 0 min-price))
(if price-per
@@ -202,29 +212,24 @@
(fn site-name-template [name]
(if
(= name "ipuer")
- [:a {:class "site-icon" :href "https://ipuer.ru"
- :alt "Логотип Институт чай пуэр"}
- [:img {:src "/static/ipuer.jpg"}]
+ [:a {:class "site-icon" :href "https://ipuer.ru"}
+ [:img {:src "/static/ipuer.jpg" :alt "Логотип Институт чай пуэр"}]
"Институт чая пуэр"]
(= name "artoftea")
- [:a {:class "site-icon" :href "https://artoftea.ru"
- :alt "Логотип Art of tea"}
- [:img {:src "/static/artoftea.png"}]
+ [:a {:class "site-icon" :href "https://artoftea.ru"}
+ [:img {:src "/static/artoftea.png" :alt "Логотип Art of tea"}]
"Art of tea"]
(= name "ozchai")
- [:a {:class "site-icon" :href "https://ozchai.ru"
- :alt "Логотип #OZCHAI"}
- [:img {:src "/static/ozchai.ico"}]
+ [:a {:class "site-icon" :href "https://ozchai.ru"}
+ [:img {:src "/static/ozchai.ico" :alt "Логотип #OZCHAI"}]
"Чайная #OZCHAI"]
(= name "clubcha")
- [:a {:class "site-icon" :href "https://clubcha.ru"
- :alt "Логотип Железный Феникс"}
- [:img {:src "/static/clubcha.png"}]
+ [:a {:class "site-icon" :href "https://clubcha.ru"}
+ [:img {:src "/static/clubcha.png" :alt "Логотип Железный Феникс"}]
"Железный Феникс"]
(= name "chaekshop")
- [:a {:class "site-icon" :href "https://chaekshop.ru"
- :alt "Логотип Интернет-магазин фермерского китайского чая «Чаёк»"}
- [:img {:src "/static/chaekshop.svg"}]
+ [:a {:class "site-icon" :href "https://chaekshop.ru"}
+ [:img {:src "/static/chaekshop.svg" :alt "Логотип Интернет-магазин «Чаёк»"}]
"Интернет-магазин «Чаёк»"]
""))
@@ -267,7 +272,7 @@
(if (< page last-page)
[:a {:href (form->path (+ page 1) form)} "→"]
"")]
- [:div {} "Всего результатов: " [:strong {} (string.format "%d" total)]]]
+ [:div {} "Всего: " [:strong {} (string.format "%d" total)]]]
""))
(fn aside-template [form paginator]
@@ -275,9 +280,9 @@
[:div {:class "aside-content"}
(if (not (form-empty? form))
[:a {:href "/" :style "display: block;"}
- [:img {:class "logo" :src "static/logo.svg"
+ [:img {:class "logo" :src "/static/logo.svg"
:alt "Логотип meicha.ru" :title "Логотип meicha.ru"}]]
- [:img {:class "logo" :src "static/logo.svg"
+ [:img {:class "logo" :src "/static/logo.svg"
:alt "Логотип meicha.ru" :title "Логотип meicha.ru"}])
[:form {:class "form"}
[:input {:type :search :name "query" :value form.query
@@ -305,22 +310,49 @@
[:button {:type :submit} "Искать"]]
paginator]])
+(fn menu-template []
+ [:nav {:class "menu"}
+ [:a {:href "/red-tea"} "Красный чай"]
+ [:a {:href "/sheng-puer"} "Шен пуэр"]
+ [:a {:href "/shou-puer"} "Шу пуэр"]
+ [:a {:href "/oolong"} "Улун"]
+ [:a {:href "/green-tea"} "Зеленый чай"]
+ [:a {:href "/white-tea"} "Белый чай"]
+ [:a {:href "/yellow-tea"} "Желтый чай"]
+ [:a {:href "/teaware"} "Посуда"]])
+
(fn base-template [form page total items]
(local paginator (paginator-template form page 48 total))
+ (local menu-path
+ (if (and form.tags (< 0 (# form.tags)))
+ (category-menu-path (. form.tags 1))
+ nil))
(local spellfix-suggestion
(if (and (not (str.empty? form.query)) items (< 0 (# items)))
nil
(spellfix.guess form.query)))
- [:html {:lang "en"}
+ [:html {:lang "ru-RU"}
[:head {}
- [:meta {:charset "UTF-8"}]
- [:link {:rel :stylesheet :href "static/style.css"}]
- [:title {} "A new cool web server for lua"]]
+ [:meta {:charset "utf-8"}]
+ [:meta {:name "viewport" :content "width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=5.0"}]
+ [:link {:rel "stylesheet" :href "/static/style.css"}]
+ [:link {:rel "icon" :href "/static/favicon.png"}]
+ [:title {} (if (str.empty? form.query)
+ texts.meta-title
+ (.. form.query " | " texts.meta-title))]
+ [:meta {:name "description" :content texts.meta-description}]]
[:body {}
[:div {:class "container"}
[:div {:class "content"}
(aside-template form paginator)
[:section {}
+ (menu-template)
+ (if (. form.tags 1)
+ [:h1 {} (. form.tags 1)]
+ "")
+ (if (and menu-path (. texts (.. menu-path "-description")))
+ [:NO-ESCAPE (. texts (.. menu-path "-description"))]
+ "")
(if (< 0 (# items))
[:div {:class "list"}
(table.unpack (map #(item-template $2) items))]
@@ -333,20 +365,40 @@
[:footer {} paginator]]]]]])
(fn root-handler [{: path : query}]
- (if (= path "/")
- (let [headers {:content-type "text/html"}
- page (or (get-query-number query "page") 1)
- form (collect-form query)
- {: results : total}
- (if (not (form-empty? form))
- (query-products form page)
- {:total 48 :results (random-products 48)})]
- (values
- 200 headers
- (html.render
- (base-template form page total results)
- true)))
- (values 404 {} "not found")))
+ (fn respond [query category]
+ (let [headers {:content-type "text/html"}
+ page (or (get-query-number query "page") 1)
+ form (collect-form query category)
+ {: results : total}
+ (if (not (form-empty? form))
+ (measure "query products" #(query-products form page))
+ {:total 48 :results (measure "random products" #(random-products 48))})]
+ (values
+ 200 headers
+ (.. "<!DOCTYPE html>\n"
+ (measure "render"
+ #(html.render
+ (base-template form page total results)
+ true))))))
+
+ (match (str.split path "/")
+ ["red-tea"] (respond query "Красный чай")
+ ["sheng-puer"] (respond query "Шен пуэр")
+ ["shou-puer"] (respond query "Шу пуэр")
+ ["oolong"] (respond query "Улун")
+ ["green-tea"] (respond query "Зеленый чай")
+ ["white-tea"] (respond query "Белый чай")
+ ["yellow-tea"] (respond query "Желтый чай")
+ ["teaware"] (respond query "Посуда")
+ [] (respond query)
+ _ (values 404 {} "not found")))
+
+(fn robots-handler []
+ (values 200 {:content-type "text/plain"} "User-agent: *\nAllow: /"))
-(must (luna.router.route "GET /" root-handler))
+(must (luna.router.route
+ "GET /"
+ (fn [req]
+ (measure "root handler" #(root-handler req)))))
+(must (luna.router.route "GET /robots.txt" robots-handler))
(must (luna.router.static "GET /static/" "static/"))
diff --git a/lib/string.fnl b/lib/string.fnl
index 1696a64..6538827 100644
--- a/lib/string.fnl
+++ b/lib/string.fnl
@@ -12,11 +12,22 @@
(table.insert result (must (luna.utf8.sub str i 1))))
result)
-(fn split [str]
- (accumulate [res [] v _ (str:gmatch "%S+")]
+(fn split [str delimiter]
+ (if (empty? str)
+ []
(do
- (table.insert res v)
- res)))
+ (local result {})
+ (local len (# str))
+ (var cursor 1)
+ (var (start end) (str:find delimiter))
+ (while start
+ (when (< cursor start)
+ (table.insert result (str:sub cursor (- start 1))))
+ (set cursor (+ end 1))
+ (set (start end) (str:find delimiter cursor)))
+ (when (<= cursor len)
+ (table.insert result (str:sub cursor len)))
+ result)))
(fn ends-with [str end]
(= (string.sub str (- (# end))) end))
diff --git a/spellfix.fnl b/spellfix.fnl
index 00642ac..5ecb870 100644
--- a/spellfix.fnl
+++ b/spellfix.fnl
@@ -301,7 +301,7 @@
(array.sort index #(< $1.distance $2.distance)))
(local most-similar (. sorted-index 1))
most-similar.word)
- (str.split string))
+ (str.split string " "))
" "))
(if (~= result string)
result
diff --git a/static/favicon.png b/static/favicon.png
new file mode 100644
index 0000000..644e91f
--- /dev/null
+++ b/static/favicon.png
Binary files differ
diff --git a/static/style.css b/static/style.css
index 39f3685..1dc0bc2 100644
--- a/static/style.css
+++ b/static/style.css
@@ -24,6 +24,17 @@ body {
top: 3rem;
}
+.menu {
+ display: flex;
+ gap: 0.75rem 1.5rem;
+ flex-wrap: wrap;
+ margin-bottom: 2rem;
+}
+
+.menu a {
+ color: blue;
+}
+
.list {
display: flex;
flex-wrap: wrap;
@@ -83,6 +94,10 @@ body {
width: 10rem;
}
+.form {
+ margin-bottom: 1rem;
+}
+
.form input[type="search"],
.form select,
.form-price,
@@ -103,7 +118,7 @@ body {
.form-price input {
flex: 1;
- max-width: calc(50% - 0.5rem);
+ max-width: calc(50% - 1rem);
}
.form-price-per input {
diff --git a/texts.fnl b/texts.fnl
index f30c037..4d769eb 100644
--- a/texts.fnl
+++ b/texts.fnl
@@ -1,2 +1,101 @@
{:no-results "По вашему запросу нет результатов. Попробуйте изменить параметры поиска."
- :no-results-with-suggestion "По вашему запросу нет результатов. Возможно, вы имели в виду <a href=\"?query=%s\">%s</a>?"}
+ :no-results-with-suggestion "По вашему запросу нет результатов. Возможно, вы имели в виду <a href=\"?query=%s\">%s</a>?"
+ :meta-title "meicha.ru — каталог китайского чая"
+ :meta-description "Каталог китайского чая и связанных товаров, автоматически собирающий данные с сайтов чайных."
+ :red-tea-description "
+<p>Красный китайский чай, известный за пределами Китая как черный чай, имеет несколько характерных особенностей:</p>
+<ol>
+<li>Процесс ферментации: Листья проходят полную ферментацию, что придаёт чаю насыщенный вкус и тёмный цвет.</li>
+<li>Вкус: Красный чай обычно обладает крепким, богатым вкусом с нотами карамели, шоколада или фруктов.</li>
+<li>Аромат: У него яркий и глубокий аромат, который может варьироваться от сладковатого до древесного.</li>
+<li>Цвет настоя: Напиток имеет тёмно-красный или бурый цвет.</li>
+<li>Польза для здоровья: Содержит антиоксиданты, которые могут поддерживать здоровье сердца и способствовать пищеварению.</li>
+<li>Популярные сорта: Среди известных сортов — Цзюньшань Хун Ча, Дянь Хун и Лапсанг Сушонг.</li>
+</ol>
+<p>Этот чай часто используется как в чистом виде, так и в сочетании с молоком или специями.</p>"
+ :white-tea-description "
+<p>Белый чай, один из самых деликатных видов чая, имеет свои особенности:</p>
+<ol>
+<li>Минимальная обработка: Листья собираются и сушатся на солнце, что сохраняет их натуральный вкус и аромат.</li>
+<li>Вкус: Обладает легким, нежным вкусом с цветочными и травяными нотами, иногда с лёгкой сладостью.</li>
+<li>Цвет настоя: Напиток имеет светло-желтый или бледно-зеленый цвет.</li>
+<li>Антиоксиданты: Содержит высокое количество антиоксидантов, полезных для здоровья.</li>
+<li>Популярные сорта: К известным сортам относятся Бянь Хао (Silver Needle) и Шуан Гу (White Peony).</li>
+<li>Чувствительность к завариванию: Требует более низкой температуры воды и короткого времени настаивания, чтобы избежать горечи.</li>
+</ol>
+<p>Этот чай часто ценится за свою утонченность и лёгкость, идеально подходит для медитативного наслаждения.</p>"
+ :green-tea-description "
+<p>Зеленый чай имеет ряд отличительных особенностей:</p>
+<ol>
+<li>Минимальная ферментация: Листья подвергаются легкой обработке (парообработке или обжарке), что сохраняет их свежесть и зеленый цвет.</li>
+<li>Вкус: Обладает свежим, травянистым вкусом, который может варьироваться от сладковатого до слегка горьковатого, в зависимости от сорта.</li>
+<li>Цвет настоя: Напиток обычно светло-зеленый или желтый.</li>
+<li>Польза для здоровья: Содержит много антиоксидантов и может поддерживать метаболизм, а также улучшать общее состояние здоровья.</li>
+<li>Популярные сорта: Известные сорта включают Сенча, Матча, Лунцзин (Драконий колодец) и Гунпай.</li>
+<li>Чувствительность к завариванию: Требует более низкой температуры воды и короткого времени настаивания, чтобы избежать горечи и сохранить аромат.</li>
+</ol>
+<p>Зеленый чай часто ценится за свою лёгкость и разнообразие вкусовых профилей, что делает его популярным выбором во многих культурах.</p>"
+ :sheng-puer-description "
+<p>Шен пуэр — это сырой (неферментированный) чай из провинции Юннань, который обладает уникальными характеристиками. Вот несколько его особенностей:</p>
+<ol>
+<li>Производственный процесс: Шен пуэр производится из свежих листьев чайного дерева, которые подвергаются процессу сушки и скручивания. В отличие от шен пуэра, шуй пуэр проходит процесс ферментации.</li>
+<li>Вкус и аромат: У шен пуэра ярко выраженный свежий, травяной вкус с легкой сладостью и иногда фруктовыми нотами. С возрастом чай становится более мягким и глубоким, развивая сложные ароматы.</li>
+<li>Возраст и созревание: Шен пуэр может долго храниться, и со временем его вкус и аромат становятся более насыщенными и гармоничными. Старые сорта ценятся высоко.</li>
+<li>Цвет настоя: Настой шен пуэра обычно светлый, золотисто-желтый, особенно в молодом виде. С возрастом цвет может становиться более насыщенным.</li>
+<li>Польза для здоровья: Шен пуэр считается полезным для пищеварения и может помогать в контроле веса. Содержит антиоксиданты и другие полезные соединения.</li>
+<li>Культуры и традиции: Потребление шен пуэра связано с определёнными культурными традициями, включая специальные ритуалы заваривания чая.</li>
+</ol>
+<p>Эти характеристики делают шен пуэр уникальным и желанным для многих любителей чая.</p>"
+ :shou-puer-description "
+<p>Шу пуэр — это ферментированный чай, также из провинции Юннань, который отличается от шен пуэра рядом особенностей:</p>
+<ol>
+<li>Производственный процесс: Шу пуэр проходит процесс искусственной ферментации, который называется \"вотя\" (или \"шу пуэр\"). Это позволяет ускорить процесс созревания и придаёт чаю характерный вкус.</li>
+<li>Вкус и аромат: Шу пуэр обычно имеет более насыщенный, земляной и глубокий вкус с нотами древесины, шоколада и иногда даже кофе. Он более мягкий и менее терпкий, чем шен пуэр.</li>
+<li>Цвет настоя: Настой шу пуэра тёмный, насыщенно коричневый или чёрный, что отражает его степень ферментации.</li>
+<li>Созревание: Шу пуэр можно пить сразу после производства, хотя и он может улучшаться с возрастом, становясь более мягким и глубоким.</li>
+<li>Польза для здоровья: Шу пуэр также обладает полезными свойствами, включая поддержку пищеварения, улучшение обмена веществ и антиоксидантные свойства.</li>
+<li>Культуры и традиции: Шу пуэр также окружён культурными традициями, с акцентом на методы заваривания и сервировки, которые могут варьироваться в зависимости от региона и предпочтений.</li>
+</ol>
+<p>Шу пуэр привлекает тех, кто предпочитает более тёмные и насыщенные чаи, и его ценят за богатство вкуса и аромата.</p>
+"
+ :oolong-description "
+<p>Улуны — это полуферментированные чаи, которые занимают промежуточное положение между зелеными и черными чаями. Вот основные особенности улунов:</p>
+<ol>
+<li>Производственный процесс: Улуны проходят частичную ферментацию, что придаёт им уникальные характеристики. Процесс включает в себя сушки, скручивание и иногда обжаривание.</li>
+<li>Вкус и аромат: Улуны могут иметь широкий спектр вкусов — от цветочных и фруктовых до ореховых и карамельных. В зависимости от степени ферментации вкус может быть как мягким и сладким, так и более насыщенным и сложным.</li>
+<li>Цвет настоя: Настой улунов обычно золотистого или медного цвета, в зависимости от типа и степени ферментации.</li>
+<li>Разнообразие: Существует множество сортов улунов, таких как Тайваньский оолонг, Да Хун Пао, Тегуаньинь и другие. Каждый сорт обладает своими уникальными особенностями и вкусами.</li>
+<li>Польза для здоровья: Улуны содержат антиоксиданты и могут способствовать улучшению обмена веществ, поддержанию здоровья кожи и снижению уровня стресса.</li>
+<li>Методы заваривания: Улуны часто заваривают в гайвани или чайниках с использованием высоких температур воды, что позволяет раскрыть их аромат и вкус. Многие любители чая практикуют многократное заваривание одних и тех же листьев.</li>
+</ol>
+<p>Улуны привлекают многих любителей чая своей сложностью и разнообразием, а также богатым ароматом и вкусом, который раскрывается в процессе заваривания.</p>"
+ :yellow-tea-description "
+<p>Желтый чай — это один из самых редких и деликатных видов чая, который ценится за свой особый процесс обработки и уникальный вкус. Вот его основные особенности:</p>
+<ol>
+<li>Производственный процесс: Желтый чай проходит легкую ферментацию, схожую с процессом производства зеленого чая, но включает дополнительный этап \"прокаливания\" или \"завяливания\". Это помогает смягчить вкус и добавить сладость.</li>
+<li>Вкус и аромат: У желтого чая мягкий, сладковатый вкус с легкими цветочными и фруктовыми нотами. Он часто менее терпкий, чем зеленый чай, и обладает более насыщенным послевкусием.</li>
+<li>Цвет настоя: Настой желтого чая имеет светло-желтый или золотистый оттенок, который становится более насыщенным с возрастом.</li>
+<li>Редкость и ценность: Желтый чай редко производится и чаще всего встречается в Китае, что делает его довольно дорогим и желанным среди ценителей.</li>
+<li>Польза для здоровья: Как и другие виды чая, желтый чай богат антиоксидантами и может способствовать улучшению обмена веществ и поддержанию здоровья сердца.</li>
+<li>Методы заваривания: Для заваривания желтого чая рекомендуется использовать воду температурой около 80-85°C и настаивать 2-3 минуты, чтобы избежать горечи и раскрыть его тонкие ароматы.</li>
+</ol>
+<p>Желтый чай привлекает тех, кто ищет что-то особенное и уникальное в мире чая, благодаря своей утонченности и редкости.</p>"
+ :teaware-description "
+<p>Чайная посуда играет важную роль в культуре чаепития и может значительно влиять на вкус и аромат чая. Вот основные особенности различных видов чайной посуды:</p>
+
+<h2>Чайники</h2>
+Материал: Чайники могут быть керамическими, фарфоровыми, стеклянными, металлическими или глиняными (например, из юннаньской глины). Каждый материал по-своему влияет на теплообмен и вкус.
+Форма: Форма чайника может варьироваться, что также влияет на процесс заваривания. Например, чайники с широким дном позволяют лучше раскрывать ароматы.
+
+<h2>Гайвани</h2>
+
+Это традиционный китайский чайник для заваривания улунов и других сортов. Он обычно имеет широкое горлышко и позволяет наблюдать за цветом настоя.
+
+<h2>Чашки</h2>
+Материалы: Чашки могут быть из фарфора, стекла, глины или металла. Фарфоровые чашки сохраняют тепло и подчеркивают аромат, а глиняные — могут добавлять свои нотки во вкус.
+Размер и форма: Меньшие чашки предпочтительнее для крепких чаёв, таких как пуэр, в то время как большие могут использоваться для легких, цветочных сортов.
+Сито и фильтры:
+Используются для отделения чайных листьев от настоя. Это может быть встроенное сито в чайнике или отдельные фильтры.
+
+<p>Выбор чайной посуды может зависеть от типа чая, способа заваривания и культурных традиций. Правильная посуда не только помогает раскрыть вкус и аромат чая, но и создает атмосферу чаепития.</p>"
+}