This is an automated email from the ASF dual-hosted git repository.
yasithdev pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airavata-portals.git
The following commit(s) were added to refs/heads/main by this push:
new 0e339b1d1 refactor(portal): source the portal app-shell chrome from
settings instead of Wagtail (#112)
0e339b1d1 is described below
commit 0e339b1d1a4c94413cc3270537fe9989448cea6f
Author: Yasith Jayawardana <[email protected]>
AuthorDate: Mon Jun 8 01:18:03 2026 -0400
refactor(portal): source the portal app-shell chrome from settings instead
of Wagtail (#112)
The portal app shell (base.html) queried Wagtail snippet models
(GatewayIcon, GatewayTitle, NavExtra) for the favicon, header logo, title, and
user-menu dropdown links, so every portal page hard-depended on Wagtail being
installed and populated.
Introduce a Wagtail-free portal_chrome template-tag library
(django_airavata/apps/api/templatetags/portal_chrome.py) that sources these
from a small PORTAL_CHROME settings dict (empty-safe defaults, overridable in
settings_local) plus three plain-Django include templates that preserve the
original HTML and CSS classes. Only base.html is repointed.
Scope is deliberately limited to the app shell: the Wagtail navigation_tags
library and the CMS-page shell (the head/header/footer/nav-extra includes,
which are used only by the Wagtail page templates and render the page-tree
menu) are left untouched and keep working until the CMS itself is extracted in
a later step. Verified on a local dev baseline: manage.py check is green and
base.html renders without Wagtail.
---
.../apps/api/templatetags/__init__.py | 0
.../apps/api/templatetags/portal_chrome.py | 41 ++++++++++++++++++++++
airavata-django-portal/django_airavata/settings.py | 19 ++++++++++
.../django_airavata/templates/base.html | 10 +++---
.../templates/portal_chrome/favicon.html | 6 ++++
.../templates/portal_chrome/logo.html | 14 ++++++++
.../templates/portal_chrome/main_menu.html | 8 +++++
7 files changed, 93 insertions(+), 5 deletions(-)
diff --git
a/airavata-django-portal/django_airavata/apps/api/templatetags/__init__.py
b/airavata-django-portal/django_airavata/apps/api/templatetags/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git
a/airavata-django-portal/django_airavata/apps/api/templatetags/portal_chrome.py
b/airavata-django-portal/django_airavata/apps/api/templatetags/portal_chrome.py
new file mode 100644
index 000000000..02ff8c975
--- /dev/null
+++
b/airavata-django-portal/django_airavata/apps/api/templatetags/portal_chrome.py
@@ -0,0 +1,41 @@
+"""Template tags that render the portal app-shell ("chrome") from settings.
+
+These replace the Wagtail-backed ``navigation_tags`` used by ``base.html``,
+sourcing the favicon, header logo, title, and user-menu links from
+``settings.PORTAL_CHROME`` / ``settings.PORTAL_TITLE``. They must not import
+Wagtail. (The Wagtail CMS-page shell keeps its own ``navigation_tags`` until
the
+CMS is extracted.)
+"""
+
+from django import template
+from django.conf import settings
+
+register = template.Library()
+
+
+def _chrome():
+ return getattr(settings, "PORTAL_CHROME", {}) or {}
+
+
[email protected]_tag("portal_chrome/favicon.html")
+def portal_favicon():
+ return {"favicon_url": _chrome().get("favicon_url")}
+
+
[email protected]_tag("portal_chrome/logo.html")
+def portal_logo():
+ chrome = _chrome()
+ return {
+ "logo_url": chrome.get("logo_url"),
+ "logo_background_color": chrome.get("logo_background_color"),
+ }
+
+
[email protected]_tag
+def portal_title():
+ return _chrome().get("title") or getattr(settings, "PORTAL_TITLE", "")
+
+
[email protected]_tag("portal_chrome/main_menu.html")
+def portal_main_menu():
+ return {"user_menu_links": _chrome().get("user_menu_links") or []}
diff --git a/airavata-django-portal/django_airavata/settings.py
b/airavata-django-portal/django_airavata/settings.py
index 81de01b9b..df8e28a64 100644
--- a/airavata-django-portal/django_airavata/settings.py
+++ b/airavata-django-portal/django_airavata/settings.py
@@ -216,6 +216,25 @@ GATEWAY_USER_DATA_ARCHIVE_MINIMUM_ARCHIVE_SIZE_GB = 1
# Legacy (PGA) Portal link - provide a link to the legacy portal
PGA_URL = None
+# Portal title shown in the header and emails. Override in settings_local.py.
+PORTAL_TITLE = 'Airavata Django Portal'
+
+# Portal app-shell "chrome" (base.html): favicon, header logo, and user-menu
+# links. Previously sourced from Wagtail snippet models; now sourced from
+# settings so the app shell does not depend on Wagtail. Every key is optional;
+# override PORTAL_CHROME (and PORTAL_TITLE) in settings_local.py.
+PORTAL_CHROME = {
+ # Favicon URL (absolute or static). Falls back to the bundled Airavata
logo.
+ "favicon_url": None,
+ # Header logo image URL. Falls back to the bundled Airavata logo.
+ "logo_url": None,
+ # Optional background color for the header logo container.
+ "logo_background_color": None,
+ # Extra dropdown items in the user menu. List of
+ # {"link": str, "link_text": str, "icon_class": str}.
+ "user_menu_links": [],
+}
+
# Django REST Framework configuration
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
diff --git a/airavata-django-portal/django_airavata/templates/base.html
b/airavata-django-portal/django_airavata/templates/base.html
index b6ed84a65..2c65ff09a 100644
--- a/airavata-django-portal/django_airavata/templates/base.html
+++ b/airavata-django-portal/django_airavata/templates/base.html
@@ -1,10 +1,10 @@
-{% load navigation_tags static %}
+{% load portal_chrome static %}
{% load render_bundle from webpack_loader %}
{% load humanize %}
<!DOCTYPE html>
<head>
- {% favicon %}
+ {% portal_favicon %}
{% include "./django_airavata/google_analytics.html" %}
{% render_bundle 'chunk-vendors' 'css' 'COMMON' %}
@@ -148,9 +148,9 @@
<body>
<header class=c-header>
{% block header %}
- {% gateway_icon %}
+ {% portal_logo %}
{% endblock %}
- <div class=c-header__title><a href="/">{% block title %}{% gateway_title
%}{% endblock %}</a>
+ <div class=c-header__title><a href="/">{% block title %}{% portal_title
%}{% endblock %}</a>
</div>
{% if user.is_authenticated %}
<div class=c-header__controls>
@@ -195,7 +195,7 @@
{% endif %}
{% endfor %}
{% endif %}
- {% main_menu_navs %}
+ {% portal_main_menu %}
</div>
</div>
</div>
diff --git
a/airavata-django-portal/django_airavata/templates/portal_chrome/favicon.html
b/airavata-django-portal/django_airavata/templates/portal_chrome/favicon.html
new file mode 100644
index 000000000..d39a146dd
--- /dev/null
+++
b/airavata-django-portal/django_airavata/templates/portal_chrome/favicon.html
@@ -0,0 +1,6 @@
+{% load static %}
+{% if favicon_url %}
+<link rel="icon" href="{{ favicon_url }}">
+{% else %}
+<link rel="icon" href="{% static 'images/airavata-logo.png' %}">
+{% endif %}
diff --git
a/airavata-django-portal/django_airavata/templates/portal_chrome/logo.html
b/airavata-django-portal/django_airavata/templates/portal_chrome/logo.html
new file mode 100644
index 000000000..6d756ba44
--- /dev/null
+++ b/airavata-django-portal/django_airavata/templates/portal_chrome/logo.html
@@ -0,0 +1,14 @@
+{% load static %}
+{% if logo_url %}
+<div class=c-header__logo{% if logo_background_color %}
style="background-color: {{ logo_background_color }}"{% endif %}>
+ <a href="/">
+ <img src="{{ logo_url }}" />
+ </a>
+</div>
+{% else %}
+<div class=c-header__logo>
+ <a href="/">
+ <img src="{% static 'images/airavata-logo.png' %}" />
+ </a>
+</div>
+{% endif %}
diff --git
a/airavata-django-portal/django_airavata/templates/portal_chrome/main_menu.html
b/airavata-django-portal/django_airavata/templates/portal_chrome/main_menu.html
new file mode 100644
index 000000000..f0299eb7f
--- /dev/null
+++
b/airavata-django-portal/django_airavata/templates/portal_chrome/main_menu.html
@@ -0,0 +1,8 @@
+{% for nav_item in user_menu_links %}
+ {% if forloop.first %}
+ <div class="dropdown-divider"></div>
+ {% endif %}
+ <a class="dropdown-item" href="{{ nav_item.link }}">
+ <i class="fa {{ nav_item.icon_class|default:'fa-link' }} mr-2"></i>{{
nav_item.link_text }}
+ </a>
+{% endfor %}