micro-sidebar 1.2.1__py3-none-any.whl → 2.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {micro_sidebar-1.2.1.dist-info → micro_sidebar-2.1.0.dist-info}/METADATA +117 -1
- micro_sidebar-2.1.0.dist-info/RECORD +29 -0
- sidebar/apps.py +10 -0
- sidebar/context_processors.py +127 -0
- sidebar/discovery.py +151 -0
- sidebar/static/sidebar/css/theme_picker.css +165 -0
- sidebar/static/sidebar/js/theme_picker.js +58 -0
- sidebar/static/sidebar/sidebar.css +32 -8
- sidebar/static/sidebar/sidebar.js +15 -40
- sidebar/static/themes/blue.css +51 -0
- sidebar/static/themes/dark.css +501 -0
- sidebar/static/themes/gold.css +51 -0
- sidebar/static/themes/green.css +63 -0
- sidebar/static/themes/light.css +51 -0
- sidebar/static/themes/main.css +6 -0
- sidebar/static/themes/main.js +41 -0
- sidebar/static/themes/red.css +51 -0
- sidebar/templates/sidebar/auto.html +13 -0
- sidebar/templates/sidebar/extra_groups.html +34 -0
- sidebar/templates/sidebar/main.html +25 -2
- sidebar/templatetags/__init__.py +1 -0
- sidebar/templatetags/sidebar_tags.py +74 -0
- micro_sidebar-1.2.1.dist-info/RECORD +0 -13
- {micro_sidebar-1.2.1.dist-info → micro_sidebar-2.1.0.dist-info}/LICENSE +0 -0
- {micro_sidebar-1.2.1.dist-info → micro_sidebar-2.1.0.dist-info}/WHEEL +0 -0
- {micro_sidebar-1.2.1.dist-info → micro_sidebar-2.1.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/* --- Gold Theme (Luxury) --- */
|
|
2
|
+
:root.theme-gold {
|
|
3
|
+
--title: #78350f;
|
|
4
|
+
--body: #fffbeb8b;
|
|
5
|
+
--htitle: #92400e;
|
|
6
|
+
--hbody: #fef3c7db;
|
|
7
|
+
--table-row: #fef9e7;
|
|
8
|
+
--table-row-hover: #fdf1c0;
|
|
9
|
+
--primal: #d97706;
|
|
10
|
+
--primal_dark: #b45309;
|
|
11
|
+
--primal-rgb: 217, 119, 6;
|
|
12
|
+
--btn-primary-shadow: rgba(217, 119, 6, 0.4);
|
|
13
|
+
|
|
14
|
+
/* Login Theme Variables */
|
|
15
|
+
--bg-gradient: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);
|
|
16
|
+
--right-bg: var(--title);
|
|
17
|
+
--primary-color: var(--primal);
|
|
18
|
+
|
|
19
|
+
/* Bootstrap Overrides */
|
|
20
|
+
--bs-primary: var(--primal);
|
|
21
|
+
--bs-primary-rgb: var(--primal-rgb);
|
|
22
|
+
--bs-btn-bg: var(--primal);
|
|
23
|
+
--bs-btn-border-color: var(--primal);
|
|
24
|
+
--bs-btn-hover-bg: var(--primal_dark);
|
|
25
|
+
--bs-btn-hover-border-color: var(--primal_dark);
|
|
26
|
+
--bs-link-color: var(--primal);
|
|
27
|
+
--bs-link-hover-color: var(--primal_dark);
|
|
28
|
+
}
|
|
29
|
+
:root.theme-gold .titlebar {
|
|
30
|
+
background: linear-gradient(90deg, #ffffff 10%, #fef9e7 90%) !important;
|
|
31
|
+
}
|
|
32
|
+
:root.theme-gold #sidebar {
|
|
33
|
+
background: linear-gradient(180deg, #ffffff 10%, #fef9e7 100%) !important;
|
|
34
|
+
border-left: 1px solid #fdf1c0 !important;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
:root.theme-gold .page .right {
|
|
38
|
+
background: var(--primal_dark) !important; /* Darker logo container */
|
|
39
|
+
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.3) !important;
|
|
40
|
+
color: #e2e8f0 !important;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Gold Overrides */
|
|
44
|
+
:root.theme-gold .dropdown-item:hover {
|
|
45
|
+
background-color: rgba(217, 119, 6, 0.08) !important;
|
|
46
|
+
color: #b45309 !important;
|
|
47
|
+
}
|
|
48
|
+
:root.theme-gold .titlebar .btn-light:hover {
|
|
49
|
+
background-color: rgba(217, 119, 6, 0.08) !important;
|
|
50
|
+
color: #b45309 !important;
|
|
51
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/* --- Green Theme (Emerald) --- */
|
|
2
|
+
:root.theme-green {
|
|
3
|
+
--title: #166534;
|
|
4
|
+
--body: #f0fdf48b;
|
|
5
|
+
--htitle: #15803d;
|
|
6
|
+
--hbody: #dcfce7db;
|
|
7
|
+
--table-row: #e9fdf0;
|
|
8
|
+
--table-row-hover: #d2f9df;
|
|
9
|
+
--primal: #10b981;
|
|
10
|
+
--primal_dark: #059669;
|
|
11
|
+
--primal-rgb: 16, 185, 129;
|
|
12
|
+
--btn-primary-shadow: rgba(16, 185, 129, 0.4);
|
|
13
|
+
|
|
14
|
+
/* Login Theme Variables */
|
|
15
|
+
--bg-gradient: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);
|
|
16
|
+
--right-bg: var(--title);
|
|
17
|
+
--primary-color: var(--primal);
|
|
18
|
+
|
|
19
|
+
/* Bootstrap Overrides */
|
|
20
|
+
--bs-primary: var(--primal);
|
|
21
|
+
--bs-primary-rgb: var(--primal-rgb);
|
|
22
|
+
--bs-btn-bg: var(--primal);
|
|
23
|
+
--bs-btn-border-color: var(--primal);
|
|
24
|
+
--bs-btn-hover-bg: var(--primal_dark);
|
|
25
|
+
--bs-btn-hover-border-color: var(--primal_dark);
|
|
26
|
+
--bs-link-color: var(--primal);
|
|
27
|
+
--bs-link-hover-color: var(--primal_dark);
|
|
28
|
+
}
|
|
29
|
+
:root.theme-green .titlebar {
|
|
30
|
+
background: linear-gradient(90deg, #ffffff 10%, #e9fdf0 90%) !important;
|
|
31
|
+
}
|
|
32
|
+
:root.theme-green #sidebar {
|
|
33
|
+
background: linear-gradient(180deg, #ffffff 10%, #e9fdf0 100%) !important;
|
|
34
|
+
border-left: 1px solid #d2f9df !important;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
:root.theme-green .page .right {
|
|
38
|
+
background: var(--primal_dark) !important; /* Darker logo container */
|
|
39
|
+
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.3) !important;
|
|
40
|
+
color: #e2e8f0 !important;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Green Overrides */
|
|
44
|
+
:root.theme-green .dropdown-item:hover {
|
|
45
|
+
background-color: rgba(16, 185, 129, 0.08) !important;
|
|
46
|
+
color: #059669 !important;
|
|
47
|
+
}
|
|
48
|
+
:root.theme-green .titlebar .btn-light:hover {
|
|
49
|
+
background-color: rgba(16, 185, 129, 0.08) !important;
|
|
50
|
+
color: #059669 !important;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* Success Button Override in Green Theme */
|
|
54
|
+
:root.theme-green .btn-outline-success {
|
|
55
|
+
color: #475569 !important;
|
|
56
|
+
border-color: #475569 !important;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
:root.theme-green .btn-outline-success:hover {
|
|
60
|
+
background-color: #475569 !important;
|
|
61
|
+
border-color: #475569 !important;
|
|
62
|
+
color: #ffffff !important;
|
|
63
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/* --- Light Theme (Neutral / Silver) --- */
|
|
2
|
+
:root.theme-light {
|
|
3
|
+
--title: #334155; /* Slate 700 */
|
|
4
|
+
--body: #f8fafc; /* Slate 50 */
|
|
5
|
+
--htitle: #64748b; /* Slate 500 */
|
|
6
|
+
--hbody: #f1f5f9; /* Slate 100 */
|
|
7
|
+
--table-row: #f7f8fa;
|
|
8
|
+
--table-row-hover: #f1f5f9;
|
|
9
|
+
--primal: #475569; /* Slate 600 - Neutral Accent */
|
|
10
|
+
--primal_dark: #334155; /* Slate 700 */
|
|
11
|
+
--primal-rgb: 71, 85, 105;
|
|
12
|
+
--btn-primary-shadow: rgba(71, 85, 105, 0.4);
|
|
13
|
+
|
|
14
|
+
/* Login Theme Variables */
|
|
15
|
+
--bg-gradient: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
|
|
16
|
+
--right-bg: var(--title);
|
|
17
|
+
--primary-color: var(--primal);
|
|
18
|
+
|
|
19
|
+
/* Bootstrap Overrides */
|
|
20
|
+
--bs-primary: var(--primal);
|
|
21
|
+
--bs-primary-rgb: var(--primal-rgb);
|
|
22
|
+
--bs-btn-bg: var(--primal);
|
|
23
|
+
--bs-btn-border-color: var(--primal);
|
|
24
|
+
--bs-btn-hover-bg: var(--primal_dark);
|
|
25
|
+
--bs-btn-hover-border-color: var(--primal_dark);
|
|
26
|
+
--bs-link-color: var(--primal);
|
|
27
|
+
--bs-link-hover-color: var(--primal_dark);
|
|
28
|
+
}
|
|
29
|
+
:root.theme-light .titlebar {
|
|
30
|
+
background: linear-gradient(90deg, #ffffff 10%, #f8fafc 90%) !important;
|
|
31
|
+
}
|
|
32
|
+
:root.theme-light #sidebar {
|
|
33
|
+
background: linear-gradient(180deg, #ffffff 10%, #f8fafc 100%) !important;
|
|
34
|
+
border-left: 1px solid #e2e8f0 !important;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
:root.theme-light .page .right {
|
|
38
|
+
background: var(--htitle) !important;
|
|
39
|
+
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.3) !important;
|
|
40
|
+
color: #f8fafc !important;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Neutral Overrides */
|
|
44
|
+
:root.theme-light .dropdown-item:hover {
|
|
45
|
+
background-color: rgba(71, 85, 105, 0.08) !important;
|
|
46
|
+
color: #334155 !important;
|
|
47
|
+
}
|
|
48
|
+
:root.theme-light .titlebar .btn-light:hover {
|
|
49
|
+
background-color: rgba(71, 85, 105, 0.08) !important;
|
|
50
|
+
color: #334155 !important;
|
|
51
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
2
|
+
const root = document.documentElement;
|
|
3
|
+
const themes = ['light', 'blue', 'gold', 'green', 'red', 'dark'];
|
|
4
|
+
|
|
5
|
+
// Load saved theme
|
|
6
|
+
const savedTheme = localStorage.getItem('appTheme');
|
|
7
|
+
if (savedTheme && themes.includes(savedTheme)) {
|
|
8
|
+
root.classList.add(`theme-${savedTheme}`);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Global function to set theme
|
|
12
|
+
window.setTheme = function(theme) {
|
|
13
|
+
// Remove all current theme classes
|
|
14
|
+
themes.forEach(t => root.classList.remove(`theme-${t}`));
|
|
15
|
+
|
|
16
|
+
if (theme && themes.includes(theme)) {
|
|
17
|
+
root.classList.add(`theme-${theme}`);
|
|
18
|
+
localStorage.setItem('appTheme', theme);
|
|
19
|
+
} else {
|
|
20
|
+
localStorage.removeItem('appTheme');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Visual Update: Highlight active theme circle
|
|
24
|
+
updateActiveThemeUI(theme || 'light');
|
|
25
|
+
|
|
26
|
+
// Dispatch event for components that might need resizing (like Plotly)
|
|
27
|
+
window.dispatchEvent(new Event('resize'));
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function updateActiveThemeUI(activeTheme) {
|
|
31
|
+
document.querySelectorAll('.theme-preview').forEach(el => {
|
|
32
|
+
el.classList.remove('active');
|
|
33
|
+
if (el.getAttribute('data-theme') === activeTheme) {
|
|
34
|
+
el.classList.add('active');
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Initialize UI on load
|
|
40
|
+
updateActiveThemeUI(savedTheme || 'light');
|
|
41
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/* --- Red Theme (Bordeaux) --- */
|
|
2
|
+
:root.theme-red {
|
|
3
|
+
--title: #7f1d1d;
|
|
4
|
+
--body: #fef2f28b;
|
|
5
|
+
--htitle: #991b1b;
|
|
6
|
+
--hbody: #fee2e2db;
|
|
7
|
+
--table-row: #fdeded;
|
|
8
|
+
--table-row-hover: #fcdbdb;
|
|
9
|
+
--primal: #ef4444;
|
|
10
|
+
--primal_dark: #dc2626;
|
|
11
|
+
--primal-rgb: 239, 68, 68;
|
|
12
|
+
--btn-primary-shadow: rgba(239, 68, 68, 0.4);
|
|
13
|
+
|
|
14
|
+
/* Login Theme Variables */
|
|
15
|
+
--bg-gradient: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%);
|
|
16
|
+
--right-bg: var(--title);
|
|
17
|
+
--primary-color: var(--primal);
|
|
18
|
+
|
|
19
|
+
/* Bootstrap Overrides */
|
|
20
|
+
--bs-primary: var(--primal);
|
|
21
|
+
--bs-primary-rgb: var(--primal-rgb);
|
|
22
|
+
--bs-btn-bg: var(--primal);
|
|
23
|
+
--bs-btn-border-color: var(--primal);
|
|
24
|
+
--bs-btn-hover-bg: var(--primal_dark);
|
|
25
|
+
--bs-btn-hover-border-color: var(--primal_dark);
|
|
26
|
+
--bs-link-color: var(--primal);
|
|
27
|
+
--bs-link-hover-color: var(--primal_dark);
|
|
28
|
+
}
|
|
29
|
+
:root.theme-red .titlebar {
|
|
30
|
+
background: linear-gradient(90deg, #ffffff 10%, #fdeded 90%) !important;
|
|
31
|
+
}
|
|
32
|
+
:root.theme-red #sidebar {
|
|
33
|
+
background: linear-gradient(180deg, #ffffff 10%, #fdeded 100%) !important;
|
|
34
|
+
border-left: 1px solid #fcdbdb !important;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
:root.theme-red .page .right {
|
|
38
|
+
background: var(--primal_dark) !important; /* Darker logo container */
|
|
39
|
+
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.3) !important;
|
|
40
|
+
color: #e2e8f0 !important;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Red Overrides */
|
|
44
|
+
:root.theme-red .dropdown-item:hover {
|
|
45
|
+
background-color: rgba(239, 68, 68, 0.08) !important;
|
|
46
|
+
color: #dc2626 !important;
|
|
47
|
+
}
|
|
48
|
+
:root.theme-red .titlebar .btn-light:hover {
|
|
49
|
+
background-color: rgba(239, 68, 68, 0.08) !important;
|
|
50
|
+
color: #dc2626 !important;
|
|
51
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{% for item in items %}
|
|
2
|
+
<a href="{{ item.url }}"
|
|
3
|
+
class="list-group-item list-group-item-action{% if item.active %} active{% endif %}"
|
|
4
|
+
data-url-name="{{ item.url_name }}">
|
|
5
|
+
<i class="bi {{ item.icon }} me-2" style="font-size: 24px;"></i>
|
|
6
|
+
<span>{{ item.label }}</span>
|
|
7
|
+
</a>
|
|
8
|
+
{% empty %}
|
|
9
|
+
<div class="p-3 text-center text-muted small">
|
|
10
|
+
<i class="bi bi-inbox mb-2" style="font-size: 24px;"></i>
|
|
11
|
+
<p class="mb-0">لا توجد عناصر</p>
|
|
12
|
+
</div>
|
|
13
|
+
{% endfor %}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{% if groups %}
|
|
2
|
+
<div class="accordion accordion-flush" id="sidebarExtraAccordion">
|
|
3
|
+
{% for group_name, group in groups.items %}
|
|
4
|
+
<div class="accordion-item">
|
|
5
|
+
<h2 class="accordion-header">
|
|
6
|
+
<button class="accordion-button{% if not group.has_active %} collapsed{% endif %}"
|
|
7
|
+
type="button"
|
|
8
|
+
data-bs-toggle="collapse"
|
|
9
|
+
data-bs-target="#extraGroup{{ forloop.counter }}"
|
|
10
|
+
aria-expanded="{% if group.has_active %}true{% else %}false{% endif %}"
|
|
11
|
+
aria-controls="extraGroup{{ forloop.counter }}">
|
|
12
|
+
<i class="bi {{ group.icon }} me-2" style="font-size: 24px;"></i>
|
|
13
|
+
<span>{{ group_name }}</span>
|
|
14
|
+
</button>
|
|
15
|
+
</h2>
|
|
16
|
+
<div id="extraGroup{{ forloop.counter }}"
|
|
17
|
+
class="accordion-collapse collapse{% if group.has_active %} show{% endif %}"
|
|
18
|
+
data-bs-parent="#sidebarExtraAccordion">
|
|
19
|
+
<div class="accordion-body p-0">
|
|
20
|
+
{% for item in group.items %}
|
|
21
|
+
<a href="{{ item.url }}"
|
|
22
|
+
class="list-group-item list-group-item-action{% if item.active %} active{% endif %}"
|
|
23
|
+
data-url-name="{{ item.url_name }}">
|
|
24
|
+
<i class="bi {{ item.icon }} me-2" style="font-size: 24px;"></i>
|
|
25
|
+
<span>{{ item.label }}</span>
|
|
26
|
+
</a>
|
|
27
|
+
{% endfor %}
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
{% endfor %}
|
|
32
|
+
</div>
|
|
33
|
+
{% endif %}
|
|
34
|
+
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
{% load static %}
|
|
2
2
|
<link rel="stylesheet" href="{% static 'sidebar/sidebar.css' %}">
|
|
3
|
+
<link rel="stylesheet" href="{% static 'sidebar/css/theme_picker.css' %}">
|
|
4
|
+
<link rel="stylesheet" href="{% static 'themes/main.css' %}">
|
|
3
5
|
<script src="{% static 'sidebar/sidebar.js' %}" nonce="{{ request.csp_nonce }}" defer></script>
|
|
6
|
+
<script src="{% static 'themes/main.js' %}" nonce="{{ request.csp_nonce }}" defer></script>
|
|
7
|
+
<script src="{% static 'sidebar/js/theme_picker.js' %}" nonce="{{ request.csp_nonce }}" defer></script>
|
|
4
8
|
<!-- Ghost Sidebar for small screens layout stability -->
|
|
5
|
-
|
|
9
|
+
{% if request.user.is_authenticated %}
|
|
10
|
+
<!-- <div class="sidebar-ghost"></div> -->
|
|
6
11
|
|
|
7
12
|
<!-- sidebar.html -->
|
|
8
13
|
<div class="col-2 flex-column shadow-sm sidebar {% if request.session.sidebarCollapsed %}collapsed{% endif %} no-print"
|
|
9
14
|
id="sidebar"
|
|
10
15
|
data-toggle-url="{% url 'toggle_sidebar' %}"
|
|
11
16
|
data-session-collapsed="{{ request.session.sidebarCollapsed|yesno:'true,false' }}">
|
|
12
|
-
<script>
|
|
17
|
+
<script nonce="{{ request.csp_nonce }}">
|
|
13
18
|
// Immediate FOUC fix for small screens
|
|
14
19
|
(function() {
|
|
15
20
|
var screenWidth = window.innerWidth;
|
|
@@ -43,4 +48,22 @@
|
|
|
43
48
|
|
|
44
49
|
{% endblock %}
|
|
45
50
|
</div>
|
|
51
|
+
|
|
52
|
+
<!-- Sidebar Toolbar (Theme Picker, etc.) -->
|
|
53
|
+
<div class="sidebar-toolbar no-print">
|
|
54
|
+
<i class="bi bi-chevron-up theme-arrow" id="sidebarThemeArrow"></i>
|
|
55
|
+
<div class="current-theme-indicator" id="sidebarThemeIndicator" title="تغيير المظهر"></div>
|
|
56
|
+
<div class="theme-popup" id="sidebarThemePopup">
|
|
57
|
+
<div class="small fw-bold mb-2 text-center border-bottom pb-1">اختر اللون</div>
|
|
58
|
+
<div class="theme-options-grid">
|
|
59
|
+
<div class="theme-option-circle theme-circle-light" data-theme="light" title="أبيض"></div>
|
|
60
|
+
<div class="theme-option-circle theme-circle-blue" data-theme="blue" title="ملكي"></div>
|
|
61
|
+
<div class="theme-option-circle theme-circle-gold" data-theme="gold" title="ذهبي"></div>
|
|
62
|
+
<div class="theme-option-circle theme-circle-green" data-theme="green" title="أخضر"></div>
|
|
63
|
+
<div class="theme-option-circle theme-circle-red" data-theme="red" title="أحمر"></div>
|
|
64
|
+
<div class="theme-option-circle theme-circle-dark" data-theme="dark" title="ليلي"></div>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
46
68
|
</div>
|
|
69
|
+
{% endif %}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# This file makes templatetags a Python package
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Template tags for the sidebar app.
|
|
3
|
+
|
|
4
|
+
Provides the {% auto_sidebar %} tag for rendering auto-discovered
|
|
5
|
+
navigation items.
|
|
6
|
+
"""
|
|
7
|
+
from django import template
|
|
8
|
+
from django.urls import reverse, NoReverseMatch
|
|
9
|
+
|
|
10
|
+
register = template.Library()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@register.inclusion_tag('sidebar/auto.html', takes_context=True)
|
|
14
|
+
def auto_sidebar(context):
|
|
15
|
+
"""
|
|
16
|
+
Render auto-discovered sidebar items.
|
|
17
|
+
|
|
18
|
+
Uses items from sidebar_auto_items context variable (provided by
|
|
19
|
+
the context processor) and adds resolved URLs and active state.
|
|
20
|
+
|
|
21
|
+
Usage:
|
|
22
|
+
{% load sidebar_tags %}
|
|
23
|
+
{% auto_sidebar %}
|
|
24
|
+
"""
|
|
25
|
+
request = context.get('request')
|
|
26
|
+
items = list(context.get('sidebar_auto_items', []))
|
|
27
|
+
|
|
28
|
+
# Add resolved URLs and active state
|
|
29
|
+
for item in items:
|
|
30
|
+
try:
|
|
31
|
+
item['url'] = reverse(item['url_name'])
|
|
32
|
+
# Check if current path matches or starts with this URL
|
|
33
|
+
item['active'] = request.path == item['url'] or request.path.startswith(item['url'].rstrip('/') + '/')
|
|
34
|
+
except NoReverseMatch:
|
|
35
|
+
item['url'] = '#'
|
|
36
|
+
item['active'] = False
|
|
37
|
+
|
|
38
|
+
return {'items': items, 'request': request}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@register.simple_tag(takes_context=True)
|
|
42
|
+
def sidebar_item_class(context, url_name):
|
|
43
|
+
"""
|
|
44
|
+
Return 'active' class if current path matches the given URL name.
|
|
45
|
+
|
|
46
|
+
Usage:
|
|
47
|
+
<a href="{% url 'decree_list' %}" class="list-group-item {% sidebar_item_class 'decree_list' %}">
|
|
48
|
+
"""
|
|
49
|
+
request = context.get('request')
|
|
50
|
+
try:
|
|
51
|
+
url = reverse(url_name)
|
|
52
|
+
if request.path == url or request.path.startswith(url.rstrip('/') + '/'):
|
|
53
|
+
return 'active'
|
|
54
|
+
except NoReverseMatch:
|
|
55
|
+
pass
|
|
56
|
+
return ''
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@register.inclusion_tag('sidebar/extra_groups.html', takes_context=True)
|
|
60
|
+
def extra_sidebar(context):
|
|
61
|
+
"""
|
|
62
|
+
Render extra sidebar items grouped in accordions.
|
|
63
|
+
|
|
64
|
+
Uses sidebar_extra_groups from context (provided by context processor).
|
|
65
|
+
Groups are rendered as Bootstrap accordions at the end of the sidebar.
|
|
66
|
+
|
|
67
|
+
Usage:
|
|
68
|
+
{% load sidebar_tags %}
|
|
69
|
+
{% extra_sidebar %}
|
|
70
|
+
"""
|
|
71
|
+
groups = context.get('sidebar_extra_groups', {})
|
|
72
|
+
request = context.get('request')
|
|
73
|
+
return {'groups': groups, 'request': request}
|
|
74
|
+
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
sidebar/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
sidebar/apps.py,sha256=4UjKXHoBGKRLxpC9AY6eaq8YZx8unirUz_8u-IrlfVQ,145
|
|
3
|
-
sidebar/urls.py,sha256=UL_9e1RLNMxZXkah65m7GRU1dbViZRGeNPBIiSZpOYg,142
|
|
4
|
-
sidebar/views.py,sha256=MebyJ1ZiylSOPESXFkkQ8QTg-ClrkJn-oYLN6KrcgiM,418
|
|
5
|
-
sidebar/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
sidebar/static/sidebar/sidebar.css,sha256=f6xLSC3JiZFABkxWlFesuzAZZtAT3WW1nZBFMDQNS6Y,5283
|
|
7
|
-
sidebar/static/sidebar/sidebar.js,sha256=xDp038tlscz5KeTjBiEQTzZ2T7a8k4NY3rC6e9NvMsM,6314
|
|
8
|
-
sidebar/templates/sidebar/main.html,sha256=m2b34IO-kG7fn5d9vnx9Sjwls2l9uBn2gDL3E5_Gj70,1912
|
|
9
|
-
micro_sidebar-1.2.1.dist-info/LICENSE,sha256=Fco89ULLSSxKkC2KKnx57SaT0R7WOkZfuk8IYcGiN50,1063
|
|
10
|
-
micro_sidebar-1.2.1.dist-info/METADATA,sha256=msQeEumoDwSbOS8n9pqkE36b9DnaD8IOzAiyBbQOZXw,4304
|
|
11
|
-
micro_sidebar-1.2.1.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
|
12
|
-
micro_sidebar-1.2.1.dist-info/top_level.txt,sha256=ih69sjMhU1wOB9HzUV90yEY98aiPuGhzPBBBE-YtJ3w,8
|
|
13
|
-
micro_sidebar-1.2.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|