모듈:Metadata
게임 메타데이터를 다루는 모듈입니다.
icon
게임 메타데이터를 바탕으로 게임아이콘을 만듭니다.
{{#invoke:metadata|icon|(게임 문서)}}
get
게임 메타데이터의 특정 속성을 불러옵니다. 이때, 원본 값을 그대로 불러오는 것이 아닌 활용하기 편한 형태로 불러오는 기능입니다. 일반적으로는 원본 값이지만, 특별히 수정된 경우 가공된 값이 불러와집니다.
{{#invoke:metadata|get|(게임 문서)|(속성)}}
rating
게임 등급을 불러옵니다. 리버티게임 등급 분류와 게임물관리위원회 등급 분류를 구별하지 않고 바로 등급만 가져옵니다.
{{#invoke:metadata|get|(게임 문서)|rating}}
if
게임 메타데이터의 특정 속성의 존재 여부를 확인하고, 있을 때와 없을 때 나올 내용을 구분합니다.
{{#invoke:metadata|if|(게임 문서)|(속성)|(있을 때)|(없을 때)}}
role
특정 사용자가 게임의 제작자인지, 기여자(조력자)인지, 이에 해당되지 않는 지 확인합니다. 제작자일 경우 author가, 기여자일 경우 contributor가 반환됩니다.
{{#invoke:metadata|role|(게임 문서)|(사용자 이름)}}
resolve
게임 메타데이터가 있는 문서를 찾습니다. 대상 문서의 하위 문서에 game.json이 없다면 그 상위 문서에서 찾고, 없으면 반복하며 있으면 찾은 game.json 문서에서 멈춥니다. 대상 문서가 넘겨주기 문서인 경우 넘어가는 문서를 기준으로 찾습니다. mw.title 객체를 반환하며 문자열로 변환해 문서 제목을 얻거나, :getContent() 함수를 통해 game.json 내용을 확인할 수 있습니다. 찾은 game.json 문서가 없다면 nil이 반환됩니다.
p.resolve(title)
root
게임의 최상위 문서를 찾습니다. 정확히는 게임 메타데이터(game.json)을 하위 문서로 갖는 문서를 찾습니다. mw.title 객체를 반환하며 문자열로 변환해 문서 제목을 얻거나, :getContent() 함수를 통해 game.json 내용을 확인할 수 있습니다. 찾은 game.json 문서가 없다면 루트 페이지가 반환됩니다.
p.root(title)
subpage
게임의 최상위 문서 바로 아래에 있는 하위 문서를 찾습니다. 첫번째 인수는 현재 위치 및 최상위 문서입니다. 현재 위치를 넣으면 root 함수를 통해 알아서 최상위 문서를 찾아줍니다. 두번째 인수는 하위 문서의 상대적 경로입니다. 예를 들어, 어떤 게임/하위
라는 문서를 가리키고 싶을 경우 두번째 인수에 /하위
만 입력하면 절대 경로인 어떤 게임/하위
를 반환합니다. mw.title 객체를 반환하며 문자열로 변환해 문서 제목을 얻거나, :getContent() 함수를 통해 game.json 내용을 확인할 수 있습니다. 찾은 game.json 문서가 없다면 nil이 반환됩니다.
p.subpage(title, path)
위 설명은 모듈:Metadata/설명문서의 내용을 가져와 보여주고 있습니다. (편집 | 역사) 이 모듈에 대한 수정 연습과 시험은 연습장 (만들기 | 미러)과 시험장 (만들기)에서 할 수 있습니다. 분류는 /설명문서에 넣어주세요. 이 모듈에 딸린 문서. |
local p = {} -- 패키지
-- 상수 시작
local DEFAULT_IMG = {
progress = "[[파일:Progress unknown.svg|완성도 정도를 입력하세요|링크=|16px]]",
openness = "[[파일:Crystal Clear action info.svg|17px|개방성 정도를 입력하세요|링크=]]",
tech = "[[파일:Tech unknown.svg|게임 구조를 입력하세요|링크=]]",
rating = "[[파일:GRAC Square Template.svg|16px|게임 제작자가 이용가 등급 판정을 하지 않았습니다|링크=]]"
}
local PROGRESS_IMG = {
[0] = "[[파일:Progress base.svg|변경하지 말아야 하는 공사중인 게임|링크=|16px]]",
[1] = "[[파일:Progress low.svg|조금 완성된 게임|링크=|16px]]",
[2] = "[[파일:Progress medium.svg|중간 정도 완성된 게임|링크=|16px]]",
[3] = "[[파일:Progress high.svg|거의 완성된 게임|링크=|16px]]",
[4] = "[[파일:Progress full.svg|완성되었지만 추가할 수 있는 게임|링크=|16px]]",
[5] = "[[파일:백괴게임 완성도 7단계.svg|완성되어 변경하지 말아야 하는 게임|링크=|16px]]"
}
local ABANDON = {} --Symbol
local OPENNESS_IMG = {
[false] = "[[파일:Crystal Clear action editdelete.png|17px|편집 금지|링크=]]",
partial = "[[파일:Crystal Clear bot on trial2.png|17px|규칙에 따라 편집 가능|링크=]]",
[true] = "[[파일:Crystal Clear app clean.png|17px|편집 가능|링크=]]",
[ABANDON] = "[[파일:Crystal Clear app logout.png|17px|버려진 게임|링크=]]"
}
local TECH_IMG = {
link = "[[파일:Tech link.svg|링크|링크=]]",
cgi = "[[파일:Tech CGI.svg|CGI|링크=]]",
windows = "[[파일:Windows logo - 2021.svg|16px|윈도우|링크=]]",
db = "[[파일:Tech DB.svg|DB|링크=]]",
javascript = "[[파일:Tech JS.svg|16px|자바스크립트|링크=]]",
lua = "[[파일:Tech Lua.svg|16px|루아|링크=]]",
other = "[[파일:Tech other.svg|기타|링크=]]"
}
local RATING_IMG = {
[18] = "[[파일:GRAC 18 Square.svg|16px|청소년 이용불가|링크=]]",
[15] = "[[파일:GRAC 15 Square.svg|16px|15세 이용가|링크=]]",
[12] = "[[파일:GRAC 12 Square.svg|16px|12세 이용가|링크=]]",
all = "[[파일:GRAC All Square.svg|16px|전체 이용가|링크=]]",
test = "[[파일:GRAC Test Square.svg|16px|평가하고 있는 중입니다|링크=]]"
}
-- 상수 끝 코드 시작
function userLink(user, display)
local title = mw.title.new(user, 'User')
return '[[' .. tostring(title) .. '|' .. (display or title.subpageText) .. ']]'
end
function p.icon(frame)
local title = frame.args[1]
local doc = mw.title.new(title .. '/game.json')
if not doc.exists then
return mw.html.create('span'):addClass('error')
:wikitext('[[' .. title .. '/game.json]] 문서가 존재하지 않습니다. 메타데이터 문서를 만들어 주세요.')
:done()
end
local data = mw.text.jsonDecode(doc:getContent())
local icon = mw.html.create('span'):addClass('gameicon')
-- status
local openness = data.openness
if data.abandon then
openness = ABANDON
end
local status = icon:tag('span'):addClass('gameicon-status')
:wikitext(data.progress ~= nil and PROGRESS_IMG[data.progress] or DEFAULT_IMG.progress)
:wikitext(openness ~= nil and OPENNESS_IMG[openness] or DEFAULT_IMG.openness)
:wikitext(data.tech and TECH_IMG[data.tech] or DEFAULT_IMG.tech)
:wikitext(data.rating and RATING_IMG[data.rating] or DEFAULT_IMG.rating)
:attr{
['data-progress'] = data.progress,
['data-openness'] = openness == ABANDON and "true" or tostring(openness),
['data-tech'] = data.tech,
['data-rating'] = data.rating
}
if data.abandon then
status:attr('data-abandon', '')
end
-- name
icon:tag('span'):addClass('gameicon-name')
:wikitext('[[' .. title .. '|' .. (data.name or title) .. ']]')
-- maker
local contributor
if data.contributor then
contributor = ""
if type(data.contributor) == 'string' then
data.contributor = {data.contributor}
end
for index, name in pairs(data.contributor) do
contributor = contributor .. userLink(name) .. ", "
end
contributor = contributor:sub(1, -3) .. " 사용자께서 도와주셨습니다."
end
local author
if data.author then
if type(data.author) == 'table' then
author = ""
for index, name in pairs(data.author) do
author = author .. userLink(name) .. ", "
end
author = author:sub(1, -2)
else
author = userLink(data.author)
end
icon:tag('span'):addClass('gameicon-maker')
:wikitext(contributor and frame:expandTemplate{
title = '툴팁',
args = {author, contributor, sym = 1, class='messagebox gameicon-contributor'}
} or author)
end
return icon:allDone()
end
function rel2abs(rel, base)
return mw.getCurrentFrame():callParserFunction('#rel2abs', rel, base)
end
function getData(source)
local title = mw.title.new(rel2abs(source))
local result, data = pcall(mw.text.jsonDecode, title and title:getContent() or source)
if result then
return data
else
error('유효하지 않은 게임 메타데이터', 2)
end
end
function p.role(frame)
local data = getData(frame.args[1])
local user = mw.title.new(frame.args[2], 'User')
local authors = type(data.author) == 'string' and {data.author} or data.author
local contributors = type(data.contributor) == 'string' and {data.contributor} or data.contributor
for index, author in ipairs(authors) do
if mw.title.equals(user, mw.title.new(author, 'User')) then
return 'author'
end
end
if contributors then
for index, contributor in ipairs(contributors) do
if mw.title.equals(user, mw.title.new(contributor, 'User')) then
return 'contributor'
end
end
end
end
return p