60. Homepage FrontEnd & navbar changes
Homepage
To update the frontend of our homepage, we will integrate the HTML structure from the home.html
file located in the Frontend
folder into homepage.html
using Django's template system.
Specifically, the content within the <main>
tag of home.html
will be copied and integrated into homepage.html
.


The code is organized into three sections, each representing a different type of banner. For our use case, we will utilize only the grid banner. As a result, the carrosel
and banner-individual
sections will be removed.
Within the banner-grid
section, we will retain only the first <a>
tag, as this will serve as a template for dynamically rendering banners from our database.
The updated homepage.html
code is shown below:
{% extends 'base.html' %}
{% load static %}
{% block body %}
<main class="principal">
<section class="banner-grid">
{% for banner in banners %}
<a
href="{% url 'store' banner.link_output %}"
class="banner-grid__imagem"
>
<img
src="{{ banner.image.url}}"
alt={{ banner.link_output}}
/>
</a>
{% endfor %}
</section>
</main>
{% endblock %}


Navbar changes
Currently, the navbar displays all types, regardless of their association with specific categories. To ensure the navbar shows only the types linked to each category, we will modify two components:
navbar.html
: Update the code to dynamically render only the types related to each category.category_type
function innew_context.py
: Adjust the logic to filter and pass the appropriate types for each category.
The updated implementations for both files are provided below:
{% load static %}
<header class="cabecalho">
<div class="cabecalho__menu">
<img
class="cabecalho__menu-icone"
src="{% static 'images/menu.svg' %}"
alt="Ícone Menu"
/>
<p class="cabecalho__menu-x">X</p>
</div>
<div class="cabecalho__container">
<a href="{% url 'homepage' %}">
<img
src="https://lojausereserva.vtexassets.com/assets/vtex/assets-builder/lojausereserva.lojausereserva-theme/5.0.16/icons/logo-black-rsv___e6008150aa5a6134f9a0ae5fe52a06d3.svg"
alt="Logo da Reserva"
class="cabecalho__logo"
/>
</a>
<nav class="cabecalho__navegacao">
<ul class="cabecalho__lista">
{% for item in categories_with_types %}
<li class="cabecalho__item-lista">
<a
class="cabecalho__link cabecalho_link-media"
href="{% url 'store' item.category.slug %}"
>
{{ item.category.name }}
</a>
<div class="cabecalho__expansao-tipos">
<a
style="width: 25%;"
class="cabecalho__imagem-link"
href="{% url 'store' item.category.slug %}"
>
<img
src="{{ item.category.image.url }}"
alt="Imagem do menu secundário"
class="cabecalho__imagem"
/>
</a>
<ul class="cabecalho__lista cabecalho__lista--tipo">
{% if item.types %}
{% for type in item.types %}
<li>
<a
class="cabecalho__link cabecalho__link--tipo"
href="{% url 'store' %}{{ item.category.slug }}-{{ type.slug }}"
>
{{ type.name }}
</a>
</li>
{% endfor %}
{% else %}
<li>
<span class="cabecalho__link cabecalho__link--tipo">
No products available
</span>
{% endif %}
</ul>
</div>
</li>
{% endfor %}
</ul>
</nav>
</div>
<div class="cabecalho__icones">
<div class="cabecalho__icone-login">
<!-- Para trocar o ícone basta adicionar a classe 'cabecalho__link-icone--logado' na âncora abaixo -->
{% if request.user.is_authenticated %}
<a class="cabecalho__link cabecalho__link-icone--logado" href="javascript: void(0)">
{% else %}
<a class="cabecalho__link-icone" href="{% url 'perform_login' %}">
{% endif %}
<svg class="cabecalho__icone" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M8 1.333a3.332 3.332 0 100 6.662 3.332 3.332 0 100-6.662zM3.334 4.664A4.665 4.665 0 018 0a4.665 4.665 0 110 9.328 4.665 4.665 0 01-4.666-4.664zm2 8.662A3.333 3.333 0 002 16.657v1.996h12v-1.996a3.333 3.333 0 00-3.333-3.333H5.334zM.667 16.657a4.666 4.666 0 014.667-4.666h5.333a4.666 4.666 0 014.667 4.666v3.33H.667v-3.33z"
fill="inherit"
/>
</svg>
<svg
class="cabecalho__icone cabecalho__icone--logado"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M16.8496 15.3103C15.526 13.6954 12.9549 12.5999 9.99992 12.5999C7.04496 12.5999 4.47379 13.6954 3.15028 15.3103M16.8496 15.3103C17.9885 13.8434 18.6666 12.0009 18.6666 9.99992C18.6666 5.21345 14.7864 1.33325 9.99992 1.33325C5.21345 1.33325 1.33325 5.21345 1.33325 9.99992C1.33325 12.0009 2.01135 13.8434 3.15028 15.3103M16.8496 15.3103C15.264 17.3525 12.7854 18.6666 9.99992 18.6666C7.21439 18.6666 4.7358 17.3525 3.15028 15.3103M13.4666 7.39992C13.4666 9.31451 11.9145 10.8666 9.99992 10.8666C8.08533 10.8666 6.53325 9.31451 6.53325 7.39992C6.53325 5.48533 8.08533 3.93325 9.99992 3.93325C11.9145 3.93325 13.4666 5.48533 13.4666 7.39992Z"
stroke="inherit"
/>
</svg>
</a>
<!-- Para exibir o menu do perfil, basta adicionar a classe 'cabecalho__informacoes-perfil--aberto' na div abaixo -->
<div class="cabecalho__informacoes-perfil ">
{% if request.user.client.name %}
<p class="cabecalho__texto">Olá, <span>{{ request.user.client.name }}</span>!</p>
{% else %}
<p class="cabecalho__texto">Olá, <span>{{ request.user.client.email }}</span>!</p>
{% endif %}
<a
class="cabecalho__link cabecalho__link--perfil"
href="{% url 'your_account' %}"
>Minha Conta</a
>
<a
class="cabecalho__link cabecalho__link--perfil"
href="{% url 'my_orders' %}"
>Meus Pedidos</a
>
{% if Team %}
<a
class="cabecalho__link cabecalho__link--perfil"
href="{% url 'manage_store' %}"
>Manage Store</a
>
{% endif %}
<hr />
<a class="cabecalho__link cabecalho__link--perfil" href="{% url 'perform_logout' %}">Sair</a>
</div>
</div>
<div class="cabecalho__icone-carrinho">
<a class="cabecalho__link-icone" href="{% url 'cart' %}">
<svg
class="cabecalho__icone cabecalho__icone--menor"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M15.328 5.484a.656.656 0 00-.672-.613h-2.219v-.613C12.437 1.903 10.454 0 8 0S3.563 1.903 3.563 4.258v.613H1.378a.656.656 0 00-.672.613L0 19.323c0 .16.067.322.168.451A.615.615 0 00.672 20h14.656c.37 0 .672-.29.672-.645l-.672-13.871zm-1.311.645l.639 12.58H1.377l.639-12.548c4.217-.015 8.103-.032 12-.032zm-9.11-1.258v-.613C4.908 2.613 6.287 1.29 8 1.29s3.092 1.323 3.092 2.968v.613H4.908z"
fill="inherit"
/>
<path
d="M11.81 16.37c-.127-.102-.7-.511-.986-.784-.095-.103-.032-.24-.16-.342l-.477-.512c-.19-.204-.35-.41-.509-.614-.159-.205-.604-.887-.955-1.331-.413-.478-1.145-1.058-1.368-1.604 0-.034-.032-.068-.032-.102a3.213 3.213 0 01-.063-.58c0-.205.063-.444.286-.785.255-.41.19-.58.127-.58-.095 0-.159 0-.095-.41.063-.376.032-.512-.032-.615-.032-.068-.095-.136-.16-.102-.095.034-.19.273-.286.341-.031.034-.159.103-.127-.239 0-.068-.032-.102-.127-.068-.096.068-.255.24-.35.58 0 .035-.032.035-.032 0 0-.034-.032-.136 0-.273.032-.136.064-.239.032-.239-.064-.034-.16.137-.223.308 0 .034 0 .034-.032.068 0 .034-.032.034-.032 0s0-.068.032-.137v-.034c-.032 0-.063 0-.095.034-.064.069-.16.171-.191.308v.477c0 .034-.064.034-.064.137.032.205.127.41.16.512 0 .034 0 .068-.033.102-.19.068-.636.205-.986.444-.032 0-.032.034-.032.068.032.034.064.034.064 0 .382-.136.923-.307 1.177-.136.191.136.223.511.096.887-.032.136-.096.273-.128.41-.54 1.57.478 2.286 1.4 3.242.064.068.223.239.35.443.096.137.192.307.192.478 0 .137-.032.307-.064.512-.064.239-.095.136-.477.034-.128-.034-.128-.034-.191.137-.064.17-.096.204-.064.204s.7 0 .796.034h.031c.096.035.478.24.573.342.032.034.064 0 .064 0 .032-.034 0-.068-.032-.068-.159-.103-.509-.41-.54-.478 0-.034.031-.17.031-.273.064-.444.064-.615.255-.683.159-.068.509.137.795.205 0 0 .032 0 .032.034a1.5 1.5 0 01-.095.307c0 .034-.032.069-.064.103-.064.034-.287-.069-.446-.103-.063-.034-.095-.068-.222.273v.034s.668.035.763.069c.032 0 .032 0 .064.034.255.136.446.239.573.341.063.034.095.068.127.034s0-.068-.032-.102c0 0-.159-.137-.318-.24-.127-.102-.286-.17-.255-.238 0-.034.032-.102.032-.137 0-.034.064-.204.064-.307l.032-.034c.7.273.923.751 1.464 1.058.573.341 1.304.034.763-.444z"
fill="inherit"
/>
</svg>
</a>
<div class="cabecalho__itens cabecalho__itens--visivel">{{product_amount_cart }} </div>
</div>
</div>
</header>
def category_type(request):
categories_navbar = Categoric.objects.all()
categories_with_types = []
for category in categories_navbar:
types = Type.objects.filter(product__category=category).distinct()
categories_with_types.append({
"category": category,
"types": types
})
return {
"categories_with_types": categories_with_types,
}
Since the order of the types matches the order of the categories obtained from the categories_navbar
queryset, we created a joined list combining both categories and types. This allows us to unpack the paired lists directly within the for
loops in the HTML file for seamless rendering.
Note: If no types are available for a category, the message "No products available" will be displayed.
In the navbar.html
file, update the images displayed for each category inside the div
with the class cabecalho__expansao-tipos
to load dynamically based on the category's associated image. Additionally, implement a category filter so that clicking on an image filters products by the selected category.
<div class="cabecalho__expansao-tipos">
<a
style="width: 25%"
class="cabecalho__imagem-link"
href="{% url 'store' item.category.slug %}"
>
<img
src="{{ item.category.image.url }}"
alt="Imagem do menu secundário"
class="cabecalho__imagem"
/>
</a>
In the models.py
file, add an image
attribute to the Categoric
class, then apply the migrations to update the database schema.
image = models.ImageField(upload_to=dynamic_upload_path, null=True, blank=True) #? image shown in the navbar

Last updated