From bc0195bbaabd3698eafc956e8340ab19eacbdf07 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 2 Oct 2011 22:37:07 +0200 Subject: [PATCH] Worked with admin interface, cleaning up and adding functionality. There are still some strange behaviour that makes e.g. the presence of inlines to auto-create empty database objects for some strange reason. Inlines are turned off at the moment (so there is no convenient way to add attributes from the admin interface at this time). Creating players now work, but one needs to create all three components (User, Player, Character) in one go and tie them together. The User-admin form was changed to also support multi-word usernames (django default didn't allow spaces). --- src/commands/default/unloggedin.py | 7 +- src/comms/admin.py | 6 +- src/help/admin.py | 20 +++- src/help/models.py | 10 +- src/locks/lockhandler.py | 6 +- src/objects/admin.py | 92 +++++++++++++++++- src/objects/models.py | 3 +- src/players/admin.py | 148 +++++++++++++++++++++++++---- src/players/models.py | 5 +- src/scripts/admin.py | 4 +- src/settings_default.py | 1 + src/typeclasses/models.py | 4 +- src/web/templates/admin/index.html | 94 ++++-------------- src/web/utils/general_context.py | 2 +- 14 files changed, 285 insertions(+), 117 deletions(-) diff --git a/src/commands/default/unloggedin.py b/src/commands/default/unloggedin.py index efdd2e4c1e..dc23596969 100644 --- a/src/commands/default/unloggedin.py +++ b/src/commands/default/unloggedin.py @@ -1,6 +1,7 @@ """ Commands that are available from the connect screen. """ +import re import traceback from django.conf import settings from django.contrib.auth.models import User @@ -121,9 +122,9 @@ class CmdCreate(MuxCommand): string = "\n\r Usage (without <>): create \"\" " session.msg(string) return - if not playername: - # entered an empty string - session.msg("\n\r You have to supply a longer playername, surrounded by quotes.") + if not re.findall('^[\w. @+-]+$', playername) or not (0 < len(playername) <= 30): + session.msg("\n\r Playername can max be 30 characters or fewer. Letters, spaces, dig\ +its and @/./+/-/_ only.") # this echoes the restrictions made by django's auth module. return if not email or not password: session.msg("\n\r You have to supply an e-mail address followed by a password." ) diff --git a/src/comms/admin.py b/src/comms/admin.py index 14e923aaa1..4ce9886978 100644 --- a/src/comms/admin.py +++ b/src/comms/admin.py @@ -15,7 +15,6 @@ class MsgAdmin(admin.ModelAdmin): save_as = True save_on_top = True list_select_related = True - #admin.site.register(Msg, MsgAdmin) class PlayerChannelConnectionInline(admin.TabularInline): @@ -24,7 +23,8 @@ class PlayerChannelConnectionInline(admin.TabularInline): (None, { 'fields':(('db_player', 'db_channel')), 'classes':('collapse',)}),) - max_num = 1 + extra = 1 + class ExternalChannelConnectionInline(admin.StackedInline): model = ExternalChannelConnection fieldsets = ( @@ -32,7 +32,7 @@ class ExternalChannelConnectionInline(admin.StackedInline): 'fields':(('db_is_enabled','db_external_key', 'db_channel'), 'db_external_send_code', 'db_external_config'), 'classes':('collapse',) }),) - max_num = 1 + extra = 1 class ChannelAdmin(admin.ModelAdmin): inlines = (PlayerChannelConnectionInline, ExternalChannelConnectionInline) diff --git a/src/help/admin.py b/src/help/admin.py index 62014cd278..b82b12b0db 100644 --- a/src/help/admin.py +++ b/src/help/admin.py @@ -1,8 +1,24 @@ +""" +This defines how to edit help entries in Admin. +""" +from django import forms from django.contrib import admin from src.help.models import HelpEntry + + +class HelpEntryForm(forms.ModelForm): + "Defines how to display the help entry" + class Meta: + model = HelpEntry + db_help_category = forms.CharField(label="Help category", initial='General', + help_text="organizes help entries in lists") + db_lock_storage = forms.CharField(label="Locks", initial='view:all()',required=False, + widget=forms.TextInput(attrs={'size':'40'}),) + class HelpEntryAdmin(admin.ModelAdmin): - + "Sets up the admin manaager for help entries" + list_display = ('id', 'db_key', 'db_help_category', 'db_lock_storage') list_display_links = ('id', 'db_key') search_fields = ['^db_key', 'db_entrytext'] @@ -10,6 +26,8 @@ class HelpEntryAdmin(admin.ModelAdmin): save_as = True save_on_top = True list_select_related = True + + form = HelpEntryForm fieldsets = ( (None, {'fields':(('db_key', 'db_help_category'), 'db_entrytext', 'db_lock_storage'), 'description':"Sets a Help entry. Set lock to view:all() unless you want to restrict it."}),) diff --git a/src/help/models.py b/src/help/models.py index 184111fa9b..87cc74ac0c 100644 --- a/src/help/models.py +++ b/src/help/models.py @@ -42,16 +42,16 @@ class HelpEntry(SharedMemoryModel): # named same as the field, but withtout the db_* prefix. # title of the help - db_key = models.CharField('help key', max_length=255, unique=True, help_text='Key to search for.') + db_key = models.CharField('help key', max_length=255, unique=True, help_text='key to search for') # help category db_help_category = models.CharField("help category", max_length=255, default="General", - help_text='Organizes help entries in lists.') + help_text='organizes help entries in lists') # the actual help entry text, in any formatting. - db_entrytext = models.TextField('help entry', blank=True, help_text='The main body of help text.') - # a string of permissionstrings, separated by commas. + db_entrytext = models.TextField('help entry', blank=True, help_text='the main body of help text') + # a string of permissionstrings, separated by commas. Not used by help entries. db_permissions = models.CharField('permissions', max_length=255, blank=True) # lock string storage - db_lock_storage = models.CharField('locks', max_length=512, blank=True, help_text='Normally view:all().') + db_lock_storage = models.CharField('locks', max_length=512, blank=True, help_text='normally view:all().') # (deprecated, only here to allow MUX helpfile load (don't use otherwise)). # TODO: remove this when not needed anymore. db_staff_only = models.BooleanField(default=False) diff --git a/src/locks/lockhandler.py b/src/locks/lockhandler.py index f42121e1af..98610bf716 100644 --- a/src/locks/lockhandler.py +++ b/src/locks/lockhandler.py @@ -193,7 +193,11 @@ class LockHandler(object): wlist = [] # warnings for raw_lockstring in storage_lockstring.split(';'): lock_funcs = [] - access_type, rhs = (part.strip() for part in raw_lockstring.split(':', 1)) + try: + access_type, rhs = (part.strip() for part in raw_lockstring.split(':', 1)) + except ValueError: + logger.log_trace() + return locks # parse the lock functions and separators funclist = RE_FUNCS.findall(rhs) diff --git a/src/objects/admin.py b/src/objects/admin.py index b51ddcbe80..6cb6fee30e 100644 --- a/src/objects/admin.py +++ b/src/objects/admin.py @@ -3,15 +3,51 @@ # in the web admin interface. # -from src.objects.models import ObjAttribute, ObjectDB +from django import forms +from django.conf import settings from django.contrib import admin +from src.objects.models import ObjAttribute, ObjectDB +from src.utils.utils import mod_import + +class ObjectAttributeAdmin(admin.ModelAdmin): + list_display = ('id', 'db_key', 'db_obj') + list_display_links = ('id', 'db_key') + ordering = ('db_obj','db_key', 'id') + search_fields = ('^db_key', 'db_obj') + save_as = True + save_on_top = True + list_select_related = True +admin.site.register(ObjAttribute, ObjectAttributeAdmin) class ObjAttributeInline(admin.TabularInline): model = ObjAttribute fields = ('db_key', 'db_value') - max_num = 1 + extra = 1 +class ObjectEditForm(forms.ModelForm): + "This form details the look of the fields" + class Meta: + model = ObjectDB + db_typeclass_path = forms.CharField(label="Typeclass",initial=settings.BASE_OBJECT_TYPECLASS, + help_text="this defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass.") + db_permissions = forms.CharField(label="Permissions", required=False, + help_text="a comma-separated list of text strings checked by certain locks. They are mainly of use for Character objects. Character permissions overload permissions defined on a controlling Player. Most objects normally don't have any permissions defined.") + db_lock_storage = forms.CharField(label="Locks", required=False, widget=forms.Textarea(attrs={'cols':'100', 'rows':'1'}), + help_text="locks limit access to an entity. A lock is defined as a 'lock string' on the form 'type:lockfunctions', defining what functionality is locked and how to determine access. Take a look at other Objects to see valid strings. An empty lock means no access is given to anything for anyone. ") + +class ObjectCreateForm(forms.ModelForm): + "This form details the look of the fields" + class Meta: + model = ObjectDB + fields = ('db_key',) + db_typeclass_path = forms.CharField(label="Typeclass",initial=settings.BASE_OBJECT_TYPECLASS, + help_text="this defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass.") + db_permissions = forms.CharField(label="Permissions", initial=settings.PERMISSION_PLAYER_DEFAULT,required=False, + help_text="a comma-separated list of text strings checked by certain locks. They are mainly of use for Character objects. Character permissions overload permissions defined on a controlling Player. Most objects normally don't have any permissions defined.") + + class ObjectDBAdmin(admin.ModelAdmin): + list_display = ('id', 'db_key', 'db_location', 'db_player', 'db_typeclass_path') list_display_links = ('id', 'db_key') ordering = ['db_player', 'db_typeclass_path', 'id'] @@ -20,6 +56,56 @@ class ObjectDBAdmin(admin.ModelAdmin): save_as = True save_on_top = True list_select_related = True - inlines = [ObjAttributeInline] + + # editing fields setup + + form = ObjectEditForm + fieldsets = ( + (None, { + 'fields': (('db_key','db_typeclass_path'), ('db_permissions', 'db_lock_storage'), + ('db_location', 'db_home'), 'db_destination','db_cmdset_storage' + )}), + ) + + #deactivated temporarily, they cause empty objects to be created in admin + #inlines = [ObjAttributeInline] + + + # Custom modification to give two different forms wether adding or not. + + add_form = ObjectCreateForm + add_fieldsets = ( + (None, { + 'fields': (('db_key','db_typeclass_path'), 'db_permissions', + ('db_location', 'db_home'), 'db_destination','db_cmdset_storage' + )}), + ) + def get_fieldsets(self, request, obj=None): + if not obj: + return self.add_fieldsets + return super(ObjectDBAdmin, self).get_fieldsets(request, obj) + + def get_form(self, request, obj=None, **kwargs): + """ + Use special form during creation + """ + defaults = {} + if obj is None: + defaults.update({ + 'form': self.add_form, + 'fields': admin.util.flatten_fieldsets(self.add_fieldsets), + }) + defaults.update(kwargs) + return super(ObjectDBAdmin, self).get_form(request, obj, **defaults) + + def save_model(self, request, obj, form, change): + if not change: + # adding a new object + obj = obj.typeclass + obj.basetype_setup() + obj.basetype_posthook_setup() + obj.at_object_creation() + obj.at_init() + admin.site.register(ObjectDB, ObjectDBAdmin) diff --git a/src/objects/models.py b/src/objects/models.py index d97b01c8ff..9cfea701a4 100644 --- a/src/objects/models.py +++ b/src/objects/models.py @@ -178,7 +178,8 @@ class ObjectDB(TypedObject): blank=True, null=True, verbose_name='destination', help_text='a destination, used only by exit objects.') # database storage of persistant cmdsets. - db_cmdset_storage = models.CharField('cmdset', max_length=255, null=True) + db_cmdset_storage = models.CharField('cmdset', max_length=255, null=True, blank=True, + help_text="optional python path to a cmdset class.") # Database manager objects = ObjectManager() diff --git a/src/players/admin.py b/src/players/admin.py index 6460292fdd..8b1b86d8d9 100644 --- a/src/players/admin.py +++ b/src/players/admin.py @@ -3,43 +3,99 @@ # in the web admin interface. # +from django import forms +from django.db import models +from django.conf import settings from django.contrib import admin from django.contrib.auth.admin import UserAdmin as BaseUserAdmin -from django.contrib.auth.models import User, Group +from django.contrib.admin import widgets +from django.contrib.auth.forms import UserChangeForm, UserCreationForm +from django.contrib.auth.models import User from src.players.models import PlayerDB, PlayerAttribute # remove User itself from admin site admin.site.unregister(User) -#admin.site.unregister(Group) -class PlayerInline(admin.TabularInline): - model = PlayerDB +# handle the custom User editor + +class CustomUserChangeForm(UserChangeForm): + username = forms.RegexField(label="Username", max_length=30, regex=r'^[\w. @+-]+$',widget=forms.TextInput(attrs={'size':'30'}), + help_text = "This should be the same as the connected Player's key name. 30 characters or fewer. Letters, spaces, digits and @/./+/-/_ only.", + error_messages = {'invalid': "This value may contain only letters, spaces, numbers and @/./+/-/_ characters."}) +class CustomUserCreationForm(UserCreationForm): + username = forms.RegexField(label="Username", max_length=30, regex=r'^[\w. @+-]+$',widget=forms.TextInput(attrs={'size':'30'}), + help_text = "This should be the same as the connected Player's key name. 30 characters or fewer. Letters, spaces, digits and @/./+/-/_ only.", + error_messages = {'invalid': "This value may contain only letters, spaces, numbers and @/./+/-/_ characters."}) + class UserAdmin(BaseUserAdmin): + "This will pop up from the Player admin." + + list_display = ('username', 'email', 'is_staff', 'is_superuser') + + form = CustomUserChangeForm + add_form = CustomUserCreationForm add_fieldsets = ( (None, {'fields': ('username', 'email', 'password1', 'password2', ('is_staff', 'is_superuser')), - 'description':'Note that whereas Player name supports spaces, This User field does not!'},), - ) - + 'description':"The User object holds all authentication information and bits for using the admin site. A superuser account represents a 'God user' in-game. This User account should have the same username as its corresponding Player object has; the two are always uniquely connected to each other."},),) admin.site.register(User, UserAdmin) -# class PlayerAttributeAdmin(admin.ModelAdmin): -# fields = ('db_key', 'db_value') -# admin.site.register(PlayerAttribute, PlayerAttributeAdmin) + +# The Player editor +class PlayerAttributeForm(forms.ModelForm): + "Defines how to display the atttributes" + class Meta: + model = PlayerAttribute + db_key = forms.CharField(label="Key", widget=forms.TextInput(attrs={'size':'15'})) + db_value = forms.CharField(label="Value", widget=forms.Textarea(attrs={'rows':'2'})) class PlayerAttributeInline(admin.TabularInline): + "Inline creation of player attributes" model = PlayerAttribute - #fields = ('db_key', 'db_value') + extra = 1 + form = PlayerAttributeForm fieldsets = ( - ("Attributes", - {'fields' : (('db_key', 'db_value')), - 'classes' : ('wide',)}), ) + (None, {'fields' : (('db_key', 'db_value'))}),) - max_num = 1 +class PlayerEditForm(forms.ModelForm): + "This form details the look of the fields" + class Meta: + # important! This allows us to not excplicitly add all fields. + model = PlayerDB + + db_key = forms.RegexField(label="Username", max_length=30, regex=r'^[\w. @+-]+$', widget=forms.TextInput(attrs={'size':'30'}), + help_text = "this should be the same as the User's name. 30 characters or fewer. Letters, spaces, digits and @/./+/-/_ only.") + db_typeclass_path = forms.CharField(label="Typeclass",initial=settings.BASE_PLAYER_TYPECLASS, widget=forms.TextInput(attrs={'size':'78'}), + help_text="this defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass.") + db_permissions = forms.CharField(label="Permissions", initial=settings.PERMISSION_PLAYER_DEFAULT,required=False, + help_text="a comma-separated list of text strings checked by certain locks. They are often used for hierarchies, such as letting a Player have permission 'Wizards', 'Builders' etc. A Player permission can be overloaded by the permissions of a controlled Character. Normal players use 'Players' by default.") + db_lock_storage = forms.CharField(label="Locks", widget=forms.Textarea(attrs={'cols':'100', 'rows':'1'}), + required=False, + help_text="locks limit access to an entity. A lock is defined as a 'lock string' on the form 'type:lockfunctions', defining what functionality is locked and how to determine access. This is set to a default upon creation.") + db_cmdset_storage = forms.CharField(label="cmdset", initial=settings.CMDSET_OOC, widget=forms.TextInput(attrs={'size':'78'}), + required=False, + help_text="python path to cmdset class.") +class PlayerCreateForm(forms.ModelForm): + "This form details the look of the fields" + + class Meta: + # important! This allows us to not excplicitly add all fields. + model = PlayerDB + + db_key = forms.RegexField(label="Username", max_length=30, regex=r'^[\w. @+-]+$', widget=forms.TextInput(attrs={'size':'30'}), + help_text = "this should be the same as the User's name. 30 characters or fewer. Letters, spaces, digits and @/./+/-/_ only.") + db_typeclass_path = forms.CharField(label="Typeclass",initial=settings.BASE_PLAYER_TYPECLASS, widget=forms.TextInput(attrs={'size':'78'}), + help_text="this defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass.") + db_permissions = forms.CharField(label="Permissions", initial=settings.PERMISSION_PLAYER_DEFAULT,required=False, + help_text="a comma-separated list of text strings checked by certain locks. They are often used for hierarchies, such as letting a Player have permission 'Wizards', 'Builders' etc. A Player permission can be overloaded by the permissions of a controlled Character. Normal players use 'Players' by default.") + db_cmdset_storage = forms.CharField(label="cmdset", initial=settings.CMDSET_OOC, widget=forms.TextInput(attrs={'size':'78'}), + required=False, + help_text="python path to cmdset class.") + class PlayerDBAdmin(admin.ModelAdmin): - inlines = [PlayerAttributeInline] + "Setting up and tying the player administration together" list_display = ('id', 'db_key', 'user', 'db_permissions', 'db_typeclass_path') list_display_links = ('id', 'db_key') @@ -48,10 +104,64 @@ class PlayerDBAdmin(admin.ModelAdmin): save_as = True save_on_top = True list_select_related = True + + # editing/adding player + form = PlayerEditForm fieldsets = ( - (None, - {'fields' : (('db_key', 'db_typeclass_path'), 'user', ('db_permissions','db_lock_storage'), 'db_obj'), - 'description': 'To create a new Player, a User object must also be created and/or assigned.', + (None, + {'fields' : (('db_key', 'db_typeclass_path'), 'user', ('db_permissions','db_lock_storage'), 'db_cmdset_storage', 'db_obj'), + 'description': 'To create a new Player, a User object must also be created and/or assigned. When deleting a Player, its connected User will also be deleted. A Character object is optional, but required for IC interactions in the game.', 'classes' : ('wide', 'extrapretty')}),) + # deactivated, they cause empty players to be created in admin. + #inlines = [PlayerAttributeInline] + + add_form = PlayerCreateForm + add_fieldsets = ( + (None, + {'fields' : (('db_key', 'db_typeclass_path'), 'user', 'db_permissions', 'db_cmdset_storage', 'db_obj'), + 'description': 'To create a new Player, a User object must also be created and/or assigned. When deleting a Player, its connected User will also be deleted. A Character object is optional, but required for IC interactions in the game.', + 'classes' : ('wide', 'extrapretty')}),) + + def get_fieldsets(self, request, obj=None): + if not obj: + return self.add_fieldsets + return super(PlayerDBAdmin, self).get_fieldsets(request, obj) + + def get_form(self, request, obj=None, **kwargs): + """ + Use special form during creation + """ + defaults = {} + if obj is None: + defaults.update({ + 'form': self.add_form, + 'fields': admin.util.flatten_fieldsets(self.add_fieldsets), + }) + defaults.update(kwargs) + return super(PlayerDBAdmin, self).get_form(request, obj, **defaults) + + def save_model(self, request, obj, form, change): + if not change: + # adding a new object + new_obj = obj.typeclass + new_obj.basetype_setup() + new_obj.at_player_creation() + if new_obj.obj: + char = new_obj.db_obj + char.db_player = obj + char.save() + new_obj.at_init() + else: + if obj.db_obj: + char = obj.db_obj + char.db_player = obj + char.save() + obj.at_init() + + def delete_model(self, request, obj): + # called when deleting a player object. Makes sure to also delete user. + user = obj.user + user.delete() + admin.site.register(PlayerDB, PlayerDBAdmin) diff --git a/src/players/models.py b/src/players/models.py index d6c7153892..7bcf1966e2 100644 --- a/src/players/models.py +++ b/src/players/models.py @@ -151,10 +151,11 @@ class PlayerDB(TypedObject): help_text="The User object holds django-related authentication. Each Player must have a unique User account linked to them at all times.") # the in-game object connected to this player (if any). # Use the property 'obj' to access. - db_obj = models.ForeignKey("objects.ObjectDB", null=True, verbose_name="character", help_text='In-game object (optional).') + db_obj = models.ForeignKey("objects.ObjectDB", null=True, verbose_name="character", help_text='In-game object.') # database storage of persistant cmdsets. - db_cmdset_storage = models.CharField('cmdset', max_length=255, null=True) + db_cmdset_storage = models.CharField('cmdset', max_length=255, null=True, + help_text="optional python path to a cmdset class.") # Database manager objects = manager.PlayerManager() diff --git a/src/scripts/admin.py b/src/scripts/admin.py index 6aa84d9e30..b6ba5610b6 100644 --- a/src/scripts/admin.py +++ b/src/scripts/admin.py @@ -12,7 +12,7 @@ class ScriptAttributeInline(admin.TabularInline): max_num = 1 class ScriptDBAdmin(admin.ModelAdmin): - inlines = [ScriptAttributeInline] + list_display = ('id', 'db_key', 'db_typeclass_path', 'db_obj', 'db_interval', 'db_repeats', 'db_persistent') list_display_links = ('id', 'db_key') ordering = ['db_obj', 'db_typeclass_path'] @@ -25,5 +25,7 @@ class ScriptDBAdmin(admin.ModelAdmin): (None, { 'fields':(('db_key', 'db_typeclass_path'), 'db_interval', 'db_repeats', 'db_start_delay', 'db_persistent', 'db_obj')}), ) + #inlines = [ScriptAttributeInline] + admin.site.register(ScriptDB, ScriptDBAdmin) diff --git a/src/settings_default.py b/src/settings_default.py index 52ee2933ff..5779d756d6 100644 --- a/src/settings_default.py +++ b/src/settings_default.py @@ -243,6 +243,7 @@ PERMISSION_PLAYER_DEFAULT = "Players" # inside these modules will be available as lock functions. LOCK_FUNC_MODULES = ("src.locks.lockfuncs",) + ################################################### # In-game Channels created from server start ################################################### diff --git a/src/typeclasses/models.py b/src/typeclasses/models.py index 9ba1fe64da..c7fdffff6b 100644 --- a/src/typeclasses/models.py +++ b/src/typeclasses/models.py @@ -549,9 +549,9 @@ class TypedObject(SharedMemoryModel): # Creation date db_date_created = models.DateTimeField('creation date', editable=False, auto_now_add=True) # Permissions (access these through the 'permissions' property) - db_permissions = models.CharField('permissions', max_length=255, blank=True, help_text="a comma-separated list of text strings checked by certain locks. They are often used for hierarchies, such as letting a Player have permission 'Wizards', 'Builders' etc. Normal players use 'Players' by default.") + db_permissions = models.CharField('permissions', max_length=255, blank=True, help_text="a comma-separated list of text strings checked by certain locks. They are often used for hierarchies, such as letting a Player have permission 'Wizards', 'Builders' etc. Character objects use 'Players' by default. Most other objects don't have any permissions.") # Lock storage - db_lock_storage = models.CharField('locks', max_length=512, blank=True, help_text="locks limit access to an entity. A lock is defined as a 'lock string' on the form 'type:lockfunctions', defining what functionality is locked and how to determine access. Take a look at other Players to set this to a valid string.") + db_lock_storage = models.CharField('locks', max_length=512, blank=True, help_text="locks limit access to an entity. A lock is defined as a 'lock string' on the form 'type:lockfunctions', defining what functionality is locked and how to determine access. Not defining a lock means no access is granted.") # Database manager objects = managers.TypedObjectManager() diff --git a/src/web/templates/admin/index.html b/src/web/templates/admin/index.html index f94f6c14cf..e5a757fdf4 100644 --- a/src/web/templates/admin/index.html +++ b/src/web/templates/admin/index.html @@ -18,6 +18,14 @@ {% if app.name in evennia_userapps %} + {% if app.name == 'Auth' %} +

Admin

+

Note: Users hold django-specific authentication and should + not be created stand-alone. Groups + define permissions only relevant to admin-site access. + To create a new In-game user, create a new Player.

+ {% endif %} +
@@ -49,12 +57,17 @@ {% endif %} {% endfor %} -

In-game

+

Game entities

{% for app in app_list %} {% if app.name in evennia_entityapps %} + {% if app.name == 'Comms' %} +

This defines entities that has an in-game precense or + effect of some kind.

+ {% endif %} +
{% blocktrans with app.name as name %}{{ name }}{% endblocktrans %}
@@ -86,80 +99,6 @@ {% endif %} {% endfor %} -

configs

- - {% for app in app_list %} - - {% if app.name in evennia_setupapps %} - -
-
{% blocktrans with app.name as name %}{{ name }}{% endblocktrans %}
- - {% for model in app.models %} - - {% if model.perms.change %} - - {% else %} - - {% endif %} - - {% if model.perms.add %} - - {% else %} - - {% endif %} - - {% if model.perms.change %} - - {% else %} - - {% endif %} - - - {% endfor %} -
{% blocktrans with app.name as name %}{{ name }}{% endblocktrans %}
{{ model.name }}{{ model.name }}{% trans 'Add' %} {% trans 'Change' %} 
-
- - {% endif %} - {% endfor %} - -

Connections

- - {% for app in app_list %} - - {% if app.name in evennia_connectapps %} - -
- - - {% for model in app.models %} - - {% if model.perms.change %} - - {% else %} - - {% endif %} - - {% if model.perms.add %} - - {% else %} - - {% endif %} - - {% if model.perms.change %} - - {% else %} - - {% endif %} - - - {% endfor %} -
{% blocktrans with app.name as name %}{{ name }}{% endblocktrans %}
{{ model.name }}{{ model.name }}{% trans 'Add' %} {% trans 'Change' %} 
-
- - {% endif %} - {% endfor %} -

Website

@@ -168,6 +107,11 @@ {% if app.name in evennia_websiteapps %} + {% if app.name == 'Flatpages' %} +

Miscellaneous objects related to the running and + managing of the Web presence.

+ {% endif %} +
diff --git a/src/web/utils/general_context.py b/src/web/utils/general_context.py index 39d6fed790..f63dc40588 100644 --- a/src/web/utils/general_context.py +++ b/src/web/utils/general_context.py @@ -22,7 +22,7 @@ SERVER_VERSION = get_evennia_version() # Setup lists of the most relevant apps so # the adminsite becomes more readable. -USER_RELATED = ['Players'] +USER_RELATED = ['Players', 'Auth'] GAME_ENTITIES = ['Objects', 'Scripts', 'Comms', 'Help'] GAME_SETUP = ['Permissions', 'Config'] CONNECTIONS = ['Irc', 'Imc2']
{% blocktrans with app.name as name %}{{ name }}{% endblocktrans %}