enigma-bbs/modding/menu-modules.html

2577 lines
37 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-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.2" />
<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="2023-09-26T14:09:57+00:00" />
<meta name="twitter:card" content="summary" />
<meta property="twitter:title" content="Menu Modules" />
<script type="application/ld+json">
{"publisher":{"@type":"Organization","logo":{"@type":"ImageObject","url":"/enigma-bbs/assets/images/enigma-logo.png"}},"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"},"headline":"Menu Modules","dateModified":"2023-09-26T14:09:57+00:00","datePublished":"2023-09-26T14:09:57+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>
<li><a href="/enigma-bbs/installation/development.html">Development Environment Setup</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/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>