diff --git a/allianceauth/apps.py b/allianceauth/apps.py
index 2e6bd289..053f71f8 100644
--- a/allianceauth/apps.py
+++ b/allianceauth/apps.py
@@ -1,5 +1,30 @@
from django.apps import AppConfig
+from django.core.checks import Warning, Error, register
class AllianceAuthConfig(AppConfig):
name = 'allianceauth'
+
+
+@register()
+def check_settings(app_configs, **kwargs):
+ from django.conf import settings
+
+ errors = []
+ if hasattr(settings, "SITE_URL"):
+ if settings.SITE_URL[-1] == "/":
+ errors.append(Warning(
+ "'SITE_URL' Has a trailing slash. This may lead to incorrect links being generated by Auth."))
+ else:
+ errors.append(Error(
+ "No 'SITE_URL' found is settings. This may lead to incorrect links being generated by Auth or Errors in 3rd party modules."))
+ if hasattr(settings, "CSRF_TRUSTED_ORIGINS"):
+ if hasattr(settings, "SITE_URL"):
+ if settings.SITE_URL not in settings.CSRF_TRUSTED_ORIGINS:
+ errors.append(Warning(
+ "'SITE_URL' not found in 'CSRF_TRUSTED_ORIGINS'. Auth may not load pages correctly until this is rectified."))
+ else:
+ errors.append(Error(
+ "No 'CSRF_TRUSTED_ORIGINS' found is settings, Auth may not load pages correctly until this is rectified"))
+
+ return errors
diff --git a/allianceauth/authentication/auth_hooks.py b/allianceauth/authentication/auth_hooks.py
new file mode 100644
index 00000000..abc22803
--- /dev/null
+++ b/allianceauth/authentication/auth_hooks.py
@@ -0,0 +1,45 @@
+from allianceauth.hooks import DashboardItemHook
+from allianceauth import hooks
+from .views import dashboard_characters, dashboard_groups, dashboard_admin
+
+
+class UserCharactersHook(DashboardItemHook):
+ def __init__(self):
+ DashboardItemHook.__init__(
+ self,
+ dashboard_characters,
+ 5
+ )
+
+
+class UserGroupsHook(DashboardItemHook):
+ def __init__(self):
+ DashboardItemHook.__init__(
+ self,
+ dashboard_groups,
+ 5
+ )
+
+
+class AdminHook(DashboardItemHook):
+ def __init__(self):
+ DashboardItemHook.__init__(
+ self,
+ dashboard_admin,
+ 0
+ )
+
+
+@hooks.register('dashboard_hook')
+def register_character_hook():
+ return UserCharactersHook()
+
+
+@hooks.register('dashboard_hook')
+def register_groups_hook():
+ return UserGroupsHook()
+
+
+@hooks.register('dashboard_hook')
+def register_admin_hook():
+ return AdminHook()
diff --git a/allianceauth/authentication/middleware.py b/allianceauth/authentication/middleware.py
index 5e2f0409..f2fc8145 100644
--- a/allianceauth/authentication/middleware.py
+++ b/allianceauth/authentication/middleware.py
@@ -31,6 +31,7 @@ class UserSettingsMiddleware(MiddlewareMixin):
except Exception as e:
logger.exception(e)
+ # AA v3 NIGHT_MODE
# Set our Night mode flag from the DB
# Null = hasnt been set by the user ever, dont act.
#
@@ -42,4 +43,11 @@ class UserSettingsMiddleware(MiddlewareMixin):
except Exception as e:
logger.exception(e)
+ # AA v4 Themes
+ try:
+ if request.user.profile.theme is not None:
+ request.session["THEME"] = request.user.profile.theme
+ except Exception as e:
+ logger.exception(e)
+
return response
diff --git a/allianceauth/authentication/migrations/0022_userprofile_theme.py b/allianceauth/authentication/migrations/0022_userprofile_theme.py
new file mode 100644
index 00000000..7dd64774
--- /dev/null
+++ b/allianceauth/authentication/migrations/0022_userprofile_theme.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.0.10 on 2023-10-07 07:59
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('authentication', '0021_alter_userprofile_language'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='userprofile',
+ name='theme',
+ field=models.CharField(blank=True, help_text='Bootstrap 5 Themes from https://bootswatch.com/ or Community Apps', max_length=200, null=True, verbose_name='Theme'),
+ ),
+ ]
diff --git a/allianceauth/authentication/models.py b/allianceauth/authentication/models.py
index 6d7a06b8..068eab14 100644
--- a/allianceauth/authentication/models.py
+++ b/allianceauth/authentication/models.py
@@ -101,6 +101,13 @@ class UserProfile(models.Model):
_("Night Mode"),
blank=True,
null=True)
+ theme = models.CharField(
+ _("Theme"),
+ max_length=200,
+ blank=True,
+ null=True,
+ help_text="Bootstrap 5 Themes from https://bootswatch.com/ or Community Apps"
+ )
def assign_state(self, state=None, commit=True):
if not state:
diff --git a/allianceauth/authentication/templates/authentication/dashboard.characters.html b/allianceauth/authentication/templates/authentication/dashboard.characters.html
new file mode 100644
index 00000000..6b4f4d09
--- /dev/null
+++ b/allianceauth/authentication/templates/authentication/dashboard.characters.html
@@ -0,0 +1,41 @@
+{% load i18n %}
+
+
+
+
+
+ {% translate "Characters" %}
+
+
+
+
+
+
+
+
+ |
+ {% translate "Name" %} |
+ {% translate "Corp" %} |
+ {% translate "Alliance" %} |
+
+
+
+ {% for char in characters %}
+
+
+ |
+ {{ char.character_name }} |
+ {{ char.corporation_name }} |
+ {{ char.alliance_name|default_if_none:"" }} |
+
+ {% endfor %}
+
+
+
+
+
+
+
diff --git a/allianceauth/authentication/templates/authentication/dashboard.groups.html b/allianceauth/authentication/templates/authentication/dashboard.groups.html
new file mode 100644
index 00000000..1a746a3b
--- /dev/null
+++ b/allianceauth/authentication/templates/authentication/dashboard.groups.html
@@ -0,0 +1,20 @@
+{% load i18n %}
+
+
+
+
{% translate "Membership" %}
+
+
+
{% translate "State:" %} {{ request.user.profile.state }}
+
+ {% for group in groups %}
+
+ {{ group.name }} |
+
+ {% endfor %}
+
+
+
+
+
+
diff --git a/allianceauth/authentication/templates/authentication/dashboard.html b/allianceauth/authentication/templates/authentication/dashboard.html
index 896dddfe..af1ece0d 100644
--- a/allianceauth/authentication/templates/authentication/dashboard.html
+++ b/allianceauth/authentication/templates/authentication/dashboard.html
@@ -1,190 +1,15 @@
-{% extends "allianceauth/base.html" %}
+{% extends "allianceauth/base-bs5.html" %}
+{% load static %}
{% load i18n %}
{% block page_title %}{% translate "Dashboard" %}{% endblock %}
-
+{% block header_nav_brand %}
+ {% translate "Dashboard" %}
+{% endblock %}
{% block content %}
-
- {% if user.is_staff %}
- {% include 'allianceauth/admin-status/include.html' %}
- {% endif %}
-
-
-
-
-
-
- {% blocktranslate with state=request.user.profile.state %}
- Main Character (State: {{ state }})
- {% endblocktranslate %}
-
-
-
- {% if request.user.profile.main_character %}
- {% with request.user.profile.main_character as main %}
-
-
-
-
-
-
- |
-
-
- {{ main.character_name }} |
-
-
-
-
-
-
-
-
- |
-
-
- {{ main.corporation_name }} |
-
-
-
-
- {% if main.alliance_id %}
-
-
-
-
- |
-
-
- {{ main.alliance_name }} |
-
-
- {% elif main.faction_id %}
-
-
-
-
- |
-
-
- {{ main.faction_name }} |
-
-
- {% endif %}
-
-
-
-
-
-
- {% if main.alliance_id %}
-
- {% endif %}
- {% if main.faction_id %}
-
- {% endif %}
-
-
- {{ main.character_name }}
- {{ main.corporation_name }}
- {% if main.alliance_id %}
- {{ main.alliance_name }}
- {% endif %}
- {% if main.faction_id %}
- {{ main.faction_name }}
- {% endif %}
-
-
- {% endwith %}
- {% else %}
-
- {% translate "No main character set." %}
-
- {% endif %}
-
-
-
-
-
-
-
-
-
{% translate "Group Memberships" %}
-
-
-
-
- {% for group in groups %}
-
- {{ group.name }} |
-
- {% endfor %}
-
-
-
-
-
-
-
-
-
-
- {% translate 'Characters' %}
-
-
-
-
-
-
- |
- {% translate 'Name' %} |
- {% translate 'Corp' %} |
- {% translate 'Alliance' %} |
-
-
-
- {% for char in characters %}
-
-
-
- |
- {{ char.character_name }} |
- {{ char.corporation_name }} |
- {{ char.alliance_name|default:"" }} |
-
- {% endfor %}
-
-
-
-
- {% for char in characters %}
-
-
-
- |
-
- {{ char.character_name }}
- {{ char.corporation_name }}
- {{ char.alliance_name|default:"" }}
- |
-
- {% endfor %}
-
-
-
-
+
+ {% for dash in views %}
+ {{ dash | safe }}
+ {% endfor %}
{% endblock %}
diff --git a/allianceauth/authentication/templates/authentication/tokens.html b/allianceauth/authentication/templates/authentication/tokens.html
index 11bb91ed..cb99e2c3 100644
--- a/allianceauth/authentication/templates/authentication/tokens.html
+++ b/allianceauth/authentication/templates/authentication/tokens.html
@@ -1,7 +1,7 @@
-{% extends "allianceauth/base.html" %}
+{% extends "allianceauth/base-bs5.html" %}
{% load i18n %}
-{% block page_title %}{% translate "Dashboard" %}{% endblock %}
+{% block page_title %}{% translate "Dashboard" %}{% endblock page_title %}
{% block content %}
@@ -10,7 +10,7 @@
{% translate "Scopes" %} |
- {% translate "Actions" %} |
+ {% translate "Actions" %} |
{% translate "Character" %} |
@@ -18,24 +18,24 @@
{% for t in tokens %}
- {% for s in t.scopes.all %}{{s.name}} {% endfor %} |
- |
- {{t.character_name}} |
+ {% for s in t.scopes.all %}{{ s.name }} {% endfor %} |
+ |
+ {{ t.character_name }} |
{% endfor %}
{% translate "This page is a best attempt, but backups or database logs can still contain your tokens. Always revoke tokens on https://community.eveonline.com/support/third-party-applications/ where possible."|urlize %}
-{% endblock %}
+{% endblock content %}
{% block extra_javascript %}
- {% include 'bundles/datatables-js.html' %}
-{% endblock %}
+ {% include "bundles/datatables-js-bs5.html" %}
+{% endblock extra_javascript %}
{% block extra_css %}
- {% include 'bundles/datatables-css.html' %}
-{% endblock %}
+ {% include "bundles/datatables-css-bs5.html" %}
+{% endblock extra_css %}
{% block extra_script %}
$(document).ready(function(){
@@ -59,4 +59,4 @@
"stateSave": true,
});
});
-{% endblock %}
+{% endblock extra_script %}
diff --git a/allianceauth/authentication/templates/public/base.html b/allianceauth/authentication/templates/public/base.html
index 62529bda..f5cb128c 100644
--- a/allianceauth/authentication/templates/public/base.html
+++ b/allianceauth/authentication/templates/public/base.html
@@ -7,6 +7,7 @@
+
diff --git a/allianceauth/authentication/views.py b/allianceauth/authentication/views.py
index 15c746c7..b6fa6411 100644
--- a/allianceauth/authentication/views.py
+++ b/allianceauth/authentication/views.py
@@ -1,4 +1,5 @@
import logging
+from allianceauth.hooks import get_hooks
from django_registration.backends.activation.views import (
REGISTRATION_SALT, ActivationView as BaseActivationView,
@@ -42,23 +43,51 @@ def index(request):
return redirect('authentication:dashboard')
-@login_required
-def dashboard(request):
+def dashboard_groups(request):
groups = request.user.groups.all()
if _has_auto_groups:
groups = groups\
.filter(managedalliancegroup__isnull=True)\
.filter(managedcorpgroup__isnull=True)
groups = groups.order_by('name')
+
+ context = {
+ 'groups': groups,
+ }
+ return render_to_string('authentication/dashboard.groups.html', context=context, request=request)
+
+
+def dashboard_characters(request):
characters = EveCharacter.objects\
.filter(character_ownership__user=request.user)\
.select_related()\
.order_by('character_name')
context = {
- 'groups': groups,
'characters': characters
}
+ return render_to_string('authentication/dashboard.characters.html', context=context, request=request)
+
+
+def dashboard_admin(request):
+ if request.user.is_superuser:
+ return render_to_string('allianceauth/admin-status/include.html', request=request)
+ else:
+ return ""
+
+
+@login_required
+def dashboard(request):
+ _dash_items = list()
+ hooks = get_hooks('dashboard_hook')
+ items = [fn() for fn in hooks]
+ items.sort(key=lambda i: i.order)
+ for item in items:
+ _dash_items.append(item.render(request))
+
+ context = {
+ 'views': _dash_items,
+ }
return render(request, 'authentication/dashboard.html', context)
diff --git a/allianceauth/context_processors.py b/allianceauth/context_processors.py
index 4feb243e..cafde2ea 100644
--- a/allianceauth/context_processors.py
+++ b/allianceauth/context_processors.py
@@ -1,5 +1,5 @@
from django.conf import settings
-from .views import NightModeRedirectView
+from .views import NightModeRedirectView, ThemeRedirectView
def auth_settings(request):
diff --git a/allianceauth/corputils/auth_hooks.py b/allianceauth/corputils/auth_hooks.py
index d90d7f3c..77bfae91 100644
--- a/allianceauth/corputils/auth_hooks.py
+++ b/allianceauth/corputils/auth_hooks.py
@@ -1,4 +1,5 @@
-from allianceauth.services.hooks import MenuItemHook, UrlHook
+from allianceauth.menu.hooks import MenuItemHook
+from allianceauth.services.hooks import UrlHook
from django.utils.translation import gettext_lazy as _
from allianceauth import hooks
from allianceauth.corputils import urls
diff --git a/allianceauth/corputils/templates/corputils/base.html b/allianceauth/corputils/templates/corputils/base.html
index 17300d94..aff00288 100644
--- a/allianceauth/corputils/templates/corputils/base.html
+++ b/allianceauth/corputils/templates/corputils/base.html
@@ -1,6 +1,8 @@
-{% extends 'allianceauth/base.html' %}
+{% extends "allianceauth/base-bs5.html" %}
{% load i18n %}
-{% block page_title %}{% translate "Corporation Member Data" %}{% endblock %}
+{% block page_title %}
+ {% translate "Corporation Member Data" %}
+{% endblock page_title %}
{% block content %}
- {% block member_data %}{% endblock %}
+ {% block member_data %}
+ {% endblock member_data %}
-{% endblock %}
+{% endblock content %}
diff --git a/allianceauth/corputils/templates/corputils/corpstats.html b/allianceauth/corputils/templates/corputils/corpstats.html
index d1d7cc16..9458bc25 100644
--- a/allianceauth/corputils/templates/corputils/corpstats.html
+++ b/allianceauth/corputils/templates/corputils/corpstats.html
@@ -87,7 +87,7 @@
{{ alt.corporation_name }} |
{{ alt.alliance_name }} |
-
+
{% translate "Killboard" %}
|
@@ -122,7 +122,7 @@
 |
{{ member }} |
- {% translate "Killboard" %}
+ {% translate "Killboard" %}
|
{{ member.character_ownership.user.profile.main_character.character_name }} |
{{ member.character_ownership.user.profile.main_character.corporation_name }} |
@@ -134,7 +134,7 @@
 |
{{ member.character_name }} |
- {% translate "Killboard" %}
+ {% translate "Killboard" %}
|
|
|
@@ -163,7 +163,7 @@
 |
{{ member.character_name }} |
-
+
{% translate "Killboard" %}
|
diff --git a/allianceauth/corputils/templates/corputils/search.html b/allianceauth/corputils/templates/corputils/search.html
index 83c34802..d5d9c6c0 100644
--- a/allianceauth/corputils/templates/corputils/search.html
+++ b/allianceauth/corputils/templates/corputils/search.html
@@ -24,7 +24,7 @@
 |
{{ result.1.character_name }} |
{{ result.0.corp.corporation_name }} |
- {% translate "Killboard" %} |
+ {% translate "Killboard" %} |
{{ result.1.main_character.character_name }} |
{{ result.1.main_character.corporation_name }} |
{{ result.1.main_character.alliance_name }} |
diff --git a/allianceauth/eveonline/templatetags/examples.html b/allianceauth/eveonline/templatetags/examples.html
index 180aa3f8..486394c8 100644
--- a/allianceauth/eveonline/templatetags/examples.html
+++ b/allianceauth/eveonline/templatetags/examples.html
@@ -8,10 +8,10 @@ Needs to be called with a context containing three objects:
-->
-{% extends 'allianceauth/base.html' %}
+{% extends "allianceauth/base-bs5.html" %}
{% load evelinks %}
-{% block page_title %}Evelinks examples{% endblock %}
+{% block page_title %}Evelinks Examples{% endblock page_title %}
{% block content %}
@@ -25,60 +25,57 @@ Needs to be called with a context containing three objects:
-
image URLs
-
character from ID: 
-
character from character object: 
+
character from ID: 
+
character from character object: 
-
corporation from ID: 
-
corporation from character object: 
-
corporation from corporation object: 
+
corporation from ID: 
+
corporation from character object: 
+
corporation from corporation object: 
-
alliance from ID: 
-
alliance from character object: 
-
alliance from alliance object: 
+
alliance from ID: 
+
alliance from character object: 
+
alliance from alliance object: 
-
-
-{% endblock %}
+{% endblock content %}
diff --git a/allianceauth/fleetactivitytracking/auth_hooks.py b/allianceauth/fleetactivitytracking/auth_hooks.py
index 8d71fc13..4c68b340 100644
--- a/allianceauth/fleetactivitytracking/auth_hooks.py
+++ b/allianceauth/fleetactivitytracking/auth_hooks.py
@@ -1,7 +1,8 @@
+from allianceauth.menu.hooks import MenuItemHook
from . import urls
from django.utils.translation import gettext_lazy as _
from allianceauth import hooks
-from allianceauth.services.hooks import MenuItemHook, UrlHook
+from allianceauth.services.hooks import UrlHook
@hooks.register('menu_item_hook')
diff --git a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/characternotexisting.html b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/characternotexisting.html
index d0b9d8ae..fe015866 100644
--- a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/characternotexisting.html
+++ b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/characternotexisting.html
@@ -1,27 +1,28 @@
-{% extends 'allianceauth/base.html' %}
+{% extends 'allianceauth/base-bs5.html' %}
{% load i18n %}
-{% block page_title %}{% translate "Fleet Participation" %}{% endblock %}
-
+{% block page_title %}
+ {% translate "Fleet Participation" %}
+{% endblock %}
{% block content %}
-
-
-
-
-
-
-
{{ character_name }}
-
-
-

-
-
-
{% translate "Character not registered!" %}
- {% translate "This character is not associated with an auth account." %}
{% translate "Add it here" %} {% translate "before attempting to click fleet attendance links." %}
+
+
+
+
+
+
+
{{ character_name }}
+
+
+

+
+
+
{% translate "Character not registered!" %}
+ {% translate "This character is not associated with an auth account." %}
{% translate "Add it here" %} {% translate "before attempting to click fleet attendance links." %}
+
-
{% endblock %}
diff --git a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkformatter.html b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkformatter.html
index 25f9656e..493bf9af 100644
--- a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkformatter.html
+++ b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkformatter.html
@@ -1,31 +1,31 @@
-{% extends "allianceauth/base.html" %}
+{% extends "allianceauth/base-bs5.html" %}
{% load bootstrap %}
{% load i18n %}
-
-{% block page_title %}{% translate "Create Fatlink" %}{% endblock page_title %}
-
+{% block page_title %}
+ {% translate "Create Fatlink" %}
+{% endblock page_title %}
{% block content %}
-
{% if badrequest %}
-
{% translate "Bad request!" %}
+
{% translate "Bad request!" %}
{% endif %}
- {% for message in errormessages %}
-
{{ message }}
- {% endfor %}
-
+ {% for message in errormessages %}
{{ message }}
{% endfor %}
+
-
{% endblock content %}
diff --git a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html
index b794b646..5415cb54 100644
--- a/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html
+++ b/allianceauth/fleetactivitytracking/templates/fleetactivitytracking/fatlinkmodify.html
@@ -1,11 +1,11 @@
-{% extends "allianceauth/base.html" %}
+{% extends "allianceauth/base-bs5.html" %}
{% load i18n %}
{% block page_title %}{% translate "Fatlink view" %}{% endblock page_title %}
{% block content %}