evennia/docs/6.x/Components/Website.html
2026-02-15 19:06:04 +01:00

487 lines
No EOL
41 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Game website &#8212; Evennia latest documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=d75fae25" />
<link rel="stylesheet" type="text/css" href="../_static/nature.css?v=279e0f84" />
<link rel="stylesheet" type="text/css" href="../_static/custom.css?v=e4a91a55" />
<script src="../_static/documentation_options.js?v=c6e86fd7"></script>
<script src="../_static/doctools.js?v=9bcbadda"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Web Client" href="Webclient.html" />
<link rel="prev" title="Signals" href="Signals.html" />
</head><body>
<div class="related" role="navigation" aria-label="Related">
<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="right" >
<a href="Webclient.html" title="Web Client"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Signals.html" title="Signals"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Components-Overview.html" accesskey="U">Core Components</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Game website</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="game-website">
<h1>Game website<a class="headerlink" href="#game-website" title="Link to this heading"></a></h1>
<p>When Evennia starts it will also start a <a class="reference internal" href="Webserver.html"><span class="std std-doc">Webserver</span></a> as part of the <a class="reference internal" href="Portal-And-Server.html"><span class="std std-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="std std-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="std std-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="std std-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="Link to this heading"></a></h2>
<p>You can modify and override all aspects of the web site from your game dir. Youll 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 gamedirs <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, its 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="std std-doc">Webserver</span></a> page, the process for getting a web page is</p>
<ol class="arabic 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/main/evennia/web">evennia/web/</a> directory youll 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 <code class="docutils literal notranslate"><span class="pre">mygame/web/</span></code> layout. If you use a game dir from an older version,
you should copy over the missing <code class="docutils literal notranslate"><span class="pre">evennia/game_template/web/</span></code> folders from
there, as well as the main <code class="docutils literal notranslate"><span class="pre">urls.py</span></code> 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="Link to this heading"></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="Link to this heading"></a></h3>
<p>The websites 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-none notranslate"><div class="highlight"><pre><span></span>SERVERNAME = &quot;My Awesome Game&quot;
GAME_SLOGAN = &quot;The best game in the world&quot;
</pre></div>
</div>
</section>
<section id="change-the-logo">
<h3>Change the Logo<a class="headerlink" href="#change-the-logo" title="Link to this heading"></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="Link to this heading"></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">&quot;base.html&quot;</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 its commonly in such a way that <code class="docutils literal notranslate"><span class="pre">base.html</span></code> defines an empty block, lets 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">&quot;base.html</span> <span class="pre">%&quot;}</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">&lt;actual</span> <span class="pre">content&gt;</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">{&quot;stats&quot;:</span> <span class="pre">{&quot;hp&quot;:</span> <span class="pre">10,</span> <span class="pre">&quot;mp&quot;:</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>Theres a lot more information to be found in the <a class="reference external" href="https://docs.djangoproject.com/en/4.1/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="Link to this heading"></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 youll 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 websites 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-none notranslate"><div class="highlight"><pre><span></span>evennia collectstatic --no-input
</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"><div class="highlight"><pre><span></span><span class="p">.</span><span class="nc">navbar</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">background-color</span><span class="p">:</span><span class="w"> </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="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">background-color</span><span class="p">:</span><span class="w"> </span><span class="mh">#7a3d54</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Reload and your website now has a red theme!</p>
<blockquote>
<div><p>Hint: Learn to use your web browsers <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="Link to this heading"></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"><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">&quot;&quot;</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">&quot;index&quot;</span><span class="p">),</span>
<span class="o">...</span>
</pre></div>
</div>
<p>The first <code class="docutils literal notranslate"><span class="pre">&quot;&quot;</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"><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="w"> </span><span class="nn">web.website.views</span><span class="w"> </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">&quot;&quot;</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">&quot;index&quot;</span><span class="p">)</span>
<span class="p">]</span>
<span class="c1"># ...</span>
</pre></div>
</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/4.1/topics/class-based-views/">Django class-based view</a>. Its 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 its 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-pages 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="Link to this heading"></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="Link to this heading"></a></h2>
<section id="using-flat-pages">
<h3>Using Flat Pages<a class="headerlink" href="#using-flat-pages" title="Link to this heading"></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="std std-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>, thats 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 its 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">&lt;id&gt;</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="Link to this heading"></a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">Flat</span> <span class="pre">Pages</span></code> page doesnt allow for (much) dynamic content and customization. For this you need to add the needed components yourself.</p>
<p>Lets 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> (dont 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/4.1/topics/class-based-views/">in the Django docs</a>):</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/web/website/views/testview.py</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.views.generic</span><span class="w"> </span><span class="kn">import</span> <span class="n">TemplateView</span>
<span class="k">class</span><span class="w"> </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">&quot;website/test.html&quot;</span>
</pre></div>
</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"><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="w"> </span><span class="nn">web.website.views</span><span class="w"> </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">&quot;test/&quot;</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>
</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="Link to this heading"></a></h2>
<p>All the pages created so far deal with <em>presenting</em> information to the user.
Its 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">&lt;form&gt;</span> <span class="pre">...</span> <span class="pre">&lt;/form&gt;</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">&lt;input&gt;</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/4.1/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. Its
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/4.1/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>. Its also a good
idea to read <a class="reference external" href="https://docs.djangoproject.com/en/4.1/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">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/evennia_logo.png" alt="Logo of Evennia"/>
</a></p>
<search 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" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>
<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>
<h4>Previous topic</h4>
<p class="topless"><a href="Signals.html"
title="previous chapter">Signals</a></p>
</div>
<div>
<h4>Next topic</h4>
<p class="topless"><a href="Webclient.html"
title="next chapter">Web Client</a></p>
</div>
<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/docs/latest/index.html">Documentation Top</a> </li>
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
<li><a href="https://github.com/evennia/evennia">Github</a> </li>
<li><a href="http://games.evennia.com">Game Index</a> </li>
<li>
<a href="https://discord.gg/AJJpcRUhtF">Discord</a> -
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
<a href="https://evennia.blogspot.com/">Blog</a>
</li>
</ul>
<h3>Doc Versions</h3>
<ul>
<li>
<a href="https://www.evennia.com/docs/latest/index.html">latest (main branch)</a>
</li>
<li>
<a href="https://www.evennia.com/docs/5.x/index.html">v5.0.0 branch (outdated)</a>
</li>
<li>
<a href="https://www.evennia.com/docs/4.x/index.html">v4.0.0 branch (outdated)</a>
</li>
<li>
<a href="https://www.evennia.com/docs/3.x/index.html">v3.0.0 branch (outdated)</a>
</li>
<li>
<a href="https://www.evennia.com/docs/2.x/index.html">v2.0.0 branch (outdated)</a>
</li>
<li>
<a href="https://www.evennia.com/docs/1.x/index.html">v1.0.0 branch (outdated)</a>
</li>
<li>
<a href="https://www.evennia.com/docs/0.x/index.html">v0.9.5 branch (outdated)</a>
</li>
</ul>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="Related">
<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="right" >
<a href="Webclient.html" title="Web Client"
>next</a> |</li>
<li class="right" >
<a href="Signals.html" title="Signals"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Components-Overview.html" >Core Components</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Game website</a></li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2024, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
</div>
</body>
</html>