<h1>Web Help System Tutorial<aclass="headerlink"href="#web-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 the <aclass="reference internal"href="Web-Changing-Webpage.html"><spanclass="doc std std-doc">Changing the Web page tutorial</span></a>.</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>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 commands:</p>
<p>This creates a new folder <codeclass="docutils literal notranslate"><spanclass="pre">help_system</span></code> in your <codeclass="docutils literal notranslate"><spanclass="pre">mygame/</span></code> folder. To keep things
tidy, let’s move it to the <codeclass="docutils literal notranslate"><spanclass="pre">web/</span></code> folder:</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span>mv help_system web (linux)
<p>We put the new app under <codeclass="docutils literal notranslate"><spanclass="pre">web/</span></code>t o keep all web-related things together, but you can organize however you like. Here’s how the structure looks:</p>
<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/4.1/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>
<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>
<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>
<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>
<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 lines:</p>
<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>
<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>
<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>
<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>
<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>
<li><p>Read the list of custom patterns defined in “web/urls.py”. There’s one pattern here, which describes to Django that all URLs beginning by ‘help/’ should be sent to the ‘help_system’ app. The ‘help/’ part is removed.</p></li>
<li><p>Then Django will check the “web.help_system/urls.py” file. It contains only one URL, which is empty (<codeclass="docutils literal notranslate"><spanclass="pre">^$</span></code>).</p></li>
<p>You can now reload or start Evennia. Open a tab in your browser and go to <aclass="reference external"href="http://localhost:4001/help/">http://localhost:4001/help/</a> . If everything goes well, you should see your new page… which isn’t empty since Evennia uses our “base.html” <em>template</em>. In the content of our page, there’s only a heading that reads “help index”. Notice that the title of our page is “mygame - Help index” (“mygame” is replaced by the name of your game).</p>
<p>The answer is… maybe. It depends on what you want to do. We have our help index accessible through the “/help/” URL. We could have the detail of a help entry accessible through “/help/desc” (to see the detail of the “desc” command). The problem is that our commands or help topics may contain special characters that aren’t to be present in URLs. There are different ways around this problem. I have decided to use a <em>GET variable</em> here, which would create URLs like this:</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>
<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>
<p>But what if the user’s not logged in? Again, we have different solutions. One of the most simple is to create a character that will behave as our default character for the help system. You can create it through your game: connect to it and enter:</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span> Created new character anonymous. Use @ic anonymous to enter the game as this character.
<p>What we’re going to do is to browse through all commands and help entries, and list all the commands that can be seen by this character (either our ‘anonymous’ character, or our logged-in character).</p>
<p>The code is longer, but it presents the entire concept in our view. Edit the “web/help_system/views.py” file and paste into it:</p>
<spanclass="k">raise</span><spanclass="n">Http404</span><spanclass="p">(</span><spanclass="s2">"This help topic doesn't exist."</span><spanclass="p">)</span>
<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>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>
<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>
<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>
<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>
<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>
<p>Remember to reload or start Evennia, and then go to <aclass="reference external"href="http://localhost:4001/help/">http://localhost:4001/help</a>. You should see the list of commands and topics accessible by all characters. Try to login (click the “login” link in the menu of your website) and go to the same page again. You should now see a more detailed list of commands and help entries. Click on one to see its detail.</p>
<p>As always, a tutorial is here to help you feel comfortable adding new features and code by yourself. Here are some ideas of things to improve this little feature:</p>
<li><p>A link in the main menu to link to this page would be great… for the time being you have to enter the URL, users won’t guess it’s there.</p></li>
<li><p>Linking help entries between one another won’t be simple, but it would be great. For instance, if you see a help entry about how to use several commands, it would be great if these commands were themselves links to display their details.</p></li>