Module:Vanguard funds/doc

This module checks Vanguard fund identifiers for validity, and generates URLs for any associated Vanguard web site fund pages.

The module uses a lookup table to validate the given fund identifier and if necessary, to convert it from a fund number into a mutual fund symbol or ETF ticker. The result of this lookup also identifies the fund type, either mutual fund or ETF.

The module's main public function is url for template use, and _url for direct Lua calls.

A secondary public function, lookup for wikitext use, and _lookup for direct Lua use, returns the raw data from the lookup table used to recognise fund identifiers. This secondary function is intended for debugging and table checking, rather than for real use from templates or wikitext.

Usage
To generate a full Vanguard fund web page URL, invoke with:

Parameters:
 * fund: The Vanguard fund identifier. Must be supplied. May be a mutual fund symbol, an ETF ticker, or a fund number. For example, VTSAX, VTI, or 0585. Case-insensitive. For fund numbers, all four digits must be present.
 * search_url: The URL for a Vanguard page search. Used where fund is not in the lookup table. Example: https://investor.vanguard.com/search (this is also the default value for this parameter).
 * mutual_fund_stem: The stem of the URL for a Vanguard mutual fund. Used where fund is identified as being a mutual fund. Example: https://investor.vanguard.com/investment-products/mutual-funds/profile/%s. Default is the same as the default for search_url, but with #q=%s appended.
 * etf_stem: The stem of the URL for a Vanguard ETF. Used where fund is identified as being an ETF. Example: https://investor.vanguard.com/investment-products/etfs/profile/%s. Default is the same as the default for search_url, but with #q=%s appended.

Parameters may also be supplied by position, in the order shown above. For URLs and URL stems, where %s appears in the string, the module will substitute the fund identifier for %s. This allows flexible placement of the fund identifier within URLs.

To return raw lookup table data, invoke with:

Parameters:
 * fund: The Vanguard fund identifier. Must be supplied. May be a mutual fund symbol, an ETF ticker, or a fund number.

Examples
Generated URLs:
 * Using
 * Results in:
 * Using
 * Results in:
 * Using
 * Results in:

Simple table lookup:
 * Using results in:
 * Using results in:
 * Using results in:

Categories
If the given fund does not appear in the lookup table, the template creates a link to a Vanguard search web page, and places the invoking page in a subcategory of Category:Vanguard URL errors.

Use in production
The module is designed to be invoked from within a template that supplies the URL strings as pseudo-constants. That way, the caller template can vary the URLs that the module generates, but without needing to edit the module's Lua code directly.

For example, template code might read:

This creates a template with a single positional parameter (a fund identifier). This is passed to the module along with information on how to form a complete Vanguard fund URL for this fund. The URL strings are not template parameters; they are hard-coded into the template. However, changing these URL strings, if it becomes necessary, is easy to do.

Also, arranging things this way allows for easier testing of the module's functions, keeps the details of Vanguard URLs largely outside Lua code, and it is 'fail-safe'; that is, if URL strings are not provided, the module does its best to generate a simple Vanguard web site search.

Technical notes
For efficiency, this module lazy-loads its table data using mw.loadData rather than Lua's require. Data loaded this way has some severe limitations. Several Lua features will not work correctly with it. And worse, these features do not fail, but rather they return incorrect or misleading results. For example #value always returns zero no matter how many elements the item contains, and unpack returns nil.

When editing this module, be very careful to ensure that the Lua language feature you are using will work correctly with a data set that is loaded in this way.

For all invocations this module uses arguments only from the caller frame. While it is called from within a template, for efficiency it has no actual wrapper template, allowing it to avoid the overhead of checking both caller and parent frames for arguments. This means that all arguments need to be supplied explicitly on each invocation.