mirror of
https://github.com/evennia/evennia.git
synced 2026-03-17 13:26:30 +01:00
440 lines
No EOL
37 KiB
HTML
440 lines
No EOL
37 KiB
HTML
|
||
<!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>Web Client — Evennia 3.x 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" />
|
||
<link rel="next" title="The Web Admin" href="Web-Admin.html" />
|
||
<link rel="prev" title="Game website" href="Website.html" />
|
||
</head><body>
|
||
|
||
|
||
<div class="admonition important">
|
||
<p class="first admonition-title">Note</p>
|
||
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
|
||
</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"
|
||
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="Web-Admin.html" title="The Web Admin"
|
||
accesskey="N">next</a> |</li>
|
||
<li class="right" >
|
||
<a href="Website.html" title="Game website"
|
||
accesskey="P">previous</a> |</li>
|
||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 3.x</a> »</li>
|
||
<li class="nav-item nav-item-1"><a href="Components-Overview.html" accesskey="U">Core Components</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">Web Client</a></li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="document">
|
||
|
||
<div class="documentwrapper">
|
||
<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>
|
||
<h3><a href="../index.html">Table of Contents</a></h3>
|
||
<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>
|
||
<li><a class="reference internal" href="#evennia-web-client-api-from-evennia-js">Evennia Web Client API (from evennia.js)</a></li>
|
||
<li><a class="reference internal" href="#plugin-manager-api-from-webclient-gui-js">Plugin Manager API (from webclient_gui.js)</a></li>
|
||
<li><a class="reference internal" href="#plugin-callbacks-api">Plugin callbacks API</a><ul>
|
||
<li><a class="reference internal" href="#example-default-plugins-plugins-js">Example/Default Plugins (<code class="docutils literal notranslate"><span class="pre">plugins/*.js</span></code>)</a></li>
|
||
<li><a class="reference internal" href="#a-side-note-on-html-messages-vs-text2html-messages">A side note on html messages vs text2html messages</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#writing-your-own-plugins">Writing your own Plugins</a><ul>
|
||
<li><a class="reference internal" href="#goldenlayout">GoldenLayout</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h4>Previous topic</h4>
|
||
<p class="topless"><a href="Website.html"
|
||
title="previous chapter">Game website</a></p>
|
||
<h4>Next topic</h4>
|
||
<p class="topless"><a href="Web-Admin.html"
|
||
title="next chapter">The Web Admin</a></p>
|
||
<div role="note" aria-label="source link">
|
||
<!--h3>This Page</h3-->
|
||
<ul class="this-page-menu">
|
||
<li><a href="../_sources/Components/Webclient.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>
|
||
</div>
|
||
</div>
|
||
<div class="bodywrapper">
|
||
<div class="body" role="main">
|
||
|
||
<section class="tex2jax_ignore mathjax_ignore" 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</span></code>:</p>
|
||
<p><code class="docutils literal notranslate"><span class="pre">templates/webclient/webclient.html</span></code> and <code class="docutils literal notranslate"><span class="pre">templates/webclient/base.html</span></code> are the very simplistic
|
||
django html templates describing the webclient layout.</p>
|
||
<p><code class="docutils literal notranslate"><span class="pre">static/webclient/js/evennia.js</span></code> is the main evennia javascript library. This handles all
|
||
communication between Evennia and the client over websockets and via AJAX/COMET if the browser can’t
|
||
handle websockets. It will make the Evennia object available to the javascript namespace, which
|
||
offers methods for sending and receiving data to/from the server transparently. This is intended to
|
||
be used also if swapping out the gui front end.</p>
|
||
<p><code class="docutils literal notranslate"><span class="pre">static/webclient/js/webclient_gui.js</span></code> is the default plugin manager. It adds the <code class="docutils literal notranslate"><span class="pre">plugins</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">plugin_manager</span></code> objects to the javascript namespace, coordinates the GUI operations between the
|
||
various plugins, and uses the Evennia object library for all in/out.</p>
|
||
<p><code class="docutils literal notranslate"><span class="pre">static/webclient/js/plugins</span></code> provides a default set of plugins that implement a “telnet-like”
|
||
interface, and a couple of example plugins to show how you could implement new plugin features.</p>
|
||
<p><code class="docutils literal notranslate"><span class="pre">static/webclient/css/webclient.css</span></code> is the CSS file for the client; it also defines things like how
|
||
to display ANSI/Xterm256 colors etc.</p>
|
||
<p>The server-side webclient protocols are found in <code class="docutils literal notranslate"><span class="pre">evennia/server/portal/webclient.py</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">webclient_ajax.py</span></code> for the two types of connections. You can’t (and should not need to) modify
|
||
these.</p>
|
||
<section id="customizing-the-web-client">
|
||
<h2>Customizing the web client<a class="headerlink" href="#customizing-the-web-client" title="Permalink to this headline">¶</a></h2>
|
||
<p>Like was the case for the website, you override the webclient from your game directory. You need to
|
||
add/modify a file in the matching directory locations within your project’s <code class="docutils literal notranslate"><span class="pre">mygame/web/</span></code> directories.
|
||
These directories are NOT directly used by the web server when the game is running, the
|
||
server copies everything web related in the Evennia folder over to <code class="docutils literal notranslate"><span class="pre">mygame/server/.static/</span></code> and then
|
||
copies in all of your <code class="docutils literal notranslate"><span class="pre">mygame/web/</span></code> files. This can cause some cases were you edit a file, but it doesn’t
|
||
seem to make any difference in the servers behavior. <strong>Before doing anything else, try shutting
|
||
down the game and running <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">collectstatic</span></code> from the command line then start it back up, clear
|
||
your browser cache, and see if your edit shows up.</strong></p>
|
||
<p>Example: To change the list of in-use plugins, you need to override base.html by copying
|
||
<code class="docutils literal notranslate"><span class="pre">evennia/web/templates/webclient/base.html</span></code> to
|
||
<code class="docutils literal notranslate"><span class="pre">mygame/web/templates/webclient/base.html</span></code> and editing it to add your new plugin.</p>
|
||
</section>
|
||
<section id="evennia-web-client-api-from-evennia-js">
|
||
<h2>Evennia Web Client API (from evennia.js)<a class="headerlink" href="#evennia-web-client-api-from-evennia-js" title="Permalink to this headline">¶</a></h2>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Evennia.init(</span> <span class="pre">opts</span> <span class="pre">)</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Evennia.connect()</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Evennia.isConnected()</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Evennia.msg(</span> <span class="pre">cmdname,</span> <span class="pre">args,</span> <span class="pre">kwargs,</span> <span class="pre">callback</span> <span class="pre">)</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Evennia.emit(</span> <span class="pre">cmdname,</span> <span class="pre">args,</span> <span class="pre">kwargs</span> <span class="pre">)</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">log()</span></code></p></li>
|
||
</ul>
|
||
</section>
|
||
<section id="plugin-manager-api-from-webclient-gui-js">
|
||
<h2>Plugin Manager API (from webclient_gui.js)<a class="headerlink" href="#plugin-manager-api-from-webclient-gui-js" title="Permalink to this headline">¶</a></h2>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">options</span></code> Object, Stores key/value ‘state’ that can be used by plugins to coordinate behavior.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">plugins</span></code> Object, key/value list of the all the loaded plugins.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">plugin_handler</span></code> Object</p>
|
||
<ul>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">plugin_handler.add("name",</span> <span class="pre">plugin)</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">plugin_handler.onSend(string)</span></code></p></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
<section id="plugin-callbacks-api">
|
||
<h2>Plugin callbacks API<a class="headerlink" href="#plugin-callbacks-api" title="Permalink to this headline">¶</a></h2>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">init()</span></code> – The only required callback</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">boolean</span> <span class="pre">onKeydown(event)</span></code> This plugin listens for Keydown events</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">onBeforeUnload()</span></code> This plugin does something special just before the webclient page/tab is
|
||
closed.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">onLoggedIn(args,</span> <span class="pre">kwargs)</span></code> This plugin does something when the webclient first logs in.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">onGotOptions(args,</span> <span class="pre">kwargs)</span></code> This plugin does something with options sent from the server.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">boolean</span> <span class="pre">onText(args,</span> <span class="pre">kwargs)</span></code> This plugin does something with messages sent from the server.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">boolean</span> <span class="pre">onPrompt(args,</span> <span class="pre">kwargs)</span></code> This plugin does something when the server sends a prompt.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">boolean</span> <span class="pre">onUnknownCmd(cmdname,</span> <span class="pre">args,</span> <span class="pre">kwargs)</span></code> This plugin does something with “unknown commands”.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">onConnectionClose(args,</span> <span class="pre">kwargs)</span></code> This plugin does something when the webclient disconnects from
|
||
the server.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">newstring</span> <span class="pre">onSend(string)</span></code> This plugin examines/alters text that other plugins generate. <strong>Use
|
||
with caution</strong></p></li>
|
||
</ul>
|
||
<p>The order of the plugins defined in <code class="docutils literal notranslate"><span class="pre">base.html</span></code> is important. All the callbacks for each plugin
|
||
will be executed in that order. Functions marked “boolean” above must return true/false. Returning
|
||
true will short-circuit the execution, so no other plugins lower in the base.html list will have
|
||
their callback for this event called. This enables things like the up/down arrow keys for the
|
||
history.js plugin to always occur before the default_in.js plugin adds that key to the current input
|
||
buffer.</p>
|
||
<section id="example-default-plugins-plugins-js">
|
||
<h3>Example/Default Plugins (<code class="docutils literal notranslate"><span class="pre">plugins/*.js</span></code>)<a class="headerlink" href="#example-default-plugins-plugins-js" title="Permalink to this headline">¶</a></h3>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">clienthelp.js</span></code> Defines onOptionsUI from the options2 plugin. This is a mostly empty plugin to
|
||
add some “How To” information for your game.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">default_in.js</span></code> Defines onKeydown. <code class="docutils literal notranslate"><span class="pre"><enter></span></code> key or mouse clicking the arrow will send the currently typed text.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">default_out.js</span></code> Defines onText, onPrompt, and onUnknownCmd. Generates HTML output for the user.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">default_unload.js</span></code> Defines onBeforeUnload. Prompts the user to confirm that they meant to
|
||
leave/close the game.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">font.js</span></code> Defines onOptionsUI. The plugin adds the ability to select your font and font size.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">goldenlayout_default_config.js</span></code> Not actually a plugin, defines a global variable that
|
||
goldenlayout uses to determine its window layout, known tag routing, etc.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">goldenlayout.js</span></code> Defines onKeydown, onText and custom functions. A very powerful “tabbed” window manager for drag-n-drop windows, text routing and more.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">history.js</span></code> Defines onKeydown and onSend. Creates a history of past sent commands, and uses arrow keys to peruse.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">hotbuttons.js</span></code> Defines onGotOptions. A Disabled-by-default plugin that defines a button bar with
|
||
user-assignable commands.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">html.js</span></code> A basic plugin to allow the client to handle “raw html” messages from the server, this
|
||
allows the server to send native HTML messages like >div style=‘s’<styled text>/div<</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">iframe.js</span></code> Defines onOptionsUI. A goldenlayout-only plugin to create a restricted browsing sub-
|
||
window for a side-by-side web/text interface, mostly an example of how to build new HTML
|
||
“components” for goldenlayout.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">message_routing.js</span></code> Defines onOptionsUI, onText, onKeydown. This goldenlayout-only plugin
|
||
implements regex matching to allow users to “tag” arbitrary text that matches, so that it gets
|
||
routed to proper windows. Similar to “Spawn” functions for other clients.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">multimedia.js</span></code> An basic plugin to allow the client to handle “image” “audio” and “video” messages from the server and display them as inline HTML.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">notifications.js</span></code> Defines onText. Generates browser notification events for each new message
|
||
while the tab is hidden.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">oob.js</span></code> Defines onSend. Allows the user to test/send Out Of Band json messages to the server.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">options.js</span></code> Defines most callbacks. Provides a popup-based UI to coordinate options settings with the server.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">options2.js</span></code> Defines most callbacks. Provides a goldenlayout-based version of the options/settings tab. Integrates with other plugins via the custom onOptionsUI callback.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">popups.js</span></code> Provides default popups/Dialog UI for other plugins to use.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">text2html.js</span></code> Provides a new message handler type: <code class="docutils literal notranslate"><span class="pre">text2html</span></code>, similar to the multimedia and html plugins. This plugin provides a way to offload rendering the regular pipe-styled ASCII messages to the client. This allows the server to do less work, while also allowing the client a place to customize this conversion process. To use this plugin you will need to override the current commands in Evennia, changing any place where a raw text output message is generated and turn it into a <code class="docutils literal notranslate"><span class="pre">text2html</span></code> message. For example: <code class="docutils literal notranslate"><span class="pre">target.msg("my</span> <span class="pre">text")</span></code> becomes: <code class="docutils literal notranslate"><span class="pre">target.msg(text2html=("my</span> <span class="pre">text"))</span></code> (even better, use a webclient pane routing tag: <code class="docutils literal notranslate"><span class="pre">target.msg(text2html=("my</span> <span class="pre">text",</span> <span class="pre">{"type":</span> <span class="pre">"sometag"}))</span></code>) <code class="docutils literal notranslate"><span class="pre">text2html</span></code> messages should format and behave identically to the server-side generated text2html() output.</p></li>
|
||
</ul>
|
||
</section>
|
||
<section id="a-side-note-on-html-messages-vs-text2html-messages">
|
||
<h3>A side note on html messages vs text2html messages<a class="headerlink" href="#a-side-note-on-html-messages-vs-text2html-messages" title="Permalink to this headline">¶</a></h3>
|
||
<p>So…lets say you have a desire to make your webclient output more like standard webpages…
|
||
For telnet clients, you could collect a bunch of text lines together, with ASCII formatted borders, etc. Then send the results to be rendered client-side via the text2html plugin.</p>
|
||
<p>But for webclients, you could format a message directly with the html plugin to render the whole thing as an HTML table, like so:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="c1"># Server Side Python Code:</span>
|
||
|
||
<span class="k">if</span> <span class="n">target</span><span class="o">.</span><span class="n">is_webclient</span><span class="p">():</span>
|
||
<span class="c1"># This can be styled however you like using CSS, just add the CSS file to web/static/webclient/css/...</span>
|
||
<span class="n">table</span> <span class="o">=</span> <span class="p">[</span>
|
||
<span class="s2">"<table>"</span><span class="p">,</span>
|
||
<span class="s2">"<tr><td>1</td><td>2</td><td>3</td></tr>"</span><span class="p">,</span>
|
||
<span class="s2">"<tr><td>4</td><td>5</td><td>6</td></tr>"</span><span class="p">,</span>
|
||
<span class="s2">"</table>"</span>
|
||
<span class="p">]</span>
|
||
<span class="n">target</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span> <span class="n">html</span><span class="o">=</span><span class="p">(</span> <span class="s2">""</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">table</span><span class="p">),</span> <span class="p">{</span><span class="s2">"type"</span><span class="p">:</span> <span class="s2">"mytag"</span><span class="p">})</span> <span class="p">)</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="c1"># This will use the client to render this as "plain, simple" ASCII text, the same</span>
|
||
<span class="c1"># as if it was rendered server-side via the Portal's text2html() functions</span>
|
||
<span class="n">table</span> <span class="o">=</span> <span class="p">[</span>
|
||
<span class="s2">"#############"</span><span class="p">,</span>
|
||
<span class="s2">"# 1 # 2 # 3 #"</span><span class="p">,</span>
|
||
<span class="s2">"#############"</span><span class="p">,</span>
|
||
<span class="s2">"# 4 # 5 # 6 #"</span><span class="p">,</span>
|
||
<span class="s2">"#############"</span>
|
||
<span class="p">]</span>
|
||
<span class="n">target</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span> <span class="n">html2html</span><span class="o">=</span><span class="p">(</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">table</span><span class="p">),</span> <span class="p">{</span><span class="s2">"type"</span><span class="p">:</span> <span class="s2">"mytag"</span><span class="p">})</span> <span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
</section>
|
||
<section id="writing-your-own-plugins">
|
||
<h2>Writing your own Plugins<a class="headerlink" href="#writing-your-own-plugins" title="Permalink to this headline">¶</a></h2>
|
||
<p>So, you love the functionality of the webclient, but your game has specific
|
||
types of text that need to be separated out into their own space, visually.
|
||
The Goldenlayout plugin framework can help with this.</p>
|
||
<section id="goldenlayout">
|
||
<h3>GoldenLayout<a class="headerlink" href="#goldenlayout" title="Permalink to this headline">¶</a></h3>
|
||
<p>GoldenLayout is a web framework that allows web developers and their users to create their own
|
||
tabbed/windowed layouts. Windows/tabs can be click-and-dragged from location to location by
|
||
clicking on their titlebar and dragging until the “frame lines” appear. Dragging a window onto
|
||
another window’s titlebar will create a tabbed “Stack”. The Evennia goldenlayout plugin defines 3
|
||
basic types of window: The Main window, input windows and non-main text output windows. The Main
|
||
window and the first input window are unique in that they can’t be “closed”.</p>
|
||
<p>The most basic customization is to provide your users with a default layout other than just one Main
|
||
output and the one starting input window. This is done by modifying your server’s
|
||
goldenlayout_default_config.js.</p>
|
||
<p>Start by creating a new
|
||
<code class="docutils literal notranslate"><span class="pre">mygame/web/static/webclient/js/plugins/goldenlayout_default_config.js</span></code> file, and adding
|
||
the following JSON variable:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">var</span> <span class="n">goldenlayout_config</span> <span class="o">=</span> <span class="p">{</span>
|
||
<span class="n">content</span><span class="p">:</span> <span class="p">[{</span>
|
||
<span class="nb">type</span><span class="p">:</span> <span class="s1">'column'</span><span class="p">,</span>
|
||
<span class="n">content</span><span class="p">:</span> <span class="p">[{</span>
|
||
<span class="nb">type</span><span class="p">:</span> <span class="s1">'row'</span><span class="p">,</span>
|
||
<span class="n">content</span><span class="p">:</span> <span class="p">[{</span>
|
||
<span class="nb">type</span><span class="p">:</span> <span class="s1">'column'</span><span class="p">,</span>
|
||
<span class="n">content</span><span class="p">:</span> <span class="p">[{</span>
|
||
<span class="nb">type</span><span class="p">:</span> <span class="s1">'component'</span><span class="p">,</span>
|
||
<span class="n">componentName</span><span class="p">:</span> <span class="s1">'Main'</span><span class="p">,</span>
|
||
<span class="n">isClosable</span><span class="p">:</span> <span class="n">false</span><span class="p">,</span>
|
||
<span class="n">tooltip</span><span class="p">:</span> <span class="s1">'Main - drag to desired position.'</span><span class="p">,</span>
|
||
<span class="n">componentState</span><span class="p">:</span> <span class="p">{</span>
|
||
<span class="n">cssClass</span><span class="p">:</span> <span class="s1">'content'</span><span class="p">,</span>
|
||
<span class="n">types</span><span class="p">:</span> <span class="s1">'untagged'</span><span class="p">,</span>
|
||
<span class="n">updateMethod</span><span class="p">:</span> <span class="s1">'newlines'</span><span class="p">,</span>
|
||
<span class="p">},</span>
|
||
<span class="p">},</span> <span class="p">{</span>
|
||
<span class="nb">type</span><span class="p">:</span> <span class="s1">'component'</span><span class="p">,</span>
|
||
<span class="n">componentName</span><span class="p">:</span> <span class="s1">'input'</span><span class="p">,</span>
|
||
<span class="nb">id</span><span class="p">:</span> <span class="s1">'inputComponent'</span><span class="p">,</span>
|
||
<span class="n">height</span><span class="p">:</span> <span class="mi">10</span><span class="p">,</span>
|
||
<span class="n">tooltip</span><span class="p">:</span> <span class="s1">'Input - The last input in the layout is always the default.'</span><span class="p">,</span>
|
||
<span class="p">},</span> <span class="p">{</span>
|
||
<span class="nb">type</span><span class="p">:</span> <span class="s1">'component'</span><span class="p">,</span>
|
||
<span class="n">componentName</span><span class="p">:</span> <span class="s1">'input'</span><span class="p">,</span>
|
||
<span class="nb">id</span><span class="p">:</span> <span class="s1">'inputComponent'</span><span class="p">,</span>
|
||
<span class="n">height</span><span class="p">:</span> <span class="mi">10</span><span class="p">,</span>
|
||
<span class="n">isClosable</span><span class="p">:</span> <span class="n">false</span><span class="p">,</span>
|
||
<span class="n">tooltip</span><span class="p">:</span> <span class="s1">'Input - The last input in the layout is always the default.'</span><span class="p">,</span>
|
||
<span class="p">}]</span>
|
||
<span class="p">},{</span>
|
||
<span class="nb">type</span><span class="p">:</span> <span class="s1">'column'</span><span class="p">,</span>
|
||
<span class="n">content</span><span class="p">:</span> <span class="p">[{</span>
|
||
<span class="nb">type</span><span class="p">:</span> <span class="s1">'component'</span><span class="p">,</span>
|
||
<span class="n">componentName</span><span class="p">:</span> <span class="s1">'evennia'</span><span class="p">,</span>
|
||
<span class="n">componentId</span><span class="p">:</span> <span class="s1">'evennia'</span><span class="p">,</span>
|
||
<span class="n">title</span><span class="p">:</span> <span class="s1">'example'</span><span class="p">,</span>
|
||
<span class="n">height</span><span class="p">:</span> <span class="mi">60</span><span class="p">,</span>
|
||
<span class="n">isClosable</span><span class="p">:</span> <span class="n">false</span><span class="p">,</span>
|
||
<span class="n">componentState</span><span class="p">:</span> <span class="p">{</span>
|
||
<span class="n">types</span><span class="p">:</span> <span class="s1">'some-tag-here'</span><span class="p">,</span>
|
||
<span class="n">updateMethod</span><span class="p">:</span> <span class="s1">'newlines'</span><span class="p">,</span>
|
||
<span class="p">},</span>
|
||
<span class="p">},</span> <span class="p">{</span>
|
||
<span class="nb">type</span><span class="p">:</span> <span class="s1">'component'</span><span class="p">,</span>
|
||
<span class="n">componentName</span><span class="p">:</span> <span class="s1">'evennia'</span><span class="p">,</span>
|
||
<span class="n">componentId</span><span class="p">:</span> <span class="s1">'evennia'</span><span class="p">,</span>
|
||
<span class="n">title</span><span class="p">:</span> <span class="s1">'sheet'</span><span class="p">,</span>
|
||
<span class="n">isClosable</span><span class="p">:</span> <span class="n">false</span><span class="p">,</span>
|
||
<span class="n">componentState</span><span class="p">:</span> <span class="p">{</span>
|
||
<span class="n">types</span><span class="p">:</span> <span class="s1">'sheet'</span><span class="p">,</span>
|
||
<span class="n">updateMethod</span><span class="p">:</span> <span class="s1">'replace'</span><span class="p">,</span>
|
||
<span class="p">},</span>
|
||
<span class="p">}],</span>
|
||
<span class="p">}],</span>
|
||
<span class="p">}]</span>
|
||
<span class="p">}]</span>
|
||
<span class="p">};</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>This is a bit ugly, but hopefully, from the indentation, you can see that it creates a side-by-side
|
||
(2-column) interface with 3 windows down the left side (The Main and 2 inputs) and a pair of windows
|
||
on the right side for extra outputs. Any text tagged with “some-tag-here” will flow to the bottom
|
||
of the “example” window, and any text tagged “sheet” will replace the text already in the “sheet”
|
||
window.</p>
|
||
<p>Note: GoldenLayout gets VERY confused and will break if you create two windows with the “Main”
|
||
componentName.</p>
|
||
<p>Now, let’s say you want to display text on each window using different CSS. This is where new
|
||
goldenlayout “components” come in. Each component is like a blueprint that gets stamped out when
|
||
you create a new instance of that component, once it is defined, it won’t be easily altered. You
|
||
will need to define a new component, preferably in a new plugin file, and then add that into your
|
||
page (either dynamically to the DOM via javascript, or by including the new plugin file into the
|
||
base.html).</p>
|
||
<p>First up, follow the directions in Customizing the Web Client section above to override the
|
||
base.html.</p>
|
||
<p>Next, add the new plugin to your copy of base.html:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o"><</span><span class="n">script</span> <span class="n">src</span><span class="o">=</span><span class="p">{</span><span class="o">%</span> <span class="n">static</span> <span class="s2">"webclient/js/plugins/myplugin.js"</span> <span class="o">%</span><span class="p">}</span> <span class="n">language</span><span class="o">=</span><span class="s2">"javascript"</span>
|
||
<span class="nb">type</span><span class="o">=</span><span class="s2">"text/javascript"</span><span class="o">></</span><span class="n">script</span><span class="o">></span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Remember, plugins are load-order dependent, so make sure the new <code class="docutils literal notranslate"><span class="pre"><script></span></code> tag comes before the <code class="docutils literal notranslate"><span class="pre">goldenlayout.js</span></code>.</p>
|
||
<p>Next, create a new plugin file <code class="docutils literal notranslate"><span class="pre">mygame/web/static/webclient/js/plugins/myplugin.js</span></code> and
|
||
edit it.</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>let myplugin = (function () {
|
||
//
|
||
//
|
||
var postInit = function() {
|
||
var myLayout = window.plugins['goldenlayout'].getGL();
|
||
|
||
// register our component and replace the default messagewindow
|
||
myLayout.registerComponent( 'mycomponent', function (container, componentState) {
|
||
let mycssdiv = $('<div>').addClass('myCSS');
|
||
mycssdiv.attr('types', 'mytag');
|
||
mycssdiv.attr('update_method', 'newlines');
|
||
mycssdiv.appendTo( container.getElement() );
|
||
});
|
||
|
||
console.log("MyPlugin Initialized.");
|
||
}
|
||
|
||
return {
|
||
init: function () {},
|
||
postInit: postInit,
|
||
}
|
||
})();
|
||
window.plugin_handler.add("myplugin", myplugin);
|
||
</pre></div>
|
||
</div>
|
||
<p>You can then add “mycomponent” to an item’s <code class="docutils literal notranslate"><span class="pre">componentName</span></code> in your <code class="docutils literal notranslate"><span class="pre">goldenlayout_default_config.js</span></code>.</p>
|
||
<p>Make sure to stop your server, evennia collectstatic, and restart your server. Then make sure to clear your browser cache before loading the webclient page.</p>
|
||
</section>
|
||
</section>
|
||
</section>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
</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="right" >
|
||
<a href="Web-Admin.html" title="The Web Admin"
|
||
>next</a> |</li>
|
||
<li class="right" >
|
||
<a href="Website.html" title="Game website"
|
||
>previous</a> |</li>
|
||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 3.x</a> »</li>
|
||
<li class="nav-item nav-item-1"><a href="Components-Overview.html" >Core Components</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">Web Client</a></li>
|
||
</ul>
|
||
</div>
|
||
|
||
|
||
<div class="admonition important">
|
||
<p class="first admonition-title">Note</p>
|
||
<p class="last">You are reading an old version of the Evennia documentation. <a href="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
|
||
</div>
|
||
|
||
|
||
<div class="footer" role="contentinfo">
|
||
© Copyright 2023, The Evennia developer community.
|
||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
||
</div>
|
||
</body>
|
||
</html> |