Commit c4482742 authored by Eduardo Silva's avatar Eduardo Silva
Browse files

ajustes pontuais no header e criacao das tags do menu #6

parent ef48e91b
{% extends "dsgov/base.html" %}
{% load br_components %}
{% load static %}
{% block content %}
<div class="br-menu" id="main-navigation">
<div class="menu-container">
<div class="menu-panel">
<div class="menu-header">
<div class="menu-title"><img src="data:image/png;base64,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" alt="Imagem ilustrativa"/><span>Identificação do site ou Sistema</span></div>
<div class="menu-close">
<button class="br-button circle" type="button" aria-label="Fechar o menu" data-dismiss="menu"><i class="fas fa-times" aria-hidden="true"></i>
</button>
</div>
</div>
<nav class="menu-body" role="tree">
<div class="menu-folder"><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="icon"><i class="fas fa-bell" aria-hidden="true"></i></span><span class="content">Camada 1</span></a>
<ul>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="icon"><i class="fas fa-heart" aria-hidden="true"></i></span><span class="content">Camada 2</span></a></li>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="icon"><i class="fas fa-address-book" aria-hidden="true"></i></span><span class="content">Camada 2</span></a>
<ul>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="icon"><i class="fas fa-book" aria-hidden="true"></i></span><span class="content">Camada 3</span></a></li>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="icon"><i class="fas fa-tree" aria-hidden="true"></i></span><span class="content">Camada 3</span></a>
<ul>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="content">Camada 4</span></a></li>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="content">Camada 4</span></a></li>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="content">Camada 4</span></a></li>
</ul>
</li>
<li><a class="menu-item" href="javascript: void(0)"><span class="icon"><i class="fas fa-moon" aria-hidden="true"></i></span><span class="content">Camada 3</span></a></li>
</ul>
</li>
<li><a class="menu-item" href="javascript: void(0)"><span class="icon"><i class="fas fa-archive" aria-hidden="true"></i></span><span class="content">Camada 2</span></a></li>
</ul>
</div>
<div class="menu-folder"><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="icon"><i class="fas fa-bell" aria-hidden="true"></i></span><span class="content">Camada 1</span></a>
<ul>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="icon"><i class="fas fa-heart" aria-hidden="true"></i></span><span class="content">Camada 2</span></a></li>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="icon"><i class="fas fa-address-book" aria-hidden="true"></i></span><span class="content">Camada 2</span></a>
<ul>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="icon"><i class="fas fa-book" aria-hidden="true"></i></span><span class="content">Camada 3</span></a></li>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="icon"><i class="fas fa-tree" aria-hidden="true"></i></span><span class="content">Camada 3</span></a>
<ul>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="content">Camada 4</span></a></li>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="content">Camada 4</span></a></li>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="content">Camada 4</span></a></li>
</ul>
</li>
<li><a class="menu-item" href="javascript: void(0)"><span class="icon"><i class="fas fa-moon" aria-hidden="true"></i></span><span class="content">Camada 3</span></a></li>
</ul>
</li>
<li><a class="menu-item" href="javascript: void(0)"><span class="icon"><i class="fas fa-archive" aria-hidden="true"></i></span><span class="content">Camada 2</span></a></li>
</ul>
</div>
<div class="menu-folder"><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="icon"><i class="fas fa-bell" aria-hidden="true"></i></span><span class="content">Camada 1</span></a>
<ul>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="icon"><i class="fas fa-heart" aria-hidden="true"></i></span><span class="content">Camada 2</span></a></li>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="icon"><i class="fas fa-address-book" aria-hidden="true"></i></span><span class="content">Camada 2</span></a>
<ul>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="icon"><i class="fas fa-book" aria-hidden="true"></i></span><span class="content">Camada 3</span></a></li>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="icon"><i class="fas fa-tree" aria-hidden="true"></i></span><span class="content">Camada 3</span></a>
<ul>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="content">Camada 4</span></a></li>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="content">Camada 4</span></a></li>
<li><a class="menu-item" href="javascript: void(0)" role="treeitem"><span class="content">Camada 4</span></a></li>
</ul>
</li>
<li><a class="menu-item" href="javascript: void(0)"><span class="icon"><i class="fas fa-moon" aria-hidden="true"></i></span><span class="content">Camada 3</span></a></li>
</ul>
</li>
<li><a class="menu-item" href="javascript: void(0)"><span class="icon"><i class="fas fa-archive" aria-hidden="true"></i></span><span class="content">Camada 2</span></a></li>
</ul>
</div><a class="menu-item divider" href="javascript: void(0)" role="treeitem"><span class="icon"><i class="fas fa-bell" aria-hidden="true"></i></span><span class="content">Item de Camada 1</span></a><a class="menu-item divider" href="javascript: void(0)" role="treeitem"><span class="icon"><i class="fas fa-bell" aria-hidden="true"></i></span><span class="content">Item de Camada 1</span></a>
</nav>
<div class="menu-footer">
<div class="menu-logos"><img src="data:image/png;base64,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" alt="Imagem ilustrativa"/><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMwAAABgCAYAAABR/J1nAAAAAXNSR0IArs4c6QAADK1JREFUeAHtXX+MHFUd/77Z3dlWaAFpr/Rut1o1BgEJig2Weu0uLWIi1NIUTeAPDKIBsQ2xJYZEbFNioijRoGmjTcBYDL9SFGlFTGmvPyggVlRoQKKk9H7U0mKrLdKZu93n5+3dm5s9Zmd372bnZma/k8y+N+/XvO/nvc9834/vzohsvijJ47B6dwqPYOL0w6gwPsM4tEt/0HIaXqTgMEaAEfBGwFOLeCflUEagfRFgDdO+bc+STwABHpJNADzO2n4IMGHar81Z4okgoMZmenw2kXI4LyPQDgiwhmmHVmYZA0OACRMYlFxQOyDAhGmHVmYZA0OACRMYlFxQOyDAhGmHVmYZA0OAd/oDg5ILSjICeiWZNUySW5llCxwBJkzgkHKBSUaACZPk1mXZAkeACRM4pFxgkhFgwiS5dVm24BFgW7LgMeUSk4sAa5jkti1L1gIEmDAtAJWLTC4CTJjkti1L1gIEmDAtAJWLTC4CTJjkti1L1gIE2JasBaBykclDgG3JktemLFEICPCQLASQ+RbJQYAJk5y2ZElCQIAJEwLIfIvkIJBulSjZruLnSciVksSnhKBzW3WfIMuVkt5GXfdTme6z+nduC7JsLisZCAg9+6/1NvrxiJnpKvzQMMTq8eSNSp5yWd472N+zJir14XpEA4HAh2RKs8SdLKpplAwVLRmNduJaRASBwAlDBq2KiGwTrwaGlBMvhEtIEgKBEwbzgEuTApCafyVFFpYjGAQCJ0wTE/w3SNIOnG8FI0rwpTQhS/A35xIjiUDLVsm8pJU4YIuzwZKptdT/zNs6jdlZOF8YtIGEKOowdhmBKCIQuC2ZXnUbK6wiCwhxrd2784mxcSPXAqtrP4jagkGQq4c15PYMzuSLNxHJj6tIoyR3WAO7nvRMyIGhIKD7dWgapqJZapNFCS0H+0/eaeamLRZCXBIKChG+iSC5VJD4QgUYQwzCZcJEoL0Cn8PUkqkyDKsV6YTvR8cQdzuX7GEEIoZAWIR5wz1n8cPALpde9IvnOEZgMhEIhzCSDjYs5MDufonRWcPpfRKinNM+0RzFCDSNQDiEIbqo0ZqZ53Wfj7F7ptH0tdJJogds25xRKsluLDf8u1Y6DmcEmkHAULN/vQLQTMam0grqUEvHjeSRqdTCRtL5pQFB7sdq3FfoyB/eGRro2SvLpSXtS5pCms4unO2H13viZhbOJLrQfE94swEfLEyhGQumNZstiunVaqk6w1slU/ssRItx4uFf4zive6YhaH2N2IaCK2Tp23kzEjv3GRzY/VKmc+ESMlLbsRn5/oYKikEiLD3fK6TsVlXFKuT1Vl/PPyrVnrVwbiZt3GYYtBw7X3Mgc0qeWYSWlfuQ8E67t+eVseKluxYVDcO4HeXNx/L/TJnvsIk6XgGKW+2+GWiTx0pj83hdZ3LFy7DCtwb1+bQcoi4x1RQyXziOtHtR9karb9dTOp+ZK8IiXM7EquhxdMardHiU3bCGZGhRUVT7LESXeg+3QJZsOvWQaqzxAuZFFl2WIk3SNA064EfR2eapU1LpfUrWbG7RSjNjvD68nyXmKrKocPWgQLqrSYq/mPnCMhVWOaAFzHzxkZRh7EAnX6rxh9/E+Unk+042d3RbXU0x67NnmLnC43jgPY/7rEA5ObgoQpFZnIPzGhLG75Dm11rjIfYSJJlHUn5iuDLR/w2PMMBCNSL2Wf6IJ8ty6lyYV0GYs1wAIt0CshwAyEoDjevwI4suMImk0bIpF7jeg055HzphGniUsVf8Gs6XcA7pdOikKWiNX1LnZ+aoYVe2JLajV39RxUMl/xdpn4fvsE5fcYW4ypyavr0qzH2Bh51pDu7Cfa/Vwbh/CeX9GeejIEQPFmCUlkETi2XmNPEsnbPkLJ02Tm5oQzINCgBTm5Jbsim0W64whOt05TGkE4zDbYQsutikDs9Ipq+GedEdiigYEm2wT9FddKLnREVuzCOyUzKPord+Tl0D82mmkb6ech1qeLoAHbpXCrES877f4roylE13FpYYKbEFbTO9kofErRgdfI9I7ZVVH2YmtQnpHKNbkG6rkEOrrb69r4+mBDm7Zn4d97kLpL0ge8bQw6hJRfuNpom+L1QNMxYORZaxYc1eN0MWXXYiNY0h16GjKr2i5jIrHbIooY89e9LqO7kUXPiXxgCddhX8q5HlNesUXTxislQhi0qDxZLtROVbdHp07tnp/PQrRq+HfVjM+ZK2SBgOkXvsvpPLrX43WVTMAdvq7/mxKNPloGT/CHlnDeeJz6+hZ//xqfJoTcdDFp07aaSpLMVL+q490POIlrHa3T8IvH4xGiZmg0DvQDNcU0Wu0QRk9x7bAu1zTAcJSR/Qfsc1aLXjl3TIsu0VXlpIp7EGdv5dlkpXBrXXpstttatXkydVw2gh0ZCbrVJpDpXL31TPSB3u506ELLrcJJEGquE/tk3f17J5uoJecIdjeLTJWVlzRzj+A1gpoz/pSwz1OrVfudlc4SMYJcxzhd1KR/bV/buGfXj3q7DE/akrX2y8k06YkY5/Iw3s7rX6d/1IivLN9UgTBFl0CynSwB/LxtMyKBcrZpvpaM8pd9hYvyyTMyRTcYMk1FK/74H/Yzh5oMWqCFMmWdSZVZtZp+09+rqei7rE8iUjk0oYr44/2LvrAT/SeOWp1zj149F8MT+w31K9suUhD5Z8neFVJTpV7vdIVh0kxVEdAC02RfuVK8jIOdeCXlVzJec6oZ5JI4xfx69FGr88CW2fQMWyBsvVm48HpzqT/No3ktV5XAmFkO5J+35XVGK9k0KYRjr+WNI0kiexrRRRwWRZHHKqJmmG40+wJ63tyNRqWRhyNtPxFWky+UUYn4vL7b6er6F+DTwRw5CC76EQwCLA39TviP/iiiehP5ofoWqYZsiicVekwUrOV3HNZNGgRMS1ysbLTlVgCmPOXvgx57qOxzDkuE2g6hTd0ujQCIMNst/YY4wiWyoZF956BA7veBNPsQP6RiJt/Az+hkYqWHH7hs4XJzc0wgCUv+KMqpZoqJGDbViY3VdM6AMwow+2Yk2VVi5Jl42Z6Ibx55p6BZhdhbuRZkG9dFGMD5MwUZR/0upk5unxbL7DMvMdsV6KVSY02LUffROQMO6BRfKDntbNnYUZ2Vzx58IQ38bw3GVnNmnN0PSNJ2zL1fQdOUPiELBL5ZWmYXwIu/6V10LBvSE7xbwSxrX78HeCF4UhbQwtLsJoTVkzTwdZNsNC9FewvPx93MBI69l/3CrO9Y0QArDSsHPzLzMpuxFzkxsrNcO/bOFfhhnNMjWtcY15N2Iue1u6q3gF3sMdm0OvJoemYQBZAap6XRQRUnWLYr1iVae+596F4dmXza5F22CJvBRaZj7q/2Elg7KiBsa7ZVludIxDVZBDI5h1xuRwET+YGmsmBlPa5JfCGngCbdCxeFY2Y51l9U97k+gpy10SHp43gFQPqjDw6WXss0V6H0f368A1DMan6ite57rBiatfyRLXukei3m89cwQsOeJZF0HuPZt/eqaJYGDgo0iQJTE2RdjJdkzbI9h2EalSIQ1tsZbyC6osmf0rd6F6X8BNOg00zR7tj7obOGHU9yGjLnTD9ZPiJw2nbceEuflTszl6Eh1+XVZmXjBz3fWHVeplGfmOxzB/ma0gw5L0Cetde1Nc4Av8vWTqY6rq+5BxAaBWPZUM/GHYWuiMhPc9dxp/QhveR4JpDFFqLyb91xFdhxVjjwMvPjEz9l5ol6U6FnP/b8XhbwFqLqvOlnwUVoHBX1HWXSLhLl7TlB2irVgZW+xIio9kYdnraVjNHsIrOf6HxTDswahXKQm8Fmp0MRlzxPVYYl7r5IuBp2WEiYHsXMXgEDAwj7kDpFkP7dHAGzPlQbyEaVUcv3nDhAmu03BJMH3JCFqh3riJyclc/G8f8xSJFwyK49Ay6q/O6p0CT9gp+TQd7Inni+LV+rJeY+YWZwRagEDwC0stqGSjRSZKmEaF5nShIhD79yW40cKQkw9GgBGoh4AehbGGqYcUxzMCLgSYMC4w2MsI1EOACVMPIY5nBFwIMGFcYLCXEaiHABOmHkIczwi4EeB9GDca7GcE/BFgDeOPD8cyAlUIMGGq4OALRsAfASaMPz4cywhUIcCEqYKDLxgBfwSYMP74cCwjUIUA25JVwcEXjIA3AmxL5o0LhzICvgjwkMwXHo5kBKoRYMJU48FXjIAvAkwYX3g4khGoRoAJU40HXzEC/giwLZk/PhzLCLgRYA3jRoP9jEAdBJgwdQDiaEbAjQATxo0G+xmBOgjU/NyF3tkcm7/W91I4/TBSjM8wDkntD6xhxj4R+JoR8EHg/z6seDvVOnj4AAAAAElFTkSuQmCC" alt="Imagem ilustrativa"/></div>
<div class="menu-links"><a href="javascript: void(0)"><span class="mr-1">Link externo 1</span><i class="fas fa-external-link-square-alt" aria-hidden="true"></i></a><a href="javascript: void(0)"><span class="mr-1">Link externo 2</span><i class="fas fa-external-link-square-alt" aria-hidden="true"></i></a></div>
<div class="social-network">
<div class="social-network-title">Redes Sociais</div>
<div class="d-flex"><a class="br-button circle" href="javascript: void(0)" aria-label="Compartilhar por Facebook"><i class="fab fa-facebook-f" aria-hidden="true"></i></a><a class="br-button circle" href="javascript: void(0)" aria-label="Compartilhar por Twitter"><i class="fab fa-twitter" aria-hidden="true"></i></a><a class="br-button circle" href="javascript: void(0)" aria-label="Compartilhar por Linkedin"><i class="fab fa-linkedin-in" aria-hidden="true"></i></a><a class="br-button circle" href="javascript: void(0)" aria-label="Compartilhar por Whatsapp"><i class="fab fa-whatsapp" aria-hidden="true"></i></a></div>
</div>
<div class="menu-info">
<div class="text-center text-down-01">Todo o conteúdo deste site está publicado sob a licença <strong>Creative Commons Atribuição-SemDerivações 3.0</strong></div>
</div>
</div>
</div>
<div class="menu-scrim" data-dismiss="menu" tabindex="0"></div>
</div>
</div>
{% endblock %}
from django import template from django import template
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.html import format_html from django.utils.html import format_html
from django.template.base import Variable, VariableDoesNotExist
register = template.Library() register = template.Library()
# Função auxiliar para resolver variáveis de contexto ou usar valores literais
def resolve_variable(value, context):
if value is None:
return ""
try:
# Tenta resolver como uma variável de contexto
return template.Variable(value).resolve(context)
except template.VariableDoesNotExist:
# Se falhar, usa o valor como uma string literal, removendo aspas
return str(value).strip('"\'')
# ========================= # =========================
# BLOCO: TAGS DE ESTRUTURA PRINCIPAL DO HEADER # BLOCO: ESTRUTURA PRINCIPAL DO HEADER
# ========================= # =========================
class SimpleBlockNode(template.Node): # --- Tag: br_header ---
def __init__(self, nodelist, tag_name, default_classes, extra_classes_var=None): @register.tag(name='br_header')
def do_br_header(parser, token):
bits = token.split_contents()
extra_classes = None
if len(bits) > 1 and 'class=' in bits[1]:
extra_classes = bits[1].split('=', 1)[1]
nodelist = parser.parse(('end_br_header',))
parser.delete_first_token()
return BRHeaderNode(nodelist, extra_classes)
class BRHeaderNode(template.Node):
def __init__(self, nodelist, extra_classes=None):
self.nodelist = nodelist self.nodelist = nodelist
self.tag_name = tag_name self.extra_classes = extra_classes
self.default_classes = default_classes def render(self, context):
self.extra_classes_var = extra_classes_var extra_classes_str = f" {resolve_variable(self.extra_classes, context)}" if self.extra_classes else ""
# Agora apenas renderiza o conteúdo, sem se preocupar com a busca.
rendered_content = self.nodelist.render(context)
return format_html(
'<header class="br-header{}"><div class="container-lg">{}</div></header>',
extra_classes_str, mark_safe(rendered_content)
)
# --- Tags de Bloco Explícitas (sem fábrica) ---
# Tag: br_header_top
@register.tag(name='br_header_top')
def do_br_header_top(parser, token):
nodelist = parser.parse(('end_br_header_top',))
parser.delete_first_token()
return BRHeaderTopNode(nodelist)
class BRHeaderTopNode(template.Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context): def render(self, context):
content = self.nodelist.render(context) content = self.nodelist.render(context)
extra_classes = '' return format_html('<div class="header-top">{}</div>', mark_safe(content))
if self.extra_classes_var:
try:
resolved = template.Variable(self.extra_classes_var).resolve(context)
extra_classes = f' {resolved}'
except template.VariableDoesNotExist:
extra_classes = f' {self.extra_classes_var}'
if self.tag_name == "header":
tag_open = f'<header class="{self.default_classes}{extra_classes}">'
tag_inner_container = f'<div class="container-lg">{content}</div>'
search_html = context.get('br_header_search_html', '')
tag_close = '</header>'
return format_html('{}{}{}{}', mark_safe(tag_open), mark_safe(tag_inner_container), mark_safe(search_html), mark_safe(tag_close))
else:
tag_open = f'<{self.tag_name} class="{self.default_classes}{extra_classes}">'
tag_close = f'</{self.tag_name}>'
return format_html('{}{}{}', mark_safe(tag_open), mark_safe(content), mark_safe(tag_close))
def create_simple_block(name, tag_name, default_classes):
def tag_func(parser, token):
bits = token.split_contents()
extra_classes_var = None
if len(bits) > 1: # Tag: br_header_bottom
for bit in bits[1:]: @register.tag(name='br_header_bottom')
if bit.startswith('class='): def do_br_header_bottom(parser, token):
extra_classes_var = bit.split('=')[1].strip('"\'') nodelist = parser.parse(('end_br_header_bottom',))
nodelist = parser.parse(['end_' + name]) parser.delete_first_token()
parser.delete_first_token() return BRHeaderBottomNode(nodelist)
return SimpleBlockNode(nodelist, tag_name, default_classes, extra_classes_var)
register.tag(name, tag_func)
# Header raiz e principais blocos class BRHeaderBottomNode(template.Node):
create_simple_block('br_header', 'header', 'br-header') # Header principal def __init__(self, nodelist):
create_simple_block('br_header_top', 'div', 'header-top') # Bloco superior do header self.nodelist = nodelist
create_simple_block('br_header_bottom', 'div', 'header-bottom') # Bloco inferior do header def render(self, context):
create_simple_block('br_header_list', 'div', 'header') # Lista de itens do header # Renderiza o conteúdo interno primeiro (o br_header_menu)
content = self.nodelist.render(context)
# Pega o HTML da busca que foi colocado no contexto
search_html = context.get('br_header_search_html', '')
# Limpa a variável para não vazar
if 'br_header_search_html' in context:
del context['br_header_search_html']
return format_html(
'<div class="header-bottom">{}{}</div>',
mark_safe(content),
mark_safe(search_html)
)
# ========================= # Tag: br_header_actions
# BLOCO: TAGS DE TÍTULO E SUBTÍTULO @register.tag(name='br_header_actions')
# ========================= def do_br_header_actions(parser, token):
nodelist = parser.parse(('end_br_header_actions',))
parser.delete_first_token()
return BRHeaderActionsNode(nodelist)
class BrListTitleNode(template.Node): class BRHeaderActionsNode(template.Node):
def __init__(self, nodelist, style=None): def __init__(self, nodelist):
self.nodelist = nodelist self.nodelist = nodelist
self.style = style
def render(self, context): def render(self, context):
content = self.nodelist.render(context) content = self.nodelist.render(context)
return format_html('<div class="header-actions">{}</div>', mark_safe(content))
if self.style: # Tag: br_header_login
try: @register.tag(name='br_header_login')
style = template.Variable(self.style).resolve(context) def do_br_header_login(parser, token):
except template.VariableDoesNotExist: nodelist = parser.parse(('end_br_header_login',))
style = self.style.strip('"\'') parser.delete_first_token()
else: return BRHeaderLoginNode(nodelist)
style = ""
return format_html('<div class="title" style="{}">{}</div>', style, mark_safe(content)) class BRHeaderLoginNode(template.Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context):
content = self.nodelist.render(context)
return format_html('<div class="header-login">{}</div>', mark_safe(content))
@register.tag(name='br_list_title') # Tag: br_list
def do_br_list_title(parser, token): @register.tag(name='br_list')
bits = token.split_contents() def do_br_list(parser, token):
style = None nodelist = parser.parse(('end_br_list',))
parser.delete_first_token()
return BRListNode(nodelist)
for bit in bits[1:]: class BRListNode(template.Node):
if bit.startswith("style="): def __init__(self, nodelist):
style = bit.split("=", 1)[1] self.nodelist = nodelist
def render(self, context):
content = self.nodelist.render(context)
return format_html('<div class="br-list">{}</div>', mark_safe(content))
nodelist = parser.parse(('end_br_list_title',)) # =========================
parser.delete_first_token() # BLOCO: LOGO E TÍTULOS
# =========================
return BrListTitleNode(nodelist, style=style) @register.simple_tag(takes_context=True)
def br_header_logo(context, src, alt, signature="", signature_style=""):
logo_html = format_html('<img src="{}" alt="{}" />', resolve_variable(src, context), resolve_variable(alt, context))
if signature:
resolved_signature = resolve_variable(signature, context)
style_attr = ''
if signature_style:
resolved_style = resolve_variable(signature_style, context)
style_attr = format_html(' style="{}"', resolved_style)
return format_html(
'<div class="header-logo">{}<span class="br-divider vertical"></span><div class="header-sign"{}>{}</div></div>',
logo_html, style_attr, resolved_signature
)
return format_html('<div class="header-logo">{}</div>', logo_html)
class BrHeaderTitleNode(template.Node): # --- Tags de Texto Explícitas ---
def __init__(self, nodelist, style):
class TextNode(template.Node):
def __init__(self, nodelist, element, default_class, style):
self.nodelist = nodelist self.nodelist = nodelist
self.element = element
self.default_class = default_class
self.style = style self.style = style
def render(self, context): def render(self, context):
content = self.nodelist.render(context) content = self.nodelist.render(context)
style_attr = f' style="{self.style}"' if self.style else '' style_attr = ''
return mark_safe(f'<div class="header-title"{style_attr}>{content}</div>') if self.style:
resolved_style = resolve_variable(self.style, context)
style_attr = format_html(' style="{}"', resolved_style)
return format_html('<{0} class="{1}"{2}>{3}</{0}>', self.element, self.default_class, style_attr, mark_safe(content))
@register.tag(name='br_header_title') @register.tag(name='br_header_title')
def do_br_header_title(parser, token): def do_br_header_title(parser, token):
bits = token.split_contents() bits = token.split_contents()
style = '' style = None
if len(bits) > 1: if len(bits) > 1 and 'style=' in bits[1]:
for bit in bits[1:]: style = bits[1].split('=', 1)[1]
if bit.startswith('style='):
style = bit.split('=', 1)[1].strip('"\'')
nodelist = parser.parse(('end_br_header_title',)) nodelist = parser.parse(('end_br_header_title',))
parser.delete_first_token() parser.delete_first_token()
return BrHeaderTitleNode(nodelist, style) return TextNode(nodelist, 'div', 'header-title', style)
class BrHeaderSubtitleNode(template.Node):
def __init__(self, nodelist, style):
self.nodelist = nodelist
self.style = style
def render(self, context):
content = self.nodelist.render(context)
style_attr = f' style="{self.style}"' if self.style else ''
return mark_safe(f'<div class="header-subtitle"{style_attr}>{content}</div>')
@register.tag(name='br_header_subtitle') @register.tag(name='br_header_subtitle')
def do_br_header_subtitle(parser, token): def do_br_header_subtitle(parser, token):
bits = token.split_contents() bits = token.split_contents()
style = '' style = None
if len(bits) > 1: if len(bits) > 1 and 'style=' in bits[1]:
for bit in bits[1:]: style = bits[1].split('=', 1)[1]
if bit.startswith('style='):
style = bit.split('=', 1)[1].strip('"\'')
nodelist = parser.parse(('end_br_header_subtitle',)) nodelist = parser.parse(('end_br_header_subtitle',))
parser.delete_first_token() parser.delete_first_token()
return BrHeaderSubtitleNode(nodelist, style) return TextNode(nodelist, 'div', 'header-subtitle', style)
# ========================= @register.tag(name='br_list_header')
# BLOCO: TAGS DE MENU E AÇÕES def do_br_list_header(parser, token):
# ========================= bits = token.split_contents()
style = None
if len(bits) > 1 and 'style=' in bits[1]:
style = bits[1].split('=', 1)[1]
nodelist = parser.parse(('end_br_list_header',))
parser.delete_first_token()
return BRListHeaderNode(nodelist, style)
class BrHeaderMenuNode(template.Node): class BRListHeaderNode(template.Node):
def __init__(self, nodelist, icon_style=''): def __init__(self, nodelist, style):
self.nodelist = nodelist self.nodelist = nodelist
self.icon_style = icon_style self.style = style
def render(self, context): def render(self, context):
content = self.nodelist.render(context) content = self.nodelist.render(context)
style_attr = f' style="{self.icon_style}"' if self.icon_style else '' style_attr = ''
return mark_safe(f''' if self.style:
<div class="header-menu"> resolved_style = resolve_variable(self.style, context)
<div class="header-menu-trigger"> style_attr = format_html(' style="{}"', resolved_style)
<button class="br-button small circle" type="button" aria-label="Menu" data-toggle="menu" data-target="#main-navigation" id="navigation"> return format_html('<div class="header"><div class="title"{}>{}</div></div>', style_attr, mark_safe(content))
<i class="fas fa-bars" aria-hidden="true"{style_attr}></i>
</button> # =========================
</div> # BLOCO: MENU E DROPDOWNS
<div class="header-info"> # =========================
{content}
</div>
</div>
''')
@register.tag(name='br_header_menu') @register.tag(name='br_header_menu')
def do_br_header_menu(parser, token): def do_br_header_menu(parser, token):
bits = token.split_contents() bits = token.split_contents()
icon_style = '' icon_style = None
if len(bits) > 1: if len(bits) > 1 and 'icon_style=' in bits[1]:
for bit in bits[1:]: icon_style = bits[1].split('=', 1)[1]
if bit.startswith('icon_style='):
icon_style = bit.split('=', 1)[1].strip('"\'')
nodelist = parser.parse(('end_br_header_menu',)) nodelist = parser.parse(('end_br_header_menu',))
parser.delete_first_token() parser.delete_first_token()
return BrHeaderMenuNode(nodelist, icon_style) return BRHeaderMenuNode(nodelist, icon_style)
class ActionsNode(template.Node): class BRHeaderMenuNode(template.Node):
def __init__(self, nodelist): def __init__(self, nodelist, icon_style):
self.nodelist = nodelist self.nodelist = nodelist
self.icon_style = icon_style
def render(self, context): def render(self, context):
content = self.nodelist.render(context) content = self.nodelist.render(context)
return format_html('<div class="header-actions">{}</div>', mark_safe(content)) style_attr = ''
if self.icon_style:
@register.tag resolved_style = resolve_variable(self.icon_style, context)
def br_header_actions(parser, token): style_attr = format_html(' style="{}"', resolved_style)
nodelist = parser.parse(['end_br_header_actions'])
parser.delete_first_token()
return ActionsNode(nodelist)
# =========================
# BLOCO: TAGS DE LOGO E AVATAR
# =========================
@register.simple_tag
def br_header_logo(src, alt, signature="", signature_style=""):
"""
Renderiza o logo do header, podendo incluir assinatura customizada.
"""
logo_html = format_html('<img src="{}" alt="{}" />', src, alt)
style_attr = format_html(' style="{}"', signature_style) if signature_style else ''
if signature:
return format_html( return format_html(
'''<div class="header-logo"> '''<div class="header-menu">
{} <div class="header-menu-trigger">
<span class="br-divider vertical"></span> <button class="br-button small circle" type="button" aria-label="Menu" data-toggle="menu" data-target="#main-navigation" id="navigation">
<div class="header-sign"{}>{}</div> <i class="fas fa-bars" aria-hidden="true"{}></i>
</button>
</div>
<div class="header-info">{}</div>
</div>''', </div>''',
logo_html,
style_attr, style_attr,
mark_safe(signature) mark_safe(content)
) )
else:
return format_html('<div class="header-logo">{}</div>', logo_html)
@register.simple_tag
def br_header_avatar(icon=""):
"""
Renderiza o avatar do usuário no header.
"""
return format_html('<div class="header-avatar">{}</div>', mark_safe(icon))
# =========================
# BLOCO: DROPDOWN DE LINKS E FUNÇÕES
# =========================
class DropdownNode(template.Node): class DropdownNode(template.Node):
def __init__(self, nodelist, tag_name, class_name, icon_style): def __init__(self, nodelist, tag_class, icon_class, extra_classes, icon_style):
self.nodelist = nodelist self.nodelist = nodelist
self.tag_name = tag_name self.tag_class = tag_class
self.class_name = class_name self.icon_class = icon_class
self.extra_classes = extra_classes
self.icon_style = icon_style self.icon_style = icon_style
def render(self, context): def render(self, context):
content = self.nodelist.render(context) content = self.nodelist.render(context)
icon_style_attr = f' style="{self.icon_style}"' if self.icon_style else '' aria_label = "Abrir " + self.tag_class.replace('-', ' ').replace('header', '').strip().title()
icon_class = 'fa-ellipsis-v' if 'links' in self.tag_name else 'fa-th' extra_classes_str = f" {resolve_variable(self.extra_classes, context)}" if self.extra_classes else ""
icon_style_attr = ''
if self.icon_style:
resolved_style = resolve_variable(self.icon_style, context)
icon_style_attr = format_html(' style="{}"', resolved_style)
html = format_html(
'''<div class="{0} dropdown{1}">
<button class="br-button circle small" type="button" data-toggle="dropdown" aria-label="{2}">
<i class="fas {3}" aria-hidden="true"{4}></i>
</button>
{5}
</div>''',
self.tag_class, extra_classes_str, aria_label, self.icon_class, icon_style_attr, mark_safe(content)
)
if 'links' in self.tag_class:
html += mark_safe('<span class="br-divider vertical mx-half mx-sm-1"></span>')
return html
html = f''' def create_dropdown_tag(name, tag_class, icon_class):
<div class="{self.tag_name} {self.class_name}"> @register.tag(name=name)
<button class="br-button circle small" type="button" data-toggle="dropdown" aria-label="Abrir {self.tag_name.replace('-', ' ').title()}"> def dropdown_tag_func(parser, token):
<i class="fas {icon_class}" aria-hidden="true"{icon_style_attr}></i>
</button>
<div class="br-list">
{content}
</div>
</div>
'''
if 'links' in self.tag_name:
html += '<span class="br-divider vertical mx-half mx-sm-1"></span>'
return mark_safe(html)
def dropdown_tag(name, tag_class):
def tag_func(parser, token):
bits = token.split_contents() bits = token.split_contents()
class_name = "dropdown" icon_style = None
icon_style = "" extra_classes = None
for bit in bits[1:]: for bit in bits[1:]:
if bit.startswith('class='): if bit.startswith('icon_style='):
class_name = bit.split('=')[1].strip('"\'') icon_style = bit.split('=', 1)[1]
elif bit.startswith('icon_style='): elif bit.startswith('class='):
icon_style = bit.split('=')[1].strip('"\'') extra_classes = bit.split('=', 1)[1]
nodelist = parser.parse((f'end_{name}',))
nodelist = parser.parse([f'end_{name}'])
parser.delete_first_token() parser.delete_first_token()
return DropdownNode(nodelist, tag_class, class_name, icon_style) return DropdownNode(nodelist, tag_class, icon_class, extra_classes, icon_style)
return dropdown_tag_func
register.tag(name, tag_func)
dropdown_tag('br_header_links', 'header-links') # Dropdown de links rápidos create_dropdown_tag('br_header_links', 'header-links', 'fa-ellipsis-v')
dropdown_tag('br_header_functions', 'header-functions') # Dropdown de funcionalidades create_dropdown_tag('br_header_functions', 'header-functions', 'fa-th')
# ========================= # =========================
# BLOCO: ITENS DE LISTA E FUNÇÕES # BLOCO: ITENS DE LISTA
# ========================= # =========================
class ItemNode(template.Node): @register.tag(name='br_header_link_item')
""" def do_br_header_link_item(parser, token):
Renderiza um item de link dentro do header, como os links de acesso rápido. bits = token.split_contents()
""" kwargs = {'href': None, 'extra_classes': None, 'style': None}
def __init__(self, nodelist, href=None, extra_classes=None, style=None): for bit in bits[1:]:
if '=' in bit:
key, value = bit.split('=', 1)
if key in kwargs:
kwargs[key] = value
nodelist = parser.parse(('end_br_header_link_item',))
parser.delete_first_token()
return BRHeaderLinkItemNode(nodelist, **kwargs)
class BRHeaderLinkItemNode(template.Node):
def __init__(self, nodelist, href, extra_classes, style):
self.nodelist = nodelist self.nodelist = nodelist
self.href = href self.href = href
self.extra_classes = extra_classes self.extra_classes = extra_classes
...@@ -287,189 +318,115 @@ class ItemNode(template.Node): ...@@ -287,189 +318,115 @@ class ItemNode(template.Node):
def render(self, context): def render(self, context):
content = self.nodelist.render(context) content = self.nodelist.render(context)
resolved_href = resolve_variable(self.href, context) or '#'
# Resolve href extra_classes_str = f" {resolve_variable(self.extra_classes, context)}" if self.extra_classes else ""
if self.href: style_attr = ''
try:
href = template.Variable(self.href).resolve(context)
except template.VariableDoesNotExist:
href = self.href.strip('"\'')
else:
href = "#"
# Resolve extra_classes
if self.extra_classes:
try:
extra_classes = template.Variable(self.extra_classes).resolve(context)
except template.VariableDoesNotExist:
extra_classes = self.extra_classes.strip('"\'')
else:
extra_classes = ''
# Resolve style
if self.style: if self.style:
try: resolved_style = resolve_variable(self.style, context)
style = template.Variable(self.style).resolve(context) style_attr = format_html(' style="{}"', resolved_style)
except template.VariableDoesNotExist:
style = self.style.strip('"\'')
else:
style = ''
return format_html( return format_html(
'<a class="br-item {}" href="{}" style="{}">{}</a>', '<a class="br-item{}" href="{}"{}>{}</a>',
extra_classes, href, style, mark_safe(content) extra_classes_str, resolved_href, style_attr, mark_safe(content)
) )
@register.tag @register.tag(name='br_function_item')
def br_item(parser, token): def do_br_function_item(parser, token):
"""
Tag para criar um item de link no header.
"""
bits = token.split_contents() bits = token.split_contents()
tag_name = bits[0] kwargs = {'icon_class': None, 'label': None, 'aria_label': None, 'extra_classes': None, 'icon_style': None, 'label_style': None}
href = None
extra_classes = None
style = None
for bit in bits[1:]: for bit in bits[1:]:
if bit.startswith("href="): if '=' in bit:
href = bit.split("=", 1)[1] key, value = bit.split('=', 1)
elif bit.startswith("extra_classes="): if key in kwargs:
extra_classes = bit.split("=", 1)[1] kwargs[key] = value
elif bit.startswith("style="): return BRFunctionItemNode(**kwargs)
style = bit.split("=", 1)[1]
nodelist = parser.parse(['end_br_item'])
parser.delete_first_token()
return ItemNode(nodelist, href=href, extra_classes=extra_classes, style=style)
class BrFunctionItemNode(template.Node): class BRFunctionItemNode(template.Node):
""" def __init__(self, icon_class, label, aria_label, extra_classes, icon_style, label_style):
Renderiza um item de funcionalidade no header, geralmente com ícone e label.
"""
def __init__(self, icon_class, extra_classes=None, icon_style=None, label=None, label_style=None, aria_label=None):
self.icon_class = icon_class self.icon_class = icon_class
self.label = label
self.aria_label = aria_label
self.extra_classes = extra_classes self.extra_classes = extra_classes
self.icon_style = icon_style self.icon_style = icon_style
self.label = label
self.label_style = label_style self.label_style = label_style
self.aria_label = aria_label
def render(self, context): def render(self, context):
def resolve(value): resolved_label = resolve_variable(self.label, context)
if value is None: resolved_aria_label = resolve_variable(self.aria_label, context) or resolved_label
return '' extra_classes_str = f" {resolve_variable(self.extra_classes, context)}" if self.extra_classes else ""
try: icon_style_attr = ''
return template.Variable(value).resolve(context) if self.icon_style:
except template.VariableDoesNotExist: resolved_style = resolve_variable(self.icon_style, context)
return value.strip('"\'') icon_style_attr = format_html(' style="{}"', resolved_style)
label_style_attr = ''
icon_class = resolve(self.icon_class) if self.label_style:
extra_classes = resolve(self.extra_classes) resolved_style = resolve_variable(self.label_style, context)
icon_style = resolve(self.icon_style) label_style_attr = format_html(' style="{}"', resolved_style)
label = resolve(self.label)
label_style = resolve(self.label_style)
aria_label = resolve(self.aria_label) or label
return format_html( return format_html(
'''<div class="br-item {0}"> '''<div class="br-item{}">
<button class="br-button circle small" type="button" aria-label="{5}"> <button class="br-button circle small" type="button" aria-label="{}">
<i class="fas {1}" aria-hidden="true" style="{2}"></i> <i class="fas {}" aria-hidden="true"{}></i><span class="text"{}>{}</span>
<span class="text" style="{4}">{3}</span>
</button> </button>
</div>''', </div>''',
extra_classes, icon_class, icon_style, label, label_style, aria_label extra_classes_str, resolved_aria_label, resolve_variable(self.icon_class, context),
icon_style_attr, label_style_attr, resolved_label
) )
@register.tag(name='br_function_item')
def do_br_function_item(parser, token):
bits = token.split_contents()
tag_name = bits[0]
kwargs = {
'icon_class': None,
'extra_classes': None,
'icon_style': None,
'label': None,
'label_style': None,
'aria_label': None,
}
for bit in bits[1:]:
if '=' in bit:
key, value = bit.split('=', 1)
if key in kwargs:
kwargs[key] = value
return BrFunctionItemNode(**kwargs)
# ========================= # =========================
# BLOCO: TAGS DE BUSCA E LOGIN # BLOCO: BUSCA E LOGIN
# ========================= # =========================
@register.simple_tag @register.simple_tag(takes_context=True)
def br_header_search_trigger(icon_style=""): def br_header_search(context, placeholder="O que você procura?", icon_style=""):
""" icon_style_attr = ''
Botão para abrir a busca no header. if icon_style:
""" resolved_style = resolve_variable(icon_style, context)
icon_style_attr = f' style="{icon_style}"' if icon_style else "" icon_style_attr = format_html(' style="{}"', resolved_style)
return mark_safe(f''' search_html = format_html(
<div class="header-search-trigger"> '''<div class="header-search">
<button class="br-button circle" type="button" aria-label="Abrir Busca" data-toggle="search" data-target=".header-search"> <div class="br-input has-icon">
<i class="fas fa-search" aria-hidden="true"{icon_style_attr}></i> <label for="searchbox-header">Texto da pesquisa</label>
</button> <input id="searchbox-header" type="text" placeholder="{}"/>
</div> <button class="br-button circle small" type="button" aria-label="Pesquisar">
''') <i class="fas fa-search" aria-hidden="true"></i>
</button>
@register.simple_tag </div>
def br_header_login(): <button class="br-button circle search-close ml-1" type="button" aria-label="Fechar Busca" data-dismiss="search">
""" <i class="fas fa-times" aria-hidden="true"{}></i>
Início do bloco de login no header. </button>
""" </div>''',
return mark_safe('<div class="header-login">') resolve_variable(placeholder, context),
icon_style_attr
@register.simple_tag )
def end_br_header_login(): # A lógica continua a mesma: popular o contexto.
""" context['br_header_search_html'] = search_html
Fim do bloco de login no header. return ''
"""
return mark_safe('</div>') @register.simple_tag(takes_context=True)
def br_header_search_trigger(context, icon_style=""):
icon_style_attr = ''
if icon_style:
resolved_style = resolve_variable(icon_style, context)
icon_style_attr = format_html(' style="{}"', resolved_style)
return mark_safe(
f'''<div class="header-search-trigger">
<button class="br-button circle" type="button" aria-label="Abrir Busca" data-toggle="search" data-target=".header-search">
<i class="fas fa-search" aria-hidden="true"{icon_style_attr}></i>
</button>
</div>'''
)
@register.simple_tag @register.simple_tag
def br_button(): def br_header_signin_button():
""" return mark_safe(
Botão de login padrão. '''<div class="header-sign-in">
""" <button class="br-sign-in small" type="button" data-trigger="login">
return mark_safe(''' <i class="fas fa-user" aria-hidden="true"></i><span class="d-sm-inline">Entrar</span>
<div class="header-sign-in"> </button>
<button class="br-sign-in small" type="button" data-trigger="login"> </div>'''
<i class="fas fa-user" aria-hidden="true"></i> )
<span class="d-sm-inline">Entrar</span>
</button>
</div>
''')
@register.simple_tag @register.simple_tag
def br_header_search(placeholder="", icon_style=""): def br_header_avatar():
""" return mark_safe('<div class="header-avatar"></div>')
Campo de busca do header.
"""
icon_style_attr = f' style="{icon_style}"' if icon_style else ""
return mark_safe(f'''
<div class="header-search">
<div class="br-input has-icon">
<label for="searchbox-114">Texto da pesquisa</label>
<input id="searchbox-114" type="text" placeholder="{placeholder}"/>
<button class="br-button circle small" type="button" aria-label="Pesquisar">
<i class="fas fa-search" aria-hidden="true"></i>
</button>
</div>
<button class="br-button circle search-close ml-1" type="button" aria-label="Fechar Busca" data-dismiss="search">
<i class="fas fa-times" aria-hidden="true"{icon_style_attr}></i>
</button>
</div>
''')
from django import template
from django.utils.safestring import mark_safe
from django.utils.html import format_html
from django.template.base import token_kwargs
register = template.Library()
@register.tag(name='br_menu_row')
def do_br_menu_row(parser, token):
nodelist = parser.parse(('end_br_menu_row',))
parser.delete_first_token()
return BRMenuRowNode(nodelist)
class BRMenuRowNode(template.Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context):
content = self.nodelist.render(context)
return format_html('<div class="row">{}</div>', mark_safe(content))
@register.tag(name='br_menu')
def do_br_menu(parser, token):
nodelist = parser.parse(('end_br_menu',))
parser.delete_first_token()
return BRMenuNode(nodelist)
class BRMenuNode(template.Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context):
content = self.nodelist.render(context)
return format_html("""
<div class="br-menu" id="main-navigation">
<div class="menu-container">
<div class="menu-panel">{}</div>
<div class="menu-scrim" data-dismiss="menu" tabindex="0"></div>
</div>
</div>
""",
content
)
@register.tag(name='br_menu_header')
def do_br_menu_header(parser, token):
nodelist = parser.parse(('end_br_menu_header',))
parser.delete_first_token()
return BRMenuHeaderNode(nodelist)
class BRMenuHeaderNode(template.Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context):
content = self.nodelist.render(context)
return mark_safe(f'''
<div class="menu-header">
{content}
<div class="menu-close">
<button class="br-button circle" type="button" aria-label="Fechar o menu" data-dismiss="menu">
<i class="fas fa-times" aria-hidden="true"></i>
</button>
</div>
</div>
''')
@register.simple_tag(name='br_menu_header_logo')
def br_menu_header_logo(src):
return mark_safe(f'<img src="{src}" alt="Imagem ilustrativa"/>')
class BrMenuTitleNode(template.Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context):
content = self.nodelist.render(context)
return format_html('<div class="menu-title">{}</div>', content)
@register.tag
def br_menu_title(parser, token):
nodelist = parser.parse(['end_br_menu_title'])
parser.delete_first_token()
return BrMenuTitleNode(nodelist)
class BrMenuTitleLogoNode(template.Node):
def __init__(self, src_expr=None, alt_expr=None):
self.src_expr = src_expr
self.alt_expr = alt_expr
def render(self, context):
src = "data:image/png;"
alt = "Imagem ilustrativa"
try:
if self.src_expr:
src_resolved = self.src_expr.resolve(context)
if src_resolved:
src = src_resolved
except template.VariableDoesNotExist:
pass
try:
if self.alt_expr:
alt_resolved = self.alt_expr.resolve(context)
if alt_resolved:
alt = alt_resolved
except template.VariableDoesNotExist:
pass
return format_html('<img src="{}" alt="{}"/>', src, alt)
class BrMenuTitleTextNode(template.Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context):
content = self.nodelist.render(context)
return format_html('<span>{}</span>', content)
@register.tag
def br_menu_title_text(parser, token):
nodelist = parser.parse(['end_br_menu_title_text'])
parser.delete_first_token()
return BrMenuTitleTextNode(nodelist)
@register.tag
def br_menu_title_logo(parser, token):
bits = token.split_contents()
src_expr = None
alt_expr = None
for bit in bits[1:]:
if bit.startswith("src="):
src_expr = parser.compile_filter(bit.split("=", 1)[1])
elif bit.startswith("alt="):
alt_expr = parser.compile_filter(bit.split("=", 1)[1])
return BrMenuTitleLogoNode(src_expr, alt_expr)
@register.tag(name='br_menu_body')
def do_br_menu_body(parser, token):
nodelist = parser.parse(('end_br_menu_body',))
parser.delete_first_token()
return BRMenuBodyNode(nodelist)
class BRMenuBodyNode(template.Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context):
content = self.nodelist.render(context)
return mark_safe(f'<nav class="menu-body" role="tree">{content}</nav>')
@register.tag(name='br_menu_folder')
def do_br_menu_folder(parser, token):
nodelist = parser.parse(('end_br_menu_folder',))
parser.delete_first_token()
return BRMenuFolderNode(nodelist)
class BRMenuFolderNode(template.Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context):
content = self.nodelist.render(context)
return mark_safe(f'<div class="menu-folder">{content}</div>')
@register.tag(name='br_menu_item')
def do_br_menu_item(parser, token):
bits = token.split_contents()
tag_name = bits[0]
kwargs = {}
for bit in bits[1:]:
try:
name, value = bit.split('=')
kwargs[name] = value.strip('"\'')
except ValueError:
raise template.TemplateSyntaxError(f"Argumento inválido em {tag_name}: {bit}")
href = kwargs.get('href')
icon = kwargs.get('icone', '')
if not href:
raise template.TemplateSyntaxError(f"'{tag_name}' requer o argumento 'href'")
nodelist = parser.parse(('end_br_menu_item',))
parser.delete_first_token()
return BRMenuItemNode(nodelist, href, icon)
class BRMenuItemNode(template.Node):
def __init__(self, nodelist, href, icon):
self.nodelist = nodelist
self.href = href
self.icon = icon
def render(self, context):
# Resolve `href`
try:
href = template.Variable(self.href).resolve(context)
except template.VariableDoesNotExist:
href = self.href
# Resolve `icon`
try:
icon = template.Variable(self.icon).resolve(context)
except template.VariableDoesNotExist:
icon = self.icon
content = self.nodelist.render(context)
icon_html = ''
if icon:
icon_html = format_html(
'<span class="icon"><i class="{}" aria-hidden="true"></i></span>',
icon
)
return format_html(
'<a class="menu-item" href="{}" role="treeitem">{}<span class="content">{}</span></a>',
href,
mark_safe(icon_html),
content
)
@register.tag(name='br_menu_divider_item')
def do_br_menu_divider_item(parser, token):
try:
bits = token.split_contents()
tag_name = bits[0]
kwargs = token_kwargs(bits[1:], parser)
href = kwargs.get('href', '"javascript: void(0)"')
icon = kwargs.get('icone', '""')
except Exception as e:
raise template.TemplateSyntaxError(f"Erro na tag {tag_name}: {str(e)}")
nodelist = parser.parse(('end_br_menu_divider_item',))
parser.delete_first_token()
return BRMenuDividerItemNode(nodelist, href, icon)
class BRMenuDividerItemNode(template.Node):
def __init__(self, nodelist, href, icon):
self.nodelist = nodelist
self.href = href
self.icon = icon
def render(self, context):
href = self.href.resolve(context) if self.href else "javascript: void(0)"
icon = self.icon.resolve(context) if self.icon else ""
content = self.nodelist.render(context).strip()
icon_html = ''
if icon:
icon_html = format_html(
'<span class="icon"><i class="{}" aria-hidden="true"></i></span>', icon
)
return format_html(
'<a class="menu-item divider" href="{}" role="treeitem">{}{}</a>',
href,
mark_safe(icon_html),
format_html('<span class="content">{}</span>', content)
)
@register.tag(name='br_menu_footer')
def do_br_menu_footer(parser, token):
nodelist = parser.parse(('end_br_menu_footer',))
parser.delete_first_token()
return BRMenuFooterNode(nodelist)
class BRMenuFooterNode(template.Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context):
content = self.nodelist.render(context)
return mark_safe(f'''
<div class="menu-footer">
{content}
<div class="menu-info">
<div class="text-center text-down-01">Todo o conteúdo deste site está publicado sob a licença <strong>Creative Commons Atribuição-SemDerivações 3.0</strong></div>
</div>
</div>
''')
class BRMenuFooterLogosNode(template.Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context):
content = self.nodelist.render(context).strip()
return format_html('<div class="menu-logos">{}</div>', mark_safe(content))
@register.tag(name='br_menu_footer_logos')
def do_br_menu_footer_logos(parser, token):
nodelist = parser.parse(('end_br_menu_footer_logos',))
parser.delete_first_token()
return BRMenuFooterLogosNode(nodelist)
class BRMenuLogoNode(template.Node):
def __init__(self, src_expr, alt_expr):
self.src_expr = src_expr
self.alt_expr = alt_expr or template.FilterExpression('"Imagem ilustrativa"', parser=None)
def render(self, context):
try:
src = self.src_expr.resolve(context)
except template.VariableDoesNotExist:
src = "data:image/png;base64"
try:
alt = self.alt_expr.resolve(context)
except template.VariableDoesNotExist:
alt = "Imagem ilustrativa"
return format_html('<img src="{}" alt="{}"/>', src, alt)
@register.tag(name='br_menu_logo')
def do_br_menu_logo(parser, token):
bits = token.split_contents()
src_expr = None
alt_expr = None
for bit in bits[1:]:
if bit.startswith("src="):
src_expr = parser.compile_filter(bit.split("=", 1)[1])
elif bit.startswith("alt="):
alt_expr = parser.compile_filter(bit.split("=", 1)[1])
if src_expr is None:
raise template.TemplateSyntaxError("A tag 'br_menu_logo' requer o argumento 'src'.")
return BRMenuLogoNode(src_expr, alt_expr)
@register.tag(name="br_menu_links")
def do_br_menu_links(parser, token):
nodelist = parser.parse(("end_br_menu_links",))
parser.delete_first_token()
return BRMenuLinksNode(nodelist)
class BRMenuLinksNode(template.Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context):
content = self.nodelist.render(context).strip()
return format_html('<div class="menu-links">{}</div>', mark_safe(content))
@register.tag(name="br_menu_link")
def do_br_menu_link(parser, token):
bits = token.split_contents()
href_expr = None
icon_expr = None
for bit in bits[1:]:
if bit.startswith("href="):
href_expr = parser.compile_filter(bit.split("=", 1)[1])
elif bit.startswith("icone=") or bit.startswith("icon="):
icon_expr = parser.compile_filter(bit.split("=", 1)[1])
nodelist = parser.parse(("end_br_menu_link",))
parser.delete_first_token()
return BRMenuLinkNode(nodelist, href_expr, icon_expr)
class BRMenuLinkNode(template.Node):
def __init__(self, nodelist, href_expr=None, icon_expr=None):
self.nodelist = nodelist
self.href_expr = href_expr
self.icon_expr = icon_expr
def render(self, context):
content = self.nodelist.render(context).strip()
href = "javascript: void(0)"
icon_class = "fas fa-external-link-square-alt"
if self.href_expr:
try:
href = self.href_expr.resolve(context)
except template.VariableDoesNotExist:
pass
if self.icon_expr:
try:
icon_class = self.icon_expr.resolve(context)
except template.VariableDoesNotExist:
pass
return format_html(
'<a href="{}"><span class="mr-1">{}</span><i class="{}" aria-hidden="true"></i></a>',
href, content, icon_class
)
@register.tag(name='br_menu_social_network')
def do_br_menu_social_network(parser, token):
nodelist = parser.parse(('end_br_menu_social_network',))
parser.delete_first_token()
return BRMenuSocialNetworkNode(nodelist)
class BRMenuSocialNetworkNode(template.Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context):
content = self.nodelist.render(context)
return mark_safe(f'''
<div class="social-network">
{content}
</div>
''')
@register.tag(name='br_menu_social_network_title')
def do_br_menu_social_network_title(parser, token):
nodelist = parser.parse(('end_br_menu_social_network_title',))
parser.delete_first_token()
return BRMenuSocialNetworkTitleNode(nodelist)
class BRMenuSocialNetworkTitleNode(template.Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context):
content = self.nodelist.render(context)
return mark_safe(f'<div class="social-network-title">{content}</div>')
@register.simple_tag(name='br_menu_social_network_icons', takes_context=True)
def br_menu_social_network_icons(context, href, icon, extra_classes=""):
# Remove aspas se for um valor literal
href = href.strip('"\'')
# Tenta resolver como variável de contexto se estiver entre {{ }}
if href.startswith('{{') and href.endswith('}}'):
var_name = href[2:-2].strip()
try:
href = template.Variable(var_name).resolve(context)
except template.VariableDoesNotExist:
href = var_name
return mark_safe(f'''
<a class="br-button circle {extra_classes}" href="{href}" aria-label="Compartilhar por {icon}">
<i class="{icon}" aria-hidden="true"></i>
</a>
''')
class BrMenuToggleNode(template.Node):
def __init__(self, label_expr=None, target_expr=None):
self.label_expr = label_expr
self.target_expr = target_expr
def render(self, context):
label = "Menu"
target = "#main-navigation"
if self.label_expr:
try:
resolved_label = self.label_expr.resolve(context)
if resolved_label:
label = resolved_label
except template.VariableDoesNotExist:
pass
if self.target_expr:
try:
resolved_target = self.target_expr.resolve(context)
if resolved_target:
target = resolved_target
except template.VariableDoesNotExist:
pass
return format_html(
"""
<div class="col">
<div class="d-flex align-items-center">
<div>
<button class="br-button small circle" type="button" aria-label="Menu" data-toggle="menu" data-target="{}">
<i class="fas fa-bars" aria-hidden="true"></i>
</button>
</div>
<div class="ml-3">{}</div>
</div>
</div>
""",
target, label
)
@register.tag
def br_menu_toggle(parser, token):
bits = token.split_contents()
label_expr = None
target_expr = None
for bit in bits[1:]:
if bit.startswith("label="):
label_expr = parser.compile_filter(bit.split("=", 1)[1])
elif bit.startswith("target="):
target_expr = parser.compile_filter(bit.split("=", 1)[1])
return BrMenuToggleNode(label_expr, target_expr)
...@@ -9,7 +9,8 @@ dependencies = [ ...@@ -9,7 +9,8 @@ dependencies = [
"django==5.2.3", "django==5.2.3",
] ]
description = "Um App Django app para dispobilizar o Design System gov.br para projeto django." description = "Um App Django app para dispobilizar o Design System gov.br para projeto django."
readme = "README.rst" readme = "README.md"
license = "MIT AND (Apache-2.0 OR BSD-2-Clause)"
requires-python = ">= 3.10" requires-python = ">= 3.10"
authors = [ authors = [
{name = "Lucas Gueiros", email = "lucas.dgueiros@ufrpe.br"}, {name = "Lucas Gueiros", email = "lucas.dgueiros@ufrpe.br"},
...@@ -20,7 +21,6 @@ classifiers = [ ...@@ -20,7 +21,6 @@ classifiers = [
"Framework :: Django", "Framework :: Django",
"Framework :: Django :: 5.2.3", "Framework :: Django :: 5.2.3",
"Intended Audience :: Developers", "Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent", "Operating System :: OS Independent",
"Programming Language :: Python", "Programming Language :: Python",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
......
...@@ -23,44 +23,49 @@ ...@@ -23,44 +23,49 @@
{# HEADER 1: Header padrão, fundo claro, sem customização de cor #} {# HEADER 1: Header padrão, fundo claro, sem customização de cor #}
<li class="mb-4">Esse primeiro header usa o tamanho padrão e o fundo branco, que são as configurações originais do componente.</li> <li class="mb-4">Esse primeiro header usa o tamanho padrão e o fundo branco, que são as configurações originais do componente.</li>
{% br_header %} {% br_header %}
{# Bloco Superior: Logo, Ações, Links, Funções, Busca e Login #}
{% br_header_top %} {% br_header_top %}
{% br_header_logo src="https://cdngovbr-ds.estaleiro.serpro.gov.br/design-system/images/logo-positive.png" alt="logo" signature="Assinatura" %} {% br_header_logo src="https://cdngovbr-ds.estaleiro.serpro.gov.br/design-system/images/logo-positive.png" alt="logo" signature="Assinatura" %}
{% br_header_actions %} {% br_header_actions %}
{% br_header_links %} {% br_header_links %}
{% br_header_list %} {% br_list %}
{% br_list_title %}Acesso Rápido{% end_br_list_title %} {% br_list_header %}Acesso Rápido{% end_br_list_header %}
{% end_br_header_list %} {% br_header_link_item href="#" %}Link de acesso 1{% end_br_header_link_item %}
{% br_item href="#" %}Link de acesso 1{% end_br_item %} {% br_header_link_item href="#" %}Link de acesso 2{% end_br_header_link_item %}
{% br_item href="#" %}Link de acesso 2{% end_br_item %} {% br_header_link_item href="#" %}Link de acesso 3{% end_br_header_link_item %}
{% br_item href="#" %}Link de acesso 3{% end_br_item %} {% end_br_list %}
{% br_item href="#" %}Link de acesso 4{% end_br_item %}
{% end_br_header_links %} {% end_br_header_links %}
{% br_header_functions %} {% br_header_functions %}
{% br_header_list %} {% br_list %}
{% br_list_title %}Funcionalidades do Sistema{% end_br_list_title %} {% br_list_header %}Funcionalidades do Sistema{% end_br_list_header %}
{% end_br_header_list %} {% br_function_item icon_class="fa-chart-bar" label="Funcionalidade 1" %}
{% br_function_item icon_class="fa-chart-bar" label="Funcionalidade 1" aria_label="Acessível" %} {% br_function_item icon_class="fa-headset" label="Funcionalidade 2" %}
{% br_function_item icon_class="fa-headset" label="Funcionalidade 2" aria_label="Acessível" %} {% br_function_item icon_class="fa-comment" label="Funcionalidade 3" %}
{% br_function_item icon_class="fa-comment" label="Funcionalidade 3" aria_label="Acessível" %} {% br_function_item icon_class="fa-adjust" label="Funcionalidade 4" %}
{% br_function_item icon_class="fa-adjust" label="Funcionalidade 4" aria_label="Acessível" %} {% end_br_list %}
{% end_br_header_functions %} {% end_br_header_functions %}
{% br_header_search_trigger %} {% br_header_search_trigger %}
{% br_header_login %} {% br_header_login %}
{% br_button %} {% br_header_signin_button %}
{% br_header_avatar %} {% br_header_avatar %}
{% end_br_header_login %} {% end_br_header_login %}
{% end_br_header_actions %} {% end_br_header_actions %}
{% end_br_header_top %} {% end_br_header_top %}
{# Bloco Inferior: Menu principal e Título #}
{% br_header_bottom %} {% br_header_bottom %}
{% br_header_menu %} {% br_header_menu %}
{% br_header_title %}Título do Header{% end_br_header_title %} {% br_header_title %}Título do Header{% end_br_header_title %}
{% br_header_subtitle %}Subtítulo do Header{% end_br_header_subtitle %} {% br_header_subtitle %}Subtítulo do Header{% end_br_header_subtitle %}
{% end_br_header_menu %} {% end_br_header_menu %}
{# Mova a tag de busca para DENTRO do header_bottom #}
{% br_header_search placeholder="O que você procura?" %} {% br_header_search placeholder="O que você procura?" %}
{% end_br_header_bottom %} {% end_br_header_bottom %}
{% end_br_header %} {% end_br_header %}
...@@ -70,46 +75,52 @@ ...@@ -70,46 +75,52 @@
{# HEADER 2: Header customizado, fundo azul escuro, textos e ícones brancos, usando classes e estilos extras #} {# HEADER 2: Header customizado, fundo azul escuro, textos e ícones brancos, usando classes e estilos extras #}
<li>Esse segundo header é o header customizado, com fundo azul escuro e textos e ícones brancos. Ele usa classes e estilos extras para personalização.</p> <li>Esse segundo header é o header customizado, com fundo azul escuro e textos e ícones brancos. Ele usa classes e estilos extras para personalização.</p>
{% br_header class="bg-blue-warm-vivid-90" %} {% br_header class="bg-blue-warm-vivid-90" %}
{% br_header_top %} {# Bloco Superior: Logo, Ações, Links, Funções, Busca e Login #}
{% br_header_logo src="https://cdngovbr-ds.estaleiro.serpro.gov.br/design-system/images/logo-negative.png" alt="logo" signature="Assinatura" signature_style="color: white;" %} {% br_header_top %}
{% br_header_logo src="https://cdngovbr-ds.estaleiro.serpro.gov.br/design-system/images/logo-negative.png" alt="logo" signature="Assinatura" signature_style="color: white;" %}
{% br_header_actions %}
{% br_header_links icon_style="color: white;" %} {% br_header_actions %}
{% br_header_list %} {% br_header_links icon_style="color: white;" %}
{% br_list_title style="color: white;" %}Acesso Rápido{% end_br_list_title %} {# ESTRUTURA CORRIGIDA: br_list agora envolve o header e os itens #}
{% end_br_header_list %} {% br_list %}
{% br_item href="#" extra_classes="bg-blue-warm-vivid-90" style="color: white;" %}Link de acesso 1{% end_br_item %} {% br_list_header style="color: white;" %}Acesso Rápido{% end_br_list_header %}
{% br_item href="#" extra_classes="bg-blue-warm-vivid-90" style="color: white;" %}Link de acesso 2{% end_br_item %} {% br_header_link_item href="#" extra_classes="bg-blue-warm-vivid-90" style="color: white;" %}Link de acesso 1{% end_br_header_link_item %}
{% br_item href="#" extra_classes="bg-blue-warm-vivid-90" style="color: white;" %}Link de acesso 3{% end_br_item %} {% br_header_link_item href="#" extra_classes="bg-blue-warm-vivid-90" style="color: white;" %}Link de acesso 2{% end_br_header_link_item %}
{% br_item href="#" extra_classes="bg-blue-warm-vivid-90" style="color: white;" %}Link de acesso 4{% end_br_item %} {% br_header_link_item href="#" extra_classes="bg-blue-warm-vivid-90" style="color: white;" %}Link de acesso 3{% end_br_header_link_item %}
{% end_br_header_links %} {% br_header_link_item href="#" extra_classes="bg-blue-warm-vivid-90" style="color: white;" %}Link de acesso 4{% end_br_header_link_item %}
{% end_br_list %}
{% br_header_functions icon_style="color: white;" %} {% end_br_header_links %}
{% br_header_list %}
{% br_list_title style="color: white;" %}Funcionalidades do Sistema{% end_br_list_title %} {% br_header_functions icon_style="color: white;" %}
{% end_br_header_list %} {# ESTRUTURA CORRIGIDA: br_list agora envolve o header e os itens #}
{% br_function_item icon_class="fa-chart-bar" extra_classes="bg-blue-warm-vivid-90" icon_style="color: white;" label="Funcionalidade 1" label_style="color: white;" aria_label="Acessível" %} {% br_list %}
{% br_function_item icon_class="fa-headset" extra_classes="bg-blue-warm-vivid-90" icon_style="color: white;" label="Funcionalidade 2" label_style="color: white;" aria_label="Acessível" %} {% br_list_header style="color: white;" %}Funcionalidades do Sistema{% end_br_list_header %}
{% br_function_item icon_class="fa-comment" extra_classes="bg-blue-warm-vivid-90" icon_style="color: white;" label="Funcionalidade 3" label_style="color: white;" aria_label="Acessível" %} {% br_function_item icon_class="fa-chart-bar" extra_classes="bg-blue-warm-vivid-90" icon_style="color: white;" label="Funcionalidade 1" label_style="color: white;" aria_label="Acessível" %}
{% br_function_item icon_class="fa-adjust" extra_classes="bg-blue-warm-vivid-90" icon_style="color: white;" label="Funcionalidade 4" label_style="color: white;" aria_label="Acessível" %} {% br_function_item icon_class="fa-headset" extra_classes="bg-blue-warm-vivid-90" icon_style="color: white;" label="Funcionalidade 2" label_style="color: white;" aria_label="Acessível" %}
{% end_br_header_functions %} {% br_function_item icon_class="fa-comment" extra_classes="bg-blue-warm-vivid-90" icon_style="color: white;" label="Funcionalidade 3" label_style="color: white;" aria_label="Acessível" %}
{% br_function_item icon_class="fa-adjust" extra_classes="bg-blue-warm-vivid-90" icon_style="color: white;" label="Funcionalidade 4" label_style="color: white;" aria_label="Acessível" %}
{% br_header_search_trigger icon_style="color: white;" %} {% end_br_list %}
{% br_header_login %} {% end_br_header_functions %}
{% br_button %}
{% br_header_avatar %} {% br_header_search_trigger icon_style="color: white;" %}
{% end_br_header_login %}
{% end_br_header_actions %} {% br_header_login %}
{% end_br_header_top %} {% br_header_signin_button %}
{% br_header_avatar %}
{% br_header_bottom %} {% end_br_header_login %}
{% br_header_menu icon_style="color: white;" %} {% end_br_header_actions %}
{% br_header_title style="color: white;" %}Título do Header{% end_br_header_title %} {% end_br_header_top %}
{% br_header_subtitle style="color: white;" %}Subtítulo do Header{% end_br_header_subtitle %}
{% end_br_header_menu %} {# Bloco Inferior: Agora contém o menu E a chamada da busca #}
{% br_header_search placeholder="O que você procura?" icon_style="color: white;" %} {% br_header_bottom %}
{% end_br_header_bottom %} {% br_header_menu icon_style="color: white;" %}
{% end_br_header %} {% br_header_title style="color: white;" %}Título do Header{% end_br_header_title %}
{% br_header_subtitle style="color: white;" %}Subtítulo do Header{% end_br_header_subtitle %}
{% end_br_header_menu %}
{% br_header_search placeholder="O que você procura?" icon_style="color: white;" %}
{% end_br_header_bottom %}
{% end_br_header %}
<br><br><br><br> <br><br><br><br>
......
{% extends "dsgov/base.html" %} {% extends "dsgov/base.html" %}
{% load br_components %} {% load br_menu_tags %}
{% load static %} {% load static %}
{% block title %} {% block title %}
...@@ -7,7 +7,51 @@ ...@@ -7,7 +7,51 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="container"> {% br_menu_row %}
{% br_menu %} {% br_menu %}
</div> {% br_menu_header %}
{% br_menu_title %}
{% br_menu_title_logo src="data:image/png;base64,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" alt="Imagem Ilustrativa" %}
{% br_menu_title_text %}Identificação do site ou Sistema{% end_br_menu_title_text %}
{% end_br_menu_title %}
{% end_br_menu_header %}
{% br_menu_body %}
{% br_menu_folder %}
{% br_menu_item href="javascript: void(0)" icone="fas fa-bell" %}Camada 1{% end_br_menu_item %}
{% br_menu_item href="javascript: void(0)" icone="fas fa-bell" %}Camada 2{% end_br_menu_item %}
{% br_menu_item href="javascript: void(0)" icone="fas fa-bell" %}Camada 3{% end_br_menu_item %}
{% end_br_menu_folder %}
{% br_menu_divider_item href="javascript: void(0)" icone="fas fa-bell" %}
Item de Camada 1
{% end_br_menu_divider_item %}
{% br_menu_divider_item href="javascript: void(0)" icone="fas fa-bell" %}
Item de Camada 1
{% end_br_menu_divider_item %}
{% end_br_menu_body %}
{% br_menu_footer %}
{% br_menu_footer_logos %}
{% br_menu_logo src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMwAAABgCAYAAABR/J1nAAAAAXNSR0IArs4c6QAADK1JREFUeAHtXX+MHFUd/77Z3dlWaAFpr/Rut1o1BgEJig2Weu0uLWIi1NIUTeAPDKIBsQ2xJYZEbFNioijRoGmjTcBYDL9SFGlFTGmvPyggVlRoQKKk9H7U0mKrLdKZu93n5+3dm5s9Zmd372bnZma/k8y+N+/XvO/nvc9834/vzohsvijJ47B6dwqPYOL0w6gwPsM4tEt/0HIaXqTgMEaAEfBGwFOLeCflUEagfRFgDdO+bc+STwABHpJNADzO2n4IMGHar81Z4okgoMZmenw2kXI4LyPQDgiwhmmHVmYZA0OACRMYlFxQOyDAhGmHVmYZA0OACRMYlFxQOyDAhGmHVmYZA0OAd/oDg5ILSjICeiWZNUySW5llCxwBJkzgkHKBSUaACZPk1mXZAkeACRM4pFxgkhFgwiS5dVm24BFgW7LgMeUSk4sAa5jkti1L1gIEmDAtAJWLTC4CTJjkti1L1gIEmDAtAJWLTC4CTJjkti1L1gIE2JasBaBykclDgG3JktemLFEICPCQLASQ+RbJQYAJk5y2ZElCQIAJEwLIfIvkIJBulSjZruLnSciVksSnhKBzW3WfIMuVkt5GXfdTme6z+nduC7JsLisZCAg9+6/1NvrxiJnpKvzQMMTq8eSNSp5yWd472N+zJir14XpEA4HAh2RKs8SdLKpplAwVLRmNduJaRASBwAlDBq2KiGwTrwaGlBMvhEtIEgKBEwbzgEuTApCafyVFFpYjGAQCJ0wTE/w3SNIOnG8FI0rwpTQhS/A35xIjiUDLVsm8pJU4YIuzwZKptdT/zNs6jdlZOF8YtIGEKOowdhmBKCIQuC2ZXnUbK6wiCwhxrd2784mxcSPXAqtrP4jagkGQq4c15PYMzuSLNxHJj6tIoyR3WAO7nvRMyIGhIKD7dWgapqJZapNFCS0H+0/eaeamLRZCXBIKChG+iSC5VJD4QgUYQwzCZcJEoL0Cn8PUkqkyDKsV6YTvR8cQdzuX7GEEIoZAWIR5wz1n8cPALpde9IvnOEZgMhEIhzCSDjYs5MDufonRWcPpfRKinNM+0RzFCDSNQDiEIbqo0ZqZ53Wfj7F7ptH0tdJJogds25xRKsluLDf8u1Y6DmcEmkHAULN/vQLQTMam0grqUEvHjeSRqdTCRtL5pQFB7sdq3FfoyB/eGRro2SvLpSXtS5pCms4unO2H13viZhbOJLrQfE94swEfLEyhGQumNZstiunVaqk6w1slU/ssRItx4uFf4zive6YhaH2N2IaCK2Tp23kzEjv3GRzY/VKmc+ESMlLbsRn5/oYKikEiLD3fK6TsVlXFKuT1Vl/PPyrVnrVwbiZt3GYYtBw7X3Mgc0qeWYSWlfuQ8E67t+eVseKluxYVDcO4HeXNx/L/TJnvsIk6XgGKW+2+GWiTx0pj83hdZ3LFy7DCtwb1+bQcoi4x1RQyXziOtHtR9karb9dTOp+ZK8IiXM7EquhxdMardHiU3bCGZGhRUVT7LESXeg+3QJZsOvWQaqzxAuZFFl2WIk3SNA064EfR2eapU1LpfUrWbG7RSjNjvD68nyXmKrKocPWgQLqrSYq/mPnCMhVWOaAFzHzxkZRh7EAnX6rxh9/E+Unk+042d3RbXU0x67NnmLnC43jgPY/7rEA5ObgoQpFZnIPzGhLG75Dm11rjIfYSJJlHUn5iuDLR/w2PMMBCNSL2Wf6IJ8ty6lyYV0GYs1wAIt0CshwAyEoDjevwI4suMImk0bIpF7jeg055HzphGniUsVf8Gs6XcA7pdOikKWiNX1LnZ+aoYVe2JLajV39RxUMl/xdpn4fvsE5fcYW4ypyavr0qzH2Bh51pDu7Cfa/Vwbh/CeX9GeejIEQPFmCUlkETi2XmNPEsnbPkLJ02Tm5oQzINCgBTm5Jbsim0W64whOt05TGkE4zDbYQsutikDs9Ipq+GedEdiigYEm2wT9FddKLnREVuzCOyUzKPord+Tl0D82mmkb6ech1qeLoAHbpXCrES877f4roylE13FpYYKbEFbTO9kofErRgdfI9I7ZVVH2YmtQnpHKNbkG6rkEOrrb69r4+mBDm7Zn4d97kLpL0ge8bQw6hJRfuNpom+L1QNMxYORZaxYc1eN0MWXXYiNY0h16GjKr2i5jIrHbIooY89e9LqO7kUXPiXxgCddhX8q5HlNesUXTxislQhi0qDxZLtROVbdHp07tnp/PQrRq+HfVjM+ZK2SBgOkXvsvpPLrX43WVTMAdvq7/mxKNPloGT/CHlnDeeJz6+hZ//xqfJoTcdDFp07aaSpLMVL+q490POIlrHa3T8IvH4xGiZmg0DvQDNcU0Wu0QRk9x7bAu1zTAcJSR/Qfsc1aLXjl3TIsu0VXlpIp7EGdv5dlkpXBrXXpstttatXkydVw2gh0ZCbrVJpDpXL31TPSB3u506ELLrcJJEGquE/tk3f17J5uoJecIdjeLTJWVlzRzj+A1gpoz/pSwz1OrVfudlc4SMYJcxzhd1KR/bV/buGfXj3q7DE/akrX2y8k06YkY5/Iw3s7rX6d/1IivLN9UgTBFl0CynSwB/LxtMyKBcrZpvpaM8pd9hYvyyTMyRTcYMk1FK/74H/Yzh5oMWqCFMmWdSZVZtZp+09+rqei7rE8iUjk0oYr44/2LvrAT/SeOWp1zj149F8MT+w31K9suUhD5Z8neFVJTpV7vdIVh0kxVEdAC02RfuVK8jIOdeCXlVzJec6oZ5JI4xfx69FGr88CW2fQMWyBsvVm48HpzqT/No3ktV5XAmFkO5J+35XVGK9k0KYRjr+WNI0kiexrRRRwWRZHHKqJmmG40+wJ63tyNRqWRhyNtPxFWky+UUYn4vL7b6er6F+DTwRw5CC76EQwCLA39TviP/iiiehP5ofoWqYZsiicVekwUrOV3HNZNGgRMS1ysbLTlVgCmPOXvgx57qOxzDkuE2g6hTd0ujQCIMNst/YY4wiWyoZF956BA7veBNPsQP6RiJt/Az+hkYqWHH7hs4XJzc0wgCUv+KMqpZoqJGDbViY3VdM6AMwow+2Yk2VVi5Jl42Z6Ibx55p6BZhdhbuRZkG9dFGMD5MwUZR/0upk5unxbL7DMvMdsV6KVSY02LUffROQMO6BRfKDntbNnYUZ2Vzx58IQ38bw3GVnNmnN0PSNJ2zL1fQdOUPiELBL5ZWmYXwIu/6V10LBvSE7xbwSxrX78HeCF4UhbQwtLsJoTVkzTwdZNsNC9FewvPx93MBI69l/3CrO9Y0QArDSsHPzLzMpuxFzkxsrNcO/bOFfhhnNMjWtcY15N2Iue1u6q3gF3sMdm0OvJoemYQBZAap6XRQRUnWLYr1iVae+596F4dmXza5F22CJvBRaZj7q/2Elg7KiBsa7ZVludIxDVZBDI5h1xuRwET+YGmsmBlPa5JfCGngCbdCxeFY2Y51l9U97k+gpy10SHp43gFQPqjDw6WXss0V6H0f368A1DMan6ite57rBiatfyRLXukei3m89cwQsOeJZF0HuPZt/eqaJYGDgo0iQJTE2RdjJdkzbI9h2EalSIQ1tsZbyC6osmf0rd6F6X8BNOg00zR7tj7obOGHU9yGjLnTD9ZPiJw2nbceEuflTszl6Eh1+XVZmXjBz3fWHVeplGfmOxzB/ma0gw5L0Cetde1Nc4Av8vWTqY6rq+5BxAaBWPZUM/GHYWuiMhPc9dxp/QhveR4JpDFFqLyb91xFdhxVjjwMvPjEz9l5ol6U6FnP/b8XhbwFqLqvOlnwUVoHBX1HWXSLhLl7TlB2irVgZW+xIio9kYdnraVjNHsIrOf6HxTDswahXKQm8Fmp0MRlzxPVYYl7r5IuBp2WEiYHsXMXgEDAwj7kDpFkP7dHAGzPlQbyEaVUcv3nDhAmu03BJMH3JCFqh3riJyclc/G8f8xSJFwyK49Ay6q/O6p0CT9gp+TQd7Inni+LV+rJeY+YWZwRagEDwC0stqGSjRSZKmEaF5nShIhD79yW40cKQkw9GgBGoh4AehbGGqYcUxzMCLgSYMC4w2MsI1EOACVMPIY5nBFwIMGFcYLCXEaiHABOmHkIczwi4EeB9GDca7GcE/BFgDeOPD8cyAlUIMGGq4OALRsAfASaMPz4cywhUIcCEqYKDLxgBfwSYMP74cCwjUIUA25JVwcEXjIA3AmxL5o0LhzICvgjwkMwXHo5kBKoRYMJU48FXjIAvAkwYX3g4khGoRoAJU40HXzEC/giwLZk/PhzLCLgRYA3jRoP9jEAdBJgwdQDiaEbAjQATxo0G+xmBOgjU/NyF3tkcm7/W91I4/TBSjM8wDkntD6xhxj4R+JoR8EHg/z6seDvVOnj4AAAAAElFTkSuQmCC" alt="Imagem Ilustrativa" %}
{% br_menu_logo src="data:image/png;base64,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" alt="Imagem Ilustrativa" %}
{% end_br_menu_footer_logos %}
{% br_menu_links %}
{% br_menu_link href="https://site.gov.br" icone="fas fa-external-link-square-alt" %}Link externo 1{% end_br_menu_link %}
{% br_menu_link href="https://twitter.com" icone="fas fa-external-link-square-alt" %}Link externo 2{% end_br_menu_link %}
{% end_br_menu_links %}
{% br_menu_social_network %}
{% br_menu_social_network_title %}Redes Sociais{% end_br_menu_social_network_title %}
{% br_menu_social_network_icons href="javascript: void(0)" icon="fab fa-facebook-f" %}
{% br_menu_social_network_icons href="javascript: void(0)" icon="fab fa-twitter" %}
{% br_menu_social_network_icons href="javascript: void(0)" icon="fab fa-linkedin-in" %}
{% br_menu_social_network_icons href="javascript: void(0)" icon="fab fa-whatsapp" %}
{% end_br_menu_social_network %}
{% end_br_menu_footer %}
{% end_br_menu %}
{% br_menu_toggle label="Acionar menu" target="#main-navigation" %}
{% end_br_menu_row %}
{% endblock %} {% endblock %}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment