Jump to content

Module:Featured

From HopperWiki

Module:Featured

This module is used to dynamically render and archive "featured" content on HopperWiki. Common themes include featured people, resources, and species. It provides a clean and maintainable way to manage, display, and update featured content using the Template:Featured register template and Cargo for automatic registration and querying.

Features

  • Dynamically displays the most recent featured item on the front page
  • Supports archive rendering for all previous featured items
  • Uses Template:Featured register on each subpage for automatic Cargo registration — no separate index page required
  • Driven by simple metadata (date_featured) stored directly in Cargo

Usage

Use this to show the latest featured item of a specific type (e.g., on the front page):

{{#invoke:Featured|render|person}}
{{#invoke:Featured|render|resource}}
{{#invoke:Featured|render|species}}

Use this to show all featured entries of a given type, in reverse chronological order:

{{#invoke:Featured|render_archive|person}}
{{#invoke:Featured|render_archive|resource}}
{{#invoke:Featured|render_archive|species}}

This will transclude each featured item subpage and display them all together.

Creating a new featured item requires only one step: create a subpage under the appropriate template and call {{Featured register}} at the top (no wrapping tags needed on the subpage itself).

For example, to add a new featured person, create Template:Featured person/Hector Medina with:

{{Featured register|type=person|date_featured=YYYY-MM-DD}}
Content of the featured card goes here...

Substitute person with resource or species as appropriate. The Cargo table updates automatically on save — no index page edit required.

Setting date_featured to a future date will suppress the item until that date arrives, since the module only selects entries on or before today.

Template:Featured register

This template handles Cargo registration for all featured subpages. It declares and stores to the Featured_content Cargo table with the following fields:

  • type — content type (person, resource, or species)
  • featured_page — full page name, auto-populated via {{FULLPAGENAME}}
  • date_featured — ISO date string (YYYY-MM-DD) controlling display order

Configuration

This module supports multiple content types via internal configuration. Each type defines:

  • template_prefix — base template namespace (e.g., Template:Featured person/)

To add a new type, add an entry to the featured_types table in the module — no changes to {{Featured register}} or the Cargo table are needed.

See also


-- Module:Featured
-- Renders featured content using Cargo for registration and lookup.
-- Replaces index-based discovery with direct Cargo queries.
-- Table: Featured_content | Fields: type, featured_page, date_featured

local p = {}

local featured_types = {
    person = {
        template_prefix = "Template:Featured person/",
    },
    resource = {
        template_prefix = "Template:Featured resource/",
    },
    species = {
        template_prefix = "Template:Featured species/",
    }
}

-- Returns the subpage slug from a full page title
-- e.g. "Template:Featured person/Hector Medina" -> "Hector Medina"
local function slug_from_page(featured_page, prefix)
    return featured_page:sub(#prefix + 1)
end

-- Queries Cargo for all featured items of a given type, sorted by date descending
local function query_featured(type_key)
    return mw.ext.cargo.query(
        'Featured_content',
        'featured_page,date_featured',
        {
            where   = 'type="' .. type_key .. '"',
            orderBy = 'date_featured DESC',
        }
    )
end

-- Renders the most recently featured item of a given type
-- Usage: {{#invoke:Featured|render|person}}
function p.render(frame)
    local type_key = mw.text.trim(frame.args[1] or "")

    if not type_key or not featured_types[type_key] then
        return "❌ Invalid or missing featured type."
    end

    local config = featured_types[type_key]
    local results = query_featured(type_key)

    if not results or #results == 0 then
        return string.format("❌ No featured %s entries found in Cargo.", type_key)
    end

    -- Most recent item is first due to ORDER BY date_featured DESC
    local slug = slug_from_page(results[1].featured_page, config.template_prefix)
    return frame:preprocess("{{" .. config.template_prefix .. slug .. "}}")
end

-- Renders an archive of all featured items of a given type, sorted by most recent
-- Usage: {{#invoke:Featured|render_archive|person}}
function p.render_archive(frame)
    local type_key = mw.text.trim(frame.args[1] or "")

    if not type_key or not featured_types[type_key] then
        return "❌ Invalid or missing featured type."
    end

    local config = featured_types[type_key]
    local results = query_featured(type_key)

    if not results or #results == 0 then
        return string.format("❌ No featured %s entries found in Cargo.", type_key)
    end

    local output = {}
    table.insert(output, '<div class="featured-archive">')
    for _, item in ipairs(results) do
        local slug = slug_from_page(item.featured_page, config.template_prefix)
        table.insert(output, frame:preprocess(string.format(
            "{{Front page card|header=Featured %s|content={{%s}}}}",
            type_key, config.template_prefix .. slug
        )))
    end
    table.insert(output, '</div>')

    return table.concat(output, "\n")
end

return p
Cookies help us deliver our services. By using our services, you agree to our use of cookies.