Libraries

From ESOUI Wiki

Jump to: navigation, search

Libraries are basically add-ons on their own, but they share re-usable code or API functions which can be used in several add-ons.


See here for an add-on's structure: https://wiki.esoui.com/Addon_manifest_(.txt)_format It will be basically the same for libraries.
The main difference is: Libraries SHOULD use the txt manifest tag ## IsLibrary: true to identify them in the ingame add-on manager as such library. They will appear at the bottom of the add-on manager's list then for an easier find.

Contents

File Encoding

To prevent issues, make sure the file is UTF-8 w/o BOM. UTF-8-BOM and ANSI can lead to some different issues during add-on loading etc..

Example

A basic manifest.txt file contains: three mandatory directives (Title:, AddOnVersion:, APIVersion:); three situational directives (DependsOn:, IsLibrary: true, OptionalDependsOn:), and one ESOUI/Minion directive (Version:). It looks something like this:

## Title: Library title, a character string for human display. Normally libraries start with the String "Lib" (e.g. LibAddonMenu-2.0, LibDialog)
## Author: The author name String of the library
## APIVersion: a six digit value, the same value as the ESO API for each release (e.g. 100026). In the same line there can be up to 2 APIVersions after another, separated by a space, to support both of them (e.g. 100026 100027
## AddOnVersion: a positive integer value (e.g. 1,2,3,etc. but not 3.4 nor -5 nor r5). This is really important for libraries in order to load ONLY the library with the highest version, and not several ones!
## Version: A version identifier for ESOUI and/or Minion (e.g. 2.0.2) to separate add-on releases and/or updates
## DependsOn: A space separated name list of add-ons/libraries that your add-on needs to run correctly (e.g. LibAddonMenu-2.0 LibDialog). If any addon/library in this line is missing your adon won't load!
## OptionalDependsOn: A name list similar to DependsOn: but the add-ons in this list will not prevent your add-on from running. Use this to assure other addons listed here are loaded before your addon (e.g. LibraryName1 AddonName1)
## IsLibrary: true  This value should be always true for libraries in order to seperate the add-ons in the ingame add-on manager's list (shown at the bottom for an easy find)

# blank lines are ignored
# both '#' and ';' are comment characters
; the double hashmarks ('##') above are parts of the "metadata" definitions for the manifest file. You must include the '##' for a
; directive to be recognized, and you cannot have whitespace in front of them

# lua files for the addon, which can come before or after XML files
SomeAddonFile.lua

# you can have internal folders; paths are relative to the manifest file
InternalPath\whatever.lua

# you can use the forward slash ('/') as a path separator too
ForwardSlashPath/AlsoWorks.lua

# XML files follow the same rules as the lua files, regarding folders
SomeAddon/InterfaceFile.xml

# Most people also include the ZOS mandated licensing boilerplate in the manifest though you are welcome to include it in any way
# that meets the definition set here: [https://account.elderscrollsonline.com/add-on-terms]
# The suggested disclosure is:

# This Add-on is not created by, affiliated with, or sponsored by, ZeniMax Media Inc. or its affiliates.
# The Elder Scrolls® and related logos are registered trademarks or trademarks of ZeniMax Media Inc. in the United States
# and/or other countries. All rights reserved.

Lines beginning with two hashmarks ## define the metadata of the addon, and are often referred to as "directives". Directives specify information and metadata about the add-on. Each directive and its values are explained in the next paragraphs; one paragraph per directive. Be very careful to leave a space after the trailing colon delimiter (e.g. ": "). If you don't, the game's parser will not find the directive's metadata values.

Lines beginning with a semi-colon (;) or hashmark (#) are comments. ESO restricts comment lines to 1024 characters per line. Comment lines can contain any characters including hashmarks. Comments terminate at the next newline.

The rest of the lines in a manifest are simply a list of relative folder and file paths that should be loaded as part of the add-on. Relative file paths can look like this:

Dir/SomeLuaFile.lua
Dir/SomeFolder/SomeLuaFile.lua

Or like this:

SomeLuaFile.lua
SomeFolder/SomeLuaFile.lua

ESO loads the files in the same order in which they are listed in the manifest. Loading a .lua file executes all the code within it except for the code snippets contained within functions. The functions are created, but none of the code within them gets executed until another code snippet outside of the function invokes it.

A total example of an AddOn's manifest txt file could be:

## Title: LibMyLibrary - Sample library
## Author: Your name
## APIVersion: 100026 100027
## AddOnVersion: 001
## Version: 0.0.1
## IsLibrary: true
## DependsOn: LibAddonMenu-2.0
## OptionalDependsOn: LibOtherLibrary1 LibOtherLibrary2 MyOtherAddon1

#Load constant values
MyLib_Constants

#Load language texts depending on the client's language
/lang/en.lua              ; Standard language file, always loaded
/lang/$(language).lua     ; de.lua/fr.lua, ...: Loaded if the client is using this language

#Addon base functions and code
MyLib.lua

#Addon functions depending on the APIVersion of the server
MyLib_functions$(APIVersion).lua   ; Will load the file MyLib_functions100026.lua for APIversion 100026 and MyLib_functions100028.lua for APIversion 100028

#Addon XML
MyLib_XML.lua

#Keybindings
/keybindings/keybindings.lua
/keybindings/keybindings.xml

# This Add-on is not created by, affiliated with, or sponsored by, ZeniMax Media Inc. or its affiliates.
# The Elder Scrolls® and related logos are registered trademarks or trademarks of ZeniMax Media Inc. in the United States
# and/or other countries. All rights reserved.

Library versioning

Because libraries could be loaded in several ways to your addons the game needs a method to check which version of the loaded library is the most up-to-date one.

LibStub - Library version control

LibStub (https://www.esoui.com/downloads/info44-LibStub.html) is a library created to assure that your libraries get loaded ONLY once with the highest possible version number.
As the base game did not provide such a possibility until the Summerset DLC, LibStub was used in about all libraries to assure this.

After the Summerset DLC release one started changing to the new manifest txt tag

## AddOnVersion: <signed integer>

in order to assure that ONLY the highest integer version gets loaded ingame.

If you build a new library do not use LibStub anymore but use the tag

## AddOnVersion: <integer version number here>

and in your addons using the library use the tag

## DependsOn: LibYourLibrary

to assure the library gets loaded properly.

How to access libraries from addons/other libraries

To make your library accessible for other addons/libraries it needs a global variable.
Please do not use LibStub anymore for this (see above at "LibStub - Library version control")!

If your library is named LibMyLibrary1.0 e.g. you could create a global variable

LibMyLibrary1

which holds all library data and functions.
Inside your addon use the global variable then to check if the library exists, and to use its functions:

local libMyLibrary = LibMyLibrary1
if libMyLibrary then
  local myData = libMyLibrary:GetData()
end

Important
Please note that - characters and versioning decimal digits in the library's name like LibAddonMenu-2.0 cannot be used as global lua variable! lua would try to subract 2.0 from a variable LibAddonMenu in this case.
You need to use a signed integer value inside the global name then, like LibAddonMenu2. And you shouldn't include any versioning or revision strings like r5 or similar into the variable name. Keep it simple.

Be sure to add the global variable name to your library description text on addon websites so authors are able to easily find and use it!

And please think about updating your library to abandon the usage of LibStub, provide it an ## AddOnVersion: and a global variable if you were using LibStub until now.

Hybrid solution - Loading library with LibStub (if it's still around) and with it's global variable

If you want to change your current addons/libraries to use LibStub as long as it is still around, but also be able to use the global variables of libraries,
you can build a hybrid lua code to check this.
In your addon/library's manifest txt you need to put LibStub into the OptionalDependsOn: tag, instead of the ## DependsOn:, so your addon/library will load properly even if LibStub is not there anymore.

## OptionalDependsOn: LibStub

In your addon/library code you can try if LibStub is present but be sure to set the "silent" flag to true so there will be no lua error message if LibStub is missing.
Check if the variable is loaded then with a == nil check (or if <variable> then). If it is nil it wasn't loaded, so try the global variable afterwards:

   local myLibrary = LibStub("MyLibrary1", true) -- Set the 2nd parameter 'silent' to true
   if not myLibrary then
      myLibrary = MyLibrary1
   end
   if myLibrary then
      --Library was loaded via LibStub or global variable
   end

Providing libraries (standalone / bundled with addon, but how?)

Libraries are meant to be excluded from addons as they are re-usable code for other addons.
But there might be reasons why libraries could be included in subfolders of addons, e.g. if the library is only build for that one addon.
Nevertheless the simplest way to update a library, or to find errors due to libraries, would be a standalone installation of the library, just like a normal addon.
Addon managers like Minion are able to download and install & update the libraries.

Dependencies Dependencies are needed addons/libraries for an addon/library to run properly. If dependencies are "hard" (txt manifest tag ## DependsOn:) the addon/library won't be loaded ingame if any dependeny is missing!
If dependencies are "soft" (txt manifest tag ## OptionalDependsOn:) the addon/library will be loaded ingame if any dependeny is missing, but the content depending on the missing dependencies cannot be used then!
The dependencies (OptionalDependsOn / DependsOn) of an addon show which libraries are needed in order to let an addon work properly.

As there is no automatism to install dependencies yet one currently needs to check the addon's description at the download page, or expand the addon ingame in the addon manager and read which extra lines (dependencies) are shown -> Install those afterwards. In the next versions of Minion (>= version 4) e.g. the dependencies will be read from the addon's txt manifest file and the manager will try to download and install those automatically.

Standalone installation

Your library got it's own manifest txt file?
The optimal way to achieve an easy update and error tracking functionality would be to install the libraris as standalone version, just like a normal addon is installed.
Therefor you download the library's zip archive, containing the library lua/xml files + the libray's manifest txt file, and extract it to the AddOns folder.

live
|AddOns
 |LibAddonMenu-2.0
  |LibAddonMenu-2.0
   |controls
 |LibDialog
 |Skyshards
 |...

The folder of the library MUST contain it's own manifest txt file then, using the ## AddOnVersion: tag (or LibStub as long as it is available)! This is needed to assure that the library get's loaded only with the highest version number and all dependencies are found properly).

Your library got no own manifest txt file?
See below at "Shipped with your addon (maybe causing problems)".

Shipped with your addon (properly included)

Your library got it's own manifest txt file?
You could also put the library's folder completely into your addon's zip archive, as it's own folder but ONLY inside your addon's folder!

IMPORTANT:
Do NOT incldue it at the same folder depth as your addon's folder (root)!
It will overwrite the libraries which were installed as standalone and if you do not update your addon's zip file directly after any library was updated, installing your addon might destroy other addons!
Reason: Installing your zip file will overwrite the libraries in the /live/AddOns folder then. If your addon's zip file contains the version 2.1 of a library and it will overwrite a version 3.0 of the same library, it might break other addons which rely on version 3.0.
Even addon updaters like Minion do not check this and think they only updated your particular addon AND NO other addons/libraries. So the version of the also updated libraries will be the same internally for Minion, like before the update. If it's not updating the library afterwards because there was a newer version pending, it will stay "updated" for Minion where it is "outdated" ingame!

Example zip archive (correct):

MyAddon1.zip
|MyAddon1
 |-MyAddon1.lua
 |-MyAddon1.txt
  |libs
   |LibDialog
    |-LibDialog.lua
    |-LibDialog.txt

Example zip archive (wrong):

MyAddon1.zip
|MyAddon1
 |-MyAddon1.lua
 |-MyAddon1.txt
|LibDialog
 |-LibDialog.lua
 |-LibDialog.txt

The folder of the library MUST contain it's own manifest txt file then, using the ## AddOnVersion: tag (or LibStub as long as it is available)! This is needed to assure that the library get's loaded only with the highest version number and all dependencies are found properly).


Your library got no own manifest txt file?
See below at "Shipped with your addon (maybe causing problems)".

Shipped with your addon (loaded via your addon's txt manifest file -> maybe causing problems)

Your library got it's own manifest txt file?
Please change it to either "Standalone installation" (see above)
or "===Shipped with your addon (properly included)===" (see also above)

Your library got no own manifest txt file?
Think about adding one so it will be available properly as standalone library!

If you do not want or need this, you can include your library in all addon's manifest txt file like this:
-Add the library's folder(s) + subfolder(s) + file(s) to your addon's manifest txt file like this:

/libs/LibAddonMenu-2.0/controls/iconpicker.lua
/libs/LibAddonMenu-2.0/controls/panel.lua
/libs/LibAddonMenu-2.0/LibAddonMenu-2.0.lua

-No ## DependsOn: or ## OptionalDependsOn: in your addons is needed as the library's files will be included from your addon's txt file
IF you would add and ## (Optional)DependsOn: it it would maybe break your addon as it will try to load the library via a txt manifest file from the AddOns folder ("Standalone installation")
or another AddOn'ss subfolder ("Shipped with your addon (properly included))", and thus overwrite your directly included variables of the library (which maybe got a newer version than the Standalone installed one)!

Including libraries this way should only be used if the library is intended to be used only for this particular addon, and not also other addons.

Personal tools
Namespaces
Variants
Actions
Menu
Wiki
Toolbox