Web帮助系统教程¶
在进行此教程之前,您可能希望阅读 Changing the Web page tutorial 中的介绍。 阅读 Django tutorial 的前三个部分可能也会有所帮助。
本教程将向您展示如何通过网站访问帮助系统。根据登录的用户或匿名角色,帮助命令和常规帮助条目都将可见。
本教程将向您展示如何:
创建一个新的页面以添加到您的网站。
利用基本视图和基本模板。
在您的网站上访问帮助系统。
确定此页面的查看者是否已登录,以及如果已登录,属于哪一个帐户。
创建我们的应用¶
第一步是创建新的 Django 应用。在 Django 中,应用可以包含页面和机制:您的网站可能包含不同的应用。实际上,Evennia 提供的开箱即用的网站已经有三个应用:一个用于处理整个网页客户端的 “webclient” 应用,一个用于包含基本页面的 “website” 应用,以及一个由 Django 提供的用于创建简单管理界面的第三个应用。因此,我们将平行创建另一个应用,并给它一个清晰的名称,以代表我们的帮助系统。
从您的游戏目录中,使用以下命令:
cd web
evennia startapp help_system
这将在您的 mygame/
文件夹中创建一个新的 help_system
文件夹。为了保持整洁,我们将其移动到 web/
文件夹中:
mv help_system web # (linux)
move help_system web # (windows)
注意:将应用命名为 “help” 会更加明确,但这个名称已经被 Django 使用。
我们将新应用放在 web/
下以将所有与 web 相关的内容放在一起,但您可以根据自己的喜好进行组织。这里的结构看起来是这样的:
mygame/
...
web/
help_system/
...
“web/help_system” 目录包含 Django 创建的文件。我们将使用其中的一些文件,但如果您想了解更多关于它们的信息,您可以阅读 Django tutorial。
最后,您需要做一件事:您的文件夹已经添加,但 Django 不知道它,Django 不知道它是一个新应用。我们需要告诉它,我们通过编辑一个简单的设置来实现。打开您的 “server/conf/settings.py” 文件,添加或编辑以下行:
# Web configuration
INSTALLED_APPS += (
"web.help_system",
)
您可以开始 Evennia,如果愿意,可以访问您的网站,可能是在 http://localhost:4001。不过您不会看到任何不同的内容:我们添加了应用,但它非常空。
我们的新页面¶
此时,我们的新 应用 主要包含空文件,您可以进行探索。为了为帮助系统创建一个页面,我们需要添加:
一个 视图,处理我们页面的逻辑。
一个 模板 来显示我们的新页面。
一个指向我们页面的新 URL。
我们可以只创建一个视图和一个新 URL,但这不是推荐的工作方式。使用模板构建会更加方便。
创建视图¶
在 Django 中,视图 是放在应用的 views.py
文件中的简单 Python 函数。它将处理当用户通过输入 URL 请求此信息时触发的行为(视图 和 URL 之间的连接稍后会进行讨论)。
让我们创建我们的视图。您可以打开 web/help_system/views.py
文件并粘贴以下内容:
from django.shortcuts import render
def index(request):
"""'index' 视图。"""
return render(request, "help_system/index.html")
我们的视图处理所有代码逻辑。这次,逻辑不多:当调用这个函数时,它将渲染我们将要创建的模板。但这也是我们将在之后进行大部分工作的地方。
创建模板¶
在我们的 视图 中调用的 render
函数请求 模板 help_system/index.html
。我们应用的 模板 存储在应用目录的 “templates” 子目录中。Django 可能已经创建了 “templates” 文件夹。如果没有,请自行创建。在该文件夹中,再创建一个文件夹 “help_system”,然后在此文件夹中创建一个名为 “index.html” 的文件。哇,这层次有点复杂。您目录结构(从 web
开始)应该如下所示:
web/
help_system/
...
templates/
help_system/
index.html
打开 “index.html” 文件并粘贴以下内容:
{% extends "base.html" %}
{% block titleblock %}Help index{% endblock %}
{% block content %}
<h2>Help index</h2>
{% endblock %}
以下是此模板逐行的小说明:
它加载 “base.html” 模板。它描述了所有页面的基本结构,顶部有菜单和底部的页脚,可能还有其他信息,如图像和每个页面上要显示的内容。您可以创建不继承 “base.html” 的模板,但您应该有充分的理由这样做。
“base.html” 模板 定义了页面的所有结构。剩下的工作是重写我们页面的一些部分。这些部分被称为 块。在第 2 行,我们重写名为 “blocktitle” 的块,这部分包含页面的标题。
这里同样,我们重写名为 “content” 的 块,它包含我们网页的主要内容。这个块比较大,因此我们在多行定义它。
这是一段完全正常的 HTML 代码,用于显示二级标题。
最后,我们关闭名为 “content” 的 块。
创建新的 URL¶
添加页面的最后一步是我们需要添加一个指向它的 URL……否则用户将无法访问它。我们应用的 URLs 存储在应用目录的 urls.py
文件中。
打开 web/help_system/urls.py
文件(您可能需要创建它),使它看起来如下:
# help_system 应用的 URL 模式
from django.urls import path
from .views import index
urlpatterns = [
path('', index)
]
urlpatterns
变量是 Django/Evennia 查找以确定如何将用户输入的 URL 定向到您编写的视图代码的内容。
最后我们需要将其绑定到您游戏的主命名空间中。编辑文件 mygame/web/urls.py
。在其中,您会再次找到 urlpatterns
列表。添加一个新的 path
到列表的末尾。
# mygame/web/urls.py
# [...]
# 添加模式
urlpatterns = [
# 网站
path("", include("web.website.urls")),
# 网页客户端
path("webclient/", include("web.webclient.urls")),
# 网站管理
path("admin/", include("web.admin.urls")),
# 我们的帮助系统
path('help/', include('web.help_system.urls')) # <--- 新增
]
# [...]
当用户请求您网站上的特定 URL 时,Django 将:
读取在 “web/urls.py” 中定义的自定义模式列表。这里有一个模式,告诉 Django 所有以 ‘help/’ 开头的 URL 应该发送到 ‘help_system’ 应用。‘help/’ 部分将被删除。
然后 Django 将检查 “web.help_system/urls.py” 文件。它只包含一个 URL,即空的 (
^$
)。
换句话说,如果 URL 是 ‘/help/’,那么 Django 将执行我们定义的视图。
让我们看看它的工作¶
您现在可以重新加载或启动 Evennia。在浏览器中打开一个标签页,访问 http://localhost:4001/help/。如果一切顺利,您应该看到新页面……它并不空,因为 Evennia 使用了我们的 “base.html” 模板。页面内容上只有一个标题,写着 “help index”。请注意,页面的标题是 “mygame - Help index”(“mygame” 由您游戏的名称替换)。
从现在开始,进行下一步并添加功能会更容易。
简要提醒¶
我们将尝试以下内容:
在线访问命令帮助和帮助条目。
根据用户是否登录拥有各种命令和帮助条目。
在页面方面,我们将会有:
一个显示帮助主题列表的页面。
一个显示帮助主题内容的页面。
第一个页面将链接到第二个页面。
我们应该创建两个 URL 吗?
答案是……也许。这取决于您想做什么。我们通过 “/help/” URL 访问我们的帮助索引。我们可以通过 “/help/desc”(查看 “desc” 命令的详细信息)访问帮助条目的详细信息。问题是我们的命令或帮助主题可能包含不应出现在 URL 中的特殊字符。解决此问题的不同方法有很多。我决定在这里使用 GET 变量,这将创建如下 URL:
/help?name=desc
如果您使用此系统,则不必添加新 URL:GET 和 POST 变量可以通过我们的请求访问,我们将很快看到。
处理已登录用户¶
我们的要求之一是让帮助系统根据我们的帐户进行定制。如果具有管理员访问权限的帐户登录,页面应该显示许多普通用户无法访问的命令。也许还有一些额外的帮助主题。
幸运的是,在我们的视图中获取已登录帐户非常简单(记住我们将在那里进行大多数编码)。传递给我们函数的 request 对象包含一个 user
属性。此属性始终存在:例如,我们无法测试它是否为 None
。但是,当请求来自未登录的用户时,user
属性将包含一个匿名 Django 用户。然后我们可以使用 is_anonymous
方法来判断用户是否已登录。甚至如果用户已登录,request.user
还包含对帐户对象的引用,这将有助于我们将游戏和在线系统联系在一起。
因此,我们可能会得到类似这样的代码:
def index(request):
"""'index' 视图。"""
user = request.user
if not user.is_anonymous() and user.character:
character = user.character
注意:当您的 MULTISESSION_MODE 设置为 0 或 1 时,此代码有效。当设置为更高的值时,您会有如下代码:
def index(request):
"""'index' 视图。"""
user = request.user
if not user.is_anonymous() and user.characters:
character = user.characters[0]
在这种情况下,它将选择该帐户的第一个角色。
但如果用户未登录怎么办?同样,我们有不同的解决方案。最简单的方法之一是创建一个作为帮助系统的默认角色的角色。您可以通过游戏创建它:连接到它并输入:
@charcreate anonymous
系统应该回答:
创建新角色 anonymous。使用 @ic anonymous 作为此角色进入游戏。
因此,在我们的视图中,我们可以有这样的代码:
from typeclasses.characters import Character
def index(request):
"""'index' 视图。"""
user = request.user
if not user.is_anonymous() and user.character:
character = user.character
else:
character = Character.objects.get(db_key="anonymous")
这次,无论如何我们都有一个有效的角色:请记住,如果您处于多会话模式高于 1,请适当调整此代码。
完整系统¶
我们要做的是浏览所有命令和帮助条目,并列出该角色(无论是我们的 ‘anonymous’ 角色,还是我们的已登录角色)可以看到的所有命令。
代码会稍微复杂一点,但总的来说,可以分成小块:
index
函数是我们的视图:它开始时获取角色,如我们在前面的部分中看到的。
它获取该角色可访问的帮助主题(命令和帮助条目)。这是另一个处理这部分的函数。
如果我们的 URL 中有一个 GET 变量 “name”(例如 “/help?name=drop”),它将检索该变量。如果这不是有效的主题名称,它返回一个 404。否则,它渲染名为 “detail.html” 的模板,以显示我们主题的详细信息。
如果没有 GET 变量 “name”,则渲染 “index.html” 来显示主题列表。
_get_topics
是一个私有函数。它的唯一任务是检索角色可以执行的命令,以及该同一角色可以看到的帮助条目。此代码更具 Evennia 特定性,而非 Django 特定性,因此在本教程中不会详细讨论。只需注意,所有帮助主题都存储在字典中。这是为了简化我们在模板中显示它们的工作。
请注意,在我们请求渲染 模板 的两个情况下,我们都向 render
传递了第三个参数,即用于模板的变量字典。我们可以通过这种方式传递变量,我们将在模板中使用它们。
索引模板¶
让我们看一下完整的 “index” 模板。您可以打开 “web/help_system/templates/help_system/index.html” 文件并将以下内容粘贴到其中:
{% extends "base.html" %}
{% block titleblock %}Help index{% endblock %}
{% block content %}
<h2>Help index</h2>
{% if categories %}
{% for category, topics in categories %}
<h2>{{ category|capfirst }}</h2>
<table>
<tr>
{% for topic in topics %}
{% if forloop.counter|divisibleby:"5" %}
</tr>
<tr>
{% endif %}
<td><a href="{% url 'help_system:index' %}?name={{ topic.name|urlencode }}">
{{ topic.name }}</td>
{% endfor %}
</tr>
</table>
{% endfor %}
{% endif %}
{% endblock %}
此模板的细节更多。它的作用是:
遍历所有类别。
对于所有类别,显示包含类别名称的二级标题。
类别中的所有主题(记住,它们可以是命令或帮助条目)都显示在表格中。比较棘手的部分是,在循环超过 5 时,它将创建一个新行。每行最多有 5 列的表格。
对于表格中的每个单元格,我们创建一个链接,重定向到详细页面(见下文)。URL 的格式类似于 “help?name=say”。我们使用
urlencode
确保特殊字符得到正确转义。
详细模板¶
现在是时候显示主题(命令或帮助条目)的详细信息了。您可以创建文件 “web/help_system/templates/help_system/detail.html”。您可以在其中粘贴以下代码:
{% extends "base.html" %}
{% block titleblock %}Help for {{ topic.name }}{% endblock %}
{% block content %}
<h2>{{ topic.name|capfirst }} help topic</h2>
<p>Category: {{ topic.category|capfirst }}</p>
{{ topic.content|linebreaks }}
{% endblock %}
这个模板更容易阅读。可能有一些 过滤器 对您来说是未知的,但它们只是用于格式化。
将所有内容组合在一起¶
请记得重新加载或启动 Evennia,然后转到 http://localhost:4001/help。您应该看到所有角色可访问的命令和主题列表。尝试登录(单击您网站菜单中的 “login” 链接)并再次转到相同的页面。您现在应该看到更详细的命令和帮助条目列表。单击一个以查看其详细信息。
改进此功能¶
如往常一样,教程旨在帮助您感到舒适,以便您可以自己添加新功能和代码。以下是一些改进此小功能的想法:
在详细模板的底部添加一个链接返回索引可能会很有用。
在主菜单中链接到此页面的链接将是很好的……目前您必须输入 URL,用户不会猜到它。
此时,颜色没有被处理,这并不奇怪。但您可以添加它。
使帮助条目相互链接将并不简单,但会很不错。例如,如果您看到一个关于如何使用多个命令的帮助条目,最好这些命令本身是链接,以显示它们的详细信息。