django-bangla-admin 0.1.0__tar.gz
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.
- django_bangla_admin-0.1.0/LICENSE +21 -0
- django_bangla_admin-0.1.0/MANIFEST.in +9 -0
- django_bangla_admin-0.1.0/PKG-INFO +198 -0
- django_bangla_admin-0.1.0/README.md +163 -0
- django_bangla_admin-0.1.0/django_bangla_admin/__init__.py +9 -0
- django_bangla_admin-0.1.0/django_bangla_admin/admin.py +71 -0
- django_bangla_admin-0.1.0/django_bangla_admin/apps.py +14 -0
- django_bangla_admin-0.1.0/django_bangla_admin/conf.py +67 -0
- django_bangla_admin-0.1.0/django_bangla_admin/context_processors.py +25 -0
- django_bangla_admin-0.1.0/django_bangla_admin/dashboard/__init__.py +5 -0
- django_bangla_admin-0.1.0/django_bangla_admin/dashboard/base.py +124 -0
- django_bangla_admin-0.1.0/django_bangla_admin/dashboard/data.py +86 -0
- django_bangla_admin-0.1.0/django_bangla_admin/dashboard/default.py +78 -0
- django_bangla_admin-0.1.0/django_bangla_admin/dashboard/registry.py +30 -0
- django_bangla_admin-0.1.0/django_bangla_admin/i18n.py +36 -0
- django_bangla_admin-0.1.0/django_bangla_admin/icons.py +42 -0
- django_bangla_admin-0.1.0/django_bangla_admin/locale/bn/LC_MESSAGES/django.mo +0 -0
- django_bangla_admin-0.1.0/django_bangla_admin/locale/bn/LC_MESSAGES/django.po +54 -0
- django_bangla_admin-0.1.0/django_bangla_admin/locale/en/LC_MESSAGES/django.mo +0 -0
- django_bangla_admin-0.1.0/django_bangla_admin/locale/en/LC_MESSAGES/django.po +55 -0
- django_bangla_admin-0.1.0/django_bangla_admin/menu.py +112 -0
- django_bangla_admin-0.1.0/django_bangla_admin/middleware.py +46 -0
- django_bangla_admin-0.1.0/django_bangla_admin/mixins.py +18 -0
- django_bangla_admin-0.1.0/django_bangla_admin/settings.py +48 -0
- django_bangla_admin-0.1.0/django_bangla_admin/sites.py +50 -0
- django_bangla_admin-0.1.0/django_bangla_admin/static/django_bangla_admin/css/bangla-admin.css +511 -0
- django_bangla_admin-0.1.0/django_bangla_admin/static/django_bangla_admin/js/bangla-admin.js +109 -0
- django_bangla_admin-0.1.0/django_bangla_admin/static/django_bangla_admin/js/charts.js +151 -0
- django_bangla_admin-0.1.0/django_bangla_admin/static/django_bangla_admin/vendor/alpine.min.js +5 -0
- django_bangla_admin-0.1.0/django_bangla_admin/static/django_bangla_admin/vendor/chart.umd.js +14 -0
- django_bangla_admin-0.1.0/django_bangla_admin/static/django_bangla_admin/vendor/htmx.min.js +1 -0
- django_bangla_admin-0.1.0/django_bangla_admin/templates/admin/base.html +63 -0
- django_bangla_admin-0.1.0/django_bangla_admin/templates/admin/base_site.html +2 -0
- django_bangla_admin-0.1.0/django_bangla_admin/templates/admin/index.html +16 -0
- django_bangla_admin-0.1.0/django_bangla_admin/templates/admin/login.html +65 -0
- django_bangla_admin-0.1.0/django_bangla_admin/templates/django_bangla_admin/partials/_activity_feed.html +21 -0
- django_bangla_admin-0.1.0/django_bangla_admin/templates/django_bangla_admin/partials/_breadcrumbs.html +5 -0
- django_bangla_admin-0.1.0/django_bangla_admin/templates/django_bangla_admin/partials/_chart.html +13 -0
- django_bangla_admin-0.1.0/django_bangla_admin/templates/django_bangla_admin/partials/_content.html +6 -0
- django_bangla_admin-0.1.0/django_bangla_admin/templates/django_bangla_admin/partials/_sidebar.html +28 -0
- django_bangla_admin-0.1.0/django_bangla_admin/templates/django_bangla_admin/partials/_stat_card.html +14 -0
- django_bangla_admin-0.1.0/django_bangla_admin/templates/django_bangla_admin/partials/_toasts.html +1 -0
- django_bangla_admin-0.1.0/django_bangla_admin/templates/django_bangla_admin/partials/_topbar.html +47 -0
- django_bangla_admin-0.1.0/django_bangla_admin/templates/django_bangla_admin/partials/_widget.html +4 -0
- django_bangla_admin-0.1.0/django_bangla_admin/templatetags/__init__.py +0 -0
- django_bangla_admin-0.1.0/django_bangla_admin/templatetags/ba_i18n.py +45 -0
- django_bangla_admin-0.1.0/django_bangla_admin/templatetags/ba_tags.py +44 -0
- django_bangla_admin-0.1.0/django_bangla_admin/urls.py +19 -0
- django_bangla_admin-0.1.0/django_bangla_admin/views.py +16 -0
- django_bangla_admin-0.1.0/django_bangla_admin.egg-info/PKG-INFO +198 -0
- django_bangla_admin-0.1.0/django_bangla_admin.egg-info/SOURCES.txt +58 -0
- django_bangla_admin-0.1.0/django_bangla_admin.egg-info/dependency_links.txt +1 -0
- django_bangla_admin-0.1.0/django_bangla_admin.egg-info/requires.txt +1 -0
- django_bangla_admin-0.1.0/django_bangla_admin.egg-info/top_level.txt +1 -0
- django_bangla_admin-0.1.0/pyproject.toml +51 -0
- django_bangla_admin-0.1.0/setup.cfg +4 -0
- django_bangla_admin-0.1.0/tests/test_config.py +34 -0
- django_bangla_admin-0.1.0/tests/test_i18n.py +36 -0
- django_bangla_admin-0.1.0/tests/test_menu.py +39 -0
- django_bangla_admin-0.1.0/tests/test_views.py +63 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ifte Samul Ohy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
include LICENSE
|
|
2
|
+
include README.md
|
|
3
|
+
recursive-include django_bangla_admin/static *
|
|
4
|
+
recursive-include django_bangla_admin/templates *
|
|
5
|
+
recursive-include django_bangla_admin/locale *
|
|
6
|
+
global-exclude *.py[cod]
|
|
7
|
+
global-exclude __pycache__
|
|
8
|
+
prune example
|
|
9
|
+
prune .venv
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: django-bangla-admin
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A free, Bangladeshi Django admin theme & dashboard — HTMX SPA feel, live Chart.js dashboards, Bangla ⇄ English.
|
|
5
|
+
Author-email: Ifte Samul Ohy <iftesamulohy@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/iftesamulohy/django-bangla-admin
|
|
8
|
+
Project-URL: Repository, https://github.com/iftesamulohy/django-bangla-admin
|
|
9
|
+
Project-URL: Author, https://iftesamulohy.com
|
|
10
|
+
Keywords: django,admin,theme,dashboard,bangla,bengali,htmx,jazzmin
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Web Environment
|
|
13
|
+
Classifier: Framework :: Django
|
|
14
|
+
Classifier: Framework :: Django :: 4.2
|
|
15
|
+
Classifier: Framework :: Django :: 5.0
|
|
16
|
+
Classifier: Framework :: Django :: 5.1
|
|
17
|
+
Classifier: Framework :: Django :: 5.2
|
|
18
|
+
Classifier: Intended Audience :: Developers
|
|
19
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
20
|
+
Classifier: Natural Language :: Bengali
|
|
21
|
+
Classifier: Natural Language :: English
|
|
22
|
+
Classifier: Operating System :: OS Independent
|
|
23
|
+
Classifier: Programming Language :: Python :: 3
|
|
24
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
27
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
28
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
29
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
30
|
+
Requires-Python: >=3.9
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
License-File: LICENSE
|
|
33
|
+
Requires-Dist: Django>=4.2
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
# django-bangla-admin
|
|
37
|
+
|
|
38
|
+
> A free, open-source, reusable **Django admin theme & dashboard** built for a
|
|
39
|
+
> Bangladeshi audience. SPA-feel via HTMX, live Chart.js dashboards,
|
|
40
|
+
> **Bangla ⇄ English** language switching, and a single config dict — no
|
|
41
|
+
> template editing for basic use.
|
|
42
|
+
|
|
43
|
+
[](LICENSE)
|
|
44
|
+
[](https://www.djangoproject.com/)
|
|
45
|
+
|
|
46
|
+

|
|
47
|
+
|
|
48
|
+
<p align="center">
|
|
49
|
+
<img src="docs/screenshots/dashboard-light-en.png" width="49%" alt="Dashboard — light, English">
|
|
50
|
+
<img src="docs/screenshots/changelist-dark-bn.png" width="49%" alt="Changelist — dark, Bangla">
|
|
51
|
+
</p>
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Features
|
|
56
|
+
|
|
57
|
+
- 🎨 **Drop-in theme** — install, add to `INSTALLED_APPS`, point your URLs at it. No template edits required.
|
|
58
|
+
- ⚙️ **One config dict** (`BANGLA_ADMIN`) controls branding, menu, colors, dashboard.
|
|
59
|
+
- ⚡ **SPA feel, no JS framework** — HTMX partial navigation; the admin never full-reloads.
|
|
60
|
+
- 🇧🇩 **First-class Bangla** — full Bn/En UI, instant cookie-based toggle, Bengali font stack, Bangla numerals (০১২৩).
|
|
61
|
+
- 📊 **Live dashboard** — stat cards, line / doughnut / bar charts (Chart.js), activity feed; charts recolor on theme/lang change.
|
|
62
|
+
- 🌗 **Dark default + light mode** — persisted toggle; charts and components follow.
|
|
63
|
+
- 📦 **Zero-build, offline-friendly** — prebuilt CSS, self-hosted fonts, vendored HTMX / Alpine / Chart.js. No CDN. Works on BDIX / offline VPS.
|
|
64
|
+
|
|
65
|
+
## Installation
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install django-bangla-admin
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
# settings.py
|
|
73
|
+
INSTALLED_APPS = [
|
|
74
|
+
"django_bangla_admin", # BEFORE django.contrib.admin
|
|
75
|
+
"django.contrib.admin",
|
|
76
|
+
# ...
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
# i18n (the Django 4.2+ correct way — cookie + LocaleMiddleware)
|
|
80
|
+
USE_I18N = True
|
|
81
|
+
LANGUAGE_CODE = "bn"
|
|
82
|
+
LANGUAGES = [("bn", "বাংলা"), ("en", "English")]
|
|
83
|
+
|
|
84
|
+
MIDDLEWARE = [
|
|
85
|
+
# ...
|
|
86
|
+
"django.contrib.sessions.middleware.SessionMiddleware",
|
|
87
|
+
"django.middleware.locale.LocaleMiddleware", # after Session, before Common
|
|
88
|
+
"django.middleware.common.CommonMiddleware",
|
|
89
|
+
# ...
|
|
90
|
+
"django_bangla_admin.middleware.HtmxShellMiddleware", # strips shell on HX-Request
|
|
91
|
+
]
|
|
92
|
+
|
|
93
|
+
# Add the context processor for theme/language in templates
|
|
94
|
+
TEMPLATES[0]["OPTIONS"]["context_processors"] += [
|
|
95
|
+
"django_bangla_admin.context_processors.bangla_admin",
|
|
96
|
+
]
|
|
97
|
+
|
|
98
|
+
BANGLA_ADMIN = {"site_title": "My Shop Admin", "default_language": "bn"}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
# urls.py
|
|
103
|
+
from django.urls import path
|
|
104
|
+
from django_bangla_admin.sites import urls as ba_urls
|
|
105
|
+
|
|
106
|
+
urlpatterns = [path("admin/", ba_urls)]
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
That's it — a fully themed, Bangla, HTMX-driven admin with charts. Your existing
|
|
110
|
+
`@admin.register` / `admin.site.register` calls work unchanged: the themed site
|
|
111
|
+
mirrors the default admin registry automatically.
|
|
112
|
+
|
|
113
|
+
## Configuration
|
|
114
|
+
|
|
115
|
+
A single `BANGLA_ADMIN` dict, deep-merged over the defaults:
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
BANGLA_ADMIN = {
|
|
119
|
+
# Branding
|
|
120
|
+
"site_title": "Bangla Admin",
|
|
121
|
+
"site_brand": {"bn": "বাংলা অ্যাডমিন", "en": "Bangla Admin"},
|
|
122
|
+
"welcome_sign": {"bn": "স্বাগতম", "en": "Welcome"},
|
|
123
|
+
|
|
124
|
+
# Theme
|
|
125
|
+
"theme": "dark", # "dark" | "light"
|
|
126
|
+
"allow_theme_toggle": True,
|
|
127
|
+
"primary_color": "#2DD4BF",
|
|
128
|
+
|
|
129
|
+
# Language
|
|
130
|
+
"default_language": "bn",
|
|
131
|
+
"allow_language_toggle": True,
|
|
132
|
+
"bangla_numerals": True,
|
|
133
|
+
|
|
134
|
+
# Navigation — omit `menu` to auto-build from registered models
|
|
135
|
+
"menu": [
|
|
136
|
+
{"section": {"bn": "প্রধান", "en": "Main"}},
|
|
137
|
+
{"label": {"bn": "ড্যাশবোর্ড", "en": "Dashboard"},
|
|
138
|
+
"icon": "layout-dashboard", "url": "bangla_admin:index"},
|
|
139
|
+
{"label": {"bn": "অর্ডার", "en": "Orders"},
|
|
140
|
+
"icon": "shopping-cart", "model": "shop.Order"},
|
|
141
|
+
],
|
|
142
|
+
"icons": {"auth.User": "user"}, # per-model Lucide icons
|
|
143
|
+
"hide_apps": [], "hide_models": [],
|
|
144
|
+
|
|
145
|
+
# Dashboard
|
|
146
|
+
"dashboard": "django_bangla_admin.dashboard.default.DefaultDashboard",
|
|
147
|
+
"show_dashboard": True,
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Read values anywhere via `from django_bangla_admin.conf import ba_conf` → `ba_conf("theme")`.
|
|
152
|
+
|
|
153
|
+
## Custom dashboards
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
from django_bangla_admin.dashboard import Dashboard, StatCard, ChartWidget, ListWidget
|
|
157
|
+
|
|
158
|
+
class MyDashboard(Dashboard):
|
|
159
|
+
widgets = [
|
|
160
|
+
StatCard(label={"bn": "অর্ডার", "en": "Orders"},
|
|
161
|
+
value=lambda r: Order.objects.count(), icon="shopping-cart", trend="+8%"),
|
|
162
|
+
ChartWidget(id="sales", kind="line",
|
|
163
|
+
title={"bn": "বিক্রি", "en": "Sales"},
|
|
164
|
+
data_url="bangla_admin:ba_chart_data", params={"metric": "sales"}),
|
|
165
|
+
]
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Point `BANGLA_ADMIN["dashboard"]` at it. Register custom chart metrics with
|
|
169
|
+
`@register_metric("name")` from `django_bangla_admin.dashboard.data`, returning
|
|
170
|
+
`{"labels": [...], "datasets": [...]}`.
|
|
171
|
+
|
|
172
|
+
## Demo project
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
cd example
|
|
176
|
+
python manage.py migrate
|
|
177
|
+
python manage.py seed_demo # creates admin/admin + sample shop data
|
|
178
|
+
python manage.py runserver
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Open <http://127.0.0.1:8000/admin/> and log in with **admin / admin**.
|
|
182
|
+
|
|
183
|
+
## Development
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
pip install -e .
|
|
187
|
+
python -m django test tests --settings=tests.settings # run the suite
|
|
188
|
+
python scripts/compile_messages.py # compile .po -> .mo (no gettext needed)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Tech
|
|
192
|
+
|
|
193
|
+
HTMX 2 · Alpine.js 3 · Chart.js 4 · self-hosted Hind Siliguri / Inter fonts ·
|
|
194
|
+
Django 4.2 LTS → 5.x.
|
|
195
|
+
|
|
196
|
+
## License
|
|
197
|
+
|
|
198
|
+
MIT © [Ifte Samul Ohy](https://iftesamulohy.com)
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# django-bangla-admin
|
|
2
|
+
|
|
3
|
+
> A free, open-source, reusable **Django admin theme & dashboard** built for a
|
|
4
|
+
> Bangladeshi audience. SPA-feel via HTMX, live Chart.js dashboards,
|
|
5
|
+
> **Bangla ⇄ English** language switching, and a single config dict — no
|
|
6
|
+
> template editing for basic use.
|
|
7
|
+
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
[](https://www.djangoproject.com/)
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
<p align="center">
|
|
14
|
+
<img src="docs/screenshots/dashboard-light-en.png" width="49%" alt="Dashboard — light, English">
|
|
15
|
+
<img src="docs/screenshots/changelist-dark-bn.png" width="49%" alt="Changelist — dark, Bangla">
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- 🎨 **Drop-in theme** — install, add to `INSTALLED_APPS`, point your URLs at it. No template edits required.
|
|
23
|
+
- ⚙️ **One config dict** (`BANGLA_ADMIN`) controls branding, menu, colors, dashboard.
|
|
24
|
+
- ⚡ **SPA feel, no JS framework** — HTMX partial navigation; the admin never full-reloads.
|
|
25
|
+
- 🇧🇩 **First-class Bangla** — full Bn/En UI, instant cookie-based toggle, Bengali font stack, Bangla numerals (০১২৩).
|
|
26
|
+
- 📊 **Live dashboard** — stat cards, line / doughnut / bar charts (Chart.js), activity feed; charts recolor on theme/lang change.
|
|
27
|
+
- 🌗 **Dark default + light mode** — persisted toggle; charts and components follow.
|
|
28
|
+
- 📦 **Zero-build, offline-friendly** — prebuilt CSS, self-hosted fonts, vendored HTMX / Alpine / Chart.js. No CDN. Works on BDIX / offline VPS.
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install django-bangla-admin
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
# settings.py
|
|
38
|
+
INSTALLED_APPS = [
|
|
39
|
+
"django_bangla_admin", # BEFORE django.contrib.admin
|
|
40
|
+
"django.contrib.admin",
|
|
41
|
+
# ...
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
# i18n (the Django 4.2+ correct way — cookie + LocaleMiddleware)
|
|
45
|
+
USE_I18N = True
|
|
46
|
+
LANGUAGE_CODE = "bn"
|
|
47
|
+
LANGUAGES = [("bn", "বাংলা"), ("en", "English")]
|
|
48
|
+
|
|
49
|
+
MIDDLEWARE = [
|
|
50
|
+
# ...
|
|
51
|
+
"django.contrib.sessions.middleware.SessionMiddleware",
|
|
52
|
+
"django.middleware.locale.LocaleMiddleware", # after Session, before Common
|
|
53
|
+
"django.middleware.common.CommonMiddleware",
|
|
54
|
+
# ...
|
|
55
|
+
"django_bangla_admin.middleware.HtmxShellMiddleware", # strips shell on HX-Request
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
# Add the context processor for theme/language in templates
|
|
59
|
+
TEMPLATES[0]["OPTIONS"]["context_processors"] += [
|
|
60
|
+
"django_bangla_admin.context_processors.bangla_admin",
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
BANGLA_ADMIN = {"site_title": "My Shop Admin", "default_language": "bn"}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
# urls.py
|
|
68
|
+
from django.urls import path
|
|
69
|
+
from django_bangla_admin.sites import urls as ba_urls
|
|
70
|
+
|
|
71
|
+
urlpatterns = [path("admin/", ba_urls)]
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
That's it — a fully themed, Bangla, HTMX-driven admin with charts. Your existing
|
|
75
|
+
`@admin.register` / `admin.site.register` calls work unchanged: the themed site
|
|
76
|
+
mirrors the default admin registry automatically.
|
|
77
|
+
|
|
78
|
+
## Configuration
|
|
79
|
+
|
|
80
|
+
A single `BANGLA_ADMIN` dict, deep-merged over the defaults:
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
BANGLA_ADMIN = {
|
|
84
|
+
# Branding
|
|
85
|
+
"site_title": "Bangla Admin",
|
|
86
|
+
"site_brand": {"bn": "বাংলা অ্যাডমিন", "en": "Bangla Admin"},
|
|
87
|
+
"welcome_sign": {"bn": "স্বাগতম", "en": "Welcome"},
|
|
88
|
+
|
|
89
|
+
# Theme
|
|
90
|
+
"theme": "dark", # "dark" | "light"
|
|
91
|
+
"allow_theme_toggle": True,
|
|
92
|
+
"primary_color": "#2DD4BF",
|
|
93
|
+
|
|
94
|
+
# Language
|
|
95
|
+
"default_language": "bn",
|
|
96
|
+
"allow_language_toggle": True,
|
|
97
|
+
"bangla_numerals": True,
|
|
98
|
+
|
|
99
|
+
# Navigation — omit `menu` to auto-build from registered models
|
|
100
|
+
"menu": [
|
|
101
|
+
{"section": {"bn": "প্রধান", "en": "Main"}},
|
|
102
|
+
{"label": {"bn": "ড্যাশবোর্ড", "en": "Dashboard"},
|
|
103
|
+
"icon": "layout-dashboard", "url": "bangla_admin:index"},
|
|
104
|
+
{"label": {"bn": "অর্ডার", "en": "Orders"},
|
|
105
|
+
"icon": "shopping-cart", "model": "shop.Order"},
|
|
106
|
+
],
|
|
107
|
+
"icons": {"auth.User": "user"}, # per-model Lucide icons
|
|
108
|
+
"hide_apps": [], "hide_models": [],
|
|
109
|
+
|
|
110
|
+
# Dashboard
|
|
111
|
+
"dashboard": "django_bangla_admin.dashboard.default.DefaultDashboard",
|
|
112
|
+
"show_dashboard": True,
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Read values anywhere via `from django_bangla_admin.conf import ba_conf` → `ba_conf("theme")`.
|
|
117
|
+
|
|
118
|
+
## Custom dashboards
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
from django_bangla_admin.dashboard import Dashboard, StatCard, ChartWidget, ListWidget
|
|
122
|
+
|
|
123
|
+
class MyDashboard(Dashboard):
|
|
124
|
+
widgets = [
|
|
125
|
+
StatCard(label={"bn": "অর্ডার", "en": "Orders"},
|
|
126
|
+
value=lambda r: Order.objects.count(), icon="shopping-cart", trend="+8%"),
|
|
127
|
+
ChartWidget(id="sales", kind="line",
|
|
128
|
+
title={"bn": "বিক্রি", "en": "Sales"},
|
|
129
|
+
data_url="bangla_admin:ba_chart_data", params={"metric": "sales"}),
|
|
130
|
+
]
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Point `BANGLA_ADMIN["dashboard"]` at it. Register custom chart metrics with
|
|
134
|
+
`@register_metric("name")` from `django_bangla_admin.dashboard.data`, returning
|
|
135
|
+
`{"labels": [...], "datasets": [...]}`.
|
|
136
|
+
|
|
137
|
+
## Demo project
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
cd example
|
|
141
|
+
python manage.py migrate
|
|
142
|
+
python manage.py seed_demo # creates admin/admin + sample shop data
|
|
143
|
+
python manage.py runserver
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Open <http://127.0.0.1:8000/admin/> and log in with **admin / admin**.
|
|
147
|
+
|
|
148
|
+
## Development
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
pip install -e .
|
|
152
|
+
python -m django test tests --settings=tests.settings # run the suite
|
|
153
|
+
python scripts/compile_messages.py # compile .po -> .mo (no gettext needed)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Tech
|
|
157
|
+
|
|
158
|
+
HTMX 2 · Alpine.js 3 · Chart.js 4 · self-hosted Hind Siliguri / Inter fonts ·
|
|
159
|
+
Django 4.2 LTS → 5.x.
|
|
160
|
+
|
|
161
|
+
## License
|
|
162
|
+
|
|
163
|
+
MIT © [Ifte Samul Ohy](https://iftesamulohy.com)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""django-bangla-admin — a Bangladeshi Django admin theme & dashboard.
|
|
2
|
+
|
|
3
|
+
A free, open-source, reusable Django admin theme: HTMX SPA feel, live
|
|
4
|
+
Chart.js dashboards, Bangla <-> English switching, config-driven design.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
__version__ = "0.1.0"
|
|
8
|
+
|
|
9
|
+
default_app_config = "django_bangla_admin.apps.BanglaAdminConfig"
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""BanglaAdminSite — themed AdminSite with dashboard + chart-data endpoints.
|
|
2
|
+
|
|
3
|
+
Drop-in replacement for ``django.contrib.admin.site``. It reuses Django's
|
|
4
|
+
admin registry/permissions and only adds theming, a dashboard index, the
|
|
5
|
+
language-switch view, and JSON chart-data endpoints.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from django.contrib.admin import AdminSite
|
|
9
|
+
from django.urls import path
|
|
10
|
+
from django.utils.translation import gettext_lazy as _
|
|
11
|
+
|
|
12
|
+
from .conf import ba_conf
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BanglaAdminSite(AdminSite):
|
|
16
|
+
"""A themed admin site for a Bangladeshi audience."""
|
|
17
|
+
|
|
18
|
+
# Defaults; overridden per-request from BANGLA_ADMIN via each_context.
|
|
19
|
+
site_title = ba_conf("site_title")
|
|
20
|
+
site_header = ba_conf("site_header")
|
|
21
|
+
index_title = _("Dashboard")
|
|
22
|
+
enable_nav_sidebar = False # we render our own sidebar
|
|
23
|
+
|
|
24
|
+
def each_context(self, request):
|
|
25
|
+
context = super().each_context(request)
|
|
26
|
+
context.update(self._ba_context(request))
|
|
27
|
+
return context
|
|
28
|
+
|
|
29
|
+
def _ba_context(self, request):
|
|
30
|
+
"""Inject Bangla-admin specifics shared by every admin page."""
|
|
31
|
+
from .menu import build_menu
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
"ba": ba_conf.as_dict(),
|
|
35
|
+
"ba_menu": build_menu(request, self),
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
def get_urls(self):
|
|
39
|
+
from . import i18n, views
|
|
40
|
+
|
|
41
|
+
custom = [
|
|
42
|
+
path("ba/set-language/", self.admin_view(i18n.set_language), name="ba_set_language"),
|
|
43
|
+
path("ba/chart-data/", self.admin_view(views.chart_data), name="ba_chart_data"),
|
|
44
|
+
]
|
|
45
|
+
# Custom routes must precede the catch-all admin URLs.
|
|
46
|
+
return custom + super().get_urls()
|
|
47
|
+
|
|
48
|
+
def index(self, request, extra_context=None):
|
|
49
|
+
"""Render the dashboard if enabled, else the stock app index."""
|
|
50
|
+
if not ba_conf("show_dashboard", True):
|
|
51
|
+
return super().index(request, extra_context=extra_context)
|
|
52
|
+
|
|
53
|
+
from .dashboard.registry import get_dashboard
|
|
54
|
+
|
|
55
|
+
dashboard = get_dashboard()
|
|
56
|
+
context = {
|
|
57
|
+
**self.each_context(request),
|
|
58
|
+
"title": self.index_title,
|
|
59
|
+
"dashboard": dashboard,
|
|
60
|
+
"widgets": dashboard.render(request),
|
|
61
|
+
**(extra_context or {}),
|
|
62
|
+
}
|
|
63
|
+
request.current_app = self.name
|
|
64
|
+
from django.template.response import TemplateResponse
|
|
65
|
+
|
|
66
|
+
return TemplateResponse(request, "admin/index.html", context)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
# A shared site instance. Host projects can either use this directly or build
|
|
70
|
+
# their own. ``sites.py`` exposes its URLConf as ``urls``.
|
|
71
|
+
site = BanglaAdminSite(name="bangla_admin")
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from django.apps import AppConfig
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class BanglaAdminConfig(AppConfig):
|
|
5
|
+
name = "django_bangla_admin"
|
|
6
|
+
verbose_name = "Bangla Admin"
|
|
7
|
+
default_auto_field = "django.db.models.BigAutoField"
|
|
8
|
+
|
|
9
|
+
def ready(self):
|
|
10
|
+
# Validate/normalize the BANGLA_ADMIN setting early so misconfiguration
|
|
11
|
+
# surfaces at startup rather than on first request.
|
|
12
|
+
from .conf import ba_conf # noqa: F401
|
|
13
|
+
|
|
14
|
+
ba_conf.reload()
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""Lazy, cached accessor for the merged BANGLA_ADMIN configuration.
|
|
2
|
+
|
|
3
|
+
Usage::
|
|
4
|
+
|
|
5
|
+
from django_bangla_admin.conf import ba_conf
|
|
6
|
+
ba_conf("theme") # -> "dark"
|
|
7
|
+
ba_conf("menu", default=[]) # -> resolved value or default
|
|
8
|
+
ba_conf.as_dict() # -> full merged dict
|
|
9
|
+
|
|
10
|
+
The merged config is the host project's ``settings.BANGLA_ADMIN`` deep-merged
|
|
11
|
+
over :data:`django_bangla_admin.settings.DEFAULTS`.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import copy
|
|
15
|
+
|
|
16
|
+
from django.conf import settings
|
|
17
|
+
from django.dispatch import receiver
|
|
18
|
+
from django.test.signals import setting_changed
|
|
19
|
+
|
|
20
|
+
from .settings import DEFAULTS
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _deep_merge(base, override):
|
|
24
|
+
"""Recursively merge ``override`` onto a copy of ``base``."""
|
|
25
|
+
result = copy.deepcopy(base)
|
|
26
|
+
for key, value in (override or {}).items():
|
|
27
|
+
if (
|
|
28
|
+
key in result
|
|
29
|
+
and isinstance(result[key], dict)
|
|
30
|
+
and isinstance(value, dict)
|
|
31
|
+
):
|
|
32
|
+
result[key] = _deep_merge(result[key], value)
|
|
33
|
+
else:
|
|
34
|
+
result[key] = copy.deepcopy(value)
|
|
35
|
+
return result
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class _Conf:
|
|
39
|
+
"""Callable config accessor with a memoized merged dict."""
|
|
40
|
+
|
|
41
|
+
_cache = None
|
|
42
|
+
|
|
43
|
+
def reload(self):
|
|
44
|
+
user = getattr(settings, "BANGLA_ADMIN", {}) or {}
|
|
45
|
+
if not isinstance(user, dict):
|
|
46
|
+
raise TypeError("BANGLA_ADMIN setting must be a dict.")
|
|
47
|
+
self._cache = _deep_merge(DEFAULTS, user)
|
|
48
|
+
return self._cache
|
|
49
|
+
|
|
50
|
+
def as_dict(self):
|
|
51
|
+
if self._cache is None:
|
|
52
|
+
self.reload()
|
|
53
|
+
return self._cache
|
|
54
|
+
|
|
55
|
+
def __call__(self, key, default=None):
|
|
56
|
+
data = self.as_dict()
|
|
57
|
+
return data.get(key, default)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
ba_conf = _Conf()
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@receiver(setting_changed)
|
|
64
|
+
def _reload_on_setting_change(sender, setting, **kwargs):
|
|
65
|
+
# Keep config in sync when tests use override_settings(BANGLA_ADMIN=...).
|
|
66
|
+
if setting == "BANGLA_ADMIN":
|
|
67
|
+
ba_conf.reload()
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Template context processor injecting Bangla-admin config, language, theme.
|
|
2
|
+
|
|
3
|
+
Add ``"django_bangla_admin.context_processors.bangla_admin"`` to the template
|
|
4
|
+
``context_processors`` so non-admin templates (and admin templates rendered
|
|
5
|
+
outside ``each_context``) can read ``ba_*`` values.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from django.utils import translation
|
|
9
|
+
|
|
10
|
+
from .conf import ba_conf
|
|
11
|
+
|
|
12
|
+
THEME_COOKIE = "ba_theme"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def bangla_admin(request):
|
|
16
|
+
theme = request.COOKIES.get(THEME_COOKIE) or ba_conf("theme", "dark")
|
|
17
|
+
if theme not in ("dark", "light"):
|
|
18
|
+
theme = "dark"
|
|
19
|
+
lang = translation.get_language() or ba_conf("default_language", "bn")
|
|
20
|
+
return {
|
|
21
|
+
"ba": ba_conf.as_dict(),
|
|
22
|
+
"ba_theme": theme,
|
|
23
|
+
"ba_lang": lang,
|
|
24
|
+
"ba_is_htmx": request.headers.get("HX-Request") == "true",
|
|
25
|
+
}
|