URL & điều hướng
Mỗi mục có đường dẫn riêng
Sản phẩm, danh mục, bộ sưu tập và trang nội dung tự sở hữu đường dẫn của mình. Đường dẫn này do cửa hàng cấu hình tại Quản trị → Website → Cấu trúc URL, và có thể đặt riêng cho từng mục.
Vì vậy trong giao diện luôn dùng url của chính mục đó:
<a href="{{ product.url }}">{{ product.title }}</a>
Đừng tự ghép đường dẫn theo tiền tố:
{% comment %} SAI — bỏ qua đường dẫn riêng của sản phẩm {% endcomment %}
<a href="/san-pham/{{ product.slug }}">{{ product.title }}</a>
Cách ghép tay ở trên chỉ đúng khi cửa hàng giữ nguyên cấu trúc URL mặc định. Ngay khi người quản trị đổi cấu trúc, hoặc đặt đường dẫn riêng cho một sản phẩm, mọi liên kết ghép tay sẽ trỏ sai.
url có thể là null
Mục chưa được gán đường dẫn sẽ có url bằng null. Khi đó đừng tạo thẻ liên
kết — hiển thị dạng chữ:
{% if product.url %}
<a href="{{ product.url }}" class="product-card__name">{{ product.title }}</a>
{% else %}
<span class="product-card__name">{{ product.title }}</span>
{% endif %}
Quy tắc này áp dụng cho product.url, category.url, collection.url,
page.url, article.url và item.product_url trong giỏ hàng.
Với thẻ bao quanh cả khối (ví dụ ảnh + tên nằm chung một liên kết), viết như sau để không phải lặp lại nội dung:
{% if product.url %}<a href="{{ product.url }}" class="card">{% else %}<span class="card">{% endif %}
<img src="{{ product.cover_image_url }}" alt="{{ product.title }}">
<span class="card__name">{{ product.title }}</span>
{% if product.url %}</a>{% else %}</span>{% endif %}
Đường dẫn cố định của website
Một số đường dẫn thuộc về website chứ không thuộc về một mục cụ thể. Những đường dẫn này viết thẳng trong giao diện:
| Đường dẫn | Trang |
|---|---|
/ |
Trang chủ |
/san-pham |
Danh sách sản phẩm |
/tim-kiem?q=... |
Tìm kiếm |
/flash-sale |
Trang flash sale |
/bai-viet |
Danh sách bài viết |
/gio-hang |
Giỏ hàng |
/thanh-toan |
Thanh toán |
/dang-nhap, /dang-ky, /dang-xuat |
Đăng nhập, đăng ký, đăng xuất |
/tai-khoan, /tai-khoan/... |
Khu vực tài khoản khách |
Lọc bài viết theo chuyên mục
Chuyên mục bài viết không có đường dẫn riêng; lọc bằng tham số truy vấn:
{% for cat in article_categories %}
<a href="/bai-viet?danh-muc={{ cat.slug }}">{{ cat.title }}</a>
{% endfor %}
Đường dẫn phân cấp danh mục
Trang danh mục nhận sẵn biến breadcrumb, mỗi mắt xích có url riêng và cũng
có thể null:
<nav class="breadcrumb">
<a href="/">Trang chủ</a>
{% for crumb in breadcrumb %}
/
{% if forloop.last %}
<span>{{ crumb.title }}</span>
{% elsif crumb.url %}
<a href="{{ crumb.url }}">{{ crumb.title }}</a>
{% else %}
<span>{{ crumb.title }}</span>
{% endif %}
{% endfor %}
</nav>
Lọc sản phẩm trong trang danh mục
Trang danh mục nhận bảng lọc ở biến filters (CategoryFilterPanel)
và trạng thái đang chọn ở active_filters. Danh mục không có đường dẫn
riêng cho từng bộ lọc — mọi lựa chọn nằm ở chuỗi truy vấn của chính đường dẫn
danh mục đó.
| Tham số | Lặp lại được | Ý nghĩa |
|---|---|---|
brand=<mã hãng> |
có | Lọc theo hãng. Lấy mã từ filters.brands[].id. |
attr=<mã thuộc tính>:<giá trị> |
có | Lọc theo một giá trị thuộc tính. Lấy từ filters.attributes[].id và options[].value. |
price=<mã khoảng giá> |
có | Khoảng giá đặt sẵn. Lấy từ filters.prices[].id. |
min_price, max_price |
không | Khoảng giá tự nhập, đơn vị đồng. |
sort=price_asc|price_desc|newest |
không | Sắp xếp. |
stock=in_stock|out_of_stock, warehouse_id |
không | Lọc theo tồn kho. warehouse_id chỉ có tác dụng khi stock=in_stock. |
cursor |
không | Trang kế; luôn bỏ khi dựng liên kết bật/tắt bộ lọc. |
Nhiều lựa chọn ghép với nhau thế nào
- Trong cùng một thuộc tính là HOẶC.
?attr=cpu01:Core i5&attr=cpu01:Core i7cho ra sản phẩm dùng i5 hoặc i7. - Giữa các thuộc tính khác nhau là VÀ.
?attr=cpu01:Core i5&attr=ram01:16GBchỉ cho ra sản phẩm vừa i5 vừa 16GB. - Nhiều hãng là HOẶC với nhau, nhưng ghép VÀ với phần thuộc tính.
- Khoảng giá là HOẶC giữa các khoảng: chọn hai khoảng đặt sẵn (hoặc một
khoảng đặt sẵn cộng
min_price/max_price) sẽ mở rộng kết quả, không thu hẹp.
Mã lạ được bỏ qua chứ không báo lỗi: ?price=khong-co-that cho ra đúng
kết quả như khi không lọc gì, và ?brand= với mã không thuộc danh mục này
cũng vậy. Nhờ đó một liên kết cũ sau khi cấu hình lọc thay đổi vẫn mở được.
Dựng liên kết bật/tắt
active_filters là chính các tham số trên, đã bỏ cursor, và chỉ chứa khoá
đang được đặt — nên active_filters rỗng nghĩa là "chưa lọc gì":
{% if active_filters %}
<a href="{{ category.url }}">Xoá tất cả bộ lọc</a>
{% endif %}
{% for brand in filters.brands %}
<a href="{{ category.url }}?brand={{ brand.id }}">{{ brand.title }}</a>
{% endfor %}
Số sản phẩm khớp bộ lọc nằm ở total_count, số còn chưa hiển thị nằm ở
remaining_count:
<h1>{{ total_count }} {{ category.title }}</h1>
{% if has_more %}
<a href="?cursor={{ next_cursor }}">Xem thêm {{ remaining_count }} sản phẩm</a>
{% endif %}