mirror of
https://github.com/evennia/evennia.git
synced 2026-03-18 13:56:30 +01:00
994 lines
No EOL
74 KiB
HTML
994 lines
No EOL
74 KiB
HTML
|
||
<!DOCTYPE html>
|
||
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>Web Character Generation — Evennia 1.0-dev documentation</title>
|
||
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
|
||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||
<script src="../_static/jquery.js"></script>
|
||
<script src="../_static/underscore.js"></script>
|
||
<script src="../_static/doctools.js"></script>
|
||
<script src="../_static/language_data.js"></script>
|
||
<link rel="shortcut icon" href="../_static/favicon.ico"/>
|
||
<link rel="index" title="Index" href="../genindex.html" />
|
||
<link rel="search" title="Search" href="../search.html" />
|
||
</head><body>
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="General Index"
|
||
accesskey="I">index</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python Module Index"
|
||
>modules</a> |</li>
|
||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">Web Character Generation</a></li>
|
||
</ul>
|
||
<div class="develop">develop branch</div>
|
||
</div>
|
||
|
||
<div class="document">
|
||
<div class="documentwrapper">
|
||
<div class="bodywrapper">
|
||
<div class="body" role="main">
|
||
|
||
<div class="section" id="web-character-generation">
|
||
<h1>Web Character Generation<a class="headerlink" href="#web-character-generation" title="Permalink to this headline">¶</a></h1>
|
||
<div class="section" id="introduction">
|
||
<h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h2>
|
||
<p>This tutorial will create a simple web-based interface for generating a new in-game Character.
|
||
Accounts will need to have first logged into the website (with their <code class="docutils literal notranslate"><span class="pre">AccountDB</span></code> account). Once
|
||
finishing character generation the Character will be created immediately and the Accounts can then
|
||
log into the game and play immediately (the Character will not require staff approval or anything
|
||
like that). This guide does not go over how to create an AccountDB on the website with the right
|
||
permissions to transfer to their web-created characters.</p>
|
||
<p>It is probably most useful to set <code class="docutils literal notranslate"><span class="pre">MULTISESSION_MODE</span> <span class="pre">=</span> <span class="pre">2</span></code> or <code class="docutils literal notranslate"><span class="pre">3</span></code> (which gives you a character-
|
||
selection screen when you log into the game later). Other modes can be used with some adaptation to
|
||
auto-puppet the new Character.</p>
|
||
<p>You should have some familiarity with how Django sets up its Model Template View framework. You need
|
||
to understand what is happening in the basic [Web Character View tutorial](Web-Character-View-
|
||
Tutorial). If you don’t understand the listed tutorial or have a grasp of Django basics, please look
|
||
at the <a class="reference external" href="https://docs.djangoproject.com/en/1.8/intro/">Django tutorial</a> to get a taste of what Django
|
||
does, before throwing Evennia into the mix (Evennia shares its API and attributes with the website
|
||
interface). This guide will outline the format of the models, views, urls, and html templates
|
||
needed.</p>
|
||
</div>
|
||
<div class="section" id="pictures">
|
||
<h2>Pictures<a class="headerlink" href="#pictures" title="Permalink to this headline">¶</a></h2>
|
||
<p>Here are some screenshots of the simple app we will be making.</p>
|
||
<p>Index page, with no character application yet done:</p>
|
||
<hr class="docutils" />
|
||
<p><img alt="Index page, with no character application yet done." src="https://lh3.googleusercontent.com/-57KuSWHXQ_M/VWcULN152tI/AAAAAAAAEZg/kINTmVlHf6M/w425-h189-no/webchargen_index2.gif" /></p>
|
||
<hr class="docutils" />
|
||
<p>Having clicked the “create” link you get to create your character (here we will only have name and
|
||
background, you can add whatever is needed to fit your game):</p>
|
||
<hr class="docutils" />
|
||
<p><img alt="Character creation." src="https://lh3.googleusercontent.com/-ORiOEM2R_yQ/VWcUKgy84rI/AAAAAAAAEZY/B3CBh3FHii4/w607-h60-no/webchargen_creation.gif" /></p>
|
||
<hr class="docutils" />
|
||
<p>Back to the index page. Having entered our character application (we called our character “TestApp”)
|
||
you see it listed:</p>
|
||
<hr class="docutils" />
|
||
<p><img alt="Having entered an application." src="https://lh6.googleusercontent.com/-HlxvkvAimj4/VWcUKjFxEiI/AAAAAAAAEZo/gLppebr05JI/w321-h194-no/webchargen_index1.gif" /></p>
|
||
<hr class="docutils" />
|
||
<p>We can also view an already written character application by clicking on it - this brings us to the
|
||
<em>detail</em> page:</p>
|
||
<hr class="docutils" />
|
||
<p><img alt="Detail view of character application." src="https://lh6.googleusercontent.com/-2m1UhSE7s_k/VWcUKfLRfII/AAAAAAAAEZc/UFmBOqVya4k/w267-h175-no/webchargen_detail.gif" /></p>
|
||
</div>
|
||
<hr class="docutils" />
|
||
<div class="section" id="installing-an-app">
|
||
<h2>Installing an App<a class="headerlink" href="#installing-an-app" title="Permalink to this headline">¶</a></h2>
|
||
<p>Assuming your game is named “mygame”, navigate to your <code class="docutils literal notranslate"><span class="pre">mygame/</span></code> directory, and type:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">evennia</span> <span class="n">startapp</span> <span class="n">chargen</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>This will initialize a new Django app we choose to call “chargen”. It is directory containing some
|
||
basic starting things Django needs. You will need to move this directory: for the time being, it is
|
||
in your <code class="docutils literal notranslate"><span class="pre">mygame</span></code> directory. Better to move it in your <code class="docutils literal notranslate"><span class="pre">mygame/web</span></code> directory, so you have
|
||
<code class="docutils literal notranslate"><span class="pre">mygame/web/chargen</span></code> in the end.</p>
|
||
<p>Next, navigate to <code class="docutils literal notranslate"><span class="pre">mygame/server/conf/settings.py</span></code> and add or edit the following line to make
|
||
Evennia (and Django) aware of our new app:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">INSTALLED_APPS</span> <span class="o">+=</span> <span class="p">(</span><span class="s1">'web.chargen'</span><span class="p">,)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>After this, we will get into defining our <em>models</em> (the description of the database storage),
|
||
<em>views</em> (the server-side website content generators), <em>urls</em> (how the web browser finds the pages)
|
||
and <em>templates</em> (how the web page should be structured).</p>
|
||
<div class="section" id="installing-checkpoint">
|
||
<h3>Installing - Checkpoint:<a class="headerlink" href="#installing-checkpoint" title="Permalink to this headline">¶</a></h3>
|
||
<ul class="simple">
|
||
<li><p>you should have a folder named <code class="docutils literal notranslate"><span class="pre">chargen</span></code> or whatever you chose in your mygame/web/ directory</p></li>
|
||
<li><p>you should have your application name added to your INSTALLED_APPS in settings.py</p></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="create-models">
|
||
<h2>Create Models<a class="headerlink" href="#create-models" title="Permalink to this headline">¶</a></h2>
|
||
<p>Models are created in <code class="docutils literal notranslate"><span class="pre">mygame/web/chargen/models.py</span></code>.</p>
|
||
<p>A <a class="reference internal" href="../Concepts/New-Models.html"><span class="doc">Django database model</span></a> is a Python class that describes the database storage of the
|
||
data you want to manage. Any data you choose to store is stored in the same database as the game and
|
||
you have access to all the game’s objects here.</p>
|
||
<p>We need to define what a character application actually is. This will differ from game to game so
|
||
for this tutorial we will define a simple character sheet with the following database fields:</p>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">app_id</span></code> (AutoField): Primary key for this character application sheet.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">char_name</span></code> (CharField): The new character’s name.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">date_applied</span></code> (DateTimeField): Date that this application was received.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">background</span></code> (TextField): Character story background.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">account_id</span></code> (IntegerField): Which account ID does this application belong to? This is an
|
||
AccountID from the AccountDB object.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">submitted</span></code> (BooleanField): <code class="docutils literal notranslate"><span class="pre">True</span></code>/<code class="docutils literal notranslate"><span class="pre">False</span></code> depending on if the application has been submitted yet.</p></li>
|
||
</ul>
|
||
<blockquote>
|
||
<div><p>Note: In a full-fledged game, you’d likely want them to be able to select races, skills,
|
||
attributes and so on.</p>
|
||
</div></blockquote>
|
||
<p>Our <code class="docutils literal notranslate"><span class="pre">models.py</span></code> file should look something like this:</p>
|
||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># in mygame/web/chargen/models.py</span>
|
||
|
||
<span class="kn">from</span> <span class="nn">django.db</span> <span class="kn">import</span> <span class="n">models</span>
|
||
|
||
<span class="k">class</span> <span class="nc">CharApp</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
|
||
<span class="n">app_id</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">AutoField</span><span class="p">(</span><span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
|
||
<span class="n">char_name</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">80</span><span class="p">,</span> <span class="n">verbose_name</span><span class="o">=</span><span class="s1">'Character Name'</span><span class="p">)</span>
|
||
<span class="n">date_applied</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="n">verbose_name</span><span class="o">=</span><span class="s1">'Date Applied'</span><span class="p">)</span>
|
||
<span class="n">background</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">(</span><span class="n">verbose_name</span><span class="o">=</span><span class="s1">'Background'</span><span class="p">)</span>
|
||
<span class="n">account_id</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">IntegerField</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">verbose_name</span><span class="o">=</span><span class="s1">'Account ID'</span><span class="p">)</span>
|
||
<span class="n">submitted</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">BooleanField</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>You should consider how you are going to link your application to your account. For this tutorial,
|
||
we are using the account_id attribute on our character application model in order to keep track of
|
||
which characters are owned by which accounts. Since the account id is a primary key in Evennia, it
|
||
is a good candidate, as you will never have two of the same IDs in Evennia. You can feel free to use
|
||
anything else, but for the purposes of this guide, we are going to use account ID to join the
|
||
character applications with the proper account.</p>
|
||
<div class="section" id="model-checkpoint">
|
||
<h3>Model - Checkpoint:<a class="headerlink" href="#model-checkpoint" title="Permalink to this headline">¶</a></h3>
|
||
<ul class="simple">
|
||
<li><p>you should have filled out <code class="docutils literal notranslate"><span class="pre">mygame/web/chargen/models.py</span></code> with the model class shown above
|
||
(eventually adding fields matching what you need for your game).</p></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="create-views">
|
||
<h2>Create Views<a class="headerlink" href="#create-views" title="Permalink to this headline">¶</a></h2>
|
||
<p><em>Views</em> are server-side constructs that make dynamic data available to a web page. We are going to
|
||
add them to <code class="docutils literal notranslate"><span class="pre">mygame/web/chargen.views.py</span></code>. Each view in our example represents the backbone of a
|
||
specific web page. We will use three views and three pages here:</p>
|
||
<ul class="simple">
|
||
<li><p>The index (managing <code class="docutils literal notranslate"><span class="pre">index.html</span></code>). This is what you see when you navigate to
|
||
<code class="docutils literal notranslate"><span class="pre">http://yoursite.com/chargen</span></code>.</p></li>
|
||
<li><p>The detail display sheet (manages <code class="docutils literal notranslate"><span class="pre">detail.html</span></code>). A page that passively displays the stats of a
|
||
given Character.</p></li>
|
||
<li><p>Character creation sheet (manages <code class="docutils literal notranslate"><span class="pre">create.html</span></code>). This is the main form with fields to fill in.</p></li>
|
||
</ul>
|
||
<div class="section" id="index-view">
|
||
<h3><em>Index</em> view<a class="headerlink" href="#index-view" title="Permalink to this headline">¶</a></h3>
|
||
<p>Let’s get started with the index first.</p>
|
||
<p>We’ll want characters to be able to see their created characters so let’s</p>
|
||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># file mygame/web/chargen.views.py</span>
|
||
|
||
<span class="kn">from</span> <span class="nn">.models</span> <span class="kn">import</span> <span class="n">CharApp</span>
|
||
|
||
<span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
|
||
<span class="n">current_user</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">user</span> <span class="c1"># current user logged in</span>
|
||
<span class="n">p_id</span> <span class="o">=</span> <span class="n">current_user</span><span class="o">.</span><span class="n">id</span> <span class="c1"># the account id</span>
|
||
<span class="c1"># submitted Characters by this account</span>
|
||
<span class="n">sub_apps</span> <span class="o">=</span> <span class="n">CharApp</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">account_id</span><span class="o">=</span><span class="n">p_id</span><span class="p">,</span> <span class="n">submitted</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
|
||
<span class="n">context</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'sub_apps'</span><span class="p">:</span> <span class="n">sub_apps</span><span class="p">}</span>
|
||
<span class="c1"># make the variables in 'context' available to the web page template</span>
|
||
<span class="k">return</span> <span class="n">render</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s1">'chargen/index.html'</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
</div>
|
||
<div class="section" id="detail-view">
|
||
<h3><em>Detail</em> view<a class="headerlink" href="#detail-view" title="Permalink to this headline">¶</a></h3>
|
||
<p>Our detail page will have pertinent character application information our users can see. Since this
|
||
is a basic demonstration, our detail page will only show two fields:</p>
|
||
<ul class="simple">
|
||
<li><p>Character name</p></li>
|
||
<li><p>Character background</p></li>
|
||
</ul>
|
||
<p>We will use the account ID again just to double-check that whoever tries to check our character page
|
||
is actually the account who owns the application.</p>
|
||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># file mygame/web/chargen.views.py</span>
|
||
|
||
<span class="k">def</span> <span class="nf">detail</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">app_id</span><span class="p">):</span>
|
||
<span class="n">app</span> <span class="o">=</span> <span class="n">CharApp</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">app_id</span><span class="o">=</span><span class="n">app_id</span><span class="p">)</span>
|
||
<span class="n">name</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">char_name</span>
|
||
<span class="n">background</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">background</span>
|
||
<span class="n">submitted</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">submitted</span>
|
||
<span class="n">p_id</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">id</span>
|
||
<span class="n">context</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'name'</span><span class="p">:</span> <span class="n">name</span><span class="p">,</span> <span class="s1">'background'</span><span class="p">:</span> <span class="n">background</span><span class="p">,</span>
|
||
<span class="s1">'p_id'</span><span class="p">:</span> <span class="n">p_id</span><span class="p">,</span> <span class="s1">'submitted'</span><span class="p">:</span> <span class="n">submitted</span><span class="p">}</span>
|
||
<span class="k">return</span> <span class="n">render</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s1">'chargen/detail.html'</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="creating-view">
|
||
<h2><em>Creating</em> view<a class="headerlink" href="#creating-view" title="Permalink to this headline">¶</a></h2>
|
||
<p>Predictably, our <em>create</em> function will be the most complicated of the views, as it needs to accept
|
||
information from the user, validate the information, and send the information to the server. Once
|
||
the form content is validated will actually create a playable Character.</p>
|
||
<p>The form itself we will define first. In our simple example we are just looking for the Character’s
|
||
name and background. This form we create in <code class="docutils literal notranslate"><span class="pre">mygame/web/chargen/forms.py</span></code>:</p>
|
||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># file mygame/web/chargen/forms.py</span>
|
||
|
||
<span class="kn">from</span> <span class="nn">django</span> <span class="kn">import</span> <span class="n">forms</span>
|
||
|
||
<span class="k">class</span> <span class="nc">AppForm</span><span class="p">(</span><span class="n">forms</span><span class="o">.</span><span class="n">Form</span><span class="p">):</span>
|
||
<span class="n">name</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">label</span><span class="o">=</span><span class="s1">'Character Name'</span><span class="p">,</span> <span class="n">max_length</span><span class="o">=</span><span class="mi">80</span><span class="p">)</span>
|
||
<span class="n">background</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">label</span><span class="o">=</span><span class="s1">'Background'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>Now we make use of this form in our view.</p>
|
||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
19
|
||
20
|
||
21
|
||
22
|
||
23
|
||
24
|
||
25
|
||
26
|
||
27
|
||
28
|
||
29
|
||
30
|
||
31
|
||
32
|
||
33
|
||
34
|
||
35
|
||
36
|
||
37
|
||
38
|
||
39
|
||
40
|
||
41
|
||
42
|
||
43
|
||
44</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># file mygame/web/chargen/views.py</span>
|
||
|
||
<span class="kn">from</span> <span class="nn">web.chargen.models</span> <span class="kn">import</span> <span class="n">CharApp</span>
|
||
<span class="kn">from</span> <span class="nn">web.chargen.forms</span> <span class="kn">import</span> <span class="n">AppForm</span>
|
||
<span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponseRedirect</span>
|
||
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
|
||
<span class="kn">from</span> <span class="nn">evennia.objects.models</span> <span class="kn">import</span> <span class="n">ObjectDB</span>
|
||
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>
|
||
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">create</span>
|
||
|
||
<span class="k">def</span> <span class="nf">creating</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
|
||
<span class="n">user</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">user</span>
|
||
<span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s1">'POST'</span><span class="p">:</span>
|
||
<span class="n">form</span> <span class="o">=</span> <span class="n">AppForm</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">POST</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="n">form</span><span class="o">.</span><span class="n">is_valid</span><span class="p">():</span>
|
||
<span class="n">name</span> <span class="o">=</span> <span class="n">form</span><span class="o">.</span><span class="n">cleaned_data</span><span class="p">[</span><span class="s1">'name'</span><span class="p">]</span>
|
||
<span class="n">background</span> <span class="o">=</span> <span class="n">form</span><span class="o">.</span><span class="n">cleaned_data</span><span class="p">[</span><span class="s1">'background'</span><span class="p">]</span>
|
||
<span class="n">applied_date</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span>
|
||
<span class="n">submitted</span> <span class="o">=</span> <span class="bp">True</span>
|
||
<span class="k">if</span> <span class="s1">'save'</span> <span class="ow">in</span> <span class="n">request</span><span class="o">.</span><span class="n">POST</span><span class="p">:</span>
|
||
<span class="n">submitted</span> <span class="o">=</span> <span class="bp">False</span>
|
||
<span class="n">app</span> <span class="o">=</span> <span class="n">CharApp</span><span class="p">(</span><span class="n">char_name</span><span class="o">=</span><span class="n">name</span><span class="p">,</span> <span class="n">background</span><span class="o">=</span><span class="n">background</span><span class="p">,</span>
|
||
<span class="n">date_applied</span><span class="o">=</span><span class="n">applied_date</span><span class="p">,</span> <span class="n">account_id</span><span class="o">=</span><span class="n">user</span><span class="o">.</span><span class="n">id</span><span class="p">,</span>
|
||
<span class="n">submitted</span><span class="o">=</span><span class="n">submitted</span><span class="p">)</span>
|
||
<span class="n">app</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
|
||
<span class="k">if</span> <span class="n">submitted</span><span class="p">:</span>
|
||
<span class="c1"># Create the actual character object</span>
|
||
<span class="n">typeclass</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">BASE_CHARACTER_TYPECLASS</span>
|
||
<span class="n">home</span> <span class="o">=</span> <span class="n">ObjectDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_id</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">GUEST_HOME</span><span class="p">)</span>
|
||
<span class="c1"># turn the permissionhandler to a string</span>
|
||
<span class="n">perms</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">user</span><span class="o">.</span><span class="n">permissions</span><span class="p">)</span>
|
||
<span class="c1"># create the character</span>
|
||
<span class="n">char</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_object</span><span class="p">(</span><span class="n">typeclass</span><span class="o">=</span><span class="n">typeclass</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="n">name</span><span class="p">,</span>
|
||
<span class="n">home</span><span class="o">=</span><span class="n">home</span><span class="p">,</span> <span class="n">permissions</span><span class="o">=</span><span class="n">perms</span><span class="p">)</span>
|
||
<span class="n">user</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_playable_characters</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">char</span><span class="p">)</span>
|
||
<span class="c1"># add the right locks for the character so the account can</span>
|
||
<span class="c1"># puppet it</span>
|
||
<span class="n">char</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"puppet:id(</span><span class="si">%i</span><span class="s2">) or pid(</span><span class="si">%i</span><span class="s2">) or perm(Developers) "</span>
|
||
<span class="s2">"or pperm(Developers)"</span> <span class="o">%</span> <span class="p">(</span><span class="n">char</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="n">user</span><span class="o">.</span><span class="n">id</span><span class="p">))</span>
|
||
<span class="n">char</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">background</span> <span class="o">=</span> <span class="n">background</span> <span class="c1"># set the character background</span>
|
||
<span class="k">return</span> <span class="n">HttpResponseRedirect</span><span class="p">(</span><span class="s1">'/chargen'</span><span class="p">)</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="n">form</span> <span class="o">=</span> <span class="n">AppForm</span><span class="p">()</span>
|
||
<span class="k">return</span> <span class="n">render</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s1">'chargen/create.html'</span><span class="p">,</span> <span class="p">{</span><span class="s1">'form'</span><span class="p">:</span> <span class="n">form</span><span class="p">})</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<blockquote>
|
||
<div><p>Note also that we basically create the character using the Evennia API, and we grab the proper
|
||
permissions from the <code class="docutils literal notranslate"><span class="pre">AccountDB</span></code> object and copy them to the character object. We take the user
|
||
permissions attribute and turn that list of strings into a string object in order for the
|
||
create_object function to properly process the permissions.</p>
|
||
</div></blockquote>
|
||
<p>Most importantly, the following attributes must be set on the created character object:</p>
|
||
<ul class="simple">
|
||
<li><p>Evennia <a class="reference external" href="Components/Locks.html#permissions">permissions</a> (copied from the <code class="docutils literal notranslate"><span class="pre">AccountDB</span></code>).</p></li>
|
||
<li><p>The right <code class="docutils literal notranslate"><span class="pre">puppet</span></code> <a class="reference internal" href="../Components/Locks.html"><span class="doc">locks</span></a> so the Account can actually play as this Character later.</p></li>
|
||
<li><p>The relevant Character <a class="reference internal" href="../Components/Typeclasses.html"><span class="doc">typeclass</span></a></p></li>
|
||
<li><p>Character name (key)</p></li>
|
||
<li><p>The Character’s home room location (<code class="docutils literal notranslate"><span class="pre">#2</span></code> by default)</p></li>
|
||
</ul>
|
||
<p>Other attributes are strictly speaking optional, such as the <code class="docutils literal notranslate"><span class="pre">background</span></code> attribute on our
|
||
character. It may be a good idea to decompose this function and create a separate _create_character
|
||
function in order to set up your character object the account owns. But with the Evennia API,
|
||
setting custom attributes is as easy as doing it in the meat of your Evennia game directory.</p>
|
||
<p>After all of this, our <code class="docutils literal notranslate"><span class="pre">views.py</span></code> file should look like something like this:</p>
|
||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
19
|
||
20
|
||
21
|
||
22
|
||
23
|
||
24
|
||
25
|
||
26
|
||
27
|
||
28
|
||
29
|
||
30
|
||
31
|
||
32
|
||
33
|
||
34
|
||
35
|
||
36
|
||
37
|
||
38
|
||
39
|
||
40
|
||
41
|
||
42
|
||
43
|
||
44
|
||
45
|
||
46
|
||
47
|
||
48
|
||
49
|
||
50
|
||
51
|
||
52
|
||
53
|
||
54
|
||
55
|
||
56
|
||
57
|
||
58
|
||
59
|
||
60
|
||
61
|
||
62
|
||
63</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># file mygame/web/chargen/views.py</span>
|
||
|
||
<span class="kn">from</span> <span class="nn">django.shortcuts</span> <span class="kn">import</span> <span class="n">render</span>
|
||
<span class="kn">from</span> <span class="nn">web.chargen.models</span> <span class="kn">import</span> <span class="n">CharApp</span>
|
||
<span class="kn">from</span> <span class="nn">web.chargen.forms</span> <span class="kn">import</span> <span class="n">AppForm</span>
|
||
<span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponseRedirect</span>
|
||
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
|
||
<span class="kn">from</span> <span class="nn">evennia.objects.models</span> <span class="kn">import</span> <span class="n">ObjectDB</span>
|
||
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>
|
||
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">create</span>
|
||
|
||
<span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
|
||
<span class="n">current_user</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">user</span> <span class="c1"># current user logged in</span>
|
||
<span class="n">p_id</span> <span class="o">=</span> <span class="n">current_user</span><span class="o">.</span><span class="n">id</span> <span class="c1"># the account id</span>
|
||
<span class="c1"># submitted apps under this account</span>
|
||
<span class="n">sub_apps</span> <span class="o">=</span> <span class="n">CharApp</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">account_id</span><span class="o">=</span><span class="n">p_id</span><span class="p">,</span> <span class="n">submitted</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
|
||
<span class="n">context</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'sub_apps'</span><span class="p">:</span> <span class="n">sub_apps</span><span class="p">}</span>
|
||
<span class="k">return</span> <span class="n">render</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s1">'chargen/index.html'</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
|
||
|
||
<span class="k">def</span> <span class="nf">detail</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">app_id</span><span class="p">):</span>
|
||
<span class="n">app</span> <span class="o">=</span> <span class="n">CharApp</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">app_id</span><span class="o">=</span><span class="n">app_id</span><span class="p">)</span>
|
||
<span class="n">name</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">char_name</span>
|
||
<span class="n">background</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">background</span>
|
||
<span class="n">submitted</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">submitted</span>
|
||
<span class="n">p_id</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">id</span>
|
||
<span class="n">context</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'name'</span><span class="p">:</span> <span class="n">name</span><span class="p">,</span> <span class="s1">'background'</span><span class="p">:</span> <span class="n">background</span><span class="p">,</span>
|
||
<span class="s1">'p_id'</span><span class="p">:</span> <span class="n">p_id</span><span class="p">,</span> <span class="s1">'submitted'</span><span class="p">:</span> <span class="n">submitted</span><span class="p">}</span>
|
||
<span class="k">return</span> <span class="n">render</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s1">'chargen/detail.html'</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
|
||
|
||
<span class="k">def</span> <span class="nf">creating</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
|
||
<span class="n">user</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">user</span>
|
||
<span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s1">'POST'</span><span class="p">:</span>
|
||
<span class="n">form</span> <span class="o">=</span> <span class="n">AppForm</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">POST</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="n">form</span><span class="o">.</span><span class="n">is_valid</span><span class="p">():</span>
|
||
<span class="n">name</span> <span class="o">=</span> <span class="n">form</span><span class="o">.</span><span class="n">cleaned_data</span><span class="p">[</span><span class="s1">'name'</span><span class="p">]</span>
|
||
<span class="n">background</span> <span class="o">=</span> <span class="n">form</span><span class="o">.</span><span class="n">cleaned_data</span><span class="p">[</span><span class="s1">'background'</span><span class="p">]</span>
|
||
<span class="n">applied_date</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span>
|
||
<span class="n">submitted</span> <span class="o">=</span> <span class="bp">True</span>
|
||
<span class="k">if</span> <span class="s1">'save'</span> <span class="ow">in</span> <span class="n">request</span><span class="o">.</span><span class="n">POST</span><span class="p">:</span>
|
||
<span class="n">submitted</span> <span class="o">=</span> <span class="bp">False</span>
|
||
<span class="n">app</span> <span class="o">=</span> <span class="n">CharApp</span><span class="p">(</span><span class="n">char_name</span><span class="o">=</span><span class="n">name</span><span class="p">,</span> <span class="n">background</span><span class="o">=</span><span class="n">background</span><span class="p">,</span>
|
||
<span class="n">date_applied</span><span class="o">=</span><span class="n">applied_date</span><span class="p">,</span> <span class="n">account_id</span><span class="o">=</span><span class="n">user</span><span class="o">.</span><span class="n">id</span><span class="p">,</span>
|
||
<span class="n">submitted</span><span class="o">=</span><span class="n">submitted</span><span class="p">)</span>
|
||
<span class="n">app</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
|
||
<span class="k">if</span> <span class="n">submitted</span><span class="p">:</span>
|
||
<span class="c1"># Create the actual character object</span>
|
||
<span class="n">typeclass</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">BASE_CHARACTER_TYPECLASS</span>
|
||
<span class="n">home</span> <span class="o">=</span> <span class="n">ObjectDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_id</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">GUEST_HOME</span><span class="p">)</span>
|
||
<span class="c1"># turn the permissionhandler to a string</span>
|
||
<span class="n">perms</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">user</span><span class="o">.</span><span class="n">permissions</span><span class="p">)</span>
|
||
<span class="c1"># create the character</span>
|
||
<span class="n">char</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_object</span><span class="p">(</span><span class="n">typeclass</span><span class="o">=</span><span class="n">typeclass</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="n">name</span><span class="p">,</span>
|
||
<span class="n">home</span><span class="o">=</span><span class="n">home</span><span class="p">,</span> <span class="n">permissions</span><span class="o">=</span><span class="n">perms</span><span class="p">)</span>
|
||
<span class="n">user</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_playable_characters</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">char</span><span class="p">)</span>
|
||
<span class="c1"># add the right locks for the character so the account can</span>
|
||
<span class="c1"># puppet it</span>
|
||
<span class="n">char</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"puppet:id(</span><span class="si">%i</span><span class="s2">) or pid(</span><span class="si">%i</span><span class="s2">) or perm(Developers) "</span>
|
||
<span class="s2">"or pperm(Developers)"</span> <span class="o">%</span> <span class="p">(</span><span class="n">char</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="n">user</span><span class="o">.</span><span class="n">id</span><span class="p">))</span>
|
||
<span class="n">char</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">background</span> <span class="o">=</span> <span class="n">background</span> <span class="c1"># set the character background</span>
|
||
<span class="k">return</span> <span class="n">HttpResponseRedirect</span><span class="p">(</span><span class="s1">'/chargen'</span><span class="p">)</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="n">form</span> <span class="o">=</span> <span class="n">AppForm</span><span class="p">()</span>
|
||
<span class="k">return</span> <span class="n">render</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="s1">'chargen/create.html'</span><span class="p">,</span> <span class="p">{</span><span class="s1">'form'</span><span class="p">:</span> <span class="n">form</span><span class="p">})</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<div class="section" id="create-views-checkpoint">
|
||
<h3>Create Views - Checkpoint:<a class="headerlink" href="#create-views-checkpoint" title="Permalink to this headline">¶</a></h3>
|
||
<ul class="simple">
|
||
<li><p>you’ve defined a <code class="docutils literal notranslate"><span class="pre">views.py</span></code> that has an index, detail, and creating functions.</p></li>
|
||
<li><p>you’ve defined a forms.py with the <code class="docutils literal notranslate"><span class="pre">AppForm</span></code> class needed by the <code class="docutils literal notranslate"><span class="pre">creating</span></code> function of
|
||
<code class="docutils literal notranslate"><span class="pre">views.py</span></code>.</p></li>
|
||
<li><p>your <code class="docutils literal notranslate"><span class="pre">mygame/web/chargen</span></code> directory should now have a <code class="docutils literal notranslate"><span class="pre">views.py</span></code> and <code class="docutils literal notranslate"><span class="pre">forms.py</span></code> file</p></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="create-urls">
|
||
<h2>Create URLs<a class="headerlink" href="#create-urls" title="Permalink to this headline">¶</a></h2>
|
||
<p>URL patterns helps redirect requests from the web browser to the right views. These patterns are
|
||
created in <code class="docutils literal notranslate"><span class="pre">mygame/web/chargen/urls.py</span></code>.</p>
|
||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># file mygame/web/chargen/urls.py</span>
|
||
|
||
<span class="kn">from</span> <span class="nn">django.conf.urls</span> <span class="kn">import</span> <span class="n">url</span>
|
||
<span class="kn">from</span> <span class="nn">web.chargen</span> <span class="kn">import</span> <span class="n">views</span>
|
||
|
||
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="p">[</span>
|
||
<span class="c1"># ex: /chargen/</span>
|
||
<span class="n">url</span><span class="p">(</span><span class="sa">r</span><span class="s1">'^$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">index</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'index'</span><span class="p">),</span>
|
||
<span class="c1"># ex: /chargen/5/</span>
|
||
<span class="n">url</span><span class="p">(</span><span class="sa">r</span><span class="s1">'^(?P<app_id>[0-9]+)/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">detail</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'detail'</span><span class="p">),</span>
|
||
<span class="c1"># ex: /chargen/create</span>
|
||
<span class="n">url</span><span class="p">(</span><span class="sa">r</span><span class="s1">'^create/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">creating</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'creating'</span><span class="p">),</span>
|
||
<span class="p">]</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>You could change the format as you desire. To make it more secure, you could remove app_id from the
|
||
“detail” url, and instead just fetch the account’s applications using a unifying field like
|
||
account_id to find all the character application objects to display.</p>
|
||
<p>We must also update the main <code class="docutils literal notranslate"><span class="pre">mygame/web/urls.py</span></code> file (that is, one level up from our chargen app),
|
||
so the main website knows where our app’s views are located. Find the <code class="docutils literal notranslate"><span class="pre">patterns</span></code> variable, and
|
||
change it to include:</p>
|
||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># in file mygame/web/urls.py</span>
|
||
|
||
<span class="kn">from</span> <span class="nn">django.conf.urls</span> <span class="kn">import</span> <span class="n">url</span><span class="p">,</span> <span class="n">include</span>
|
||
|
||
<span class="c1"># default evennia patterns</span>
|
||
<span class="kn">from</span> <span class="nn">evennia.web.urls</span> <span class="kn">import</span> <span class="n">urlpatterns</span>
|
||
|
||
<span class="c1"># eventual custom patterns</span>
|
||
<span class="n">custom_patterns</span> <span class="o">=</span> <span class="p">[</span>
|
||
<span class="c1"># url(r'/desired/url/', view, name='example'),</span>
|
||
<span class="p">]</span>
|
||
|
||
<span class="c1"># this is required by Django.</span>
|
||
<span class="n">urlpatterns</span> <span class="o">+=</span> <span class="p">[</span>
|
||
<span class="n">url</span><span class="p">(</span><span class="sa">r</span><span class="s1">'^chargen/'</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s1">'web.chargen.urls'</span><span class="p">)),</span>
|
||
<span class="p">]</span>
|
||
|
||
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">custom_patterns</span> <span class="o">+</span> <span class="n">urlpatterns</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<div class="section" id="urls-checkpoint">
|
||
<h3>URLs - Checkpoint:<a class="headerlink" href="#urls-checkpoint" title="Permalink to this headline">¶</a></h3>
|
||
<ul class="simple">
|
||
<li><p>You’ve created a urls.py file in the <code class="docutils literal notranslate"><span class="pre">mygame/web/chargen</span></code> directory</p></li>
|
||
<li><p>You have edited the main <code class="docutils literal notranslate"><span class="pre">mygame/web/urls.py</span></code> file to include urls to the <code class="docutils literal notranslate"><span class="pre">chargen</span></code> directory.</p></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="html-templates">
|
||
<h2>HTML Templates<a class="headerlink" href="#html-templates" title="Permalink to this headline">¶</a></h2>
|
||
<p>So we have our url patterns, views, and models defined. Now we must define our HTML templates that
|
||
the actual user will see and interact with. For this tutorial we us the basic <em>prosimii</em> template
|
||
that comes with Evennia.</p>
|
||
<p>Take note that we use <code class="docutils literal notranslate"><span class="pre">user.is_authenticated</span></code> to make sure that the user cannot create a character
|
||
without logging in.</p>
|
||
<p>These files will all go into the <code class="docutils literal notranslate"><span class="pre">/mygame/web/chargen/templates/chargen/</span></code> directory.</p>
|
||
<div class="section" id="index-html">
|
||
<h3>index.html<a class="headerlink" href="#index-html" title="Permalink to this headline">¶</a></h3>
|
||
<p>This HTML template should hold a list of all the applications the account currently has active. For
|
||
this demonstration, we will only list the applications that the account has submitted. You could
|
||
easily adjust this to include saved applications, or other types of applications if you have
|
||
different kinds.</p>
|
||
<p>Please refer back to <code class="docutils literal notranslate"><span class="pre">views.py</span></code> to see where we define the variables these templates make use of.</p>
|
||
<div class="highlight-html notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
19</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c"><!-- file mygame/web/chargen/templates/chargen/index.html--></span>
|
||
|
||
{% extends "base.html" %}
|
||
{% block content %}
|
||
{% if user.is_authenticated %}
|
||
<span class="p"><</span><span class="nt">h1</span><span class="p">></span>Character Generation<span class="p"></</span><span class="nt">h1</span><span class="p">></span>
|
||
{% if sub_apps %}
|
||
<span class="p"><</span><span class="nt">ul</span><span class="p">></span>
|
||
{% for sub_app in sub_apps %}
|
||
<span class="p"><</span><span class="nt">li</span><span class="p">><</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"/chargen/{{ sub_app.app_id }}/"</span><span class="p">></span>{{ sub_app.char_name }}<span class="p"></</span><span class="nt">a</span><span class="p">></</span><span class="nt">li</span><span class="p">></span>
|
||
{% endfor %}
|
||
<span class="p"></</span><span class="nt">ul</span><span class="p">></span>
|
||
{% else %}
|
||
<span class="p"><</span><span class="nt">p</span><span class="p">></span>You haven't submitted any character applications.<span class="p"></</span><span class="nt">p</span><span class="p">></span>
|
||
{% endif %}
|
||
{% else %}
|
||
<span class="p"><</span><span class="nt">p</span><span class="p">></span>Please <span class="p"><</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"{% url 'login'%}"</span><span class="p">></span>login<span class="p"></</span><span class="nt">a</span><span class="p">></span>first.<span class="p"><</span><span class="nt">a</span><span class="p">/></</span><span class="nt">p</span><span class="p">></span>
|
||
{% endif %}
|
||
{% endblock %}
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
</div>
|
||
<div class="section" id="detail-html">
|
||
<h3>detail.html<a class="headerlink" href="#detail-html" title="Permalink to this headline">¶</a></h3>
|
||
<p>This page should show a detailed character sheet of their application. This will only show their
|
||
name and character background. You will likely want to extend this to show many more fields for your
|
||
game. In a full-fledged character generation, you may want to extend the boolean attribute of
|
||
submitted to allow accounts to save character applications and submit them later.</p>
|
||
<div class="highlight-html notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c"><!-- file mygame/web/chargen/templates/chargen/detail.html--></span>
|
||
|
||
{% extends "base.html" %}
|
||
{% block content %}
|
||
<span class="p"><</span><span class="nt">h1</span><span class="p">></span>Character Information<span class="p"></</span><span class="nt">h1</span><span class="p">></span>
|
||
{% if user.is_authenticated %}
|
||
{% if user.id == p_id %}
|
||
<span class="p"><</span><span class="nt">h2</span><span class="p">></span>{{name}}<span class="p"></</span><span class="nt">h2</span><span class="p">></span>
|
||
<span class="p"><</span><span class="nt">h2</span><span class="p">></span>Background<span class="p"></</span><span class="nt">h2</span><span class="p">></span>
|
||
<span class="p"><</span><span class="nt">p</span><span class="p">></span>{{background}}<span class="p"></</span><span class="nt">p</span><span class="p">></span>
|
||
<span class="p"><</span><span class="nt">p</span><span class="p">></span>Submitted: {{submitted}}<span class="p"></</span><span class="nt">p</span><span class="p">></span>
|
||
{% else %}
|
||
<span class="p"><</span><span class="nt">p</span><span class="p">></span>You didn't submit this character.<span class="p"></</span><span class="nt">p</span><span class="p">></span>
|
||
{% endif %}
|
||
{% else %}
|
||
<span class="p"><</span><span class="nt">p</span><span class="p">></span>You aren't logged in.<span class="p"></</span><span class="nt">p</span><span class="p">></span>
|
||
{% endif %}
|
||
{% endblock %}
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
</div>
|
||
<div class="section" id="create-html">
|
||
<h3>create.html<a class="headerlink" href="#create-html" title="Permalink to this headline">¶</a></h3>
|
||
<p>Our create HTML template will use the Django form we defined back in views.py/forms.py to drive the
|
||
majority of the application process. There will be a form input for every field we defined in
|
||
forms.py, which is handy. We have used POST as our method because we are sending information to the
|
||
server that will update the database. As an alternative, GET would be much less secure. You can read
|
||
up on documentation elsewhere on the web for GET vs. POST.</p>
|
||
<div class="highlight-html notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c"><!-- file mygame/web/chargen/templates/chargen/create.html--></span>
|
||
|
||
{% extends "base.html" %}
|
||
{% block content %}
|
||
<span class="p"><</span><span class="nt">h1</span><span class="p">></span>Character Creation<span class="p"></</span><span class="nt">h1</span><span class="p">></span>
|
||
{% if user.is_authenticated %}
|
||
<span class="p"><</span><span class="nt">form</span> <span class="na">action</span><span class="o">=</span><span class="s">"/chargen/create/"</span> <span class="na">method</span><span class="o">=</span><span class="s">"post"</span><span class="p">></span>
|
||
{% csrf_token %}
|
||
{{ form }}
|
||
<span class="p"><</span><span class="nt">input</span> <span class="na">type</span><span class="o">=</span><span class="s">"submit"</span> <span class="na">name</span><span class="o">=</span><span class="s">"submit"</span> <span class="na">value</span><span class="o">=</span><span class="s">"Submit"</span><span class="p">/></span>
|
||
<span class="p"></</span><span class="nt">form</span><span class="p">></span>
|
||
{% else %}
|
||
<span class="p"><</span><span class="nt">p</span><span class="p">></span>You aren't logged in.<span class="p"></</span><span class="nt">p</span><span class="p">></span>
|
||
{% endif %}
|
||
{% endblock %}
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
</div>
|
||
<div class="section" id="templates-checkpoint">
|
||
<h3>Templates - Checkpoint:<a class="headerlink" href="#templates-checkpoint" title="Permalink to this headline">¶</a></h3>
|
||
<ul class="simple">
|
||
<li><p>Create a <code class="docutils literal notranslate"><span class="pre">index.html</span></code>, <code class="docutils literal notranslate"><span class="pre">detail.html</span></code> and <code class="docutils literal notranslate"><span class="pre">create.html</span></code> template in your
|
||
<code class="docutils literal notranslate"><span class="pre">mygame/web/chargen/templates/chargen</span></code> directory</p></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="activating-your-new-character-generation">
|
||
<h2>Activating your new character generation<a class="headerlink" href="#activating-your-new-character-generation" title="Permalink to this headline">¶</a></h2>
|
||
<p>After finishing this tutorial you should have edited or created the following files:</p>
|
||
<div class="highlight-bash notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7</pre></div></td><td class="code"><div class="highlight"><pre><span></span>mygame/web/urls.py
|
||
mygame/web/chargen/models.py
|
||
mygame/web/chargen/views.py
|
||
mygame/web/chargen/urls.py
|
||
mygame/web/chargen/templates/chargen/index.html
|
||
mygame/web/chargen/templates/chargen/create.html
|
||
mygame/web/chargen/templates/chargen/detail.html
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>Once you have all these files stand in your <code class="docutils literal notranslate"><span class="pre">mygame/</span></code>folder and run:</p>
|
||
<div class="highlight-bash notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
|
||
2</pre></div></td><td class="code"><div class="highlight"><pre><span></span>evennia makemigrations
|
||
evennia migrate
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>This will create and update the models. If you see any errors at this stage, read the traceback
|
||
carefully, it should be relatively easy to figure out where the error is.</p>
|
||
<p>Login to the website (you need to have previously registered an Player account with the game to do
|
||
this). Next you navigate to <code class="docutils literal notranslate"><span class="pre">http://yourwebsite.com/chargen</span></code> (if you are running locally this will
|
||
be something like <code class="docutils literal notranslate"><span class="pre">http://localhost:4001/chargen</span></code> and you will see your new app in action.</p>
|
||
<p>This should hopefully give you a good starting point in figuring out how you’d like to approach your
|
||
own web generation. The main difficulties are in setting the appropriate settings on your newly
|
||
created character object. Thankfully, the Evennia API makes this easy.</p>
|
||
</div>
|
||
<div class="section" id="adding-a-no-capcha-recapcha-on-your-character-generation">
|
||
<h2>Adding a no CAPCHA reCAPCHA on your character generation<a class="headerlink" href="#adding-a-no-capcha-recapcha-on-your-character-generation" title="Permalink to this headline">¶</a></h2>
|
||
<p>As sad as it is, if your server is open to the web, bots might come to visit and take advantage of
|
||
your open form to create hundreds, thousands, millions of characters if you give them the
|
||
opportunity. This section shows you how to use the <a class="reference external" href="https://www.google.com/recaptcha/intro/invisible.html">No CAPCHA
|
||
reCAPCHA</a> designed by Google. Not only is it
|
||
easy to use, it is user-friendly… for humans. A simple checkbox to check, except if Google has
|
||
some suspicion, in which case you will have a more difficult test with an image and the usual text
|
||
inside. It’s worth pointing out that, as long as Google doesn’t suspect you of being a robot, this
|
||
is quite useful, not only for common users, but to screen-reader users, to which reading inside of
|
||
an image is pretty difficult, if not impossible. And to top it all, it will be so easy to add in
|
||
your website.</p>
|
||
<div class="section" id="step-1-obtain-a-sitekey-and-secret-from-google">
|
||
<h3>Step 1: Obtain a SiteKey and secret from Google<a class="headerlink" href="#step-1-obtain-a-sitekey-and-secret-from-google" title="Permalink to this headline">¶</a></h3>
|
||
<p>The first thing is to ask Google for a way to safely authenticate your website to their service. To
|
||
do it, we need to create a site key and a secret. Go to
|
||
<a class="reference external" href="https://www.google.com/recaptcha/admin">https://www.google.com/recaptcha/admin</a> to create such a
|
||
site key. It’s quite easy when you have a Google account.</p>
|
||
<p>When you have created your site key, save it safely. Also copy your secret key as well. You should
|
||
find both information on the web page. Both would contain a lot of letters and figures.</p>
|
||
</div>
|
||
<div class="section" id="step-2-installing-and-configuring-the-dedicated-django-app">
|
||
<h3>Step 2: installing and configuring the dedicated Django app<a class="headerlink" href="#step-2-installing-and-configuring-the-dedicated-django-app" title="Permalink to this headline">¶</a></h3>
|
||
<p>Since Evennia runs on Django, the easiest way to add our CAPCHA and perform the proper check is to
|
||
install the dedicated Django app. Quite easy:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pip</span> <span class="n">install</span> <span class="n">django</span><span class="o">-</span><span class="n">nocaptcha</span><span class="o">-</span><span class="n">recaptcha</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>And add it to the installed apps in your settings. In your <code class="docutils literal notranslate"><span class="pre">mygame/server/conf/settings.py</span></code>, you
|
||
might have something like this:</p>
|
||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
|
||
2
|
||
3
|
||
4
|
||
5</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># ...</span>
|
||
<span class="n">INSTALLED_APPS</span> <span class="o">+=</span> <span class="p">(</span>
|
||
<span class="s1">'web.chargen'</span><span class="p">,</span>
|
||
<span class="s1">'nocaptcha_recaptcha'</span><span class="p">,</span>
|
||
<span class="p">)</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>Don’t close the setting file just yet. We have to add in the site key and secret key. You can add
|
||
them below:</p>
|
||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
|
||
2
|
||
3
|
||
4</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># NoReCAPCHA site key</span>
|
||
<span class="n">NORECAPTCHA_SITE_KEY</span> <span class="o">=</span> <span class="s2">"PASTE YOUR SITE KEY HERE"</span>
|
||
<span class="c1"># NoReCAPCHA secret key</span>
|
||
<span class="n">NORECAPTCHA_SECRET_KEY</span> <span class="o">=</span> <span class="s2">"PUT YOUR SECRET KEY HERE"</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
</div>
|
||
<div class="section" id="step-3-adding-the-capcha-to-our-form">
|
||
<h3>Step 3: Adding the CAPCHA to our form<a class="headerlink" href="#step-3-adding-the-capcha-to-our-form" title="Permalink to this headline">¶</a></h3>
|
||
<p>Finally we have to add the CAPCHA to our form. It will be pretty easy too. First, open your
|
||
<code class="docutils literal notranslate"><span class="pre">web/chargen/forms.py</span></code> file. We’re going to add a new field, but hopefully, all the hard work has
|
||
been done for us. Update at your convenience, You might end up with something like this:</p>
|
||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django</span> <span class="kn">import</span> <span class="n">forms</span>
|
||
<span class="kn">from</span> <span class="nn">nocaptcha_recaptcha.fields</span> <span class="kn">import</span> <span class="n">NoReCaptchaField</span>
|
||
|
||
<span class="k">class</span> <span class="nc">AppForm</span><span class="p">(</span><span class="n">forms</span><span class="o">.</span><span class="n">Form</span><span class="p">):</span>
|
||
<span class="n">name</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">label</span><span class="o">=</span><span class="s1">'Character Name'</span><span class="p">,</span> <span class="n">max_length</span><span class="o">=</span><span class="mi">80</span><span class="p">)</span>
|
||
<span class="n">background</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">label</span><span class="o">=</span><span class="s1">'Background'</span><span class="p">)</span>
|
||
<span class="n">captcha</span> <span class="o">=</span> <span class="n">NoReCaptchaField</span><span class="p">()</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>As you see, we added a line of import (line 2) and a field in our form.</p>
|
||
<p>And lastly, we need to update our HTML file to add in the Google library. You can open
|
||
<code class="docutils literal notranslate"><span class="pre">web/chargen/templates/chargen/create.html</span></code>. There’s only one line to add:</p>
|
||
<div class="highlight-html notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="p"><</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">"https://www.google.com/recaptcha/api.js"</span> <span class="na">async</span> <span class="na">defer</span><span class="p">></</span><span class="nt">script</span><span class="p">></span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>And you should put it at the bottom of the page. Just before the closing body would be good, but
|
||
for the time being, the base page doesn’t provide a footer block, so we’ll put it in the content
|
||
block. Note that it’s not the best place, but it will work. In the end, your
|
||
<code class="docutils literal notranslate"><span class="pre">web/chargen/templates/chargen/create.html</span></code> file should look like this:</p>
|
||
<div class="highlight-html notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14</pre></div></td><td class="code"><div class="highlight"><pre><span></span>{% extends "base.html" %}
|
||
{% block content %}
|
||
<span class="p"><</span><span class="nt">h1</span><span class="p">></span>Character Creation<span class="p"></</span><span class="nt">h1</span><span class="p">></span>
|
||
{% if user.is_authenticated %}
|
||
<span class="p"><</span><span class="nt">form</span> <span class="na">action</span><span class="o">=</span><span class="s">"/chargen/create/"</span> <span class="na">method</span><span class="o">=</span><span class="s">"post"</span><span class="p">></span>
|
||
{% csrf_token %}
|
||
{{ form }}
|
||
<span class="p"><</span><span class="nt">input</span> <span class="na">type</span><span class="o">=</span><span class="s">"submit"</span> <span class="na">name</span><span class="o">=</span><span class="s">"submit"</span> <span class="na">value</span><span class="o">=</span><span class="s">"Submit"</span><span class="p">/></span>
|
||
<span class="p"></</span><span class="nt">form</span><span class="p">></span>
|
||
{% else %}
|
||
<span class="p"><</span><span class="nt">p</span><span class="p">></span>You aren't logged in.<span class="p"></</span><span class="nt">p</span><span class="p">></span>
|
||
{% endif %}
|
||
<span class="p"><</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">"https://www.google.com/recaptcha/api.js"</span> <span class="na">async</span> <span class="na">defer</span><span class="p">></</span><span class="nt">script</span><span class="p">></span>
|
||
{% endblock %}
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>Reload and open <a class="reference external" href="http://localhost:4001/chargen/create/">http://localhost:4001/chargen/create</a> and
|
||
you should see your beautiful CAPCHA just before the “submit” button. Try not to check the checkbox
|
||
to see what happens. And do the same while checking the checkbox!</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<div class="clearer"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||
<div class="sphinxsidebarwrapper">
|
||
<p class="logo"><a href="../index.html">
|
||
<img class="logo" src="../_static/evennia_logo.png" alt="Logo"/>
|
||
</a></p>
|
||
<div id="searchbox" style="display: none" role="search">
|
||
<h3 id="searchlabel">Quick search</h3>
|
||
<div class="searchformwrapper">
|
||
<form class="search" action="../search.html" method="get">
|
||
<input type="text" name="q" aria-labelledby="searchlabel" />
|
||
<input type="submit" value="Go" />
|
||
</form>
|
||
</div>
|
||
</div>
|
||
<script>$('#searchbox').show(0);</script>
|
||
<p><h3><a href="../index.html">Table of Contents</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#">Web Character Generation</a><ul>
|
||
<li><a class="reference internal" href="#introduction">Introduction</a></li>
|
||
<li><a class="reference internal" href="#pictures">Pictures</a></li>
|
||
<li><a class="reference internal" href="#installing-an-app">Installing an App</a><ul>
|
||
<li><a class="reference internal" href="#installing-checkpoint">Installing - Checkpoint:</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#create-models">Create Models</a><ul>
|
||
<li><a class="reference internal" href="#model-checkpoint">Model - Checkpoint:</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#create-views">Create Views</a><ul>
|
||
<li><a class="reference internal" href="#index-view"><em>Index</em> view</a></li>
|
||
<li><a class="reference internal" href="#detail-view"><em>Detail</em> view</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#creating-view"><em>Creating</em> view</a><ul>
|
||
<li><a class="reference internal" href="#create-views-checkpoint">Create Views - Checkpoint:</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#create-urls">Create URLs</a><ul>
|
||
<li><a class="reference internal" href="#urls-checkpoint">URLs - Checkpoint:</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#html-templates">HTML Templates</a><ul>
|
||
<li><a class="reference internal" href="#index-html">index.html</a></li>
|
||
<li><a class="reference internal" href="#detail-html">detail.html</a></li>
|
||
<li><a class="reference internal" href="#create-html">create.html</a></li>
|
||
<li><a class="reference internal" href="#templates-checkpoint">Templates - Checkpoint:</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#activating-your-new-character-generation">Activating your new character generation</a></li>
|
||
<li><a class="reference internal" href="#adding-a-no-capcha-recapcha-on-your-character-generation">Adding a no CAPCHA reCAPCHA on your character generation</a><ul>
|
||
<li><a class="reference internal" href="#step-1-obtain-a-sitekey-and-secret-from-google">Step 1: Obtain a SiteKey and secret from Google</a></li>
|
||
<li><a class="reference internal" href="#step-2-installing-and-configuring-the-dedicated-django-app">Step 2: installing and configuring the dedicated Django app</a></li>
|
||
<li><a class="reference internal" href="#step-3-adding-the-capcha-to-our-form">Step 3: Adding the CAPCHA to our form</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<div role="note" aria-label="source link">
|
||
<!--h3>This Page</h3-->
|
||
<ul class="this-page-menu">
|
||
<li><a href="../_sources/Howto/Web-Character-Generation.md.txt"
|
||
rel="nofollow">Show Page Source</a></li>
|
||
</ul>
|
||
</div>
|
||
<h3>Versions</h3>
|
||
<ul>
|
||
<li><a href="Web-Character-Generation.html">1.0-dev (develop branch)</a></li>
|
||
<li><a href="../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||
</ul>
|
||
|
||
</div>
|
||
</div>
|
||
<div class="clearer"></div>
|
||
</div>
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="General Index"
|
||
>index</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python Module Index"
|
||
>modules</a> |</li>
|
||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0-dev</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">Web Character Generation</a></li>
|
||
</ul>
|
||
<div class="develop">develop branch</div>
|
||
</div>
|
||
<div class="footer" role="contentinfo">
|
||
© Copyright 2020, The Evennia developer community.
|
||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
||
</div>
|
||
</body>
|
||
</html> |