Module:Versions

From Dune: Awakening Community Wiki
Jump to navigation Jump to search

Module:Versions

Provides utility functions related to game versions by pulling all existing version pages by title, without the need to maintain a separate dataset.

This module provides the following function(s):

  • latest - returns the latest version string.
  • check - returns whether a given version string has a corresponding version page.
  • get - renders an InfoboxNavRow with the prev and next versions populated correspondingly.

Usage

Return latest version

Returns the latest version, i.e. the highest version number among the version pages, as a string.

{{#invoke:Versions|latest}}

Check whether a version exists

Returns true if a version page with the given title exists, or false otherwise.

{{#invoke:Versions|check|1.3.15.0}}

The module is invoked by the template to render navigation buttons.

{{#invoke:Versions|get|{{{version|{{BASEPAGENAME}}}}}}}

The version parameter defaults to the current page name if not specified. The module returns a Template:InfoboxNavRow invocation with the previous and next update versions as parameters.

Parameters

latest

<No parameters>

check

1
string
The version string to look up, matching a version page title.

get

1
string
The version string corresponding to a version page title.

Notes

  • The third segment of a version must be either 0 or two digits long, so 1.3.5.0 MUST be written as 1.3.05.0. This keeps the module's order consistent with Template:VersionNavbox, which sorts by title.
    • Pages that do not follow the rule are ignored by the module, and their infobox shows an error.

local p = {}

local common = require("Module:Common")

-- ---------- Data ----------

local DPL_QUERY = "{{ #dpl: titleregexp = ^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$ | format = ,%TITLE%\\n, }}"
local VERSION_PATTERN = "^%d+%.%d+%.(%d+)%.%d+$"

local cache

-- ---------- Processing ----------

local function isVersion(s)
    local patch = s:match(VERSION_PATTERN)
    return patch ~= nil and (patch == "0" or #patch >= 2)
end

local function parse(ver)
    local parts = {}
    for n in ver:gmatch("%d+") do parts[#parts+1] = tonumber(n) end
    return parts
end

local function isOlder(a, b)
    local pa, pb = parse(a), parse(b)
    for i = 1, 4 do
        if pa[i] ~= pb[i] then return pa[i] < pb[i] end
    end
    return false
end

local function load(frame)
    if cache then return cache end

    local raw = frame:preprocess(DPL_QUERY)

    local list, seen = {}, {}
    for line in raw:gmatch("[^\r\n]+") do
        line = common.trim(line)
        if isVersion(line) and not seen[line] then
            seen[line] = true
            list[#list+1] = line
        end
    end

    -- a page being created is not in the page table yet
    local current = mw.title.getCurrentTitle().text
    if isVersion(current) and not seen[current] then list[#list+1] = current end

    table.sort(list, isOlder)
    cache = list
    return cache
end

-- ---------- Rendering ----------

local function renderNavRow(frame, prevVer, nextVer)
    local args = {}

    if prevVer then args.prev = prevVer end
    if nextVer then args.next = nextVer end

    return frame:expandTemplate{
        title = "InfoboxNavRow",
        args = args
    }
end

-- ---------- Interface ----------

function p.latest(frame)
    local list = load(frame)
    return list[#list]
end

function p.check(frame)
    local inputVer = common.trim(frame.args[1])

    for _, version in ipairs(load(frame)) do
        if version == inputVer then return "true" end
    end

    return "false"
end

function p.get(frame)
    local inputVer = common.trim(frame.args[1])
    if inputVer == "" then return common.renderError("No version specified") end

    local list = load(frame)
    for i, version in ipairs(list) do
        if version == inputVer then return renderNavRow(frame, list[i-1], list[i+1]) end
    end

    if not isVersion(inputVer) then
        return common.renderError("Invalid version: <code>%s</code>. The third segment must be zero-padded: <code>1.3.05.0</code>, not <code>1.3.5.0</code>.", inputVer)
    end

    return common.renderError("Unknown version: <code>%s</code>.", inputVer)
end

return p