mirror of
https://github.com/evennia/evennia.git
synced 2026-04-05 23:47:16 +02:00
Updated HTML docs
This commit is contained in:
parent
1bbc93507a
commit
8c5212d5ff
409 changed files with 17441 additions and 15857 deletions
|
|
@ -76,7 +76,7 @@ command:</p>
|
|||
<span class="normal">2</span>
|
||||
<span class="normal">3</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="k">if</span> <span class="ow">not</span> <span class="n">obj</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">accessing_obj</span><span class="p">,</span> <span class="s1">'delete'</span><span class="p">):</span>
|
||||
<span class="n">accessing_obj</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"Sorry, you may not delete that."</span><span class="p">)</span>
|
||||
<span class="k">return</span>
|
||||
<span class="k">return</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</section>
|
||||
|
|
@ -89,9 +89,9 @@ definitions to the object’s <code class="docutils literal notranslate"><span c
|
|||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="n">delete</span><span class="p">:</span><span class="nb">id</span><span class="p">(</span><span class="mi">34</span><span class="p">)</span> <span class="c1"># only allow obj #34 to delete</span>
|
||||
<span class="n">edit</span><span class="p">:</span><span class="nb">all</span><span class="p">()</span> <span class="c1"># let everyone edit </span>
|
||||
<span class="n">edit</span><span class="p">:</span><span class="nb">all</span><span class="p">()</span> <span class="c1"># let everyone edit</span>
|
||||
<span class="c1"># only those who are not "very_weak" or are Admins may pick this up</span>
|
||||
<span class="n">get</span><span class="p">:</span> <span class="ow">not</span> <span class="n">attr</span><span class="p">(</span><span class="n">very_weak</span><span class="p">)</span> <span class="ow">or</span> <span class="n">perm</span><span class="p">(</span><span class="n">Admin</span><span class="p">)</span>
|
||||
<span class="n">get</span><span class="p">:</span> <span class="ow">not</span> <span class="n">attr</span><span class="p">(</span><span class="n">very_weak</span><span class="p">)</span> <span class="ow">or</span> <span class="n">perm</span><span class="p">(</span><span class="n">Admin</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>Formally, a lockstring has the following syntax:</p>
|
||||
|
|
@ -106,7 +106,7 @@ returns either <code class="docutils literal notranslate"><span class="pre">True
|
|||
total result is <code class="docutils literal notranslate"><span class="pre">True</span></code>, the lock is passed.</p>
|
||||
<p>You can create several lock types one after the other by separating them with a semicolon (<code class="docutils literal notranslate"><span class="pre">;</span></code>) in
|
||||
the lockstring. The string below yields the same result as the previous example:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">delete</span><span class="p">:</span><span class="nb">id</span><span class="p">(</span><span class="mi">34</span><span class="p">);</span><span class="n">edit</span><span class="p">:</span><span class="nb">all</span><span class="p">();</span><span class="n">get</span><span class="p">:</span> <span class="ow">not</span> <span class="n">attr</span><span class="p">(</span><span class="n">very_weak</span><span class="p">)</span> <span class="ow">or</span> <span class="n">perm</span><span class="p">(</span><span class="n">Admin</span><span class="p">)</span>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">delete</span><span class="p">:</span><span class="nb">id</span><span class="p">(</span><span class="mi">34</span><span class="p">);</span><span class="n">edit</span><span class="p">:</span><span class="nb">all</span><span class="p">();</span><span class="n">get</span><span class="p">:</span> <span class="ow">not</span> <span class="n">attr</span><span class="p">(</span><span class="n">very_weak</span><span class="p">)</span> <span class="ow">or</span> <span class="n">perm</span><span class="p">(</span><span class="n">Admin</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<section id="valid-access-types">
|
||||
|
|
@ -205,7 +205,7 @@ trying to read the board):</p>
|
|||
<span class="normal">2</span>
|
||||
<span class="normal">3</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="k">if</span> <span class="ow">not</span> <span class="n">obj</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">accessing_obj</span><span class="p">,</span> <span class="s1">'read'</span><span class="p">):</span>
|
||||
<span class="n">accessing_obj</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"Sorry, you may not read that."</span><span class="p">)</span>
|
||||
<span class="k">return</span>
|
||||
<span class="k">return</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</section>
|
||||
|
|
@ -230,12 +230,12 @@ arguments explicitly given in the lock definition will appear as extra arguments
|
|||
<span class="normal">7</span>
|
||||
<span class="normal">8</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="c1"># A simple example lock function. Called with e.g. `id(34)`. This is</span>
|
||||
<span class="c1"># defined in, say mygame/server/conf/lockfuncs.py</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">id</span><span class="p">(</span><span class="n">accessing_obj</span><span class="p">,</span> <span class="n">accessed_obj</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="n">args</span><span class="p">:</span>
|
||||
<span class="n">wanted_id</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
||||
<span class="k">return</span> <span class="n">accessing_obj</span><span class="o">.</span><span class="n">id</span> <span class="o">==</span> <span class="n">wanted_id</span>
|
||||
<span class="k">return</span> <span class="kc">False</span>
|
||||
<span class="k">return</span> <span class="kc">False</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>The above could for example be used in a lock function like this:</p>
|
||||
|
|
@ -313,126 +313,6 @@ child object to change the default. Also creation commands like <code class="doc
|
|||
objects you create - for example it sets the <code class="docutils literal notranslate"><span class="pre">control</span></code> lock_type so as to allow you, its creator, to
|
||||
control and delete the object.</p>
|
||||
</section>
|
||||
</section>
|
||||
<section id="permissions">
|
||||
<h1>Permissions<a class="headerlink" href="#permissions" title="Permalink to this headline">¶</a></h1>
|
||||
<blockquote>
|
||||
<div><p>This section covers the underlying code use of permissions. If you just want to learn how to
|
||||
practically assign permissions in-game, refer to the <a class="reference internal" href="../Concepts/Building-Permissions.html"><span class="doc">Building Permissions</span></a>
|
||||
page, which details how you use the <code class="docutils literal notranslate"><span class="pre">perm</span></code> command.</p>
|
||||
</div></blockquote>
|
||||
<p>A <em>permission</em> is simply a list of text strings stored in the handler <code class="docutils literal notranslate"><span class="pre">permissions</span></code> on <code class="docutils literal notranslate"><span class="pre">Objects</span></code>
|
||||
and <code class="docutils literal notranslate"><span class="pre">Accounts</span></code>. Permissions can be used as a convenient way to structure access levels and
|
||||
hierarchies. It is set by the <code class="docutils literal notranslate"><span class="pre">perm</span></code> command. Permissions are especially handled by the <code class="docutils literal notranslate"><span class="pre">perm()</span></code> and
|
||||
<code class="docutils literal notranslate"><span class="pre">pperm()</span></code> lock functions listed above.</p>
|
||||
<p>Let’s say we have a <code class="docutils literal notranslate"><span class="pre">red_key</span></code> object. We also have red chests that we want to unlock with this key.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">perm</span> <span class="n">red_key</span> <span class="o">=</span> <span class="n">unlocks_red_chests</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This gives the <code class="docutils literal notranslate"><span class="pre">red_key</span></code> object the permission “unlocks_red_chests”. Next we lock our red chests:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">lock</span> <span class="n">red</span> <span class="n">chest</span> <span class="o">=</span> <span class="n">unlock</span><span class="p">:</span><span class="n">perm</span><span class="p">(</span><span class="n">unlocks_red_chests</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>What this lock will expect is to the fed the actual key object. The <code class="docutils literal notranslate"><span class="pre">perm()</span></code> lock function will
|
||||
check the permissions set on the key and only return true if the permission is the one given.</p>
|
||||
<p>Finally we need to actually check this lock somehow. Let’s say the chest has an command <code class="docutils literal notranslate"><span class="pre">open</span> <span class="pre"><key></span></code>
|
||||
sitting on itself. Somewhere in its code the command needs to figure out which key you are using and
|
||||
test if this key has the correct permission:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span>
|
||||
<span class="normal">5</span>
|
||||
<span class="normal">6</span>
|
||||
<span class="normal">7</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="c1"># self.obj is the chest </span>
|
||||
<span class="c1"># and used_key is the key we used as argument to</span>
|
||||
<span class="c1"># the command. The self.caller is the one trying</span>
|
||||
<span class="c1"># to unlock the chest</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">used_key</span><span class="p">,</span> <span class="s2">"unlock"</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"The key does not fit!"</span><span class="p">)</span>
|
||||
<span class="k">return</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>All new accounts are given a default set of permissions defined by
|
||||
<code class="docutils literal notranslate"><span class="pre">settings.PERMISSION_ACCOUNT_DEFAULT</span></code>.</p>
|
||||
<p>Selected permission strings can be organized in a <em>permission hierarchy</em> by editing the tuple
|
||||
<code class="docutils literal notranslate"><span class="pre">settings.PERMISSION_HIERARCHY</span></code>. Evennia’s default permission hierarchy is as follows:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">Developer</span> <span class="c1"># like superuser but affected by locks</span>
|
||||
<span class="n">Admin</span> <span class="c1"># can administrate accounts</span>
|
||||
<span class="n">Builder</span> <span class="c1"># can edit the world</span>
|
||||
<span class="n">Helper</span> <span class="c1"># can edit help files</span>
|
||||
<span class="n">Player</span> <span class="c1"># can chat and send tells (default level)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>(Also the plural form works, so you could use <code class="docutils literal notranslate"><span class="pre">Developers</span></code> etc too).</p>
|
||||
<blockquote>
|
||||
<div><p>There is also a <code class="docutils literal notranslate"><span class="pre">Guest</span></code> level below <code class="docutils literal notranslate"><span class="pre">Player</span></code> that is only active if <code class="docutils literal notranslate"><span class="pre">settings.GUEST_ENABLED</span></code> is
|
||||
set. This is never part of <code class="docutils literal notranslate"><span class="pre">settings.PERMISSION_HIERARCHY</span></code>.</p>
|
||||
</div></blockquote>
|
||||
<p>The main use of this is that if you use the lock function <code class="docutils literal notranslate"><span class="pre">perm()</span></code> mentioned above, a lock check for
|
||||
a particular permission in the hierarchy will <em>also</em> grant access to those with <em>higher</em> hierarchy
|
||||
access. So if you have the permission “Admin” you will also pass a lock defined as <code class="docutils literal notranslate"><span class="pre">perm(Builder)</span></code>
|
||||
or any of those levels below “Admin”.</p>
|
||||
<p>When doing an access check from an <a class="reference internal" href="Objects.html"><span class="doc">Object</span></a> or Character, the <code class="docutils literal notranslate"><span class="pre">perm()</span></code> lock function will
|
||||
always first use the permissions of any Account connected to that Object before checking for
|
||||
permissions on the Object. In the case of hierarchical permissions (Admins, Builders etc), the
|
||||
Account permission will always be used (this stops an Account from escalating their permission by
|
||||
puppeting a high-level Character). If the permission looked for is not in the hierarchy, an exact
|
||||
match is required, first on the Account and if not found there (or if no Account is connected), then
|
||||
on the Object itself.</p>
|
||||
<p>Here is how you use <code class="docutils literal notranslate"><span class="pre">perm</span></code> to give an account more permissions:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">perm</span><span class="o">/</span><span class="n">account</span> <span class="n">Tommy</span> <span class="o">=</span> <span class="n">Builders</span>
|
||||
<span class="n">perm</span><span class="o">/</span><span class="n">account</span><span class="o">/</span><span class="k">del</span> <span class="n">Tommy</span> <span class="o">=</span> <span class="n">Builders</span> <span class="c1"># remove it again</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Note the use of the <code class="docutils literal notranslate"><span class="pre">/account</span></code> switch. It means you assign the permission to the
|
||||
<a class="reference internal" href="Accounts.html"><span class="doc">Accounts</span></a> Tommy instead of any <a class="reference internal" href="Objects.html"><span class="doc">Character</span></a> that also happens to be named
|
||||
“Tommy”.</p>
|
||||
<p>Putting permissions on the <em>Account</em> guarantees that they are kept, <em>regardless</em> of which Character
|
||||
they are currently puppeting. This is especially important to remember when assigning permissions
|
||||
from the <em>hierarchy tree</em> - as mentioned above, an Account’s permissions will overrule that of its
|
||||
character. So to be sure to avoid confusion you should generally put hierarchy permissions on the
|
||||
Account, not on their Characters (but see also <a class="reference external" href="Components/Locks.html#Quelling">quelling</a>).</p>
|
||||
<p>Below is an example of an object without any connected account</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="n">obj1</span><span class="o">.</span><span class="n">permissions</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"Builders"</span><span class="p">,</span> <span class="s2">"cool_guy"</span><span class="p">]</span>
|
||||
<span class="n">obj2</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">"enter:perm_above(Accounts) and perm(cool_guy)"</span><span class="p">)</span>
|
||||
|
||||
<span class="n">obj2</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">obj1</span><span class="p">,</span> <span class="s2">"enter"</span><span class="p">)</span> <span class="c1"># this returns True!</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>And one example of a puppet with a connected account:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span>
|
||||
<span class="normal">5</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="n">account</span><span class="o">.</span><span class="n">permissions</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"Accounts"</span><span class="p">)</span>
|
||||
<span class="n">puppet</span><span class="o">.</span><span class="n">permissions</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"Builders"</span><span class="p">,</span> <span class="s2">"cool_guy"</span><span class="p">)</span>
|
||||
<span class="n">obj2</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">"enter:perm_above(Accounts) and perm(cool_guy)"</span><span class="p">)</span>
|
||||
|
||||
<span class="n">obj2</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">puppet</span><span class="p">,</span> <span class="s2">"enter"</span><span class="p">)</span> <span class="c1"># this returns False!</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<section id="superusers">
|
||||
<h2>Superusers<a class="headerlink" href="#superusers" title="Permalink to this headline">¶</a></h2>
|
||||
<p>There is normally only one <em>superuser</em> account and that is the one first created when starting
|
||||
Evennia (User #1). This is sometimes known as the “Owner” or “God” user. A superuser has more than
|
||||
full access - it completely <em>bypasses</em> all locks so no checks are even run. This allows for the
|
||||
superuser to always have access to everything in an emergency. But it also hides any eventual errors
|
||||
you might have made in your lock definitions. So when trying out game systems you should either use
|
||||
quelling (see below) or make a second Developer-level character so your locks get tested correctly.</p>
|
||||
</section>
|
||||
<section id="quelling">
|
||||
<h2>Quelling<a class="headerlink" href="#quelling" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">quell</span></code> command can be used to enforce the <code class="docutils literal notranslate"><span class="pre">perm()</span></code> lockfunc to ignore permissions on the
|
||||
Account and instead use the permissions on the Character only. This can be used e.g. by staff to
|
||||
test out things with a lower permission level. Return to the normal operation with <code class="docutils literal notranslate"><span class="pre">unquell</span></code>. Note
|
||||
that quelling will use the smallest of any hierarchical permission on the Account or Character, so
|
||||
one cannot escalate one’s Account permission by quelling to a high-permission Character. Also the
|
||||
superuser can quell their powers this way, making them affectable by locks.</p>
|
||||
</section>
|
||||
<section id="more-lock-definition-examples">
|
||||
<h2>More Lock definition examples<a class="headerlink" href="#more-lock-definition-examples" title="Permalink to this headline">¶</a></h2>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">examine</span><span class="p">:</span> <span class="n">attr</span><span class="p">(</span><span class="n">eyesight</span><span class="p">,</span> <span class="n">excellent</span><span class="p">)</span> <span class="ow">or</span> <span class="n">perm</span><span class="p">(</span><span class="n">Builders</span><span class="p">)</span>
|
||||
|
|
@ -441,7 +321,7 @@ superuser can quell their powers this way, making them affectable by locks.</p>
|
|||
<p>You are only allowed to do <em>examine</em> on this object if you have ‘excellent’ eyesight (that is, has
|
||||
an Attribute <code class="docutils literal notranslate"><span class="pre">eyesight</span></code> with the value <code class="docutils literal notranslate"><span class="pre">excellent</span></code> defined on yourself) or if you have the
|
||||
“Builders” permission string assigned to you.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">open</span><span class="p">:</span> <span class="n">holds</span><span class="p">(</span><span class="s1">'the green key'</span><span class="p">)</span> <span class="ow">or</span> <span class="n">perm</span><span class="p">(</span><span class="n">Builder</span><span class="p">)</span>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">open</span><span class="p">:</span> <span class="n">holds</span><span class="p">(</span><span class="s1">'the green key'</span><span class="p">)</span> <span class="ow">or</span> <span class="n">perm</span><span class="p">(</span><span class="n">Builder</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This could be called by the <code class="docutils literal notranslate"><span class="pre">open</span></code> command on a “door” object. The check is passed if you are a
|
||||
|
|
@ -534,20 +414,20 @@ strength above 50 however and you’ll pick it up no problem. Done! A very heavy
|
|||
<span class="normal">12</span>
|
||||
<span class="normal">13</span>
|
||||
<span class="normal">14</span>
|
||||
<span class="normal">15</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span>
|
||||
<span class="normal">15</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span>
|
||||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">create_object</span>
|
||||
|
||||
|
||||
<span class="c1"># create, then set the lock</span>
|
||||
<span class="n">box</span> <span class="o">=</span> <span class="n">create_object</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="s2">"box"</span><span class="p">)</span>
|
||||
<span class="n">box</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">"get:attr_gt(strength, 50)"</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="c1"># or we can assign locks in one go right away</span>
|
||||
<span class="n">box</span> <span class="o">=</span> <span class="n">create_object</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="s2">"box"</span><span class="p">,</span> <span class="n">locks</span><span class="o">=</span><span class="s2">"get:attr_gt(strength, 50)"</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="c1"># set the attributes</span>
|
||||
<span class="n">box</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">desc</span> <span class="o">=</span> <span class="s2">"This is a very big and heavy box."</span>
|
||||
<span class="n">box</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">get_err_msg</span> <span class="o">=</span> <span class="s2">"You are not strong enough to lift this box."</span>
|
||||
|
||||
|
||||
<span class="c1"># one heavy box, ready to withstand all but the strongest...</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
|
|
@ -601,11 +481,6 @@ interface. It’s stand-alone from the permissions described above.</p>
|
|||
</li>
|
||||
<li><a class="reference internal" href="#checking-simple-strings">Checking simple strings</a></li>
|
||||
<li><a class="reference internal" href="#default-locks">Default locks</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#permissions">Permissions</a><ul>
|
||||
<li><a class="reference internal" href="#superusers">Superusers</a></li>
|
||||
<li><a class="reference internal" href="#quelling">Quelling</a></li>
|
||||
<li><a class="reference internal" href="#more-lock-definition-examples">More Lock definition examples</a></li>
|
||||
<li><a class="reference internal" href="#a-complete-example-of-setting-locks-on-an-object">A complete example of setting locks on an object</a></li>
|
||||
<li><a class="reference internal" href="#on-django-s-permission-system">On Django’s permission system</a></li>
|
||||
|
|
|
|||
240
docs/1.0-dev/Components/Permissions.html
Normal file
240
docs/1.0-dev/Components/Permissions.html
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>Permissions — 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="">Permissions</a></li>
|
||||
</ul>
|
||||
<div class="develop">develop branch</div>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="permissions">
|
||||
<h1>Permissions<a class="headerlink" href="#permissions" title="Permalink to this headline">¶</a></h1>
|
||||
<p>A <em>permission</em> is simply a text string stored in the handler <code class="docutils literal notranslate"><span class="pre">permissions</span></code> on <code class="docutils literal notranslate"><span class="pre">Objects</span></code>
|
||||
and <code class="docutils literal notranslate"><span class="pre">Accounts</span></code>. Think of it as a specialized sort of <a class="reference internal" href="Tags.html"><span class="doc">Tag</span></a> - one specifically dedicated
|
||||
to access checking. They are thus often tightly coupled to <a class="reference internal" href="Locks.html"><span class="doc">Locks</span></a>.</p>
|
||||
<p>Permissions are used as a convenient way to structure access levels and
|
||||
hierarchies. It is set by the <code class="docutils literal notranslate"><span class="pre">perm</span></code> command. Permissions are especially
|
||||
handled by the <code class="docutils literal notranslate"><span class="pre">perm()</span></code> and <code class="docutils literal notranslate"><span class="pre">pperm()</span></code> <a class="reference internal" href="Locks.html"><span class="doc">lock functions</span></a>.</p>
|
||||
<p>Let’s say we have a <code class="docutils literal notranslate"><span class="pre">red_key</span></code> object. We also have red chests that we want to unlock with this key.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">perm</span> <span class="n">red_key</span> <span class="o">=</span> <span class="n">unlocks_red_chests</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This gives the <code class="docutils literal notranslate"><span class="pre">red_key</span></code> object the permission “unlocks_red_chests”. Next we
|
||||
lock our red chests:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">lock</span> <span class="n">red</span> <span class="n">chest</span> <span class="o">=</span> <span class="n">unlock</span><span class="p">:</span><span class="n">perm</span><span class="p">(</span><span class="n">unlocks_red_chests</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>When trying to unlock the red chest with this key, the chest Typeclass could
|
||||
then take the key and do an access check:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># in some typeclass file where chest is defined</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">TreasureChest</span><span class="p">(</span><span class="n">Object</span><span class="p">):</span>
|
||||
|
||||
<span class="c1"># ...</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">open_chest</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">who</span><span class="p">,</span> <span class="n">tried_key</span><span class="p">):</span>
|
||||
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">chest</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">who</span><span class="p">,</span> <span class="n">tried_key</span><span class="p">,</span> <span class="s2">"unlock"</span><span class="p">):</span>
|
||||
<span class="n">who</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"The key does not fit!"</span><span class="p">)</span>
|
||||
<span class="k">return</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>All new accounts are given a default set of permissions defined by
|
||||
<code class="docutils literal notranslate"><span class="pre">settings.PERMISSION_ACCOUNT_DEFAULT</span></code>.</p>
|
||||
<p>Selected permission strings can be organized in a <em>permission hierarchy</em> by editing the tuple
|
||||
<code class="docutils literal notranslate"><span class="pre">settings.PERMISSION_HIERARCHY</span></code>. Evennia’s default permission hierarchy is as follows:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">Developer</span> <span class="c1"># like superuser but affected by locks</span>
|
||||
<span class="n">Admin</span> <span class="c1"># can administrate accounts</span>
|
||||
<span class="n">Builder</span> <span class="c1"># can edit the world</span>
|
||||
<span class="n">Helper</span> <span class="c1"># can edit help files</span>
|
||||
<span class="n">Player</span> <span class="c1"># can chat and send tells (default level)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>(Also the plural form works, so you could use <code class="docutils literal notranslate"><span class="pre">Developers</span></code> etc too).</p>
|
||||
<blockquote>
|
||||
<div><p>There is also a <code class="docutils literal notranslate"><span class="pre">Guest</span></code> level below <code class="docutils literal notranslate"><span class="pre">Player</span></code> that is only active if <code class="docutils literal notranslate"><span class="pre">settings.GUEST_ENABLED</span></code> is
|
||||
set. This is never part of <code class="docutils literal notranslate"><span class="pre">settings.PERMISSION_HIERARCHY</span></code>.</p>
|
||||
</div></blockquote>
|
||||
<p>The main use of this is that if you use the lock function <code class="docutils literal notranslate"><span class="pre">perm()</span></code> mentioned above, a lock check for
|
||||
a particular permission in the hierarchy will <em>also</em> grant access to those with <em>higher</em> hierarchy
|
||||
access. So if you have the permission “Admin” you will also pass a lock defined as <code class="docutils literal notranslate"><span class="pre">perm(Builder)</span></code>
|
||||
or any of those levels below “Admin”.</p>
|
||||
<p>When doing an access check from an <a class="reference internal" href="Objects.html"><span class="doc">Object</span></a> or Character, the <code class="docutils literal notranslate"><span class="pre">perm()</span></code> lock function will
|
||||
always first use the permissions of any Account connected to that Object before checking for
|
||||
permissions on the Object. In the case of hierarchical permissions (Admins, Builders etc), the
|
||||
Account permission will always be used (this stops an Account from escalating their permission by
|
||||
puppeting a high-level Character). If the permission looked for is not in the hierarchy, an exact
|
||||
match is required, first on the Account and if not found there (or if no Account is connected), then
|
||||
on the Object itself.</p>
|
||||
<p>Here is how you use <code class="docutils literal notranslate"><span class="pre">perm</span></code> to give an account more permissions:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">perm</span><span class="o">/</span><span class="n">account</span> <span class="n">Tommy</span> <span class="o">=</span> <span class="n">Builders</span>
|
||||
<span class="n">perm</span><span class="o">/</span><span class="n">account</span><span class="o">/</span><span class="k">del</span> <span class="n">Tommy</span> <span class="o">=</span> <span class="n">Builders</span> <span class="c1"># remove it again</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Note the use of the <code class="docutils literal notranslate"><span class="pre">/account</span></code> switch. It means you assign the permission to the
|
||||
<a class="reference internal" href="Accounts.html"><span class="doc">Accounts</span></a> Tommy instead of any <a class="reference internal" href="Objects.html"><span class="doc">Character</span></a> that also happens to be named
|
||||
“Tommy”.</p>
|
||||
<p>Putting permissions on the <em>Account</em> guarantees that they are kept, <em>regardless</em> of which Character
|
||||
they are currently puppeting. This is especially important to remember when assigning permissions
|
||||
from the <em>hierarchy tree</em> - as mentioned above, an Account’s permissions will overrule that of its
|
||||
character. So to be sure to avoid confusion you should generally put hierarchy permissions on the
|
||||
Account, not on their Characters (but see also <a class="reference external" href="Components/Locks.html#Quelling">quelling</a>).</p>
|
||||
<p>Below is an example of an object without any connected account</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="n">obj1</span><span class="o">.</span><span class="n">permissions</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"Builders"</span><span class="p">,</span> <span class="s2">"cool_guy"</span><span class="p">]</span>
|
||||
<span class="n">obj2</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">"enter:perm_above(Accounts) and perm(cool_guy)"</span><span class="p">)</span>
|
||||
|
||||
<span class="n">obj2</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">obj1</span><span class="p">,</span> <span class="s2">"enter"</span><span class="p">)</span> <span class="c1"># this returns True!</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>And one example of a puppet with a connected account:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span>
|
||||
<span class="normal">5</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="n">account</span><span class="o">.</span><span class="n">permissions</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"Accounts"</span><span class="p">)</span>
|
||||
<span class="n">puppet</span><span class="o">.</span><span class="n">permissions</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">"Builders"</span><span class="p">,</span> <span class="s2">"cool_guy"</span><span class="p">)</span>
|
||||
<span class="n">obj2</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">"enter:perm_above(Accounts) and perm(cool_guy)"</span><span class="p">)</span>
|
||||
|
||||
<span class="n">obj2</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">puppet</span><span class="p">,</span> <span class="s2">"enter"</span><span class="p">)</span> <span class="c1"># this returns False!</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<section id="superusers">
|
||||
<h2>Superusers<a class="headerlink" href="#superusers" title="Permalink to this headline">¶</a></h2>
|
||||
<p>There is normally only one <em>superuser</em> account and that is the one first created when starting
|
||||
Evennia (User #1). This is sometimes known as the “Owner” or “God” user. A superuser has more than
|
||||
full access - it completely <em>bypasses</em> all locks so no checks are even run. This allows for the
|
||||
superuser to always have access to everything in an emergency. But it also hides any eventual errors
|
||||
you might have made in your lock definitions. So when trying out game systems you should either use
|
||||
quelling (see below) or make a second Developer-level character so your locks get tested correctly.</p>
|
||||
</section>
|
||||
<section id="quelling">
|
||||
<h2>Quelling<a class="headerlink" href="#quelling" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">quell</span></code> command can be used to enforce the <code class="docutils literal notranslate"><span class="pre">perm()</span></code> lockfunc to ignore permissions on the
|
||||
Account and instead use the permissions on the Character only. This can be used e.g. by staff to
|
||||
test out things with a lower permission level. Return to the normal operation with <code class="docutils literal notranslate"><span class="pre">unquell</span></code>. Note
|
||||
that quelling will use the smallest of any hierarchical permission on the Account or Character, so
|
||||
one cannot escalate one’s Account permission by quelling to a high-permission Character. Also the
|
||||
superuser can quell their powers this way, making them affectable by locks.</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
<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="#">Permissions</a><ul>
|
||||
<li><a class="reference internal" href="#superusers">Superusers</a></li>
|
||||
<li><a class="reference internal" href="#quelling">Quelling</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div role="note" aria-label="source link">
|
||||
<!--h3>This Page</h3-->
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/Components/Permissions.md.txt"
|
||||
rel="nofollow">Show Page Source</a></li>
|
||||
</ul>
|
||||
</div><h3>Links</h3>
|
||||
<ul>
|
||||
<li><a href="https://www.evennia.com">Home page</a> </li>
|
||||
<li><a href="https://github.com/evennia/evennia">Evennia Github</a> </li>
|
||||
<li><a href="http://games.evennia.com">Game Index</a> </li>
|
||||
<li><a href="http://webchat.freenode.net/?channels=evennia&uio=MT1mYWxzZSY5PXRydWUmMTE9MTk1JjEyPXRydWUbb">IRC</a> -
|
||||
<a href="https://discord.gg/NecFePw">Discord</a> -
|
||||
<a href="https://groups.google.com/forum/#%21forum/evennia">Forums</a>
|
||||
</li>
|
||||
<li><a href="http://evennia.blogspot.com/">Evennia Dev blog</a> </li>
|
||||
</ul>
|
||||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Permissions.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="">Permissions</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>
|
||||
231
docs/1.0-dev/Components/Web-API.html
Normal file
231
docs/1.0-dev/Components/Web-API.html
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>Evennia REST API — 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="">Evennia REST API</a></li>
|
||||
</ul>
|
||||
<div class="develop">develop branch</div>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="evennia-rest-api">
|
||||
<h1>Evennia REST API<a class="headerlink" href="#evennia-rest-api" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Evennia makes its database accessible via a REST API found on
|
||||
<a class="reference external" href="http://localhost:4001/api">http://localhost:4001/api</a> if running locally with
|
||||
default setup. The API allows you to retrieve, edit and create resources from
|
||||
outside the game, for example with your own custom client or game editor.</p>
|
||||
<p>While you can view and learn about the api in the web browser, it is really
|
||||
meant to be accessed in code, by other programs.</p>
|
||||
<p>The API is using <a class="reference external" href="https://www.django-rest-framework.org/">Django Rest Framework</a>. This automates the process
|
||||
of setting up <em>views</em> (Python code) to process the result of web requests.
|
||||
The process of retrieving data is similar to that explained on the
|
||||
<a class="reference internal" href="Webserver.html"><span class="doc">Webserver</span></a> page, except the views will here return <a class="reference external" href="https://en.wikipedia.org/wiki/JSON">JSON</a>
|
||||
data for the resource you want. You can also <em>send</em> such JSON data
|
||||
in order to update the database from the outside.</p>
|
||||
<section id="usage">
|
||||
<h2>Usage<a class="headerlink" href="#usage" title="Permalink to this headline">¶</a></h2>
|
||||
<p>To activate the API, add this to your settings file.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">REST_API_ENABLED</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The main controlling setting is <code class="docutils literal notranslate"><span class="pre">REST_FRAMEWORK</span></code>, which is a dict. The keys
|
||||
<code class="docutils literal notranslate"><span class="pre">DEFAULT_LIST_PERMISSION</span></code> and <code class="docutils literal notranslate"><span class="pre">DEFAULT_CREATE_PERMISSIONS</span></code> control who may
|
||||
view and create new objects via the api respectively. By default, users with
|
||||
<a class="reference internal" href="Permissions.html"><span class="doc">‘Builder’-level permission</span></a> or higher may access both actions.</p>
|
||||
<p>While the api is meant to be expanded upon, Evennia supplies several operations
|
||||
out of the box. If you click the <code class="docutils literal notranslate"><span class="pre">Autodoc</span></code> button in the upper right of the <code class="docutils literal notranslate"><span class="pre">/api</span></code>
|
||||
website you’ll get a fancy graphical presentation of the available endpoints.</p>
|
||||
<p>Here is an example of calling the api in Python using the standard <code class="docutils literal notranslate"><span class="pre">requests</span></code> library.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">requests</span>
|
||||
<span class="gp">>>> </span><span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"https://www.mygame.com/api"</span><span class="p">,</span> <span class="n">auth</span><span class="o">=</span><span class="p">(</span><span class="s2">"MyUsername"</span><span class="p">,</span> <span class="s2">"password123"</span><span class="p">))</span>
|
||||
<span class="gp">>>> </span><span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
|
||||
<span class="go">{'accounts': 'http://www.mygame.com/api/accounts/',</span>
|
||||
<span class="go"> 'objects': 'http://www.mygame.com/api/objects/',</span>
|
||||
<span class="go">'characters': 'http://www.mygame.comg/api/characters/',</span>
|
||||
<span class="go">'exits': 'http://www.mygame.com/api/exits/',</span>
|
||||
<span class="go">'rooms': 'http://www.mygame.com/api/rooms/',</span>
|
||||
<span class="go">'scripts': 'http://www.mygame.com/api/scripts/'</span>
|
||||
<span class="go">'helpentries': 'http://www.mygame.com/api/helpentries/' }</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>To list a specific type of object:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"https://www.mygame.com/api/objects"</span><span class="p">,</span>
|
||||
<span class="go"> auth=("Myusername", "password123"))</span>
|
||||
<span class="gp">>>> </span><span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
|
||||
<span class="go">{</span>
|
||||
<span class="go">"count": 125,</span>
|
||||
<span class="go">"next": "https://www.mygame.com/api/objects/?limit=25&offset=25",</span>
|
||||
<span class="go">"previous": null,</span>
|
||||
<span class="go">"results" : [{"db_key": "A rusty longsword", "id": 57, "db_location": 213, ...}]}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>In the above example, it now displays the objects inside the “results” array,
|
||||
while it has a “count” value for the number of total objects, and “next” and
|
||||
“previous” links for the next and previous page, if any. This is called
|
||||
<a class="reference external" href="https://www.django-rest-framework.org/api-guide/pagination/">pagination</a>, and the link displays “limit” and “offset” as query
|
||||
parameters that can be added to the url to control the output.</p>
|
||||
<p>Other query parameters can be defined as <a class="reference external" href="https://www.django-rest-framework.org/api-guide/filtering/#filtering">filters</a> which allow you to
|
||||
further narrow the results. For example, to only get accounts with developer
|
||||
permissions:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"https://www.mygame.com/api/accounts/?permission=developer"</span><span class="p">,</span>
|
||||
<span class="go"> auth=("MyUserName", "password123"))</span>
|
||||
<span class="gp">>>> </span><span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
|
||||
<span class="go">{</span>
|
||||
<span class="go">"count": 1,</span>
|
||||
<span class="go">"results": [{"username": "bob",...}]</span>
|
||||
<span class="go">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now suppose that you want to use the API to create an <a class="reference internal" href="Objects.html"><span class="doc">Object</span></a>:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">data</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"db_key"</span><span class="p">:</span> <span class="s2">"A shiny sword"</span><span class="p">}</span>
|
||||
<span class="gp">>>> </span><span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="s2">"https://www.mygame.com/api/objects"</span><span class="p">,</span>
|
||||
<span class="go"> data=data, auth=("Anotherusername", "mypassword"))</span>
|
||||
<span class="gp">>>> </span><span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
|
||||
<span class="go">{"db_key": "A shiny sword", "id": 214, "db_location": None, ...}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Here we made a HTTP POST request to the <code class="docutils literal notranslate"><span class="pre">/api/objects</span></code> endpoint with the <code class="docutils literal notranslate"><span class="pre">db_key</span></code>
|
||||
we wanted. We got back info for the newly created object. You can now make
|
||||
another request with PUT (replace everything) or PATCH (replace only what you
|
||||
provide). By providing the id to the endpoint (<code class="docutils literal notranslate"><span class="pre">/api/objects/214</span></code>),
|
||||
we make sure to update the right sword:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">data</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"db_key"</span><span class="p">:</span> <span class="s2">"An even SHINIER sword"</span><span class="p">,</span> <span class="s2">"db_location"</span><span class="p">:</span> <span class="mi">50</span><span class="p">}</span>
|
||||
<span class="gp">>>> </span><span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="s2">"https://www.mygame.com/api/objects/214"</span><span class="p">,</span>
|
||||
<span class="go"> data=data, auth=("Anotherusername", "mypassword"))</span>
|
||||
<span class="gp">>>> </span><span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
|
||||
<span class="go">{"db_key": "An even SHINIER sword", "id": 214, "db_location": 50, ...}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>In most cases, you won’t be making API requests to the backend with Python,
|
||||
but with Javascript from some frontend application.
|
||||
There are many Javascript libraries which are meant to make this process
|
||||
easier for requests from the frontend, such as <a class="reference external" href="https://github.com/axios/axios">AXIOS</a>, or using
|
||||
the native <a class="reference external" href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">Fetch</a>.</p>
|
||||
</section>
|
||||
<section id="customizing-the-api">
|
||||
<h2>Customizing the API<a class="headerlink" href="#customizing-the-api" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Overall, reading up on <a class="reference external" href="https://www.django-rest-framework.org/api-guide/viewsets">Django Rest Framework ViewSets</a> and
|
||||
other parts of their documentation is required for expanding and
|
||||
customizing the API.</p>
|
||||
<p>Check out the <a class="reference internal" href="Website.html"><span class="doc">Website</span></a> page for help on how to override code, templates
|
||||
and static files.</p>
|
||||
<ul class="simple">
|
||||
<li><p>API templates (for the web-display) is located in <code class="docutils literal notranslate"><span class="pre">evennia/web/api/templates/rest_framework/</span></code> (it must
|
||||
be named such to allow override of the original REST framework templates).</p></li>
|
||||
<li><p>Static files is in <code class="docutils literal notranslate"><span class="pre">evennia/web/api/static/rest_framework/</span></code></p></li>
|
||||
<li><p>The api code is located in <code class="docutils literal notranslate"><span class="pre">evennia/web/api/</span></code> - the <code class="docutils literal notranslate"><span class="pre">url.py</span></code> file here is responsible for
|
||||
collecting all view-classes.</p></li>
|
||||
</ul>
|
||||
<p>Contrary to other web components, there is no pre-made urls.py set up for
|
||||
<code class="docutils literal notranslate"><span class="pre">mygame/web/api/</span></code>. This is because the registration of models with the api is
|
||||
strongly integrated with the REST api functionality. Easiest is probably to
|
||||
copy over <code class="docutils literal notranslate"><span class="pre">evennia/web/api/urls.py</span></code> and modify it in place.</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
<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="#">Evennia REST API</a><ul>
|
||||
<li><a class="reference internal" href="#usage">Usage</a></li>
|
||||
<li><a class="reference internal" href="#customizing-the-api">Customizing the API</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div role="note" aria-label="source link">
|
||||
<!--h3>This Page</h3-->
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/Components/Web-API.md.txt"
|
||||
rel="nofollow">Show Page Source</a></li>
|
||||
</ul>
|
||||
</div><h3>Links</h3>
|
||||
<ul>
|
||||
<li><a href="https://www.evennia.com">Home page</a> </li>
|
||||
<li><a href="https://github.com/evennia/evennia">Evennia Github</a> </li>
|
||||
<li><a href="http://games.evennia.com">Game Index</a> </li>
|
||||
<li><a href="http://webchat.freenode.net/?channels=evennia&uio=MT1mYWxzZSY5PXRydWUmMTE9MTk1JjEyPXRydWUbb">IRC</a> -
|
||||
<a href="https://discord.gg/NecFePw">Discord</a> -
|
||||
<a href="https://groups.google.com/forum/#%21forum/evennia">Forums</a>
|
||||
</li>
|
||||
<li><a href="http://evennia.blogspot.com/">Evennia Dev blog</a> </li>
|
||||
</ul>
|
||||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Web-API.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="">Evennia REST API</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>
|
||||
284
docs/1.0-dev/Components/Web-Admin.html
Normal file
284
docs/1.0-dev/Components/Web-Admin.html
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>The Web Admin — 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="">The Web Admin</a></li>
|
||||
</ul>
|
||||
<div class="develop">develop branch</div>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="the-web-admin">
|
||||
<h1>The Web Admin<a class="headerlink" href="#the-web-admin" title="Permalink to this headline">¶</a></h1>
|
||||
<p>The Evennia <em>Web admin</em> is a customized <a class="reference external" href="https://docs.djangoproject.com/en/3.2/ref/contrib/admin/">Django admin site</a>
|
||||
used for manipulating the game database using a graphical interface. You
|
||||
have to be logged into the site to use it. It then appears as an <code class="docutils literal notranslate"><span class="pre">Admin</span></code> link
|
||||
the top of your website. You can also go to <a class="reference external" href="http://localhost:4001/admin">http://localhost:4001/admin</a> when
|
||||
running locally.</p>
|
||||
<p>Almost all actions done in the admin can also be done in-game by use of Admin-
|
||||
or Builder-commands.</p>
|
||||
<section id="usage">
|
||||
<h2>Usage<a class="headerlink" href="#usage" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The admin is pretty self-explanatory - you can see lists of each object type,
|
||||
create new instances of each type and also add new Attributes/tags them. The
|
||||
admin frontpage will give a summary of all relevant entities and how they are
|
||||
used.</p>
|
||||
<p>There are a few use cases that requires some additional explanation though.</p>
|
||||
<section id="adding-objects-to-attributes">
|
||||
<h3>Adding objects to Attributes<a class="headerlink" href="#adding-objects-to-attributes" title="Permalink to this headline">¶</a></h3>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">value</span></code> field of an Attribute is pickled into a special form. This is usually not
|
||||
something you need to worry about (the admin will pickle/unpickle) the value
|
||||
for you), <em>except</em> if you want to store a database-object in an attribute. Such
|
||||
objects are actually stored as a <code class="docutils literal notranslate"><span class="pre">tuple</span></code> with object-unique data.</p>
|
||||
<ol>
|
||||
<li><p>Find the object you want to add to the Attribute. At the bottom of the first section
|
||||
you’ll find the field <em>Serialized string</em>. This string shows a Python tuple like</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="s1">'__packed_dbobj__'</span><span class="p">,</span> <span class="p">(</span><span class="s1">'objects'</span><span class="p">,</span> <span class="s1">'objectdb'</span><span class="p">),</span> <span class="s1">'2021:05:15-08:59:30:624660'</span><span class="p">,</span> <span class="mi">358</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Mark and copy this tuple-string to your clipboard exactly as it stands (parentheses and all).</p>
|
||||
</li>
|
||||
<li><p>Go to the entity that should have the new Attribute and create the Attribute. In its <code class="docutils literal notranslate"><span class="pre">value</span></code>
|
||||
field, paste the tuple-string you copied before. Save!</p></li>
|
||||
<li><p>If you want to store multiple objects in, say, a list, you can do so by literally
|
||||
typing a python list <code class="docutils literal notranslate"><span class="pre">[tuple,</span> <span class="pre">tuple,</span> <span class="pre">tuple,</span> <span class="pre">...]</span></code> where you paste in the serialized
|
||||
tuple-strings with commas. At some point it’s probably easier to do this in code though …</p></li>
|
||||
</ol>
|
||||
</section>
|
||||
<section id="linking-accounts-and-characters">
|
||||
<h3>Linking Accounts and Characters<a class="headerlink" href="#linking-accounts-and-characters" title="Permalink to this headline">¶</a></h3>
|
||||
<p>In <code class="docutils literal notranslate"><span class="pre">MULTISESSION_MODE</span></code> 0 or 1, each connection can have one Account and one
|
||||
Character, usually with the same name. Normally this is done by the user
|
||||
creating a new account and logging in - a matching Character will then be
|
||||
created for them. You can however also do so manually in the admin:</p>
|
||||
<ol class="simple">
|
||||
<li><p>First create the complete Account in the admin.</p></li>
|
||||
<li><p>Next, create the Object (usually of <code class="docutils literal notranslate"><span class="pre">Character</span></code> typeclass) and name it the same
|
||||
as the Account. It also needs a command-set. The default CharacterCmdset is a good bet.</p></li>
|
||||
<li><p>In the <code class="docutils literal notranslate"><span class="pre">Puppeting</span> <span class="pre">Account</span></code> field, select the Account.</p></li>
|
||||
<li><p>Make sure to save everything.</p></li>
|
||||
<li><p>Click the <code class="docutils literal notranslate"><span class="pre">Link</span> <span class="pre">to</span> <span class="pre">Account</span></code> button (this will only work if you saved first). This will
|
||||
add the needed locks and Attributes to the Account to allow them to immediately
|
||||
connect to the Character when they next log in. This will (where possible):</p>
|
||||
<ul class="simple">
|
||||
<li><p>Set <code class="docutils literal notranslate"><span class="pre">account.db._last_puppet</span></code> to the Character.</p></li>
|
||||
<li><p>Add Character to <code class="docutils literal notranslate"><span class="pre">account.db._playabel_characters</span></code> list.</p></li>
|
||||
<li><p>Add/extend the <code class="docutils literal notranslate"><span class="pre">puppet:</span></code> lock on the Character to include <code class="docutils literal notranslate"><span class="pre">puppet:pid(<Character.id>)</span></code></p></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
</section>
|
||||
<section id="building-with-the-admin">
|
||||
<h3>Building with the Admin<a class="headerlink" href="#building-with-the-admin" title="Permalink to this headline">¶</a></h3>
|
||||
<p>It’s possible (if probably not very practical at scale) to build and describe
|
||||
rooms in the Admin.</p>
|
||||
<ol class="simple">
|
||||
<li><p>Create an <code class="docutils literal notranslate"><span class="pre">Object</span></code> of a Room-typeclass with a suitable room-name.</p></li>
|
||||
<li><p>Set an Attribute ‘desc’ on the room - the value of this Attribute is the
|
||||
room’s description.</p></li>
|
||||
<li><p>Add <code class="docutils literal notranslate"><span class="pre">Tags</span></code> of <code class="docutils literal notranslate"><span class="pre">type</span></code> ‘alias’ to add room-aliases (no type for regular tags)</p></li>
|
||||
</ol>
|
||||
<p>Exits:</p>
|
||||
<ol class="simple">
|
||||
<li><p>Exits are <code class="docutils literal notranslate"><span class="pre">Objects</span></code> of an <code class="docutils literal notranslate"><span class="pre">Exit</span></code> typeclass, so create one.</p></li>
|
||||
<li><p>The exit has <code class="docutils literal notranslate"><span class="pre">Location</span></code> of the room you just created.</p></li>
|
||||
<li><p>Set <code class="docutils literal notranslate"><span class="pre">Destination</span></code> set to where the exit leads to.</p></li>
|
||||
<li><p>Set a ‘desc’ Attribute, this is shown if someone looks at the exit.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">Tags</span></code> of <code class="docutils literal notranslate"><span class="pre">type</span></code> ‘alias’ are alternative names users can use to go through
|
||||
this exit.</p></li>
|
||||
</ol>
|
||||
</section>
|
||||
</section>
|
||||
<section id="grant-others-access-to-the-admin">
|
||||
<h2>Grant others access to the admin<a class="headerlink" href="#grant-others-access-to-the-admin" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The access to the admin is controlled by the <code class="docutils literal notranslate"><span class="pre">Staff</span> <span class="pre">status</span></code> flag on the
|
||||
Account. Without this flag set, even superusers will not even see the admin
|
||||
link on the web page. The staff-status has no in-game equivalence.</p>
|
||||
<p>Only Superusers can change the <code class="docutils literal notranslate"><span class="pre">Superuser</span> <span class="pre">status</span></code> flag, and grant new
|
||||
permissions to accounts. The superuser is the only permission level that is
|
||||
also relevant in-game. <code class="docutils literal notranslate"><span class="pre">User</span> <span class="pre">Permissions</span></code> and <code class="docutils literal notranslate"><span class="pre">Groups</span></code> found on the <code class="docutils literal notranslate"><span class="pre">Account</span></code>
|
||||
admin page <em>only</em> affects the admin - they have no connection to the in-game
|
||||
<a class="reference internal" href="Permissions.html"><span class="doc">Permissions</span></a> (Player, Builder, Admin etc).</p>
|
||||
<p>For a staffer with <code class="docutils literal notranslate"><span class="pre">Staff</span> <span class="pre">status</span></code> to be able to actually do anything, the
|
||||
superuser must grant at least some permissions for them on their Account. This
|
||||
can also be good in order to limit mistakes. It can be a good idea to not allow
|
||||
the <code class="docutils literal notranslate"><span class="pre">Can</span> <span class="pre">delete</span> <span class="pre">Account</span></code> permission, for example.</p>
|
||||
<div class="admonition important">
|
||||
<p class="admonition-title">Important</p>
|
||||
<p>If you grant staff-status and permissions to an Account and they still cannot
|
||||
access the admin’s content, try reloading the server.</p>
|
||||
</div>
|
||||
<div class="admonition warning">
|
||||
<p class="admonition-title">Warning</p>
|
||||
<p>If a staff member has access to the in-game <code class="docutils literal notranslate"><span class="pre">py</span></code> command, they can just as
|
||||
well have their admin <code class="docutils literal notranslate"><span class="pre">Superuser</span> <span class="pre">status</span></code> set too. The reason is that <code class="docutils literal notranslate"><span class="pre">py</span></code>
|
||||
grants them all the power they need to set the <code class="docutils literal notranslate"><span class="pre">is_superuser</span></code> flag on their
|
||||
account manually. There is a reason access to the <code class="docutils literal notranslate"><span class="pre">py</span></code> command must be
|
||||
considered carefully …</p>
|
||||
</div>
|
||||
</section>
|
||||
<section id="customizing-the-web-admin">
|
||||
<h2>Customizing the web admin<a class="headerlink" href="#customizing-the-web-admin" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Customizing the admin is a big topic and something beyond the scope of this
|
||||
documentation. See the <a class="reference external" href="https://docs.djangoproject.com/en/3.2/ref/contrib/admin/">official Django docs</a> for
|
||||
the details. This is just a brief summary.</p>
|
||||
<p>See the <a class="reference internal" href="Website.html"><span class="doc">Website</span></a> page for an overview of the components going into
|
||||
generating a web page. The Django admin uses the same principle except that
|
||||
Django provides a lot of tools to automate the admin-generation for us.</p>
|
||||
<p>Admin templates are found in <code class="docutils literal notranslate"><span class="pre">evennia/web/templates/admin/</span></code> but you’ll find
|
||||
this is relatively empty. This is because most of the templates are just
|
||||
inherited directly from their original location in the Django package
|
||||
(<code class="docutils literal notranslate"><span class="pre">django/contrib/admin/templates/</span></code>). So if you wanted to override one you’d have
|
||||
to copy it from <em>there</em> into your <code class="docutils literal notranslate"><span class="pre">mygame/templates/admin/</span></code> folder. Same is true
|
||||
for CSS files.</p>
|
||||
<p>The admin site’s backend code (the views) is found in <code class="docutils literal notranslate"><span class="pre">evennia/web/admin/</span></code>. It
|
||||
is organized into <code class="docutils literal notranslate"><span class="pre">admin</span></code>-classes, like <code class="docutils literal notranslate"><span class="pre">ObjectAdmin</span></code>, <code class="docutils literal notranslate"><span class="pre">AccountAdmin</span></code> etc.
|
||||
These automatically use the underlying database models to generate useful views
|
||||
for us without us havint go code the forms etc ourselves.</p>
|
||||
<p>The top level <code class="docutils literal notranslate"><span class="pre">AdminSite</span></code> (the admin configuration referenced in django docs)
|
||||
is found in <code class="docutils literal notranslate"><span class="pre">evennia/web/utils/adminsite.py</span></code>.</p>
|
||||
<section id="change-the-title-of-the-admin">
|
||||
<h3>Change the title of the admin<a class="headerlink" href="#change-the-title-of-the-admin" title="Permalink to this headline">¶</a></h3>
|
||||
<p>By default the admin’s title is <code class="docutils literal notranslate"><span class="pre">Evennia</span> <span class="pre">web</span> <span class="pre">admin</span></code>. To change this, add the
|
||||
following to your <code class="docutils literal notranslate"><span class="pre">mygame/web/urls.py</span></code>:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># in mygame/web/urls.py</span>
|
||||
|
||||
<span class="c1"># ...</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">django.conf.admin</span> <span class="kn">import</span> <span class="n">site</span>
|
||||
|
||||
<span class="c1">#...</span>
|
||||
|
||||
<span class="n">site</span><span class="o">.</span><span class="n">site_header</span> <span class="o">=</span> <span class="s2">"My great game admin"</span>
|
||||
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>Reload the server and the admin’s title header will have changed.</p>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
<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="#">The Web Admin</a><ul>
|
||||
<li><a class="reference internal" href="#usage">Usage</a><ul>
|
||||
<li><a class="reference internal" href="#adding-objects-to-attributes">Adding objects to Attributes</a></li>
|
||||
<li><a class="reference internal" href="#linking-accounts-and-characters">Linking Accounts and Characters</a></li>
|
||||
<li><a class="reference internal" href="#building-with-the-admin">Building with the Admin</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#grant-others-access-to-the-admin">Grant others access to the admin</a></li>
|
||||
<li><a class="reference internal" href="#customizing-the-web-admin">Customizing the web admin</a><ul>
|
||||
<li><a class="reference internal" href="#change-the-title-of-the-admin">Change the title of the admin</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/Components/Web-Admin.md.txt"
|
||||
rel="nofollow">Show Page Source</a></li>
|
||||
</ul>
|
||||
</div><h3>Links</h3>
|
||||
<ul>
|
||||
<li><a href="https://www.evennia.com">Home page</a> </li>
|
||||
<li><a href="https://github.com/evennia/evennia">Evennia Github</a> </li>
|
||||
<li><a href="http://games.evennia.com">Game Index</a> </li>
|
||||
<li><a href="http://webchat.freenode.net/?channels=evennia&uio=MT1mYWxzZSY5PXRydWUmMTE9MTk1JjEyPXRydWUbb">IRC</a> -
|
||||
<a href="https://discord.gg/NecFePw">Discord</a> -
|
||||
<a href="https://groups.google.com/forum/#%21forum/evennia">Forums</a>
|
||||
</li>
|
||||
<li><a href="http://evennia.blogspot.com/">Evennia Dev blog</a> </li>
|
||||
</ul>
|
||||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Web-Admin.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="">The Web Admin</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>
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>Webclient — Evennia 1.0-dev documentation</title>
|
||||
<title>Web Client — 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>
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
<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="">Webclient</a></li>
|
||||
<li class="nav-item nav-item-this"><a href="">Web Client</a></li>
|
||||
</ul>
|
||||
<div class="develop">develop branch</div>
|
||||
</div>
|
||||
|
|
@ -38,11 +38,8 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="webclient">
|
||||
<h1>Webclient<a class="headerlink" href="#webclient" title="Permalink to this headline">¶</a></h1>
|
||||
</section>
|
||||
<section id="web-client">
|
||||
<h1><strong>Web client</strong><a class="headerlink" href="#web-client" title="Permalink to this headline">¶</a></h1>
|
||||
<section id="web-client">
|
||||
<h1>Web Client<a class="headerlink" href="#web-client" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Evennia comes with a MUD client accessible from a normal web browser. During development you can try
|
||||
it at <code class="docutils literal notranslate"><span class="pre">http://localhost:4001/webclient</span></code>. The client consists of several parts, all under
|
||||
<code class="docutils literal notranslate"><span class="pre">evennia/web/webclient/</span></code>:</p>
|
||||
|
|
@ -317,8 +314,7 @@ window.plugin_handler.add("myplugin", myplugin);
|
|||
<script>$('#searchbox').show(0);</script>
|
||||
<p><h3><a href="../index.html">Table of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Webclient</a></li>
|
||||
<li><a class="reference internal" href="#web-client"><strong>Web client</strong></a><ul>
|
||||
<li><a class="reference internal" href="#">Web Client</a><ul>
|
||||
<li><a class="reference internal" href="#customizing-the-web-client">Customizing the web client</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
|
@ -369,7 +365,7 @@ window.plugin_handler.add("myplugin", myplugin);
|
|||
<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="">Webclient</a></li>
|
||||
<li class="nav-item nav-item-this"><a href="">Web Client</a></li>
|
||||
</ul>
|
||||
<div class="develop">develop branch</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,75 @@
|
|||
|
||||
<section id="webserver">
|
||||
<h1>Webserver<a class="headerlink" href="#webserver" title="Permalink to this headline">¶</a></h1>
|
||||
<p>TODO: There is no central docs for this component yet.</p>
|
||||
<p>When Evennia starts it also spins up its own Twisted-based web server. The
|
||||
webserver is responsible for serving the html pages of the game’s website. It
|
||||
can also serve static resources like images and music.</p>
|
||||
<p>The webclient runs as part of the <a class="reference internal" href="Portal-And-Server.html"><span class="doc">Server</span></a> process of
|
||||
Evennia. This means that it can directly access cached objects modified
|
||||
in-game, and there is no risk of working with objects that are temporarily
|
||||
out-of-sync in the database.</p>
|
||||
<p>The webserver runs on Twisted and is meant to be used in a production
|
||||
environment. It leverages the Django web framework and provides:</p>
|
||||
<ul class="simple">
|
||||
<li><p>A <a class="reference internal" href="Website.html"><span class="doc">Game Website</span></a> - this is what you see when you go to
|
||||
<code class="docutils literal notranslate"><span class="pre">localhost:4001</span></code>. The look of the website is meant to be customized to your
|
||||
game. Users logged into the website will be auto-logged into the game if they
|
||||
do so with the webclient since they share the same login credentials (there
|
||||
is no way to safely do auto-login with telnet clients).</p></li>
|
||||
<li><p>The <a class="reference internal" href="Web-Admin.html"><span class="doc">Web Admin</span></a> is based on the Django web admin and allows you to
|
||||
edit the game database in a graphical interface.</p></li>
|
||||
<li><p>The <a class="reference internal" href="Webclient.html"><span class="doc">Webclient</span></a> page is served by the webserver, but the actual
|
||||
game communication (sending/receiving data) is done by the javascript client
|
||||
on the page opening a websocket connection directly to Evennia’s Portal.</p></li>
|
||||
<li><p>The <a class="reference internal" href="Web-API.html"><span class="doc">Evennia REST-API</span></a> allows for accessing the database from outside the game
|
||||
(only if `REST_API_ENABLED=True).</p></li>
|
||||
</ul>
|
||||
<section id="basic-webserver-data-flow">
|
||||
<h2>Basic Webserver data flow<a class="headerlink" href="#basic-webserver-data-flow" title="Permalink to this headline">¶</a></h2>
|
||||
<ol class="simple">
|
||||
<li><p>A user enters an url in their browser (or clicks a button). This leads to
|
||||
the browser sending a <em>HTTP request</em> to the server containing an url-path
|
||||
(like for <code class="docutils literal notranslate"><span class="pre">https://localhost:4001/</span></code>, the part of the url we need to consider
|
||||
<code class="docutils literal notranslate"><span class="pre">/</span></code>). Other possibilities would be <code class="docutils literal notranslate"><span class="pre">/admin/</span></code>, <code class="docutils literal notranslate"><span class="pre">/login/</span></code>, <code class="docutils literal notranslate"><span class="pre">/channels/</span></code> etc.</p></li>
|
||||
<li><p>evennia (through Django) will make use of the regular expressions registered
|
||||
in the <code class="docutils literal notranslate"><span class="pre">urls.py</span></code> file. This acts as a rerouter to <em>views</em>, which are
|
||||
regular Python functions or callable classes able to process the incoming
|
||||
request (think of these as similar to the right Evennia Command being
|
||||
selected to handle your input - views are like Commands in this sense). In
|
||||
the case of <code class="docutils literal notranslate"><span class="pre">/</span></code> we reroute to a view handling the main index-page of the
|
||||
website.</p></li>
|
||||
<li><p>The view code will prepare all the data needed by the web page. For the default
|
||||
index page, this means gather the game statistics so you can see how many
|
||||
are currently connected to the game etc.</p></li>
|
||||
<li><p>The view will next fetch a <em>template</em>. A template is a HTML-document with special
|
||||
‘placeholder’ tags (written as <code class="docutils literal notranslate"><span class="pre">{{...}}</span></code> or <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">...</span> <span class="pre">%}</span></code> usually). These
|
||||
placeholders allow the view to inject dynamic content into the HTML and make
|
||||
the page customized to the current situation. For the index page, it means
|
||||
injecting the current player-count in the right places of the html page. This
|
||||
is called ‘rendering’ the template. The result is a complete HTML page.</p></li>
|
||||
<li><p>(The view can also pull in a <em>form</em> to customize user-input in a similar way.)</p></li>
|
||||
<li><p>The finished HTML page is packed into a <em>HTTP response</em> and returned to the
|
||||
web browser, which can now display the page!</p></li>
|
||||
</ol>
|
||||
<section id="a-note-on-the-webclient">
|
||||
<h3>A note on the webclient<a class="headerlink" href="#a-note-on-the-webclient" title="Permalink to this headline">¶</a></h3>
|
||||
<p>The web browser can also execute code directly without talking to the Server.
|
||||
This code must be written/loaded into the web page and is written using the
|
||||
Javascript programming language (there is no way around this, it is what web
|
||||
browsers understand). Executing Javascript is something the web browser does,
|
||||
it operates independently from Evennia. Small snippets of javascript can be
|
||||
used on a page to have buttons react, make small animations etc that doesn’t
|
||||
require the server.</p>
|
||||
<p>In the case of the <a class="reference internal" href="Webclient.html"><span class="doc">Webclient</span></a>, Evennia will load the Webclient page
|
||||
as above, but the page then initiates Javascript code (a lot of it) responsible
|
||||
for actually displaying the client GUI, allows you to resize windows etc.</p>
|
||||
<p>After it starts, the webclient ‘calls home’ and spins up a
|
||||
<a class="reference external" href="https://en.wikipedia.org/wiki/WebSocket">websocket</a> link to the Evennia Portal - this
|
||||
is how all data is then exchanged. So after the initial loading of the
|
||||
webclient page, the above sequence doesn’t happen again until close the tab and
|
||||
come back or you reload it manually in your browser.</p>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
|
|
@ -63,6 +131,17 @@
|
|||
</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="#">Webserver</a><ul>
|
||||
<li><a class="reference internal" href="#basic-webserver-data-flow">Basic Webserver data flow</a><ul>
|
||||
<li><a class="reference internal" href="#a-note-on-the-webclient">A note on the webclient</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div role="note" aria-label="source link">
|
||||
<!--h3>This Page</h3-->
|
||||
<ul class="this-page-menu">
|
||||
|
|
|
|||
542
docs/1.0-dev/Components/Website.html
Normal file
542
docs/1.0-dev/Components/Website.html
Normal file
|
|
@ -0,0 +1,542 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>Game website — 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="">Game website</a></li>
|
||||
</ul>
|
||||
<div class="develop">develop branch</div>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="game-website">
|
||||
<h1>Game website<a class="headerlink" href="#game-website" title="Permalink to this headline">¶</a></h1>
|
||||
<p>When Evennia starts it will also start a <a class="reference internal" href="Webserver.html"><span class="doc">Webserver</span></a> as part of the
|
||||
<a class="reference internal" href="Portal-And-Server.html"><span class="doc">Server</span></a> process. This uses <a class="reference external" href="https://docs.djangoproject.com">Django</a>
|
||||
to present a simple but functional default game website. With the default setup,
|
||||
open your browser to <a class="reference external" href="http://localhost:4001">localhost:4001</a> or <a class="reference external" href="http://127.0.0.1:4001">127.0.0.1:4001</a>
|
||||
to see it.</p>
|
||||
<p>The website allows existing players to log in using an account-name and
|
||||
password they previously used to register with the game. If a user logs in with
|
||||
the <a class="reference internal" href="Webclient.html"><span class="doc">Webclient</span></a> they will also log into the website and vice-versa.
|
||||
So if you are logged into the website, opening the webclient will automatically
|
||||
log you into the game as that account.</p>
|
||||
<p>The default website shows a “Welcome!” page with a few links to useful
|
||||
resources. It also shows some statistics about how many players are currently
|
||||
connected.</p>
|
||||
<p>In the top menu you can find</p>
|
||||
<ul class="simple">
|
||||
<li><p><em>Home</em> - Get back to front page.</p></li>
|
||||
<li><p><em>Documentation</em> - A link to the latest stable Evennia documentation.</p></li>
|
||||
<li><p><em>Characters</em> - This is a demo of connecting in-game characters to the website.
|
||||
It will display a list of all entities of the
|
||||
_typeclasses.characters.Character` typeclass and allow you to view their
|
||||
description with an optional image. The list is only available to logged-in
|
||||
users.</p></li>
|
||||
<li><p><em>Channels</em> - This is a demo of connecting in-game chats to the website. It will
|
||||
show a list of all channels available to you and allow you to view the latest
|
||||
discussions. Most channels require logging in, but the <code class="docutils literal notranslate"><span class="pre">Public</span></code> channel can
|
||||
also be viewed by non-loggedin users.</p></li>
|
||||
<li><p><em>Help</em> - This ties the in-game <a class="reference internal" href="Help-System.html"><span class="doc">Help system</span></a> to the website. All
|
||||
database-based help entries that are publicly available or accessible to your
|
||||
account can be read. This is a good way to present a body of help for people
|
||||
to read outside of the game.</p></li>
|
||||
<li><p><em>Play Online</em> - This opens the <a class="reference internal" href="Webclient.html"><span class="doc">Webclient</span></a> in the browser.</p></li>
|
||||
<li><p><em>Admin</em> The [Web admin](Web admin) will only show if you are logged in.</p></li>
|
||||
<li><p><em>Log in/out</em> - Allows you to authenticate using the same credentials you use
|
||||
in the game.</p></li>
|
||||
<li><p><em>Register</em> - Allows you to register a new account. This is the same as
|
||||
creating a new account upon first logging into the game).</p></li>
|
||||
</ul>
|
||||
<section id="modifying-the-default-website">
|
||||
<h2>Modifying the default Website<a class="headerlink" href="#modifying-the-default-website" title="Permalink to this headline">¶</a></h2>
|
||||
<p>You can modify and override all aspects of the web site from your game dir.
|
||||
You’ll mostly be doing so in your settings file
|
||||
(<code class="docutils literal notranslate"><span class="pre">mygame/server/conf/settings.py</span></code> and in the gamedir’s <code class="docutils literal notranslate"><span class="pre">web/folder</span></code>
|
||||
(<code class="docutils literal notranslate"><span class="pre">mygame/web/</span></code> if your game folder is <code class="docutils literal notranslate"><span class="pre">mygame/</span></code>).</p>
|
||||
<blockquote>
|
||||
<div><p>When testing your modifications, it’s a good idea to add <code class="docutils literal notranslate"><span class="pre">DEBUG</span> <span class="pre">=</span> <span class="pre">True</span></code> to
|
||||
your settings file. This will give you nice informative tracebacks directly
|
||||
in your browser instead of generic 404 or 500 error pages. Just remember that
|
||||
DEBUG mode leaks memory (for retaining debug info) and is <em>not</em> safe to use
|
||||
for a production game!</p>
|
||||
</div></blockquote>
|
||||
<p>As explained on the <a class="reference internal" href="Webserver.html"><span class="doc">Webserver</span></a> page, the process for getting a web
|
||||
page is</p>
|
||||
<ol class="simple">
|
||||
<li><p>Web browser sends HTTP request to server with an URL</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">urls.py</span></code> uses regex to match that URL to a <em>view</em> (a Python function or callable class).</p></li>
|
||||
<li><p>The correct Python view is loaded and executes.</p></li>
|
||||
<li><p>The view pulls in a <em>template</em>, a HTML document with placeholder markers in it,
|
||||
and fills those in as needed (it may also use a <em>form</em> to customize user-input in the same way).
|
||||
A HTML page may also in turn point to static resources (usually CSS, sometimes images etc).</p></li>
|
||||
<li><p>The rendered HTML page is returned to the browser as a HTTP response. If
|
||||
the HTML page requires static resources are requested, the browser will
|
||||
fetch those separately before displaying it to the user.</p></li>
|
||||
</ol>
|
||||
<p>If you look at the <a class="reference external" href="https://github.com/evennia/evennia/blob/develop/evennia/web">evennia/web/</a> directory you’ll find the following
|
||||
structure (leaving out stuff not relevant to the website):</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">evennia</span><span class="o">/</span><span class="n">web</span><span class="o">/</span>
|
||||
<span class="o">...</span>
|
||||
<span class="n">static</span><span class="o">/</span>
|
||||
<span class="n">website</span><span class="o">/</span>
|
||||
<span class="n">css</span><span class="o">/</span>
|
||||
<span class="p">(</span><span class="n">css</span> <span class="n">style</span> <span class="n">files</span><span class="p">)</span>
|
||||
<span class="n">images</span><span class="o">/</span>
|
||||
<span class="p">(</span><span class="n">images</span> <span class="n">to</span> <span class="n">show</span><span class="p">)</span>
|
||||
|
||||
<span class="n">templates</span><span class="o">/</span>
|
||||
<span class="n">website</span><span class="o">/</span>
|
||||
<span class="p">(</span><span class="n">html</span> <span class="n">files</span><span class="p">)</span>
|
||||
|
||||
<span class="n">website</span><span class="o">/</span>
|
||||
<span class="n">urls</span><span class="o">.</span><span class="n">py</span>
|
||||
<span class="n">views</span><span class="o">/</span>
|
||||
<span class="p">(</span><span class="n">python</span> <span class="n">files</span> <span class="n">related</span> <span class="n">to</span> <span class="n">website</span><span class="p">)</span>
|
||||
|
||||
<span class="n">urls</span><span class="o">.</span><span class="n">py</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The top-level <code class="docutils literal notranslate"><span class="pre">web/urls.py</span></code> file ‘includes’ the <code class="docutils literal notranslate"><span class="pre">web/website/urls.py</span></code> file -
|
||||
that way all the website-related url-handling is kept in the same place.</p>
|
||||
<p>This is the layout of the <code class="docutils literal notranslate"><span class="pre">mygame/web/</span></code> folder relevant for the website:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">mygame</span><span class="o">/</span><span class="n">web</span><span class="o">/</span>
|
||||
<span class="o">...</span>
|
||||
<span class="n">static</span><span class="o">/</span>
|
||||
<span class="n">website</span><span class="o">/</span>
|
||||
<span class="n">css</span><span class="o">/</span>
|
||||
<span class="n">images</span><span class="o">/</span>
|
||||
|
||||
<span class="n">templates</span><span class="o">/</span>
|
||||
<span class="n">website</span><span class="o">/</span>
|
||||
|
||||
<span class="n">website</span><span class="o">/</span>
|
||||
<span class="n">urls</span><span class="o">.</span><span class="n">py</span>
|
||||
<span class="n">views</span><span class="o">/</span>
|
||||
|
||||
<span class="n">urls</span><span class="o">.</span><span class="n">py</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="versionchanged">
|
||||
<p><span class="versionmodified changed">Changed in version 1.0: </span>Game folders created with older versions of Evennia will lack most of this
|
||||
convenient <cite>mygame/web/</cite> layout. If you use a game dir from an older version,
|
||||
you should copy over the missing <cite>evennia/game_template/web/</cite> folders from
|
||||
there, as well as the main urls.py file.</p>
|
||||
</div>
|
||||
<p>As you can see, the <code class="docutils literal notranslate"><span class="pre">mygame/web/</span></code> folder is a copy of the <code class="docutils literal notranslate"><span class="pre">evennia/web/</span></code> folder
|
||||
structure except the <code class="docutils literal notranslate"><span class="pre">mygame</span></code> folders are mostly empty.</p>
|
||||
<p>For static- and template-files, Evennia will <em>first</em>
|
||||
look in <code class="docutils literal notranslate"><span class="pre">mygame/static</span></code> and <code class="docutils literal notranslate"><span class="pre">mygame/templates</span></code> before going to the default
|
||||
locations in <code class="docutils literal notranslate"><span class="pre">evennia/web/</span></code>. So override these resources, you just need to put
|
||||
a file with the same name in the right spot under <code class="docutils literal notranslate"><span class="pre">mygame/web/</span></code> (and then
|
||||
reload the server). Easiest is often to copy the original over and modify it.</p>
|
||||
<p>Overridden views (Python modules) also need an additional tweak to the
|
||||
<code class="docutils literal notranslate"><span class="pre">website/urls.py</span></code> file - you must make sure to repoint the url to the new
|
||||
version rather than it using the original.</p>
|
||||
</section>
|
||||
<section id="examples-of-commom-web-changes">
|
||||
<h2>Examples of commom web changes<a class="headerlink" href="#examples-of-commom-web-changes" title="Permalink to this headline">¶</a></h2>
|
||||
<div class="admonition important">
|
||||
<p class="admonition-title">Important</p>
|
||||
<p>Django is a very mature web-design framework. There are endless
|
||||
internet-tutorials, courses and books available to explain how to use Django.
|
||||
So these examples only serve as a first primer to get you started.</p>
|
||||
</div>
|
||||
<section id="change-title-and-blurb">
|
||||
<h3>Change Title and blurb<a class="headerlink" href="#change-title-and-blurb" title="Permalink to this headline">¶</a></h3>
|
||||
<p>The website’s title and blurb are simply changed by tweaking
|
||||
<code class="docutils literal notranslate"><span class="pre">settings.SERVERNAME</span></code> and <code class="docutils literal notranslate"><span class="pre">settings.GAME_SLOGAN</span></code>. Your settings file is in
|
||||
<code class="docutils literal notranslate"><span class="pre">mygame/server/conf/settings.py</span></code>, just set/add</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">SERVERNAME</span> <span class="o">=</span> <span class="s2">"My Awesome Game"</span>
|
||||
<span class="n">GAME_SLOGAN</span> <span class="o">=</span> <span class="s2">"The best game in the world"</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="change-the-logo">
|
||||
<h3>Change the Logo<a class="headerlink" href="#change-the-logo" title="Permalink to this headline">¶</a></h3>
|
||||
<p>The Evennia googly-eyed snake logo is probably not what you want for your game.
|
||||
The template looks for a file <code class="docutils literal notranslate"><span class="pre">web/static/website/images/evennia_logo.png</span></code>. Just
|
||||
plop your own PNG logo (64x64 pixels large) in there and name it the same.</p>
|
||||
</section>
|
||||
<section id="change-front-page-html">
|
||||
<h3>Change front page HTML<a class="headerlink" href="#change-front-page-html" title="Permalink to this headline">¶</a></h3>
|
||||
<p>The front page of the website is usually referred to as the ‘index’ in HTML
|
||||
parlance.</p>
|
||||
<p>The frontpage template is found in <code class="docutils literal notranslate"><span class="pre">evennia/web/templates/website/index.html</span></code>.
|
||||
Just copy this to the equivalent place in <code class="docutils literal notranslate"><span class="pre">mygame/web/</span></code>. Modify it there and
|
||||
reload the server to see your changes.</p>
|
||||
<p>Django templates has a few special features that separate them from normal HTML
|
||||
documents - they contain a special templating language marked with <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">...</span> <span class="pre">%}</span></code> and
|
||||
<code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">...</span> <span class="pre">}}</span></code>.</p>
|
||||
<p>Some important things to know:</p>
|
||||
<ul class="simple">
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">extends</span> <span class="pre">"base.html"</span> <span class="pre">%}</span></code> - This is equivalent to a Python
|
||||
<code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">othermodule</span> <span class="pre">import</span> <span class="pre">*</span></code> statement, but for templates. It allows a given template
|
||||
to use everything from the imported (extended) template, but also to override anything
|
||||
it wants to change. This makes it easy to keep all pages looking the same and avoids
|
||||
a lot of boiler plate.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">block</span> <span class="pre">blockname</span> <span class="pre">%}...{%</span> <span class="pre">endblock</span> <span class="pre">%}</span></code> - Blocks are inheritable, named pieces of code
|
||||
that are modified in one place and then used elsewhere. This works a bit in reverse to
|
||||
normal inheritance, because it’s commonly in such a way that <code class="docutils literal notranslate"><span class="pre">base.html</span></code> defines an empty
|
||||
block, let’s say <code class="docutils literal notranslate"><span class="pre">contents</span></code>: <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">block</span> <span class="pre">contents</span> <span class="pre">%}{%</span> <span class="pre">endblock</span> <span class="pre">%}</span></code> but makes sure to put
|
||||
that <em>in the right place</em>, say in the main body, next to the sidebar etc. Then each page
|
||||
does <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">extends</span> <span class="pre">"base.html</span> <span class="pre">%"}</span></code> and makes their own <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">block</span> <span class="pre">contents}</span> <span class="pre"><actual</span> <span class="pre">content></span> <span class="pre">{%</span> <span class="pre">endblock</span> <span class="pre">%}</span></code>.
|
||||
Their <code class="docutils literal notranslate"><span class="pre">contents</span></code> block will now override the empty one in <code class="docutils literal notranslate"><span class="pre">base.html</span></code> and appear in the right
|
||||
place in the document, without the extending template having to specifying everything else
|
||||
around it!</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">...</span> <span class="pre">}}</span></code> are ‘slots’ usually embedded inside HTML tags or content. They reference a
|
||||
<em>context</em> (basically a dict) that the Python <em>view</em> makes available to it.
|
||||
Keys on the context are accessed with dot-notation, so if you provide a
|
||||
context <code class="docutils literal notranslate"><span class="pre">{"stats":</span> <span class="pre">{"hp":</span> <span class="pre">10,</span> <span class="pre">"mp":</span> <span class="pre">5}}</span></code> to your template, you could access
|
||||
that as <code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">stats.hp</span> <span class="pre">}}</span></code> to display <code class="docutils literal notranslate"><span class="pre">10</span></code> at that location to display <code class="docutils literal notranslate"><span class="pre">10</span></code> at
|
||||
that location.</p></li>
|
||||
</ul>
|
||||
<p>This allows for template inheritance (making it easier to make all
|
||||
pages look the same without rewriting the same thing over and over)</p>
|
||||
<p>There’s a lot more information to be found in the <a class="reference external" href="https://docs.djangoproject.com/en/3.2/ref/templates/language/">Django template language documentation</a>.</p>
|
||||
</section>
|
||||
<section id="change-webpage-colors-and-styling">
|
||||
<h3>Change webpage colors and styling<a class="headerlink" href="#change-webpage-colors-and-styling" title="Permalink to this headline">¶</a></h3>
|
||||
<p>You can tweak the <a class="reference external" href="https://en.wikipedia.org/wiki/Cascading_Style_Sheets">CSS</a> of the entire
|
||||
website. If you investigate the <code class="docutils literal notranslate"><span class="pre">evennia/web/templates/website/base.html</span></code> file you’ll see that we
|
||||
use the <a class="reference external" href="https://getbootstrap.com/docs/4.6/getting-started/introduction/">Bootstrap
|
||||
4</a> toolkit.</p>
|
||||
<p>Much structural HTML functionality is actually coming from bootstrap, so you
|
||||
will often be able to just add bootstrap CSS classes to elements in the HTML
|
||||
file to get various effects like text-centering or similar.</p>
|
||||
<p>The website’s custom CSS is found in
|
||||
<code class="docutils literal notranslate"><span class="pre">evennia/web/static/website/css/website.css</span></code> but we also look for a (currently
|
||||
empty) <code class="docutils literal notranslate"><span class="pre">custom.css</span></code> in the same location. You can override either, but it may
|
||||
be easier to revert your changes if you only add things to <code class="docutils literal notranslate"><span class="pre">custom.css</span></code>.</p>
|
||||
<p>Copy the CSS file you want to modify to the corresponding location in <code class="docutils literal notranslate"><span class="pre">mygame/web</span></code>.
|
||||
Modify it and reload the server to see your changes.</p>
|
||||
<p>You can also apply static files without reloading, but running this in the
|
||||
terminal:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">evennia</span> <span class="n">collectstatic</span> <span class="o">--</span><span class="n">no</span><span class="o">-</span><span class="nb">input</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>(this is run automatically when reloading the server).</p>
|
||||
<blockquote>
|
||||
<div><p>Note that before you see new CSS files applied you may need to refresh your
|
||||
browser without cache (Ctrl-F5 in Firefox, for example).</p>
|
||||
</div></blockquote>
|
||||
<p>As an example, add/copy <code class="docutils literal notranslate"><span class="pre">custom.css</span></code> to <code class="docutils literal notranslate"><span class="pre">mygame/web/static/website/css/</span></code> and
|
||||
add the following:</p>
|
||||
<div class="highlight-css notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span>
|
||||
<span class="normal">5</span>
|
||||
<span class="normal">6</span>
|
||||
<span class="normal">7</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="p">.</span><span class="nc">navbar</span> <span class="p">{</span>
|
||||
<span class="k">background-color</span><span class="p">:</span> <span class="mh">#7a3d54</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="p">.</span><span class="nc">footer</span> <span class="p">{</span>
|
||||
<span class="k">background-color</span><span class="p">:</span> <span class="mh">#7a3d54</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>Reload and your website now has a red theme!</p>
|
||||
<blockquote>
|
||||
<div><p>Hint: Learn to use your web browser’s <a class="reference external" href="https://torquemag.io/2020/06/browser-developer-tools-tutorial/">Developer tools</a>.
|
||||
These allow you to tweak CSS ‘live’ to find a look you like and copy it into
|
||||
the .css file only when you want to make the changes permanent.</p>
|
||||
</div></blockquote>
|
||||
</section>
|
||||
<section id="change-front-page-functionality">
|
||||
<h3>Change front page functionality<a class="headerlink" href="#change-front-page-functionality" title="Permalink to this headline">¶</a></h3>
|
||||
<p>The logic is all in the view. To find where the index-page view is found, we
|
||||
look in <code class="docutils literal notranslate"><span class="pre">evennia/web/website/urls.py</span></code>. Here we find the following line:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span>
|
||||
<span class="normal">5</span>
|
||||
<span class="normal">6</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># in evennia/web/website/urls.py</span>
|
||||
|
||||
<span class="o">...</span>
|
||||
<span class="c1"># website front page</span>
|
||||
<span class="n">path</span><span class="p">(</span><span class="s2">""</span><span class="p">,</span> <span class="n">index</span><span class="o">.</span><span class="n">EvenniaIndexView</span><span class="o">.</span><span class="n">as_view</span><span class="p">(),</span> <span class="n">name</span><span class="o">=</span><span class="s2">"index"</span><span class="p">),</span>
|
||||
<span class="o">...</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>The first <code class="docutils literal notranslate"><span class="pre">""</span></code> is the empty url - root - what you get if you just enter <code class="docutils literal notranslate"><span class="pre">localhost:4001/</span></code>
|
||||
with no extra path. As expected, this leads to the index page. By looking at the imports
|
||||
we find the view is in in <code class="docutils literal notranslate"><span class="pre">evennia/web/website/views/index.py</span></code>.</p>
|
||||
<p>Copy this file to the corresponding location in <code class="docutils literal notranslate"><span class="pre">mygame/web</span></code>. Then tweak your <code class="docutils literal notranslate"><span class="pre">mygame/web/website/urls.py</span></code>
|
||||
file to point to the new file:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span>
|
||||
<span class="normal">11</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># in mygame/web/website/urls.py</span>
|
||||
|
||||
<span class="c1"># ...</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">web.website.views</span> <span class="kn">import</span> <span class="n">index</span>
|
||||
|
||||
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="n">path</span><span class="p">(</span><span class="s2">""</span><span class="p">,</span> <span class="n">index</span><span class="o">.</span><span class="n">EvenniaIndexView</span><span class="o">.</span><span class="n">as_view</span><span class="p">(),</span> <span class="n">name</span><span class="o">=</span><span class="s2">"index"</span><span class="p">)</span>
|
||||
|
||||
<span class="p">]</span>
|
||||
<span class="c1"># ...</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
<p>So we just import <code class="docutils literal notranslate"><span class="pre">index</span></code> from the new location and point to it. After a reload
|
||||
the front page will now redirect to use your copy rather than the original.</p>
|
||||
<p>The frontpage view is a class <code class="docutils literal notranslate"><span class="pre">EvenniaIndexView</span></code>. This is a <a class="reference external" href="https://docs.djangoproject.com/en/3.2/topics/class-based-views/">Django class-based view</a>.
|
||||
It’s a little less visible what happens in a class-based view than in a function (since
|
||||
the class implements a lot of functionality as methods), but it’s powerful and
|
||||
much easier to extend/modify.</p>
|
||||
<p>The class property <code class="docutils literal notranslate"><span class="pre">template_name</span></code> sets the location of the template used under
|
||||
the <code class="docutils literal notranslate"><span class="pre">templates/</span></code> folder. So <code class="docutils literal notranslate"><span class="pre">website/index.html</span></code> points to
|
||||
<code class="docutils literal notranslate"><span class="pre">web/templates/website/index.html</span></code> (as we already explored above.</p>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">get_context_data</span></code> is a convenient method for providing the context for the
|
||||
template. In the index-page’s case we want the game stats (number of recent
|
||||
players etc). These are then made available to use in <code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">...</span> <span class="pre">}}</span></code> slots in the
|
||||
template as described in the previous section.</p>
|
||||
</section>
|
||||
<section id="change-other-website-pages">
|
||||
<h3>Change other website pages<a class="headerlink" href="#change-other-website-pages" title="Permalink to this headline">¶</a></h3>
|
||||
<p>The other sub pages are handled in the same way - copy the template or static
|
||||
resource to the right place, or copy the view and repoint your <code class="docutils literal notranslate"><span class="pre">website/urls.py</span></code> to
|
||||
your copy. Just remember to reload.</p>
|
||||
</section>
|
||||
</section>
|
||||
<section id="adding-a-new-web-page">
|
||||
<h2>Adding a new web page<a class="headerlink" href="#adding-a-new-web-page" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="using-flat-pages">
|
||||
<h3>Using Flat Pages<a class="headerlink" href="#using-flat-pages" title="Permalink to this headline">¶</a></h3>
|
||||
<p>The absolutely simplest way to add a new web page is to use the <code class="docutils literal notranslate"><span class="pre">Flat</span> <span class="pre">Pages</span></code>
|
||||
app available in the <a class="reference internal" href="Web-Admin.html"><span class="doc">Web Admin</span></a>. The page will appear with the same
|
||||
styling as the rest of the site.</p>
|
||||
<p>For the <code class="docutils literal notranslate"><span class="pre">Flat</span> <span class="pre">pages</span></code> module to work you must first set up a <em>Site</em> (or
|
||||
domain) to use. You only need to this once.</p>
|
||||
<ul class="simple">
|
||||
<li><p>Go to the Web admin and select <code class="docutils literal notranslate"><span class="pre">Sites</span></code>. If your
|
||||
game is at <code class="docutils literal notranslate"><span class="pre">mygreatgame.com</span></code>, that’s the domain you need to add. For local
|
||||
experimentation, add the domain <code class="docutils literal notranslate"><span class="pre">localhost:4001</span></code>. Note the <code class="docutils literal notranslate"><span class="pre">id</span></code> of the domain
|
||||
(look at the url when you click on the new domain, if it’s for example
|
||||
<code class="docutils literal notranslate"><span class="pre">http://localhost:4001/admin/sites/site/2/change/</span></code>, then the id is <code class="docutils literal notranslate"><span class="pre">2</span></code>).</p></li>
|
||||
<li><p>Now add the line <code class="docutils literal notranslate"><span class="pre">SITE_ID</span> <span class="pre">=</span> <span class="pre"><id></span></code> to your settings file.</p></li>
|
||||
</ul>
|
||||
<p>Next you create new pages easily.</p>
|
||||
<ul class="simple">
|
||||
<li><p>Go the <code class="docutils literal notranslate"><span class="pre">Flat</span> <span class="pre">Pages</span></code> web admin and choose to add a new flat page.</p></li>
|
||||
<li><p>Set the url. If you want the page to appear as e.g. <code class="docutils literal notranslate"><span class="pre">localhost:4001/test/</span></code>, then
|
||||
add <code class="docutils literal notranslate"><span class="pre">/test/</span></code> here. You need to add both leading and trailing slashes.</p></li>
|
||||
<li><p>Set <code class="docutils literal notranslate"><span class="pre">Title</span></code> to the name of the page.</p></li>
|
||||
<li><p>The <code class="docutils literal notranslate"><span class="pre">Content</span></code> is the HTML content of the body of the page. Go wild!</p></li>
|
||||
<li><p>Finally pick the <code class="docutils literal notranslate"><span class="pre">Site</span></code> you made before, and save.</p></li>
|
||||
<li><p>(in the advanced section you can make it so that you have to login to see the page etc).</p></li>
|
||||
</ul>
|
||||
<p>You can now go to <code class="docutils literal notranslate"><span class="pre">localhost:4001/test/</span></code> and see your new page!</p>
|
||||
</section>
|
||||
<section id="add-custom-new-page">
|
||||
<h3>Add Custom new page<a class="headerlink" href="#add-custom-new-page" title="Permalink to this headline">¶</a></h3>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">Flat</span> <span class="pre">Pages</span></code> page doesn’t allow for (much) dynamic content and customization. For
|
||||
this you need to add the needed components yourself.</p>
|
||||
<p>Let’s see how to make a <code class="docutils literal notranslate"><span class="pre">/test/</span></code> page from scratch.</p>
|
||||
<ul>
|
||||
<li><p>Add a new <code class="docutils literal notranslate"><span class="pre">test.html</span></code> file under <code class="docutils literal notranslate"><span class="pre">mygame/web/templates/website/</span></code>. Easiest is to base
|
||||
this off an existing file. Make sure to <code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">extend</span> <span class="pre">base.html</span> <span class="pre">%}</span></code> if you want to
|
||||
get the same styling as the rest of your site.</p></li>
|
||||
<li><p>Add a new view <code class="docutils literal notranslate"><span class="pre">testview.py</span></code> under <code class="docutils literal notranslate"><span class="pre">mygame/web/website/views/</span></code> (don’t name it <code class="docutils literal notranslate"><span class="pre">test.py</span></code> or
|
||||
Django/Evennia will think it contains unit tests). Add a view there to process
|
||||
your page. This is a minimal view to start from (read much more <a class="reference external" href="https://docs.djangoproject.com/en/3.2/topics/class-based-views/">in the Django docs</a>):</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
|
||||
<span class="normal">2</span>
|
||||
<span class="normal">3</span>
|
||||
<span class="normal">4</span>
|
||||
<span class="normal">5</span>
|
||||
<span class="normal">6</span>
|
||||
<span class="normal">7</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># mygame/web/website/views/testview.py</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">django.views.generic</span> <span class="kn">import</span> <span class="n">TemplateView</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">MyTestView</span><span class="p">(</span><span class="n">TemplateView</span><span class="p">):</span>
|
||||
<span class="n">template_name</span> <span class="o">=</span> <span class="s2">"website/test.html"</span>
|
||||
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</li>
|
||||
<li><p>Finally, point to your view from the <code class="docutils literal notranslate"><span class="pre">mygame/web/website/urls.py</span></code>:</p>
|
||||
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
|
||||
<span class="normal"> 2</span>
|
||||
<span class="normal"> 3</span>
|
||||
<span class="normal"> 4</span>
|
||||
<span class="normal"> 5</span>
|
||||
<span class="normal"> 6</span>
|
||||
<span class="normal"> 7</span>
|
||||
<span class="normal"> 8</span>
|
||||
<span class="normal"> 9</span>
|
||||
<span class="normal">10</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1"># in mygame/web/website/urls.py</span>
|
||||
|
||||
<span class="c1"># ...</span>
|
||||
<span class="kn">from</span> <span class="nn">web.website.views</span> <span class="kn">import</span> <span class="n">testview</span>
|
||||
|
||||
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="c1"># ...</span>
|
||||
<span class="c1"># we can skip the initial / here</span>
|
||||
<span class="n">path</span><span class="p">(</span><span class="s2">"test/"</span><span class="p">,</span> <span class="n">testview</span><span class="o">.</span><span class="n">MyTestView</span><span class="o">.</span><span class="n">as_view</span><span class="p">())</span>
|
||||
<span class="p">]</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</li>
|
||||
<li><p>Reload the server and your new page is available. You can now continue to add
|
||||
all sorts of advanced dynamic content through your view and template!</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
</section>
|
||||
<section id="user-forms">
|
||||
<h2>User forms<a class="headerlink" href="#user-forms" title="Permalink to this headline">¶</a></h2>
|
||||
<p>All the pages created so far deal with <em>presenting</em> information to the user.
|
||||
It’s also possible for the user to <em>input</em> data on the page through <em>forms</em>. An
|
||||
example would be a page of fields and sliders you fill in to create a
|
||||
character, with a big ‘Submit’ button at the bottom.</p>
|
||||
<p>Firstly, this must be represented in HTML. The <code class="docutils literal notranslate"><span class="pre"><form></span> <span class="pre">...</span> <span class="pre"></form></span></code> is a
|
||||
standard HTML element you need to add to your template. It also has some other
|
||||
requirements, such as <code class="docutils literal notranslate"><span class="pre"><input></span></code> and often Javascript components as well (but
|
||||
usually Django will help with this). If you are unfamiliar with how HTML forms
|
||||
work, <a class="reference external" href="https://docs.djangoproject.com/en/3.2/topics/forms/#html-forms">read about them here</a>.</p>
|
||||
<p>The basic gist of it is that when you click to ‘submit’ the form, a POST HTML
|
||||
request will be sent to the server containing the data the user entered. It’s
|
||||
now up to the server to make sure the data makes sense (validation) and then
|
||||
process the input somehow (like creating a new character).</p>
|
||||
<p>On the backend side, we need to specify the logic for validating and processing
|
||||
the form data. This is done by the <code class="docutils literal notranslate"><span class="pre">Form</span></code> <a class="reference external" href="https://docs.djangoproject.com/en/3.2/topics/forms/#forms-in-django">Django class</a>.
|
||||
This specifies <em>fields</em> on itself that define how to validate that piece of data.</p>
|
||||
<p>The form is then linked into the view-class by adding <code class="docutils literal notranslate"><span class="pre">form_class</span> <span class="pre">=</span> <span class="pre">MyFormClass</span></code> to
|
||||
the view (next to <code class="docutils literal notranslate"><span class="pre">template_name</span></code>).</p>
|
||||
<p>There are several example forms in <code class="docutils literal notranslate"><span class="pre">evennia/web/website/forms.py</span></code>. It’s also a good
|
||||
idea to read <a class="reference external" href="https://docs.djangoproject.com/en/3.2/topics/forms/#building-a-form-in-django">Building a form in Django</a>
|
||||
on the Django website - it covers all you need.</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
<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="#">Game website</a><ul>
|
||||
<li><a class="reference internal" href="#modifying-the-default-website">Modifying the default Website</a></li>
|
||||
<li><a class="reference internal" href="#examples-of-commom-web-changes">Examples of commom web changes</a><ul>
|
||||
<li><a class="reference internal" href="#change-title-and-blurb">Change Title and blurb</a></li>
|
||||
<li><a class="reference internal" href="#change-the-logo">Change the Logo</a></li>
|
||||
<li><a class="reference internal" href="#change-front-page-html">Change front page HTML</a></li>
|
||||
<li><a class="reference internal" href="#change-webpage-colors-and-styling">Change webpage colors and styling</a></li>
|
||||
<li><a class="reference internal" href="#change-front-page-functionality">Change front page functionality</a></li>
|
||||
<li><a class="reference internal" href="#change-other-website-pages">Change other website pages</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#adding-a-new-web-page">Adding a new web page</a><ul>
|
||||
<li><a class="reference internal" href="#using-flat-pages">Using Flat Pages</a></li>
|
||||
<li><a class="reference internal" href="#add-custom-new-page">Add Custom new page</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#user-forms">User forms</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div role="note" aria-label="source link">
|
||||
<!--h3>This Page</h3-->
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/Components/Website.md.txt"
|
||||
rel="nofollow">Show Page Source</a></li>
|
||||
</ul>
|
||||
</div><h3>Links</h3>
|
||||
<ul>
|
||||
<li><a href="https://www.evennia.com">Home page</a> </li>
|
||||
<li><a href="https://github.com/evennia/evennia">Evennia Github</a> </li>
|
||||
<li><a href="http://games.evennia.com">Game Index</a> </li>
|
||||
<li><a href="http://webchat.freenode.net/?channels=evennia&uio=MT1mYWxzZSY5PXRydWUmMTE9MTk1JjEyPXRydWUbb">IRC</a> -
|
||||
<a href="https://discord.gg/NecFePw">Discord</a> -
|
||||
<a href="https://groups.google.com/forum/#%21forum/evennia">Forums</a>
|
||||
</li>
|
||||
<li><a href="http://evennia.blogspot.com/">Evennia Dev blog</a> </li>
|
||||
</ul>
|
||||
<h3>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Website.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="">Game website</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>
|
||||
Loading…
Add table
Add a link
Reference in a new issue