diff --git a/matrix.db b/matrix.db
index e5e5217..93ff5b0 100644
Binary files a/matrix.db and b/matrix.db differ
diff --git a/static/js/index.js b/static/js/index.js
index 8c277cf..aeb778d 100644
--- a/static/js/index.js
+++ b/static/js/index.js
@@ -296,7 +296,8 @@
? `
`
: `${v.name.slice(0,2).toUpperCase()}`;
let linksHtml = '';
- if (v.mont_page) linksHtml += `MONT ↗`;
+ if (v.slug) linksHtml += `Подробнее →`;
+ if (v.mont_page) linksHtml += `MONT ↗`;
if (v.website) linksHtml += `Сайт ↗`;
bar.innerHTML = `
${logoInner}
@@ -313,7 +314,17 @@
const card = document.createElement("article");
card.className = "row-card";
const title = document.createElement("strong");
- title.textContent = row.vendor.name;
+ if (row.vendor.slug) {
+ const a = document.createElement("a");
+ a.href = `/vendor/${row.vendor.slug}`;
+ a.textContent = row.vendor.name;
+ a.style.cssText = "color:inherit;text-decoration:none;";
+ a.addEventListener("mouseenter", () => a.style.textDecoration = "underline");
+ a.addEventListener("mouseleave", () => a.style.textDecoration = "none");
+ title.appendChild(a);
+ } else {
+ title.textContent = row.vendor.name;
+ }
card.appendChild(title);
const tags = document.createElement("div");
tags.className = "tags";
diff --git a/templates/vendor.html b/templates/vendor.html
new file mode 100644
index 0000000..6436c9e
--- /dev/null
+++ b/templates/vendor.html
@@ -0,0 +1,194 @@
+
+
+
+
+
+ {{ vendor.name }} — вендор МОНТ | матрица продуктов MONT
+
+
+
+
+
+
+
+
+ {% if vendor.logo %}{% endif %}
+
+
+
+
+
+
+
+
+
+
+
+
← Все вендоры МОНТ
+
+
+
+
+
+ {% if vendor.logo %}
+

+ {% else %}
+
{{ vendor.name[:2].upper() }}
+ {% endif %}
+
+
+
{{ vendor.name }}
+ {% if vendor.description %}
+
{{ vendor.description }}
+ {% endif %}
+
+
+
+
+ {% if products %}
+
+
Продукты {{ vendor.name }} в корзине МОНТ
+
+ {% for p in products %}
+ {% if p.url %}
+
{{ p.name }} ↗
+ {% else %}
+
{{ p.name }}
+ {% endif %}
+ {% endfor %}
+
+
+ {% endif %}
+
+ {% if categories %}
+
+
Категории
+ {% for c in categories %}
+ {{ c }}
+ {% endfor %}
+
+ {% endif %}
+
+
+
diff --git a/zkart_app/db.py b/zkart_app/db.py
index efa9b54..ac759e2 100644
--- a/zkart_app/db.py
+++ b/zkart_app/db.py
@@ -411,7 +411,7 @@ def fetch_scope_data(scope: str) -> dict:
conn = get_db()
vendors = [dict(r) for r in conn.execute(
f"SELECT id, name, COALESCE(logo,'') as logo, COALESCE(description,'') as description, "
- f"COALESCE(website,'') as website, COALESCE(mont_page,'') as mont_page "
+ f"COALESCE(website,'') as website, COALESCE(mont_page,'') as mont_page, COALESCE(slug,'') as slug "
f"FROM {tables['vendors']} ORDER BY lower(name)"
)]
categories = [dict(r) for r in conn.execute(f"SELECT id, name FROM {tables['categories']} ORDER BY lower(name)")]
diff --git a/zkart_app/routes.py b/zkart_app/routes.py
index 8b306a0..f5ca6b5 100644
--- a/zkart_app/routes.py
+++ b/zkart_app/routes.py
@@ -582,15 +582,69 @@ def sitemap_xml():
from flask import Response
proto = request.headers.get("X-Forwarded-Proto", "https")
base = f"{proto}://{request.host}"
+ conn = get_db()
+ slugs = [r[0] for r in conn.execute(
+ "SELECT slug FROM vendors WHERE slug IS NOT NULL "
+ "UNION SELECT slug FROM ib_vendors WHERE slug IS NOT NULL"
+ )]
+ conn.close()
+ urls = [f' {base}/weekly1.0']
+ for slug in slugs:
+ urls.append(f' {base}/vendor/{slug}monthly0.7')
body = (
'\n'
'\n'
- f' {base}/weekly1.0\n'
- ''
+ + '\n'.join(urls) + '\n'
)
return Response(body, mimetype="application/xml")
+@bp.get("/vendor/")
+def vendor_page(slug: str):
+ from flask import abort
+ conn = get_db()
+ # Search in both tables, prefer infra
+ vendor = conn.execute(
+ "SELECT id, name, COALESCE(logo,'') as logo, COALESCE(description,'') as description, "
+ "COALESCE(website,'') as website, COALESCE(mont_page,'') as mont_page, 'infra' as scope "
+ "FROM vendors WHERE slug = ?", (slug,)
+ ).fetchone()
+ if not vendor:
+ vendor = conn.execute(
+ "SELECT id, name, COALESCE(logo,'') as logo, COALESCE(description,'') as description, "
+ "COALESCE(website,'') as website, COALESCE(mont_page,'') as mont_page, 'ib' as scope "
+ "FROM ib_vendors WHERE slug = ?", (slug,)
+ ).fetchone()
+ if not vendor:
+ conn.close()
+ abort(404)
+
+ vendor = dict(vendor)
+ tables = scope_tables(vendor['scope'])
+
+ products = [dict(r) for r in conn.execute(
+ f"SELECT name, COALESCE(url,'') as url FROM {tables['products']} "
+ f"WHERE vendor_id = ? ORDER BY lower(name)", (vendor['id'],)
+ )]
+ categories = [r[0] for r in conn.execute(
+ f"SELECT c.name FROM {tables['categories']} c "
+ f"JOIN {tables['vendor_categories']} vc ON vc.category_id = c.id "
+ f"WHERE vc.vendor_id = ? ORDER BY lower(c.name)", (vendor['id'],)
+ )]
+ conn.close()
+
+ proto = request.headers.get("X-Forwarded-Proto", "https")
+ base_url = f"{proto}://{request.host}"
+ canonical_url = f"{base_url}/vendor/{slug}"
+ return render_template("vendor.html",
+ vendor=vendor,
+ products=products,
+ categories=categories,
+ canonical_url=canonical_url,
+ base_url=base_url,
+ )
+
+
@bp.get("/api/data")
def api_data():
scope = (request.args.get("scope") or "infra").strip().lower()