<h1>Help System Tutorial<aclass="headerlink"href="#help-system-tutorial"title="Permalink to this headline">¶</a></h1>
<p><strong>Before doing this tutorial you will probably want to read the intro in [Basic Web tutorial](Web-
Tutorial).</strong> Reading the three first parts of the <aclass="reference external"href="https://docs.djangoproject.com/en/4.0/intro/tutorial01/">Django
tutorial</a> might help as well.</p>
<p>This tutorial will show you how to access the help system through your website. Both help commands
and regular help entries will be visible, depending on the logged-in user or an anonymous character.</p>
<p>This tutorial will show you how to:</p>
<ulclass="simple">
<li><p>Create a new page to add to your website.</p></li>
<li><p>Take advantage of a basic view and basic templates.</p></li>
<li><p>Access the help system on your website.</p></li>
<li><p>Identify whether the viewer of this page is logged-in and, if so, to what account.</p></li>
</ul>
<sectionid="creating-our-app">
<h2>Creating our app<aclass="headerlink"href="#creating-our-app"title="Permalink to this headline">¶</a></h2>
<p>The first step is to create our new Django <em>app</em>. An app in Django can contain pages and
mechanisms: your website may contain different apps. Actually, the website provided out-of-the-box
by Evennia has already three apps: a “webclient” app, to handle the entire webclient, a “website”
app to contain your basic pages, and a third app provided by Django to create a simple admin
interface. So we’ll create another app in parallel, giving it a clear name to represent our help
system.</p>
<p>From your game directory, use the following command:</p>
<div><p>Note: calling the app “help” would have been more explicit, but this name is already used by
Django.</p>
</div></blockquote>
<p>This will create a directory named <codeclass="docutils literal notranslate"><spanclass="pre">help_system</span></code> at the root of your game directory. It’s a good
idea to keep things organized and move this directory in the “web” directory of your game. Your
<p>The “web/help_system” directory contains files created by Django. We’ll use some of them, but if
you want to learn more about them all, you should read <aclass="reference external"href="https://docs.djangoproject.com/en/1.9/intro/tutorial01/">the Django
tutorial</a>.</p>
<p>There is a last thing to be done: your folder has been added, but Django doesn’t know about it, it
doesn’t know it’s a new app. We need to tell it, and we do so by editing a simple setting. Open
your “server/conf/settings.py” file and add, or edit, these lines:</p>
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="c1"># Web configuration</span>
<p>You can start Evennia if you want, and go to your website, probably at
<aclass="reference external"href="http://localhost:4001">http://localhost:4001</a> . You won’t see anything different though: we added
the app but it’s fairly empty.</p>
</section>
<sectionid="our-new-page">
<h2>Our new page<aclass="headerlink"href="#our-new-page"title="Permalink to this headline">¶</a></h2>
<p>At this point, our new <em>app</em> contains mostly empty files that you can explore. In order to create
a page for our help system, we need to add:</p>
<ulclass="simple">
<li><p>A <em>view</em>, dealing with the logic of our page.</p></li>
<li><p>A <em>template</em> to display our new page.</p></li>
<li><p>A new <em>URL</em> pointing to our page.</p></li>
</ul>
<blockquote>
<div><p>We could get away by creating just a view and a new URL, but that’s not a recommended way to work
with your website. Building on templates is so much more convenient.</p>
</div></blockquote>
<sectionid="create-a-view">
<h3>Create a view<aclass="headerlink"href="#create-a-view"title="Permalink to this headline">¶</a></h3>
<p>A <em>view</em> in Django is a simple Python function placed in the “<aclass="reference external"href="http://views.py">views.py</a>” file in your app. It will
handle the behavior that is triggered when a user asks for this information by entering a <em>URL</em> (the
connection between <em>views</em> and <em>URLs</em> will be discussed later).</p>
<p>So let’s create our view. You can open the “web/help_system/views.py” file and paste the following
<p>Our view handles all code logic. This time, there’s not much: when this function is called, it will
render the template we will now create. But that’s where we will do most of our work afterward.</p>
</section>
<sectionid="create-a-template">
<h3>Create a template<aclass="headerlink"href="#create-a-template"title="Permalink to this headline">¶</a></h3>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">render</span></code> function called into our <em>view</em> asks the <em>template</em><codeclass="docutils literal notranslate"><spanclass="pre">help_system/index.html</span></code>. The
<em>templates</em> of our apps are stored in the app directory, “templates” sub-directory. Django may have
created the “templates” folder already. If not, create it yourself. In it, create another folder
“help_system”, and inside of this folder, create a file named “index.html”. Wow, that’s some
hierarchy. Your directory structure (starting from <codeclass="docutils literal notranslate"><spanclass="pre">web</span></code>) should look like this:</p>
<p>Here’s a little explanation line by line of what this template does:</p>
<olclass="simple">
<li><p>It loads the “base.html” <em>template</em>. This describes the basic structure of all your pages, with
a menu at the top and a footer, and perhaps other information like images and things to be present
on each page. You can create templates that do not inherit from “base.html”, but you should have a
good reason for doing so.</p></li>
<li><p>The “base.html” <em>template</em> defines all the structure of the page. What is left is to override
some sections of our pages. These sections are called <em>blocks</em>. On line 2, we override the block
named “blocktitle”, which contains the title of our page.</p></li>
<li><p>Same thing here, we override the <em>block</em> named “content”, which contains the main content of our
web page. This block is bigger, so we define it on several lines.</p></li>
<li><p>This is perfectly normal HTML code to display a level-2 heading.</p></li>
<li><p>And finally we close the <em>block</em> named “content”.</p></li>
</ol>
</section>
<sectionid="create-a-new-url">
<h3>Create a new URL<aclass="headerlink"href="#create-a-new-url"title="Permalink to this headline">¶</a></h3>
<p>Last step to add our page: we need to add a <em>URL</em> leading to it… otherwise users won’t be able to
access it. The URLs of our apps are stored in the app’s directory “<aclass="reference external"href="http://urls.py">urls.py</a>” file.</p>
<p>Open the <codeclass="docutils literal notranslate"><spanclass="pre">web/help_system/urls.py</span></code> file (you might have to create it) and make it look like this.</p>
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="c1"># URL patterns for the help_system app</span>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">urlpatterns</span></code> variable is what Django/Evennia looks for to figure out how to
direct a user entering an URL in their browser to the view-code you have
written.</p>
<p>Last we need to tie this into the main namespace for your game. Edit the file
<codeclass="docutils literal notranslate"><spanclass="pre">mygame/web/urls.py</span></code>. In it you will find the <codeclass="docutils literal notranslate"><spanclass="pre">urlpatterns</span></code> list again.
Add a new <codeclass="docutils literal notranslate"><spanclass="pre">path</span></code> to the end of the list.</p>
<p>If you use this system, you don’t have to add a new URL: GET and POST variables are accessible
through our requests and we’ll see how soon enough.</p>
</section>
</section>
<sectionid="handling-logged-in-users">
<h2>Handling logged-in users<aclass="headerlink"href="#handling-logged-in-users"title="Permalink to this headline">¶</a></h2>
<p>One of our requirements is to have a help system tailored to our accounts. If an account with admin
access logs in, the page should display a lot of commands that aren’t accessible to common users.
And perhaps even some additional help topics.</p>
<p>Fortunately, it’s fairly easy to get the logged in account in our view (remember that we’ll do most
of our coding there). The <em>request</em> object, passed to our function, contains a <codeclass="docutils literal notranslate"><spanclass="pre">user</span></code> attribute.
This attribute will always be there: we cannot test whether it’s <codeclass="docutils literal notranslate"><spanclass="pre">None</span></code> or not, for instance. But
when the request comes from a user that isn’t logged in, the <codeclass="docutils literal notranslate"><spanclass="pre">user</span></code> attribute will contain an
anonymous Django user. We then can use the <codeclass="docutils literal notranslate"><spanclass="pre">is_anonymous</span></code> method to see whether the user is logged-
in or not. Last gift by Evennia, if the user is logged in, <codeclass="docutils literal notranslate"><spanclass="pre">request.user</span></code> contains a reference to
an account object, which will help us a lot in coupling the game and online system.</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span>Created new character anonymous. Use @ic anonymous to enter the game as this character.
</pre></div>
</div>
<p>So in our view, we could have something like this:</p>
<spanclass="k">raise</span><spanclass="n">Http404</span><spanclass="p">(</span><spanclass="s2">"This help topic doesn't exist."</span><spanclass="p">)</span>
<p>That’s a bit more complicated here, but all in all, it can be divided in small chunks:</p>
<ulclass="simple">
<li><p>The <codeclass="docutils literal notranslate"><spanclass="pre">index</span></code> function is our view:</p>
<ul>
<li><p>It begins by getting the character as we saw in the previous section.</p></li>
<li><p>It gets the help topics (commands and help entries) accessible to this character. It’s another
function that handles that part.</p></li>
<li><p>If there’s a <em>GET variable</em> “name” in our URL (like “/help?name=drop”), it will retrieve it. If
it’s not a valid topic’s name, it returns a <em>404</em>. Otherwise, it renders the template called
“detail.html”, to display the detail of our topic.</p></li>
<li><p>If there’s no <em>GET variable</em> “name”, render “index.html”, to display the list of topics.</p></li>
</ul>
</li>
<li><p>The <codeclass="docutils literal notranslate"><spanclass="pre">_get_topics</span></code> is a private function. Its sole mission is to retrieve the commands a character
can execute, and the help entries this same character can see. This code is more Evennia-specific
than Django-specific, it will not be detailed in this tutorial. Just notice that all help topics
are stored in a dictionary. This is to simplify our job when displaying them in our templates.</p></li>
</ul>
<p>Notice that, in both cases when we asked to render a <em>template</em>, we passed to <codeclass="docutils literal notranslate"><spanclass="pre">render</span></code> a third
argument which is the dictionary of variables used in our templates. We can pass variables this
way, and we will use them in our templates.</p>
<sectionid="the-index-template">
<h3>The index template<aclass="headerlink"href="#the-index-template"title="Permalink to this headline">¶</a></h3>
<p>Let’s look at our full “index” <em>template</em>. You can open the
“web/help_system/templates/help_sstem/index.html” file and paste the following into it:</p>
<p>This template is definitely more detailed. What it does is:</p>
<olclass="simple">
<li><p>Browse through all categories.</p></li>
<li><p>For all categories, display a level-2 heading with the name of the category.</p></li>
<li><p>All topics in a category (remember, they can be either commands or help entries) are displayed in
a table. The trickier part may be that, when the loop is above 5, it will create a new line. The
table will have 5 columns at the most per row.</p></li>
<li><p>For every cell in the table, we create a link redirecting to the detail page (see below). The
URL would look something like “help?name=say”. We use <codeclass="docutils literal notranslate"><spanclass="pre">urlencode</span></code> to ensure special characters are
properly escaped.</p></li>
</ol>
</section>
<sectionid="the-detail-template">
<h3>The detail template<aclass="headerlink"href="#the-detail-template"title="Permalink to this headline">¶</a></h3>
<p>It’s now time to show the detail of a topic (command or help entry). You can create the file
“web/help_system/templates/help_system/detail.html”. You can paste into it the following code:</p>