Module:Concert location
This Lua module is designed to automatically generate categories for concert pages based on the location, date, and artist provided in an infobox.
Features
- Detects U.S. states by abbreviation (e.g., "CA") or full name (e.g., "California").
- Detects non-U.S. countries by using the text after the last comma in the location string, with support for multi-word country names and common aliases (e.g., "London, UK" → "United Kingdom").
- Automatically prefixes "the" for country names when appropriate (e.g., "The Bahamas", "The Netherlands").
- Supports sorting by year, extracted from the date parameter in the infobox.
- Restricts automatic category creation to a predefined list of allowed artists.
Parameters
|location=
: The location of the concert as entered in the infobox.|date=
: The date of the concert (used to extract the year for sort keys).|artist=
: The performing artist (only allowed artists trigger automatic categories).
Usage
This module is intended to be invoked from an infobox template using #invoke and is not meant to be used on its own:
{{#invoke:Concert location|getCategory|{{{location}}}|{{{date}}}|{{{artist}}}}}
Examples
{{Infobox concert
| artist = Weezer
| location = Los Angeles, CA
| date = March 19, 1992
}}
Result: [[Category:Weezer concerts in California|1992]]
{{Infobox concert
| artist = Weezer
| location = London, United Kingdom
| date = August 1, 2022
}}
Result: [[Category:Weezer concerts in the United Kingdom|2022]]
Notes
- If the location is not recognized or the artist is not in the allowed list, no category is generated.
- The module assumes the last word in a non-U.S. location corresponds to the country.
-- Module:Concert location
local p = {}
-- Allowed artists for automatic categorization
local allowed_artists = {
["Weezer"] = true,
}
local states = {
AL="Alabama", AK="Alaska", AZ="Arizona", AR="Arkansas", CA="California",
CO="Colorado", CT="Connecticut", DE="Delaware", FL="Florida", GA="Georgia",
HI="Hawaii", ID="Idaho", IL="Illinois", IN="Indiana", IA="Iowa",
KS="Kansas", KY="Kentucky", LA="Louisiana", ME="Maine", MD="Maryland",
MA="Massachusetts", MI="Michigan", MN="Minnesota", MS="Mississippi",
MO="Missouri", MT="Montana", NE="Nebraska", NV="Nevada", NH="New Hampshire",
NJ="New Jersey", NM="New Mexico", NY="New York", NC="North Carolina",
ND="North Dakota", OH="Ohio", OK="Oklahoma", OR="Oregon", PA="Pennsylvania",
RI="Rhode Island", SC="South Carolina", SD="South Dakota", TN="Tennessee",
TX="Texas", UT="Utah", VT="Vermont", VA="Virginia", WA="Washington",
WV="West Virginia", WI="Wisconsin", WY="Wyoming"
}
-- Reverse lookup table for full state names
local stateNames = {}
for abbr, fullname in pairs(states) do
stateNames[string.upper(fullname)] = fullname
end
-- Countries that require "the" prefix
local countriesWithThe = {
["UNITED KINGDOM"] = true,
["NETHERLANDS"] = true,
["BAHAMAS"] = true,
["PHILIPPINES"] = true,
["CZECH REPUBLIC"] = true,
}
-- Country aliases
local countryAliases = {
["UK"] = "United Kingdom",
["U.K."] = "United Kingdom",
}
-- Extract year from date string
local function extractYear(dateStr)
if not dateStr then return "" end
local year = string.match(dateStr, "%d%d%d%d")
return year or ""
end
-- Trim helper
local function trim(s)
return (s and s:match("^%s*(.-)%s*$")) or ""
end
-- Main function
function p.getCategory(frame)
local location = trim(frame.args[1] or "")
local date = trim(frame.args[2] or "")
local artist = trim(frame.args[3] or "")
local loc_upper = string.upper(location)
local sortKey = extractYear(date)
-- Only process if artist is allowed
if not allowed_artists[artist] or location == "" then
return ""
end
local categoryBase = artist .. " concerts in "
-- Check US state abbreviations first (with or without comma)
for abbr, fullname in pairs(states) do
local abbr_upper = string.upper(abbr)
if string.sub(loc_upper, -string.len(", " .. abbr_upper)) == ", " .. abbr_upper
or string.sub(loc_upper, -string.len(" " .. abbr_upper)) == " " .. abbr_upper
or loc_upper == abbr_upper then
if sortKey ~= "" then
return "[[Category:" .. categoryBase .. fullname .. "|" .. sortKey .. "]]"
else
return "[[Category:" .. categoryBase .. fullname .. "]]"
end
end
end
-- Check full state names
for full_upper, fullname in pairs(stateNames) do
if string.sub(loc_upper, -string.len(", " .. full_upper)) == ", " .. full_upper
or string.sub(loc_upper, -string.len(" " .. full_upper)) == " " .. full_upper
or loc_upper == full_upper then
if sortKey ~= "" then
return "[[Category:" .. categoryBase .. fullname .. "|" .. sortKey .. "]]"
else
return "[[Category:" .. categoryBase .. fullname .. "]]"
end
end
end
-- Fallback for non-US countries: take text after the last comma, trimmed
local place = location:match(",%s*([^,]+)$") or location
place = trim(place)
-- Apply aliases if present
local alias_upper = string.upper(place)
if countryAliases[alias_upper] then
place = countryAliases[alias_upper]
end
-- Add "the" for certain countries
if countriesWithThe[string.upper(place)] then
place = "the " .. place
end
if place ~= "" then
if sortKey ~= "" then
return "[[Category:" .. categoryBase .. place .. "|" .. sortKey .. "]]"
else
return "[[Category:" .. categoryBase .. place .. "]]"
end
end
return "" -- nothing matched
end
return p