Jump to content

Module:LuaTemplateLibraryInterview

From ICANNWiki

Documentation for this module may be created at Module:LuaTemplateLibraryInterview/doc

-- Module:LuaTemplateLibraryInterview
-- Module for rendering the Library Interview template with semantics

local p = {}

-- Dependencies
local TemplateStructure = require('Module:TemplateStructure')
local dateNormalization = require('Module:DateNormalization')
local SemanticAnnotations = require('Module:SemanticAnnotations')
local TemplateHelpers = require('Module:TemplateHelpers')

--------------------------------------------------------------------------------
-- Configuration and Constants
--------------------------------------------------------------------------------
local Config = TemplateHelpers.createStandardConfig({
    meta = {
        description = "Module for rendering the Library Interview template with semantics"
    },
    
    constants = {
        title = "Internet & Digital Governance Library",
        tableClass = "library-box"
    },
    
    fields = {
        {key="Title", label="Title"},
        {key="Format", label="Format"},
        {key="Date", label="Date"},
        {key="Interviewer", label="Interviewer"},
        {key="Interviewee", label="Interviewee"},
        {key="ID", label="Permanent ID"}
    },
    
    semantics = {
        -- Property mappings (semantic property to template field)
        properties = {
            ["Has interview format"] = "Format",
            ["Has date"] = "Date",
            ["Has interviewer"] = "Interviewer", 
            ["Has interviewee"] = "Interviewee"
        },
        
        -- Additional properties not in 1:1 mapping
        additionalProperties = {
            ["Has person"] = {"Interviewer", "Interviewee"}
        },
        
        -- Transformation functions for properties
        transforms = {
            ["Has date"] = function(value) 
                return tostring(dateNormalization.formatDate(value)) 
            end
        },
        
        -- Categories
        categories = {
            "Internet & Digital Governance Library",
            "ICANNWiki Interviews"
        }
    }
})

--------------------------------------------------------------------------------
-- Helper Functions
--------------------------------------------------------------------------------

-- Extract page name from wiki link [[Name]] or [[Name|Text]]
local function extractFromWikiLink(value)
    local name = value:match("%[%[([^%|%]]+)%]%]") or value:match("%[%[([^%|%]]+)%|.-%]%]")
    return name or value
end

-- Generate fallback markup when mw.smw unavailable
local function generatePropertyMarkup(property, value)
    return '<div style="display:none;">\n  {{#set: ' .. property .. '=' .. value .. ' }}\n</div>'
end

-- Generate semantic properties
local function generateSemanticProperties(args)
    -- Set up transforms including wiki link extraction
    local transformFunctions = Config.semantics.transforms
    -- Add wiki link extraction for person properties
    transformFunctions["Has interviewer"] = extractFromWikiLink
    transformFunctions["Has interviewee"] = extractFromWikiLink
    
    -- Set options
    local options = {
        transform = transformFunctions
    }
    
    -- Set basic properties
    local semanticOutput = SemanticAnnotations.setSemanticProperties(
        args, 
        Config.semantics.properties, 
        options
    )
    
    -- Set additional properties from config
    for property, sourceFields in pairs(Config.semantics.additionalProperties) do
        for _, fieldName in ipairs(sourceFields) do
            if args[fieldName] and args[fieldName] ~= "" then
                local value = extractFromWikiLink(args[fieldName])
                if mw.smw then
                    mw.smw.set({[property] = value})
                else
                    semanticOutput = semanticOutput .. "\n" .. generatePropertyMarkup(property, value)
                end
            end
        end
    end
    
    return semanticOutput
end

-- Use TemplateHelpers for common functions
local getFieldValue = TemplateHelpers.getFieldValue

-- Get current page ID
local function getCurrentPageId()
    local title = mw.title.getCurrentTitle()
    return title and title.id
end

--------------------------------------------------------------------------------
-- Rendering Functions
--------------------------------------------------------------------------------

-- Render title block
local function renderTitleBlock(args) 
    return TemplateHelpers.renderTitleBlock(args, "template-title", Config.constants.title)
end

-- Render fields block with special handling for ID field
local function renderFieldsBlock(args)
    -- Define field processors
    local processors = {
        Date = function(value)
            return tostring(dateNormalization.formatDate(value))
        end
    }
    
    local out = {}
    
    for _, field in ipairs(Config.fields) do
        local key, value = getFieldValue(args, field)
        
        -- Special handling for ID field
        if key == "ID" then
            if not value or value == "" then
                value = tostring(getCurrentPageId() or "")
            end
            table.insert(out, string.format("|-\n| '''%s''':\n| %s", field.label, value))
        else
            -- Standard processing for other fields
            if value then
                -- Apply processor if available for this field
                if key and processors[key] and type(processors[key]) == "function" then
                    value = processors[key](value, args)
                end
                
                -- Skip insertion if processor returned nil or false
                if value ~= nil and value ~= false then
                    table.insert(out, string.format("|-\n| '''%s''':\n| %s", field.label, value))
                end
            else
                -- For empty fields, show a placeholder with the default value
                local defaultValue = field.key .. " goes here"
                table.insert(out, string.format("|-\n| '''%s''':\n| {{{%s|%s}}}", field.label, field.key, defaultValue))
            end
        end
    end
    
    return table.concat(out, "\n")
end

-- Compute categories
local function computeCategories()
    local cats = {}
    for _, category in ipairs(Config.semantics.categories) do
        table.insert(cats, category)
    end
    return TemplateHelpers.buildCategories(cats)
end

--------------------------------------------------------------------------------
-- Main Render Function
--------------------------------------------------------------------------------
function p.render(frame)
    local args = frame:getParent().args or {}
    
    -- Configure block rendering
    local config = {
        tableClass = Config.constants.tableClass,
        blocks = {
            function(a) return renderTitleBlock(a) end,
            function(a) return renderFieldsBlock(a) end
        }
    }
    
    -- Generate template output
    local output = TemplateStructure.render(args, config)
    
    -- Add semantic properties
    local semantics = generateSemanticProperties(args)
    if semantics and semantics ~= "" then
        output = output .. "\n" .. semantics
    end
    
    -- Add categories
    local categories = computeCategories()
    if categories and categories ~= "" then
        output = output .. "\n" .. categories
    end
    
    return output
end

return p