enigma-bbs/modding/menu-modules.html

2577 lines
37 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset='utf-8'>
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/png" sizes="16x16" href="/enigma-bbs/assets/images/favicon-16x16.png">
<link rel="icon" type="image/png" sizes="32x32" href="/enigma-bbs/assets/images/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="32x32" href="/enigma-bbs/assets/images/favicon-32x32.png">
<link rel="stylesheet" href="/enigma-bbs/assets/css/style.css?v=">
<!-- Begin Jekyll SEO tag v2.7.1 -->
<title>Menu Modules | ENiGMA½ BBS Software</title>
<meta name="generator" content="Jekyll v4.2.1" />
<meta property="og:title" content="Menu Modules" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="Menu Modules From initial connection to the screens and mods your users interact with, the entire experience is made up of menu entries — And all menu entries found within menu.hjson are backed by Menu Modules. For basic menus, a standard handler is implemented requiring no code. However, if you would like to create a menu that has custom handling, you will very likely be inheriting from from MenuModule. More on this below." />
<meta property="og:description" content="Menu Modules From initial connection to the screens and mods your users interact with, the entire experience is made up of menu entries — And all menu entries found within menu.hjson are backed by Menu Modules. For basic menus, a standard handler is implemented requiring no code. However, if you would like to create a menu that has custom handling, you will very likely be inheriting from from MenuModule. More on this below." />
<meta property="og:site_name" content="ENiGMA½ BBS Software" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2022-10-10T17:24:41+00:00" />
<meta name="twitter:card" content="summary" />
<meta property="twitter:title" content="Menu Modules" />
<script type="application/ld+json">
{"description":"Menu Modules From initial connection to the screens and mods your users interact with, the entire experience is made up of menu entries — And all menu entries found within menu.hjson are backed by Menu Modules. For basic menus, a standard handler is implemented requiring no code. However, if you would like to create a menu that has custom handling, you will very likely be inheriting from from MenuModule. More on this below.","url":"/enigma-bbs/modding/menu-modules.html","@type":"BlogPosting","mainEntityOfPage":{"@type":"WebPage","@id":"/enigma-bbs/modding/menu-modules.html"},"publisher":{"@type":"Organization","logo":{"@type":"ImageObject","url":"/enigma-bbs/assets/images/enigma-logo.png"}},"headline":"Menu Modules","dateModified":"2022-10-10T17:24:41+00:00","datePublished":"2022-10-10T17:24:41+00:00","@context":"https://schema.org"}</script>
<!-- End Jekyll SEO tag -->
</head>
<body>
<div id="container">
<div class="sidebar" id="sidebar">
<hr class="mobile-divide">
<div class="container">
<a href="/enigma-bbs/"><img src="/enigma-bbs/assets/images/enigma-logo.png" class="logo" alt="Enigma logo"></a>
</div>
<ul>
<li>Installation</li>
<ul>
<li><a href="/enigma-bbs/installation/installation-methods.html">Installation Methods</a></li>
<li><a href="/enigma-bbs/installation/install-script.html">Install Script</a></li>
<li><a href="/enigma-bbs/installation/docker.html">Docker</a></li>
<li><a href="/enigma-bbs/installation/manual.html">Manual Installation</a></li>
<li>OS / Hardware Specific</li>
<ul>
<li><a href="/enigma-bbs/installation/hardware/rpi.html">Raspberry Pi</a></li>
<li><a href="/enigma-bbs/installation/hardware/windows.html">Installation Under Windows</a></li>
</ul>
<li><a href="/enigma-bbs/installation/network.html">Network Setup</a></li>
<li><a href="/enigma-bbs/installation/testing.html">Testing Your Installation</a></li>
<li><a href="/enigma-bbs/installation/production.html">Production Installation</a></li>
</ul>
<li>Configuration</li>
<ul>
<li><a href="/enigma-bbs/configuration/creating-config.html">Creating Initial Config Files</a></li>
<li><a href="/enigma-bbs/configuration/sysop-setup.html">SysOp Setup</a></li>
<li><a href="/enigma-bbs/configuration/config-files.html">Configuration Files</a></li>
<li><a href="/enigma-bbs/configuration/config-hjson.html">System Configuration</a></li>
<li><a href="/enigma-bbs/configuration/hjson.html">HJSON Config Files</a></li>
<li><a href="/enigma-bbs/configuration/menu-hjson.html">Menu HSJON</a></li>
<li><a href="/enigma-bbs/configuration/directory-structure.html">Directory Structure</a></li>
<li><a href="/enigma-bbs/configuration/external-binaries.html">External Support Binaries</a></li>
<li><a href="/enigma-bbs/configuration/archivers.html">Archivers</a></li>
<li><a href="/enigma-bbs/configuration/file-transfer-protocols.html">File Transfer Protocols</a></li>
<li><a href="/enigma-bbs/configuration/email.html">Email</a></li>
<li><a href="/enigma-bbs/configuration/colour-codes.html">Colour Codes</a></li>
<li><a href="/enigma-bbs/configuration/event-scheduler.html">Event Scheduler</a></li>
<li><a href="/enigma-bbs/configuration/acs.html">Access Condition System (ACS)</a></li>
<li><a href="/enigma-bbs/configuration/security.html">Security</a></li>
</ul>
<li>Miscellaneous</li>
<ul>
<li><a href="/enigma-bbs/misc/user-interrupt.html">User Interruptions</a></li>
</ul>
<li>File Base</li>
<ul>
<li><a href="/enigma-bbs/filebase/index.html">About File Areas</a></li>
<li><a href="/enigma-bbs/filebase/first-file-area.html">Configuring a File Base</a></li>
<li><a href="/enigma-bbs/filebase/acs.html">ACS</a></li>
<li><a href="/enigma-bbs/filebase/uploads.html">Uploads</a></li>
<li><a href="/enigma-bbs/filebase/web-access.html">Web Access</a></li>
<li><a href="/enigma-bbs/filebase/tic-support.html">TIC Support</a></li>
<li><a href="/enigma-bbs/filebase/network-mounts-and-symlinks.html">Network Mounts &amp; Symlinks</a></li>
</ul>
<li>Message Areas</li>
<ul>
<li><a href="/enigma-bbs/messageareas/configuring-a-message-area.html">Message Base</a></li>
<li><a href="/enigma-bbs/messageareas/message-networks.html">Message Networks</a></li>
<li><a href="/enigma-bbs/messageareas/bso-import-export.html">BSO Import / Export</a></li>
<li><a href="/enigma-bbs/messageareas/netmail.html">Netmail</a></li>
<li><a href="/enigma-bbs/messageareas/qwk.html">QWK Support</a></li>
<li><a href="/enigma-bbs/messageareas/ftn.html">FidoNet-Style Networks (FTN)</a></li>
</ul>
<li>Art</li>
<ul>
<li><a href="/enigma-bbs/art/general.html">General Art Information</a></li>
<li><a href="/enigma-bbs/art/themes.html">Themes</a></li>
<li><a href="/enigma-bbs/art/mci.html">MCI Codes</a></li>
<li>Views</li>
<ul>
<li><a href="/enigma-bbs/art/views/button_view.html">Button View</a></li>
<li><a href="/enigma-bbs/art/views/edit_text_view.html">Edit Text View</a></li>
<li><a href="/enigma-bbs/art/views/full_menu_view.html">Full Menu View</a></li>
<li><a href="/enigma-bbs/art/views/horizontal_menu_view.html">Horizontal Menu View</a></li>
<li><a href="/enigma-bbs/art/views/mask_edit_text_view.html">Mask Edit Text View</a></li>
<li><a href="/enigma-bbs/art/views/multi_line_edit_text_view.html">Multi Line Edit Text View</a></li>
<li><a href="/enigma-bbs/art/views/predefined_label_view.html">Predefined Label View</a></li>
<li><a href="/enigma-bbs/art/views/spinner_menu_view.html">Spinner Menu View</a></li>
<li><a href="/enigma-bbs/art/views/text_view.html">Text View</a></li>
<li><a href="/enigma-bbs/art/views/toggle_menu_view.html">Toggle Menu View</a></li>
<li><a href="/enigma-bbs/art/views/vertical_menu_view.html">Vertical Menu View</a></li>
</ul>
</ul>
<li>Servers</li>
<ul>
<li>Login Servers</li>
<ul>
<li><a href="/enigma-bbs/servers/loginservers/telnet.html">Telnet Server</a></li>
<li><a href="/enigma-bbs/servers/loginservers/ssh.html">SSH Server</a></li>
<li><a href="/enigma-bbs/servers/loginservers/websocket.html">Web Socket / Web Interface Server</a></li>
</ul>
<li>Content Servers</li>
<ul>
<li><a href="/enigma-bbs/servers/contentservers/web-server.html">Web Server</a></li>
<li><a href="/enigma-bbs/servers/contentservers/gopher.html">Gopher Server</a></li>
<li><a href="/enigma-bbs/servers/contentservers/nntp.html">NNTP Server</a></li>
</ul>
</ul>
<li>Modding</li>
<ul>
<li><a href="/enigma-bbs/modding/local-doors.html">Local Doors</a></li>
<li><a href="/enigma-bbs/modding/door-servers.html">Door Servers</a></li>
<li><a href="/enigma-bbs/modding/telnet-bridge.html">Telnet Bridge</a></li>
<li><a href="/enigma-bbs/modding/existing-mods.html">Existing Mods</a></li>
<li><a href="/enigma-bbs/modding/file-area-list.html">File Area List</a></li>
<li><a href="/enigma-bbs/modding/last-callers.html">Last Callers</a></li>
<li><a href="/enigma-bbs/modding/whos-online.html">Who's Online</a></li>
<li><a href="/enigma-bbs/modding/user-list.html">User List</a></li>
<li><a href="/enigma-bbs/modding/msg-conf-list.html">Message Conference List</a></li>
<li><a href="/enigma-bbs/modding/msg-area-list.html">Message Area List</a></li>
<li><a href="/enigma-bbs/modding/bbs-list.html">BBS List</a></li>
<li><a href="/enigma-bbs/modding/rumorz.html">Rumorz</a></li>
<li><a href="/enigma-bbs/modding/file-transfer-protocol-select.html">File Transfer Protocol Select</a></li>
<li><a href="/enigma-bbs/modding/onelinerz.html">Onelinerz</a></li>
<li><a href="/enigma-bbs/modding/show-art.html">The Show Art Module</a></li>
<li><a href="/enigma-bbs/modding/file-base-download-manager.html">File Base Download Manager</a></li>
<li><a href="/enigma-bbs/modding/file-base-web-download-manager.html">File Base Web Download Manager</a></li>
<li><a href="/enigma-bbs/modding/set-newscan-date.html">Set Newscan Date Module</a></li>
<li><a href="/enigma-bbs/modding/node-msg.html">Node to Node Messaging</a></li>
<li><a href="/enigma-bbs/modding/top-x.html">TopX</a></li>
<li><a href="/enigma-bbs/modding/user-2fa-otp-config.html">2FA/OTP Config</a></li>
<li><a href="/enigma-bbs/modding/autosig-edit.html">Auto Signature Editor</a></li>
<li class="active-nav">Menu Modules</li>
</ul>
<li>Administration</li>
<ul>
<li><a href="/enigma-bbs/admin/administration.html">Administration</a></li>
</ul>
<li>Modding</li>
<ul>
<li><a href="/enigma-bbs/modding/wfc.html">Waiting For Caller (WFC)</a></li>
</ul>
<li>Administration</li>
<ul>
<li><a href="/enigma-bbs/admin/oputil.html">oputil</a></li>
<li><a href="/enigma-bbs/admin/updating.html">Updating</a></li>
</ul>
<li>Troubleshooting</li>
<ul>
<li><a href="/enigma-bbs/troubleshooting/monitoring-logs.html">Monitoring Logs</a></li>
</ul>
</ul>
</div>
<div class="main_area">
<div class="container">
<section id="main_content">
<div class="PageNavigation">
<a class="btn" style="float:left;margin-right: 20px;" href="/enigma-bbs/modding/autosig-edit.html">« Auto Signature Editor</a>
<a href="#sidebar" class="btn menu_button">MENU</a>
<a class="btn" style="float: right;margin-left: 20px" href="/enigma-bbs/admin/administration.html">Administration »</a>
<br clear="both">
</div>
<div class="page">
<h1 class="page-title">Menu Modules</h1>
<h2 id="menu-modules">Menu Modules</h2>
<p>From initial connection to the screens and mods your users interact with, the entire experience is made up of menu entries — And all menu entries found within <a href="/enigma-bbs/configuration/menu-hjson.html">menu.hjson</a> are backed by <em>Menu Modules</em>. For basic menus, a standard handler is implemented requiring no code. However, if you would like to create a menu that has custom handling, you will very likely be inheriting from from <code class="language-plaintext highlighter-rouge">MenuModule</code>. More on this below.</p>
<blockquote>
<p><img class="emoji" title=":information_source:" alt=":information_source:" src="https://github.githubassets.com/images/icons/emoji/unicode/2139.png" height="20" width="20"> Remember that ENiGMA does not impose any stucture to your system! The “flow” of all <code class="language-plaintext highlighter-rouge">menu.hjson</code> entries is up to you!</p>
</blockquote>
<blockquote>
<p><img class="emoji" title=":bulb:" alt=":bulb:" src="https://github.githubassets.com/images/icons/emoji/unicode/1f4a1.png" height="20" width="20"> If the <code class="language-plaintext highlighter-rouge">module</code> entry is not present in a <code class="language-plaintext highlighter-rouge">menu.hjson</code> entry, the system automatically uses <a href="/core/standard_menu.js">standard_menu.js</a>.</p>
</blockquote>
<h2 id="creating-a-new-module">Creating a New Module</h2>
<p>At the highest level, to create a new custom menu or mod, inherit from <code class="language-plaintext highlighter-rouge">MenuModule</code> and expose it via the <code class="language-plaintext highlighter-rouge">getModule</code> exported method:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// my_fancy_module.js</span>
<span class="nx">exports</span><span class="p">.</span><span class="nx">getModule</span> <span class="o">=</span> <span class="kd">class</span> <span class="nx">MyFancyModule</span> <span class="kd">extends</span> <span class="nx">MenuModule</span> <span class="p">{</span>
<span class="kd">constructor</span><span class="p">(</span><span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="k">super</span><span class="p">(</span><span class="nx">options</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">};</span>
</code></pre></div></div>
<p>Next, override the appropriate methods to add some functionality! Below is an example fragment overriding just <code class="language-plaintext highlighter-rouge">initSequence()</code>:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">initSequence</span><span class="p">()</span> <span class="p">{</span>
<span class="k">async</span><span class="p">.</span><span class="nx">series</span><span class="p">(</span>
<span class="p">[</span>
<span class="nx">callback</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="c1">// call base method</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">beforeArt</span><span class="p">(</span><span class="nx">callback</span><span class="p">);</span>
<span class="p">},</span>
<span class="nx">callback</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="c1">// a private method to display a main "page"</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_displayMainPage</span><span class="p">(</span><span class="kc">false</span><span class="p">,</span> <span class="nx">callback</span><span class="p">);</span>
<span class="p">},</span>
<span class="p">],</span>
<span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">finishedLoading</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<blockquote>
<p><img class="emoji" title=":bulb:" alt=":bulb:" src="https://github.githubassets.com/images/icons/emoji/unicode/1f4a1.png" height="20" width="20"> Remember that <em>all</em> menus within ENiGMA are created by inheriting from <code class="language-plaintext highlighter-rouge">MenuModule</code>. Take a look at existing examples such as <a href="/core/wfc.js">WFC</a>, <a href="/core/nua.js">NUA</a>, <a href="/core/mrc.js">MRC</a> and more!</p>
</blockquote>
<h3 id="moduleinfo">ModuleInfo</h3>
<p>To register your module with the system, include a <code class="language-plaintext highlighter-rouge">moduleInfo</code> declaration in your exports. The following members are available:</p>
<table>
<thead>
<tr>
<th>Field</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="language-plaintext highlighter-rouge">name</code></td>
<td><img class="emoji" title=":+1:" alt=":+1:" src="https://github.githubassets.com/images/icons/emoji/unicode/1f44d.png" height="20" width="20"></td>
<td>Short name of the module</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">desc</code></td>
<td><img class="emoji" title=":+1:" alt=":+1:" src="https://github.githubassets.com/images/icons/emoji/unicode/1f44d.png" height="20" width="20"></td>
<td>Long description of this module</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">author</code></td>
<td><img class="emoji" title=":+1:" alt=":+1:" src="https://github.githubassets.com/images/icons/emoji/unicode/1f44d.png" height="20" width="20"></td>
<td>Author(s) of module</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">packageName</code></td>
<td><img class="emoji" title=":-1:" alt=":-1:" src="https://github.githubassets.com/images/icons/emoji/unicode/1f44e.png" height="20" width="20"></td>
<td>Defines a reverse DNS style package name. Can be used in conjunction with the <code class="language-plaintext highlighter-rouge">getModDatabasePath()</code> call form <a href="/core/database.js">database.js</a> to interact with a database specific to your module (See example below)</td>
</tr>
</tbody>
</table>
<p><strong>Example</strong>:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">exports</span><span class="p">.</span><span class="nx">moduleInfo</span> <span class="o">=</span> <span class="p">{</span>
<span class="na">name</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Super Dope Mod</span><span class="dl">'</span><span class="p">,</span>
<span class="na">desc</span><span class="p">:</span> <span class="dl">'</span><span class="s1">...a super dope mod, duh.</span><span class="dl">'</span><span class="p">,</span>
<span class="na">author</span><span class="p">:</span> <span class="dl">'</span><span class="s1">You!</span><span class="dl">'</span><span class="p">,</span>
<span class="na">packageName</span><span class="p">:</span> <span class="s2">`com.myname.foo.super-dope-mod`</span><span class="p">,</span>
<span class="p">};</span>
</code></pre></div></div>
<h3 id="per-mod-databases">Per-Mod Databases</h3>
<p>Custom mods often need their own data persistence. This can be acheived with <code class="language-plaintext highlighter-rouge">getModDatabsePath()</code> and your <code class="language-plaintext highlighter-rouge">moduleInfo</code>s <code class="language-plaintext highlighter-rouge">packageName</code>.</p>
<p><strong>Example</strong>:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">self</span><span class="p">.</span><span class="nx">database</span> <span class="o">=</span> <span class="nx">getTransactionDatabase</span><span class="p">(</span>
<span class="k">new</span> <span class="nx">sqlite3</span><span class="p">.</span><span class="nx">Database</span><span class="p">(</span><span class="nx">getModDatabasePath</span><span class="p">(</span><span class="nx">moduleInfo</span><span class="p">),</span> <span class="nx">callback</span><span class="p">)</span>
<span class="p">);</span>
</code></pre></div></div>
<p>Given the <code class="language-plaintext highlighter-rouge">packageName</code> above, a database will be created at the following location:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$enigma</span><span class="nt">-bbs</span>/db/mods/com.myname.foo.super-dope-mod.sqlite3
</code></pre></div></div>
<h3 id="menu-methods">Menu Methods</h3>
<p>Form handler methods specified by <code class="language-plaintext highlighter-rouge">@method:someName</code> in your <code class="language-plaintext highlighter-rouge">menu.hjson</code> entries map to those found in your modules <code class="language-plaintext highlighter-rouge">menuMethods</code> object. That is, <code class="language-plaintext highlighter-rouge">this.menuMethods</code> and have the following signature <code class="language-plaintext highlighter-rouge">(formData, extraArgs, cb)</code>. For example, consider the following <code class="language-plaintext highlighter-rouge">menu.hjson</code> fragment:</p>
<pre><code class="language-hjson">actionKeys: [
{
keys: [ "a", "shift + a" ]
action: @method:toggleAvailable
}
]
</code></pre>
<p>We can handle this in our module as such:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">exports</span><span class="p">.</span><span class="nx">getModule</span> <span class="o">=</span> <span class="kd">class</span> <span class="nx">MyFancyModule</span> <span class="kd">extends</span> <span class="nx">MenuModule</span> <span class="p">{</span>
<span class="kd">constructor</span><span class="p">(</span><span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="k">super</span><span class="p">(</span><span class="nx">options</span><span class="p">);</span>
<span class="k">this</span><span class="p">.</span><span class="nx">menuMethods</span> <span class="o">=</span> <span class="p">{</span>
<span class="na">toggleAvailable</span><span class="p">:</span> <span class="p">(</span><span class="nx">formData</span><span class="p">,</span> <span class="nx">extraArgs</span><span class="p">,</span> <span class="nx">cb</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="c1">// ...do something fancy...</span>
<span class="k">return</span> <span class="nx">cb</span><span class="p">(</span><span class="kc">null</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">};</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h2 id="menumodule-lifecycle">MenuModule Lifecycle</h2>
<p>Below is a very high level diagram showing the basic lifecycle of a MenuModule.</p>
<p><img src="/enigma-bbs/assets/images/basic_menu_lifecycle.png" alt="Basic Menu Lifecycle"></p>
<p>Methods indicated above with <code class="language-plaintext highlighter-rouge">()</code> in their name such as <code class="language-plaintext highlighter-rouge">enter()</code> are overridable when inheriting form <code class="language-plaintext highlighter-rouge">MenuModule</code>.</p>
<ul>
<li>
<code class="language-plaintext highlighter-rouge">enter()</code> is the first to be called. There is no callback. The default implementation is to simply call <code class="language-plaintext highlighter-rouge">this.initSequence()</code>.</li>
<li>
<code class="language-plaintext highlighter-rouge">displayQueuedInterruptions(callback)</code> is called, and if interruptions are allowed for this menu, any that may be queued will be displayed first.</li>
<li>
<code class="language-plaintext highlighter-rouge">beforeArt(callback)</code> is called before any art is displayed. The default implementation will set emulated baud rate, and clear the screen if either are requested by the menus <code class="language-plaintext highlighter-rouge">config</code> block.</li>
<li>
<code class="language-plaintext highlighter-rouge">mciReady(mciData, callback)</code> is called when art is loaded and MCI codes are initialized. The default implementation of a custom <code class="language-plaintext highlighter-rouge">MenuModule</code> simply continues. See also <a href="#standardmcireadyhandlermcidata-callback">standardMCIReadyHandler</a>.</li>
</ul>
<h2 id="menumodule-helper-methods">MenuModule Helper Methods</h2>
<p>Many helper methods exist and are available to code inheriting from <code class="language-plaintext highlighter-rouge">MenuModule</code>. Below are some examples. Poke around at <a href="../../../core/menu_module.js">menu_module.js</a> to discover more!</p>
<h3 id="views--view-controller">Views &amp; View Controller</h3>
<h4 id="displayassetname--buffer-options-callback">
<code class="language-plaintext highlighter-rouge">displayAsset(name | Buffer, options, callback)</code>:</h4>
<p>Display an asset by <code class="language-plaintext highlighter-rouge">name</code> or by supplying an <code class="language-plaintext highlighter-rouge">Buffer</code>.
<code class="language-plaintext highlighter-rouge">options</code> is an optional Object with any of the following properties:</p>
<ul>
<li>
<code class="language-plaintext highlighter-rouge">clearScreen</code> (Boolean): Should the screen be cleared first?</li>
<li>
<code class="language-plaintext highlighter-rouge">encoding</code> (String): Encoding of <code class="language-plaintext highlighter-rouge">Buffer</code> if used. Defaults to <code class="language-plaintext highlighter-rouge">cp437</code>.</li>
<li>
<code class="language-plaintext highlighter-rouge">font</code> (String): SyncTERM style font to use.</li>
<li>
<code class="language-plaintext highlighter-rouge">trailingLF</code> (Boolean): Should a trailing LF be allowed?</li>
<li>
<code class="language-plaintext highlighter-rouge">startRow</code> (Number): Row in which to start drawing at</li>
</ul>
<h4 id="prepviewcontrollername-formid-mcimap-callback">
<code class="language-plaintext highlighter-rouge">prepViewController(name, formId, mciMap, callback)</code>:</h4>
<p>Prepares the menus View Controller for a form of <code class="language-plaintext highlighter-rouge">name</code> and <code class="language-plaintext highlighter-rouge">formId</code> using the supplied <code class="language-plaintext highlighter-rouge">mciMap</code>. <code class="language-plaintext highlighter-rouge">callback</code> has the following siguature: <code class="language-plaintext highlighter-rouge">(err, viewController, created)</code> where <code class="language-plaintext highlighter-rouge">created</code> is <code class="language-plaintext highlighter-rouge">true</code> if a new View Controller was made.</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">prepViewControllerWithArt()</code></li>
<li><code class="language-plaintext highlighter-rouge">displayArtAndPrepViewController()</code></li>
<li><code class="language-plaintext highlighter-rouge">setViewText()</code></li>
<li><code class="language-plaintext highlighter-rouge">getView()</code></li>
<li><code class="language-plaintext highlighter-rouge">updateCustomViewTextsWithFilter()</code></li>
<li><code class="language-plaintext highlighter-rouge">refreshPredefinedMciViewsByCode()</code></li>
</ul>
<h3 id="validation">Validation</h3>
<ul>
<li><code class="language-plaintext highlighter-rouge">validateMCIByViewIds()</code></li>
<li><code class="language-plaintext highlighter-rouge">validateConfigFields()</code></li>
</ul>
<h3 id="datetime-helpers">Date/Time Helpers</h3>
<p>The following methods take a single input to specify style, defaulting to <code class="language-plaintext highlighter-rouge">short</code>. If your menu or theme <code class="language-plaintext highlighter-rouge">config</code> block specifies a cooresponding value such as <code class="language-plaintext highlighter-rouge">dateFormat</code> or <code class="language-plaintext highlighter-rouge">dateTimeFormat</code>, that value will be used, else standard fallbacks apply:</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">getDateFormat()</code></li>
<li><code class="language-plaintext highlighter-rouge">getTimeFormat()</code></li>
<li><code class="language-plaintext highlighter-rouge">getDateTimeFormat()</code></li>
</ul>
<h3 id="misc">Misc</h3>
<ul>
<li><code class="language-plaintext highlighter-rouge">promptForInput()</code></li>
</ul>
<h4 id="standardmcireadyhandlermcidata-callback">
<code class="language-plaintext highlighter-rouge">standardMCIReadyHandler(mciData, callback)</code>:</h4>
<p>This is a standard and commonly used <code class="language-plaintext highlighter-rouge">mciReady()</code> implementation:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">mciReady</span><span class="p">(</span><span class="nx">mciData</span><span class="p">,</span> <span class="nx">cb</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">standardMCIReadyHandler</span><span class="p">(</span><span class="nx">mciData</span><span class="p">,</span> <span class="nx">cb</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Where <code class="language-plaintext highlighter-rouge">mciData</code> is a Object mapping <a href="/enigma-bbs/art/mci.html">MCI codes</a> such as <code class="language-plaintext highlighter-rouge">TL2</code> to their properties:</p>
<ul>
<li>
<code class="language-plaintext highlighter-rouge">SGR</code>: Graphics rendition</li>
<li>
<code class="language-plaintext highlighter-rouge">focusSGR</code> (Only present if art contained both, ie: <code class="language-plaintext highlighter-rouge">TL2^[0;mTL2</code>)</li>
<li>
<code class="language-plaintext highlighter-rouge">position</code> (Array of Number): Position in [Row, Column] order</li>
<li>
<code class="language-plaintext highlighter-rouge">args</code> (Array): Any arguments to the MCI code</li>
<li>
<code class="language-plaintext highlighter-rouge">code</code> (String): The code itself, such as <code class="language-plaintext highlighter-rouge">TL</code>
</li>
<li>
<code class="language-plaintext highlighter-rouge">id</code> (Number): The MCI codes ID such as <code class="language-plaintext highlighter-rouge">1</code>
</li>
</ul>
<blockquote>
<p><img class="emoji" title=":information_source:" alt=":information_source:" src="https://github.githubassets.com/images/icons/emoji/unicode/2139.png" height="20" width="20"> Search the code for the above methods to see how they are used in the base system!</p>
</blockquote>
<h2 id="custom-mods">Custom Mods</h2>
<p>Most mods will also derive from <code class="language-plaintext highlighter-rouge">MenuModule</code>. Some things to be aware of:</p>
<ul>
<li>Custom mods that bring in their own dependencies must also include their own <code class="language-plaintext highlighter-rouge">package.json</code> and other Node requirements</li>
<li>Be sure to use <code class="language-plaintext highlighter-rouge">packageName</code> and <code class="language-plaintext highlighter-rouge">getModDatabasePath()</code> for any (database) peristence needs.</li>
<li>Custom mods in <code class="language-plaintext highlighter-rouge">mods/the_mod_name/</code> and the <code class="language-plaintext highlighter-rouge">MenuModule</code> entry point must be within a file of the same name: <code class="language-plaintext highlighter-rouge">mods/the_mod_name/the_mod_name.js</code>
</li>
<li>To import ENiGMA modules <code class="language-plaintext highlighter-rouge">require()</code> from <code class="language-plaintext highlighter-rouge">../../core/</code>
</li>
</ul>
</div>
<div class="PageNavigation">
<a class="btn" style="float:left;margin-right: 20px;" href="/enigma-bbs/modding/autosig-edit.html">« Auto Signature Editor</a>
<a class="btn" style="float: right;margin-left: 20px" href="/enigma-bbs/admin/administration.html">Administration »</a>
<br clear="both">
</div>
</section>
</div>
</div>
</div>
</body>
</html>