feat(base): create detail view templates
purpose is to aid in the development of a detail form #22 #24 #226
This commit is contained in:
@ -65,6 +65,119 @@ input[type=submit] {
|
|||||||
height: 30px;
|
height: 30px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Style the navigation tabs at the top of a content page */
|
||||||
|
.content-navigation-tabs {
|
||||||
|
display: block;
|
||||||
|
overflow: hidden;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
/* background-color: #f1f1f1; */
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.content-navigation-tabs-link {
|
||||||
|
border: 0px;
|
||||||
|
margin: none;
|
||||||
|
padding: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style the buttons that are used to open the tab content */
|
||||||
|
.content-navigation-tabs button {
|
||||||
|
display: inline;
|
||||||
|
background-color: inherit;
|
||||||
|
float: left;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
cursor: pointer;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
padding: 14px 16px;
|
||||||
|
transition: 0.3s;
|
||||||
|
font-size: inherit;
|
||||||
|
color: #6a6e73;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Change background color of buttons on hover */
|
||||||
|
.content-navigation-tabs button:hover {
|
||||||
|
/* background-color: #ddd; */
|
||||||
|
border-bottom: 3px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Create an active/current tablink class */
|
||||||
|
.content-navigation-tabs button.active {
|
||||||
|
/* background-color: #ccc; */
|
||||||
|
border-bottom: 3px solid #177ee6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Style content for each tab */
|
||||||
|
.content-tab {
|
||||||
|
width: 100%;
|
||||||
|
display: none;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
border: none;
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-tab hr {
|
||||||
|
border: none;
|
||||||
|
border-top: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-tab pre {
|
||||||
|
word-wrap: break-word;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style for section fields on details page */
|
||||||
|
.detail-view-field {
|
||||||
|
display: unset;
|
||||||
|
height: 30px;
|
||||||
|
line-height: 30px;
|
||||||
|
padding: 0px 20px 40px 20px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-view-field label {
|
||||||
|
display: inline-block;
|
||||||
|
font-weight: bold;
|
||||||
|
width: 200px;
|
||||||
|
margin: 10px;
|
||||||
|
height: 30px;
|
||||||
|
line-height: 30px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-view-field span {
|
||||||
|
display: inline-block;
|
||||||
|
width: 340px;
|
||||||
|
margin: 10px;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
height: 30px;
|
||||||
|
line-height: 30px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
EoF refactored
|
EoF refactored
|
||||||
@ -124,61 +237,6 @@ input[type=checkbox]:checked::after {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Style the tab */
|
|
||||||
.tab {
|
|
||||||
display: block;
|
|
||||||
overflow: hidden;
|
|
||||||
border-bottom: 1px solid #ccc;
|
|
||||||
/* background-color: #f1f1f1; */
|
|
||||||
width: 100%;
|
|
||||||
text-align: left;
|
|
||||||
padding: 0px;
|
|
||||||
margin: 0px
|
|
||||||
}
|
|
||||||
|
|
||||||
.tablinks {
|
|
||||||
border: 0px;
|
|
||||||
margin: none;
|
|
||||||
padding: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Style the buttons that are used to open the tab content */
|
|
||||||
.tab button {
|
|
||||||
display: inline;
|
|
||||||
background-color: inherit;
|
|
||||||
float: left;
|
|
||||||
border: none;
|
|
||||||
outline: none;
|
|
||||||
cursor: pointer;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
padding: 14px 16px;
|
|
||||||
transition: 0.3s;
|
|
||||||
font-size: inherit;
|
|
||||||
color: #6a6e73;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Change background color of buttons on hover */
|
|
||||||
.tab button:hover {
|
|
||||||
/* background-color: #ddd; */
|
|
||||||
border-bottom: 3px solid #ccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create an active/current tablink class */
|
|
||||||
.tab button.active {
|
|
||||||
/* background-color: #ccc; */
|
|
||||||
border-bottom: 3px solid #177ee6;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Style the tab content */
|
|
||||||
.tabcontent {
|
|
||||||
width: 100%;
|
|
||||||
display: none;
|
|
||||||
/* padding: 6px 12px; */
|
|
||||||
padding-bottom: 0px;
|
|
||||||
border: none;
|
|
||||||
border-top: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
16
app/project-static/functions.js
Normal file
16
app/project-static/functions.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
function openContentNavigationTab(evt, TabName) {
|
||||||
|
var i, tabcontent, tablinks;
|
||||||
|
|
||||||
|
tabcontent = document.getElementsByClassName("content-tab");
|
||||||
|
for (i = 0; i < tabcontent.length; i++) {
|
||||||
|
tabcontent[i].style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
tablinks = document.getElementsByClassName("content-navigation-tabs-link");
|
||||||
|
for (i = 0; i < tablinks.length; i++) {
|
||||||
|
tablinks[i].className = tablinks[i].className.replace(" active", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById(TabName).style.display = "block";
|
||||||
|
evt.currentTarget.className += " active";
|
||||||
|
}
|
@ -14,6 +14,7 @@
|
|||||||
<link rel="stylesheet" href="{% static 'base.css' %}">
|
<link rel="stylesheet" href="{% static 'base.css' %}">
|
||||||
<link rel="stylesheet" href="{% static 'code.css' %}">
|
<link rel="stylesheet" href="{% static 'code.css' %}">
|
||||||
<link rel="stylesheet" href="{% static 'content.css' %}">
|
<link rel="stylesheet" href="{% static 'content.css' %}">
|
||||||
|
<script src="{% static 'functions.js' %}"></script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
72
app/templates/content/field.html.j2
Normal file
72
app/templates/content/field.html.j2
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
{% load json %}
|
||||||
|
{% load markdown %}
|
||||||
|
|
||||||
|
{% if field.widget_type == 'textarea' or field.label == 'Notes' %}
|
||||||
|
|
||||||
|
{% if field.name in section.json and field.value %}
|
||||||
|
|
||||||
|
<pre style="width: 80%; text-align: left; display:inline; border: 1px solid #ccc; padding: 22px;">{{ field.value.strip | json_pretty | safe }}</pre>
|
||||||
|
|
||||||
|
{% elif field.name in section.markdown or field.label == 'Notes' %}
|
||||||
|
|
||||||
|
{% if field.label == 'Notes' %}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label style="font-weight: bold; width: 100%; border-bottom: 1px solid #ccc; display: block; text-align: inherit;">
|
||||||
|
{{ field.label }}
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div style="display: inline-block; text-align: left;">
|
||||||
|
{% if field.value %}
|
||||||
|
{{ field.value | markdown | safe }}
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
{% if field.value %}
|
||||||
|
|
||||||
|
{{ field.value | markdown | safe }}
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% elif not field.value %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="detail-view-field">
|
||||||
|
<label>{{ field.label }}</label>
|
||||||
|
<span>
|
||||||
|
{% if field.field.choices %} {# Display the selected choice text value #}
|
||||||
|
{% for id, value in field.field.choices %}
|
||||||
|
|
||||||
|
{% if field.value == id %}
|
||||||
|
|
||||||
|
{{ value }}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{%endfor%}
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
{{ field.value }}
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endif %}
|
93
app/templates/content/section.html.j2
Normal file
93
app/templates/content/section.html.j2
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
{% load json %}
|
||||||
|
{% load markdown %}
|
||||||
|
|
||||||
|
{% for section in tab.sections %}
|
||||||
|
|
||||||
|
|
||||||
|
{% if forloop.first %}
|
||||||
|
|
||||||
|
<h3>{{ tab.name }}</h3>
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<h3>{{ section.name }}</h3>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div style="align-items:flex-start; align-content: center; display: flexbox; width: 100%">
|
||||||
|
|
||||||
|
{% if section.layout == 'single' %}
|
||||||
|
|
||||||
|
{% for section_field in section.fields %}
|
||||||
|
{% for field in form %}
|
||||||
|
|
||||||
|
{% if field.name in section_field %}
|
||||||
|
|
||||||
|
{% include 'content/field.html.j2' %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% elif section.layout == 'double' %}
|
||||||
|
|
||||||
|
{% if section.left %}
|
||||||
|
|
||||||
|
<div style="display: inline; width: 40%; margin: 30px;">
|
||||||
|
|
||||||
|
{% for section_field in section.left %}
|
||||||
|
{% for field in form %}
|
||||||
|
|
||||||
|
{% if field.name in section_field %}
|
||||||
|
|
||||||
|
{% include 'content/field.html.j2' %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{% if section.right %}
|
||||||
|
|
||||||
|
<div style="display: inline; width: 40%; margin: 30px; text-align: left;">
|
||||||
|
|
||||||
|
{% for section_field in section.right %}
|
||||||
|
{% for field in form %}
|
||||||
|
|
||||||
|
{% if field.name in section_field %}
|
||||||
|
|
||||||
|
{% include 'content/field.html.j2' %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if forloop.first %}
|
||||||
|
|
||||||
|
{% if tab.edit_url %}
|
||||||
|
|
||||||
|
<div style="display:block;">
|
||||||
|
<input type="button" value="Edit" onclick="window.location='{{ tab.edit_url }}';">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endfor %}
|
33
app/templates/detail.html.j2
Normal file
33
app/templates/detail.html.j2
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{% extends 'base.html.j2' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="content-navigation-tabs">
|
||||||
|
|
||||||
|
<button onclick="window.location='{% url 'ITIM:Services' %}';" style="vertical-align: middle; padding: auto; margin: 0px">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="25px" viewBox="0 -960 960 960" width="25px"
|
||||||
|
style="vertical-align: middle; margin: 0px; padding: 0px border: none; " fill="#6a6e73">
|
||||||
|
<path d="m313-480 155 156q11 11 11.5 27.5T468-268q-11 11-28 11t-28-11L228-452q-6-6-8.5-13t-2.5-15q0-8 2.5-15t8.5-13l184-184q11-11 27.5-11.5T468-692q11 11 11 28t-11 28L313-480Zm264 0 155 156q11 11 11.5 27.5T732-268q-11 11-28 11t-28-11L492-452q-6-6-8.5-13t-2.5-15q0-8 2.5-15t8.5-13l184-184q11-11 27.5-11.5T732-692q11 11 11 28t-11 28L577-480Z" />
|
||||||
|
</svg>
|
||||||
|
Back to Services
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{% for key, tab in form.tabs.items %}
|
||||||
|
|
||||||
|
{% if forloop.first %}
|
||||||
|
|
||||||
|
<button id="defaultOpen" class="content-navigation-tabs-link" onclick="openContentNavigationTab(event, '{{ tab.slug }}')">{{ tab.name }}</button>
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
<button class="content-navigation-tabs-link" onclick="openContentNavigationTab(event, '{{ tab.slug }}')">{{ tab.name }}</button>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% block tabs %}{% endblock %}
|
||||||
|
|
||||||
|
{% endblock %}
|
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
@ -0,0 +1,46 @@
|
|||||||
|
<mxfile host="app.diagrams.net" modified="2024-08-13T04:59:07.625Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" etag="UnD9NsC2nlQotuYi3Jgi" version="24.4.13" type="device">
|
||||||
|
<diagram name="Page-1" id="43mCgrILUMj9ztUM_gXM">
|
||||||
|
<mxGraphModel dx="1434" dy="766" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
|
||||||
|
<root>
|
||||||
|
<mxCell id="0" />
|
||||||
|
<mxCell id="1" parent="0" />
|
||||||
|
<mxCell id="S1pZBpeQw_pKLN31ISmP-2" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="110" y="80" width="1000" height="520" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="S1pZBpeQw_pKLN31ISmP-3" value="Page Header" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="110" y="80" width="1000" height="60" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="S1pZBpeQw_pKLN31ISmP-4" value="Navigation<div><br></div>" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="110" y="140" width="200" height="460" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="S1pZBpeQw_pKLN31ISmP-5" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="310" y="140" width="800" height="460" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="S1pZBpeQw_pKLN31ISmP-6" value="Page Title" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#D1FCFF;strokeColor=#d6b656;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="310" y="140" width="800" height="60" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="S1pZBpeQw_pKLN31ISmP-7" value="Section Content, Single Column" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="320" y="210" width="780" height="150" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="S1pZBpeQw_pKLN31ISmP-8" value="Page Footer" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="310" y="560" width="800" height="40" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="S1pZBpeQw_pKLN31ISmP-9" value="Section Navigation Tabs" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="320" y="210" width="780" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="S1pZBpeQw_pKLN31ISmP-10" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="320" y="370" width="780" height="150" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="S1pZBpeQw_pKLN31ISmP-11" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="390" y="370" width="320" height="150" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="S1pZBpeQw_pKLN31ISmP-15" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="710" y="370" width="320" height="150" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="S1pZBpeQw_pKLN31ISmP-12" value="<span style="color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: center; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(251, 251, 251); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; display: inline !important; float: none;">Section Content, Double Column</span>" style="text;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="620" y="425" width="210" height="40" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
</root>
|
||||||
|
</mxGraphModel>
|
||||||
|
</diagram>
|
||||||
|
</mxfile>
|
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
@ -7,3 +7,51 @@ about: https://gitlab.com/nofusscomputing/infrastructure/configuration-managemen
|
|||||||
---
|
---
|
||||||
|
|
||||||
This section of the documentation contains the details related to the templates used within Centurion ERP for rendering data for the end user to view.
|
This section of the documentation contains the details related to the templates used within Centurion ERP for rendering data for the end user to view.
|
||||||
|
The base template is common to all templates and is responsible for the rendering of the common layout. Each subsequent template includes this template. This enables **ALL** pages within the site to share the same layout.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Point of note is that the orange area of the template is what each template is "filling out."
|
||||||
|
|
||||||
|
This view contains the following areas:
|
||||||
|
|
||||||
|
- Page Header
|
||||||
|
- Navigation
|
||||||
|
- Page Title
|
||||||
|
- Content Area
|
||||||
|
- Page footer
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
This template should not be included directly as it is incomplete and requires subsequent templates to populate the contents of the orange area.
|
||||||
|
|
||||||
|
|
||||||
|
## Detail
|
||||||
|
|
||||||
|
This template is intended to be used to render the details of a single model. The layout of the detail view is as follows:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
This view contains the following areas:
|
||||||
|
|
||||||
|
- Section navigation tabs
|
||||||
|
- Section Content
|
||||||
|
|
||||||
|
The page title represents the "what" to the contents of the page. i.e. for a device this would be the device name. A detail page contains navigation tabs to aid in displaying multiple facets of an item, with each "tabbed" page containing one or more sections. Point of note is that the tabs are only rendered within the top section of each "tabbed" page.
|
||||||
|
|
||||||
|
Base definition for defining a detail page is as follows:
|
||||||
|
|
||||||
|
``` jinja
|
||||||
|
|
||||||
|
{% extends 'detail.html.j2' %}
|
||||||
|
|
||||||
|
{% load json %}
|
||||||
|
{% load markdown %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block tabs %}
|
||||||
|
|
||||||
|
your tabs content here
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
```
|
||||||
|
Reference in New Issue
Block a user