Creating a Mod-The Least You Need To Know
This page gives a very basic introduction to creating a TNG mod, it introduces the Mod Manager tags used to implement two example mods (or perhaps more accurately, two versions of one example mod):
- Make one change to one file, that is, make the search string field in the Admin>>Media search form a bit wider.
- Add an HTML placeholder to the search string field, and define English and English-UTF8 language strings to provide the placeholder text.
The native Admin>>Media search form looks like this:
and our goal at end of the second version of the mod is this:
That's a pretty small Search box, and we want to make it larger.
To understand this article, you should be familiar with the use of TNG mods and configuration files (.cfg files), but you do not need to know any of the Mod Manager tags, commands, or syntax. I'll just review one important concept - that the Mod Manager simply changes text, whether that text is PHP code, HTML markup, HTML content, CSS, or data.
The first version
In this mod, we will simply make the search field wide enough to accommodate a placeholder. We'll add the placeholder in the second mod.
There are several ways to find the PHP and/or HTML code that generates the search field, but, for this article, we're just worrying about how to make a simple change, not how to figure out the details of what to change. So, one way or another, we have discovered that the search field is defined by this line in admin_media.php:→→→→<input type="text" name="searchstring" value="<?php echo $originalstring; ?>" class="longfield">
Note that
- The arrows represent four tabs at beginning of the line. Some examples of Mod Manager commands and text in this article do not explicitly show that there are four tabs at the beginning of this line (nor of the replacement line), but it is important to be aware that they must be present in the appropriate text strings in the Mod Manager configuration file.
- This line of text contains a combination of HTML and PHP code. At this point in the admin_media.php, the file is in "HTML mode", meaning that each line represents HTML, not PHP. But PHP code can be inserted in HTML lines within the delimiters
<?php
and?>
. - In this line, the embedded PHP code simply uses the PHP variable $originalstring to fill in the text field's value.
We can infer from the screenshots above that the style class longfield
is providing a field width. To make the field wider, we'll need either to provide a different class or remove the class and enter an explicit inline style. Again, this article is about make a change to a TNG file, not deciding what the change should be, so I'll just note that we want to change the code to this:→→→→<input type="text" name="searchstring" value="<?php echo $originalstring; ?>" style="width:33em;">
The Manager Tags
The Mod Manager specification language, like HTML, is based on tags. Mod manager commands (called "directives" in most Mod Manager documentation) are like HTML elements in that they combine tags and arguments in a particular syntax. Each Mod Manager command has the following components:
- A percent sign
- The tag (always lower case)
- Arguments, separated by colons, and
- A closing percent sign
The .cfg file heading
These three Mod Manager commands are the essential components of the heading of a Mod Manager configuration file. They describe aspects of the mod or script rather than provide instruction on how to make modifications.
%name:Mod Creation Example%
%version:13.0.0.1%
%description:This is a very simple example mod%
Commands that tell the Mod Manager what to do and where to do it follow the heading.
A Target Block
To specify the file that needs to be edited (which we call the "Target file"), use a %target tag, like this:%target:admin_media.php%
A target block contains Mod Manager commands that tell the Mod Manager what changes to make in the file. After those changes are specified, the configuration file can then specify another %target command to start a new target block. In this example, we're just changing one file, so we have only one target block. It is important to note here that it is not necessary to explicitly mark the end of a target block (whereas, in HTML, it would be important to end a <div> element with a </div> element). In the Mod Manager, a target block is terminated by the next %target:% command or the end of the file.
A Location Block
Within a target block, to specify where a changes needs to occur, we must specify a search string, which, in this case, is the HTML <input> element shown above. The search string can be multiple lines long (i.e. it can be a "block" of text), but in our example, it is just one line long. The tag that specifies search string (i.e. the location of the change) is %location:%
. Note that the %location tag doesn't not need an argument. Instead, the search text follows the %location:% tag and is terminated by an %end:%
tag, forming a search block like this:
%location:%
<input type="text" name="searchstring" value="<?php echo $originalstring; ?>" class="longfield">
%end:%
Once the search text has been specified, we need to say what need to be done about that search text. We can insert new text above or below the search string, or replace it. In this example, we want to replace the entire line with a new one. Thus, we'll use the %replace:%
tag (which is known as an "action tag"), followed by the text that is inserted in place of the search text. The insertion text can be multiple lines long, and like the search text, is terminated with %end:%:
%replace:%
<input type="text" name="searchstring" value="<?php echo $originalstring; ?>" style="width:33em;">
%end:%
Put the search and insertion blocks together, and we have a location block:
%location:%
<input type="text" name="searchstring" value="<?php echo $originalstring; ?>" class="longfield">
%end:%
%replace:%
<input type="text" name="searchstring" value="<?php echo $originalstring; ?>" style="width:33em;">
%end:%
A Full Mod
Here is a draft of our first mod:
%name:Mod Creation Example%
%version:13.0.0.1%
%description:This is a very simple example mod%
%target:admin_media.php%
%location:%
<input type="text" name="searchstring" value="<?php echo $originalstring; ?>" class="longfield">
%end:%
%replace:%
<input type="text" name="searchstring" value="<?php echo $originalstring; ?>" style="width:33em;">
%end:%
(where the lines of search and replacement text begin with four tabs)
Some details:
- The %description command above, unlike any of the other commands you've seen so far, can occupy multiple lines and can contain HTML code, perhaps like this
- This example replaced the search text with what we called "insertion text". In Mod Manager documentation (including the documentation of specific mods), you'll often see the term "replacement text" used. The two terms are functionally equivalent.
- The configuration file shown above contains blank lines, which can be inserted fairly arbitrarily in Mod Manager configuration files. Blank lines, and, equivalently, free-text comments can be placed anywhere in the file except
- Inside a Mod Manager command, or
- Inside a search or replacement block.
%description:This example mod changes the size of the Search field in the search form at Admin>>DNA Tests
<p>It comes from the TNG Wiki Article
<a href="https://tng.lythgoes.net/wiki/index.php?title=Creating_a_Mod-The_Least_You_Need_To_Know">Creating a Mod-The Least You Need To Know</a>
</p>%
Insertion Text Comment
Something important is still missing from this mod. It does not add any text to the modified PHP file to indicate that the file has been change, or who or what changed it. If someone were to compare the new PHP file to an original copy of the distributed TNG code, that person would be able to see that the file has been changed, but still would have no idea how that change came about.
The solution for this problem is simply to insert a PHP or HTML comment with the insertion text, like this:
%replace:%
<!-- Insertion by ###Mod Creation Example -->
<input type="text" name="searchstring" value="<?php echo $originalstring; ?>" style="width:33em;">
%end:%
(The three pound signs serve two purposes: & In PHP code a pound sign acts exactly like two slashes as an end-of-line comment, and
- Some mod programmers have picked up the practice of using three pound signs in front of mod names in these insertion text comments as an explicit marker of a target location's insertion.
The First Complete Mod
Adding a more meaningful description and the replacement text comment, we get this configuration file.
%name:Mod Creation Example%
%version:13.0.0.1%
%description:This example mod simply makes the Admin>>Search form's search string wider.%
%target:admin_media.php%
%location:%
<input type="text" name="searchstring" value="<?php echo $originalstring; ?>" class="longfield">
%end:%
%replace:%
<!-- Insertion by ###Mod Creation Example -->
<input type="text" name="searchstring" value="<?php echo $originalstring; ?>" style="width:33em;">
%end:%
(Again, remember that the white space at the beginning of each line in the search text must consist of four tabs.)
First Version Review
- We've introduced these Mod Manager tags:
- %name:
- %version:
- %description:
- %target:
- %location:
- %end:
- %replace:
- With the name "Mod Creation Example" and version 13.0.0.1, this mod's configuration file would be expected to have the filename mod_creation_example_v13.0.0.1.cfg. The mod can be downloaded as a zip file from File:Mod creation example v13.0.0.1.zip
Second Version
This example is be a continuation of the first. We'll change the mod version to 13.0.0.2, add a placeholder argument to the <insert> tag, and define English versions of the language string that will serve as the placeholder text.
Search Field Placeholder
To add the placeholder we need to place an HTML placeholder argument in the insertion, and use a PHP variable to supply the placeholder text. The syntax for the placeholder text is pretty much the same as the syntax for the field value.
Here, it is important to know that, in Admin programs, language strings are stored in the PHP $admtext array, using string subscripts (aka 'indexes') that should represent the string value (in English). It is good practice to also give the index a prefix that represents the mod name so that the index is likely to be unique in the very large array of TNG language strings. Here's our new replacement text, which is
- Broken into two lines of HTML code just for readability, and
- Has a comment both before and after the insertion.
%replace:%
<!-- Insertion by ###Mod Creation Example 2 -->
<input type="text" name="searchstring" value="<?php echo $originalstring; ?>"
style="width:33em;" placeholder="<?php echo $admtext['mce2placeholder']; ?>">
<!-- End of Insertion by ###Mod Creation Example 2 -->
%end:%
Of course, we already know how to put this replacement text in a target location block.
Language Strings
Mods add language strings to each language's cust_text.php file. In each cust_text.php file, there is a specific line of text (a PHP comment) whose purpose is to mark the point where language strings are to be inserted. Note that we are talking about an insertion here, not a replacement. The standard cust_text.php search text is//Mods should put their changes before this line, local changes should come after it.
Note that we essentially always have to define equal strings for English and English-UTF8, and, if we have translations, we can insert strings for other languages.
Then, just before that search text we want to insert PHP lines that define the language strings. Let's not show the cust_text.php target blocks in isolation, and just skip to a complete English-only mod configuration file.
The Second Complete Mod
%name:Mod Creation Example%
%version:13.0.0.2%
%description:This example mod makes the Admin>>Search form's search string wider and add placeholder text
that lists the database fields that are searched.%
*****************************************************************
%target:admin_media.php%
%location:%
<input type="text" name="searchstring" value="<?php echo $originalstring; ?>" class="longfield">
%end:%
%replace:%
<!-- Insertion by ###Mod Creation Example -->
<input type="text" name="searchstring" value="<?php echo $originalstring; ?>"
style="width:33em;" placeholder="<?php echo $admtext['mce-placeholder']; ?>">
<!-- End of Insertion by ###Mod Creation Example -->
%end:%
*******************************************************************
%target:languages/English/cust_text.php%
%location:%
//Mods should put their changes before this line, local changes should come after it.
%end:%
%insert:before%
$admtext['mce-placeholder'] = "Searches the mediaID, title, description, bodytext, and owner fields"; ###New string for ###Mod Creation Example
%end:%
*******************************************************************
%target:@languages/English-UTF8/cust_text.php%
%location:%
//Mods should put their changes before this line, local changes should come after it.
%end:%
%insert:before%
$admtext['mce-placeholder'] = "Searches the mediaID, title, description, bodytext, and owner fields"; ###New string for ###Mod Creation Example
Second Version Review
- In addition to the seven Mod Manager tags introduced by version 1 (%name:, %version:, %description:, %target:, %location:, %end:, %replace:), we've introduced
- %insert:before% and, by implication
- %insert:after:%
- This version of the example can be downloaded from File:Mod creation example v13.0.0.2.zip
A Variant of Version 1
It turns out that the Mod Manager can handle search and insertion strings that are just part of a line. These strings are called "code fragments", and use the action tags %trimreplace:%, %triminsert:before%, and %triminsert:after%. Assuming that the string class="longfield'
does't occur elsewhere in admin_media.php, the target location block in the first version of this example could have been
%location:%
class="longfield">
%end:%
%replace:%
style="width:33em;"> <!-- Inserted by ###Mod Creation Example -->
%end:%
A Few Other Commands
- Four other header directives are used widely:
- %note:any note text, including HTML code
- The note is shown in the Status column of the Mod Manager manager list, before the Status cell is expanded.
- %private:note%
- Just flags the mod as unpublished, and displays the word "private" and the note in the unexpanded status column of the Mod Manager list.
- %author:name:URL%
- The URL is generally the author's personal page on the TNG Wiki, e.g.
%author:Robin Richmond:https://tng.lythgoes.net/wiki/index.php?title=User:Robinrichm%
- The URL is generally the author's personal page on the TNG Wiki, e.g.
- %wikipage:modname%
- This mod directive provides the link for the stylized "W" in the Mod Manager list. The Wiki article's name should be the same as the Mod name as defined in the %name:% directive in the configuration file. For example, the Admin Media Search mod contains the directive
%wikipage:Admin Media Search%
- As with Wiki article names in URLs, you must use underscores rather than spaces in the %wikipage directive for the Mod Manager to create the correct link.
- This mod directive provides the link for the stylized "W" in the Mod Manager list. The Wiki article's name should be the same as the Mod name as defined in the %name:% directive in the configuration file. For example, the Admin Media Search mod contains the directive
- %note:any note text, including HTML code
See also
A more advanced example at Mod_Manager_-_Config_File_Creation_Example
Mod Manager
- Overview
- Why Use It ?
- Installing Config Files
- Batch Updates
- Interpreting Status
- Editing Parameters
- Deleting Mods
Mod Manager Controls
For Mod Developers
- Mod Guidelines
- Mod Manager Syntax
- Creating Config Files
- Config File Creation Example
- Avoiding Mod Conflicts
- Using the TNG File Analyzer
- Mod_Manager_Enhancements_TNG_v12
Technical
Developer Tools
Example Mods