Implements HelpViews.

This commit is contained in:
Johnny 2018-10-27 11:07:25 +00:00
parent bb3cb9ed58
commit 0bd9d9a647
5 changed files with 308 additions and 16 deletions

View file

@ -29,7 +29,10 @@ folder and edit it to add/remove links to the menu.
<a class="nav-link" href="https://github.com/evennia/evennia/wiki/Evennia-Introduction/">About</a>
</li>
<li><a class="nav-link" href="https://github.com/evennia/evennia/wiki">Documentation</a></li>
<li><a class="nav-link" href="{% url 'admin:index' %}">Admin Interface</a></li>
{% if user.is_staff %}
<li><a class="nav-link" href="{% url 'admin:index' %}">Admin</a></li>
{% endif %}
<li><a class="nav-link" href="{% url 'help' %}">Help</a></li>
{% if webclient_enabled %}
<li><a class="nav-link" href="{% url 'webclient:index' %}">Play Online</a></li>
{% endif %}

View file

@ -0,0 +1,86 @@
{% extends "base.html" %}
{% block titleblock %}
{{ view.page_title }} ({{ object|title }})
{% endblock %}
{% block content %}
{% load addclass %}
<div class="row">
<div class="col">
<!-- main content -->
<div class="card mb-3">
<div class="card-body">
<h1 class="card-title">{{ view.page_title }} ({{ object|title }})</h1>
<hr />
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'help' %}">Compendium</a></li>
<li class="breadcrumb-item"><a href="{% url 'help' %}#{{ object.db_help_category }}">{{ object.db_help_category|title }}</a></li>
<li class="breadcrumb-item active" aria-current="page">{{ object.db_key|title }}</li>
</ol>
<hr />
<div class="row">
<!-- left column -->
<div class="col-lg-9 col-sm-12">
<p>{{ entry_text|safe }}</p>
{% if topic_previous or topic_next %}
<hr />
<!-- navigation -->
<nav aria-label="Topic Navigation">
<ul class="pagination justify-content-center">
{% if topic_previous %}
<li class="page-item">
<a class="page-link" href="{{ topic_previous.web_get_detail_url }}">Previous ({{ topic_previous|title }})</a>
</li>
{% endif %}
{% if topic_next %}
<li class="page-item">
<a class="page-link" href="{{ topic_next.web_get_detail_url }}">Next ({{ topic_next|title }})</a>
</li>
{% endif %}
</ul>
</nav>
<!-- end navigation -->
{% endif %}
</div>
<!-- end left column -->
<!-- right column (sidebar) -->
<div class="col-lg-3 col-sm-12">
{% if request.user.is_staff %}
<!-- admin button -->
<a class="btn btn-info btn-block mb-3" href="{{ object.web_get_admin_url }}">Edit</a>
<!-- end admin button -->
<hr />
{% endif %}
<div class="card mb-3">
<div class="card-header">{{ object.db_help_category|title }}</div>
<ul class="list-group list-group-flush">
{% for topic in topic_list %}
<a href="{{ topic.web_get_detail_url }}" class="list-group-item {% if topic == object %}active disabled{% endif %}">{{ topic|title }}</a>
{% endfor %}
</ul>
</div>
</div>
<!-- end right column -->
</div>
<hr />
</div>
</div>
<!-- end main content -->
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,110 @@
{% extends "base.html" %}
{% block titleblock %}
{{ view.page_title }}
{% endblock %}
{% block content %}
{% load addclass %}
<div class="row">
<div class="col">
<div class="card">
<div class="card-body">
<h1 class="card-title">{{ view.page_title }}</h1>
<hr />
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'help' %}">Compendium</a></li>
</ol>
<hr />
<div class="row">
{% regroup object_list by help_category as category_list %}
{% if category_list %}
<!-- left column -->
<div class="col-lg-9 col-sm-12">
<!-- intro -->
<div class="card border-light">
<div class="card-body">
<h4 class="card-title">The {{ game_name }} Compendium</h4>
<p>This section of the site is your guide to learning all about {{ game_name }}-- its rules, its setting, its people, customs, classes, castes, conflicts, races, religions, lore and more!</p>
<p>It is organized first by category, then by topic. The box to the right will let you skip to particular categories.</p>
</div>
</div>
<hr />
<!-- end intro -->
<!-- index list -->
<div class="mx-3">
{% for help_category in category_list %}
<h5><a id="{{ help_category.grouper }}"></a>{{ help_category.grouper|title }}</h5>
<ul>
{% for object in help_category.list %}
<li><a href="{{ object.web_get_detail_url }}">{{ object|title }}</a></li>
{% endfor %}
</ul>
{% endfor %}
<!-- end index list -->
</div>
</div>
<!-- end left column -->
<!-- right column (index) -->
<div class="col-lg-3 col-sm-12">
{% if user.is_staff %}
<!-- admin button -->
<a class="btn btn-info btn-block mb-3" href="/admin/help/helpentry/add/">Create New</a>
<!-- end admin button -->
<hr />
{% endif %}
<div class="card mb-3">
<div class="card-header">Category Index</div>
<ul class="list-group list-group-flush">
{% for category in category_list %}
<a href="#{{ category.grouper }}" class="list-group-item">{{ category.grouper|title }}</a>
{% endfor %}
</ul>
</div>
</div>
<!-- end right column -->
{% else %}
{% if user.is_staff %}
<div class="col-lg-12 col-sm-12">
<div class="alert alert-warning" role="alert">
<h4 class="alert-heading">Hey, staff member {{ user.get_username }}!</h4>
<hr />
<p><strong>Your Help section is currently blank!</strong></p>
<p>You're missing out on an opportunity to attract visitors (and potentially new players) to {{ game_name }}!</p>
<p>Use Evennia's <a href="https://github.com/evennia/evennia/wiki/Help-System#database-help-entries" class="alert-link" target="_blank">Help System</a> to tell the world about the universe you've created, its lore and legends, its people and creatures, and their customs and conflicts!</p>
<p>You don't even need coding skills-- writing Help Entries is no more complicated than writing an email or blog post. Once you publish your first entry, these ugly boxes go away and this page will turn into an index of everything you've written about {{ game_name }}.</p>
<p>The documentation you write is eventually picked up by search engines, so the more you write about how {{ game_name }} works, the larger your web presence will be-- and the more traffic you'll attract.
<p>Everything you write can be viewed either on this site or within the game itself, using the in-game help commands.</p>
<hr>
<p class="mb-0"><a href="/admin/help/helpentry/add/" class="alert-link">Click here</a> to start writing about {{ game_name }}!</p>
</div>
</div>
{% endif %}
<div class="col-lg-12 col-sm-12">
<div class="alert alert-secondary" role="alert">
<h4 class="alert-heading">Under Construction!</h4>
<p>Thanks for your interest, but we're still working on developing and documenting the {{ game_name }} universe!</p>
<p>Check back later for more information as we publish it.</p>
<hr>
<p class="mb-0"><a href="{% url 'index' %}" class="alert-link">Click here</a> to go back to the main page.</p>
</div>
</div>
{% endif %}
</div>
<hr />
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -13,8 +13,12 @@ urlpatterns = [
url(r'^tbi/', website_views.to_be_implemented, name='to_be_implemented'),
# User Authentication (makes login/logout url names available)
url(r'^auth/', include('django.contrib.auth.urls')),
url(r'^auth/register', website_views.AccountCreateView.as_view(), name="register"),
url(r'^auth/', include('django.contrib.auth.urls')),
# Help Topics
url(r'^help/$', website_views.HelpListView.as_view(), name="help"),
url(r'^help/(?P<category>[\w\d\-]+)/(?P<topic>[\w\d\-]+)/$', website_views.HelpDetailView.as_view(), name="help-entry-detail"),
# Character management
url(r'^characters/create/$', website_views.CharacterCreateView.as_view(), name="character-create"),

View file

@ -512,7 +512,7 @@ class AccountMixin(object):
form_class = AccountForm
class AccountCreateView(AccountMixin, ObjectCreateView):
class AccountCreateView(AccountMixin, EvenniaCreateView):
"""
Account creation view.
@ -729,7 +729,7 @@ class CharacterCreateView(CharacterMixin, ObjectCreateView):
#
# Help views
#
#from evennia.help.models import HelpEntry
class HelpMixin(object):
"""
This is a "mixin", a modifier of sorts.
@ -741,27 +741,36 @@ class HelpMixin(object):
# -- Django constructs --
model = HelpEntry
# -- Evennia constructs --
page_title = 'Help'
def get_queryset(self):
"""
Django hook; here we want to return a list of only those HelpEntries
that the current user is allowed to see.
and other documentation that the current user is allowed to see.
Returns:
queryset (QuerySet): List of Help entries available to the user.
"""
account = self.request.user
# Get list of all HelpEntries
entries = HelpEntry.objects.all()
entries = self.model.objects.all().iterator()
# Now figure out which ones the current user is allowed to see
bucket = []
for entry in entries:
if entry.access(self.request.user, 'view'):
bucket.append(entry.id)
# Re-query to just get those
entries = HelpEntry.objects.filter(id__in=bucket)
return entries
bucket = [entry.id for entry in entries if entry.access(account, 'view')]
# Re-query and set a sorted list
filtered = self.model.objects.filter(
id__in=bucket
).order_by(
Lower('db_key')
).order_by(
Lower('db_help_category')
)
return filtered
class HelpListView(HelpMixin, ListView):
"""
@ -770,5 +779,85 @@ class HelpListView(HelpMixin, ListView):
"""
# -- Django constructs --
paginate_by = 10
template_name = 'website/object_list.html'
paginate_by = 500
template_name = 'website/help_list.html'
# -- Evennia constructs --
page_title = "Help Index"
class HelpDetailView(HelpMixin, EvenniaDetailView):
"""
Returns the detail page for a given help entry.
"""
# -- Django constructs --
template_name = 'website/help_detail.html'
def get_context_data(self, **kwargs):
"""
Adds navigational data to the template to let browsers go to the next
or previous entry in the help list.
Returns:
context (dict): Django context object
"""
context = super(HelpDetailView, self).get_context_data(**kwargs)
# Get the object in question
obj = self.get_object()
# Get queryset and filter out non-related categories
queryset = self.get_queryset().filter(db_help_category=obj.db_help_category).order_by(Lower('db_key'))
context['topic_list'] = queryset
# Find the index position of the given obj in the queryset
objs = list(queryset)
for i, x in enumerate(objs):
if obj is x:
break
# Find the previous and next topics, if either exist
try:
assert i+1 <= len(objs) and objs[i+1] is not obj
context['topic_next'] = objs[i+1]
except: context['topic_next'] = None
try:
assert i-1 >= 0 and objs[i-1] is not obj
context['topic_previous'] = objs[i-1]
except: context['topic_previous'] = None
# Format the help entry using HTML instead of newlines
text = obj.db_entrytext
text = text.replace('\r\n\r\n', '\n\n')
text = text.replace('\r\n', '\n')
text = text.replace('\n', '<br />')
context['entry_text'] = text
return context
def get_object(self, queryset=None):
"""
Override of Django hook that retrieves an object by category and topic
instead of pk and slug.
Returns:
entry (HelpEntry): HelpEntry requested in the URL.
"""
# Get the queryset for the help entries the user can access
if not queryset:
queryset = self.get_queryset()
# Find the object in the queryset
category = slugify(self.kwargs.get('category', ''))
topic = slugify(self.kwargs.get('topic', ''))
obj = next((x for x in queryset if slugify(x.db_help_category)==category and slugify(x.db_key)==topic), None)
# Check if this object was requested in a valid manner
if not obj:
raise HttpResponseBadRequest(u"No %(verbose_name)s found matching the query" %
{'verbose_name': queryset.model._meta.verbose_name})
return obj