Mô đun:Author
Mô đun này xử lý logic trong các trang không gian tên Tác gia. Nó dùng Wikidata khi có thể, và cho phép ghi đè nếu cần.
Kiểm thử tại Mô đun:Author/kiểm thử và kết quả có thể xem tại Thảo luận Mô đun:Author/kiểm thử.
Hàm: dates
sửa
Lấy chuỗi ngày tháng trang tác gia và ghi thể loại.
- Cách dùng
- Thường dùng:
{{#gọi|Author|dates}}
- Đầy đủ tham số:
{{#gọi|Author|dates|birthyear=|deathyear=|dates=|wikidata_id=}}
{{#gọi|Author|dates|năm sinh=|năm mất=|năm=|mã wikidata=}}
- Tham số
-
năm
— nếu có thì dùng chính tham số để hiển thị năm (tuy nhiên, năm sinh và năm mất vẫn có thể dùng để tạo thể loại)năm sinh
vànăm mất
— năm sinh và mất, theo định dạng sau:- năm số
- "?" hoặc để trống nếu không rõ (hoặc còn sống)
- dùng TCN cho năm trước Năm 1
- Năm xấp xỉ:
- Thập niên hoặc thế kỷ: "1930s" or "20th century"
- Circa: "c/1930" or "c. 1930" or "ca 1930" or "circa 1930"
- Tenuous year: "1932/?"
- Choice of two or more years: "1932/1933"
wikidata_id
— the Wikidata identifier to use. Will default to the current page if not supplied.pagetitle
— a page title to use instead of the current page (only used for testing purposes).
- Returns
- This function returns the author's birth and death years, wrapped in parentheses and separated by an en dash. The return string is prefixed with a <br />, and suffixed with the list of appropriate categories (see below).
Thể loại
sửaHàm này thêm trang vào các thể loại sau:
- Trong mọi trường hợp (khi có thể):
Thể loại:Sinh <năm>
vàThể loại:Mất <năm>
Thể loại:Tác gia <thời kỳ>
với thời kỳ được định nghĩa tạiMô đun:Date.era()
- Thể loại:Tác gia không rõ năm sinh và Thể loại:Tác gia không rõ năm mất
- Thể loại:Tác gia có năm sinh xấp xỉ và Thể loại:Tác gia có năm mất xấp xỉ
- Thể loại:Tác gia thiếu năm sinh và Thể loại:Tác gia thiếu năm mất
- Thể loại:Tác gia có khoảng thời gian sống
- Thể loại:Tác gia còn sống
- Thể loại:Tác gia có tiêu đề năm không khớp (nếu ngày hiện trong tiêu đề trang - khi cần định hướng, và nó không khớp với Wikidata)
- Nếu năm sinh và/hoặc năm mất bị ghi đè:
- Thể loại:Tác gia có năm bị ghi đè (khi dùng tham số
năm
) - Thể loại:Tác gia có năm sinh bị ghi đè và Thể loại:Tác gia có năm mất bị ghi đè
- Thể loại:Tác gia có năm sinh không phải số và Thể loại:Tác gia có năm mất không phải số
- Thể loại:Tác gia có năm sinh khác với Wikidata và Thể loại:Tác gia có năm mất khác với Wikidata
- Thể loại:Tác gia có năm bị ghi đè (khi dùng tham số
Function: date
sửa
Get a single formatted date, with no categories.
- Usage
- Common usage:
{{#invoke|Author|date|type=}}
- All parameters:
{{#invoke|Author|date|type=|year=|wikidata_id=}}
- Parameters
-
type
— eitherbirth
ordeath
.year
— the year to display, following the same format asbirthyear
in the dates function above.wikidata_id
— the Wikdiata Q-identifier of the author to use.
- Returns
- A simple string with no categories or leading or trailing line breaks.
-- Global variables.
dateModule = require( "Mô đun:Date" )
tableToolsModule = require( "Mô đun:TableTools" )
categories = {} -- List of categories to add page to.
-- Việt hóa tham số
local argByViArg = {
["năm sinh"] = "birthyear",
["năm mất"] = "deathyear",
["trôi"] = "dates",
["rộng"] = "wikidata_id"
}
local rawGetArgs = require('Mô đun:Arguments').getArgs
local getArgs = function (frame, options)
local args = rawGetArgs(frame, options)
for viArgName, argName in pairs(argByViArg) do
if args[viArgName] then
args[argName] = args[viArgName]
end
end
return args
end
--------------------------------------------------------------------------------
-- Get a given or family name property. This concatenates (with spaces) all
-- statements of the given property in order of the series ordinal (P1545)
-- qualifier. @TODO fix this.
function getNameFromWikidata( item, property )
local statements = item:getBestStatements( property )
local out = {}
if statements[1] ~= nil and statements[1].mainsnak.datavalue ~= nil then
local itemId = statements[1].mainsnak.datavalue.value.id
table.insert( out, mw.wikibase.label( itemId ) or '' )
end
return table.concat( out, ' ' )
end
--------------------------------------------------------------------------------
function getPropertyValue( item, property )
local statements = item:getBestStatements( property )
if statements[1] ~= nil and statements[1].mainsnak.datavalue ~= nil then
return statements[1].mainsnak.datavalue.value
end
end
--------------------------------------------------------------------------------
-- Định dạng năm sinh và mất tại 'Wikisource' như sau:
-- "?" hoặc để trống nếu không rõ (hoặc còn sống)or empty for unknown (or still alive)
-- Dùng TCN cho năm trước Năm 1
-- Năm gần đúng:
-- Thập niên hoặc thế kỷ: "thập niên 1930" hoặc "thế kỷ 20"
-- Khoảng: "k/1930" hoặc "k. 1930" hoặc "kh 1930" hoặc "khoảng 1930"
-- Có năm nhưng không chắc: "1932/?"
-- Có thể là một trong nhiều năm: "1932/1933"
-- Hàm này hơi phức tạp hơn bình thường, nhưng sau này có thể xóa.
-- @param dạng chuỗi hoặc 'sinh' hoặc 'mất'
-- @return dãy năm để hiển thị
function formatWikisourceYear( year, type )
if year == nil or year == '' then
return ''
end
local yearParts = mw.text.split( year, '/', true )
-- Ends in a question mark.
if yearParts[2] == '?' then
addCategory( 'Tác gia không rõ năm ' .. type)
if tonumber( yearParts[1] ) == nil then
addCategory( 'Tác gia có năm ' .. type .. ' không phải số' )
else
addCategory( 'Tác gia ' .. dateModule.era( yearParts[1] ) )
addCategory( type .. ' ' .. yearParts[1] )
end
return yearParts[1] .. '?'
end
-- Bắt đầu bằng viết tắt 'khoảng'
local circaNames = { 'k', 'k.', 'kh', 'kh.', 'khoảng' }
for _, circaName in pairs( circaNames ) do
if yearParts[1] == circaName then
addCategory( 'Tác gia có năm ' .. type .. ' xấp xỉ' )
local out = 'khoảng ' .. yearParts[2]
if tonumber( yearParts[2] ) == nil then
addCategory( 'Tác gia có năm ' .. type .. ' không phải số' )
else
addCategory( 'Tác gia ' .. dateModule.era( yearParts[2] ) )
addCategory( type .. ' ' .. yearParts[2] )
end
return out
end
end
-- Nếu có nhiều hơn một năm, và tất cả đều là số, thêm thể loại.
local allPartsAreNumeric = true
if #yearParts > 1 then
for _, yearPart in pairs( yearParts ) do
if tonumber( yearPart ) ~= nil then
addCategory( type .. ' ' .. yearPart )
addCategory( 'Tác gia ' .. dateModule.era( yearPart ) )
else
allPartsAreNumeric = false
end
end
if allPartsAreNumeric then
addCategory( 'Tác gia có năm sinh xấp xỉ' )
end
end
-- Ngược lại, chỉ dùng cái được cung cấp
if #yearParts == 1 and tonumber( year ) == nil then
addCategory( 'Tác gia có năm ' .. type .. ' không phải số' )
end
if #yearParts == 1 or allPartsAreNumeric == false then
addCategory( type .. ' ' .. year )
end
return year
end
--------------------------------------------------------------------------------
-- Lấy năm được định dạng từ thuộc tính có sẵn và thêm thể loại phù hợp.
-- P569 ngày sinh
-- P570 ngày mất
-- P1317 sống vào khoảng
function formatWikidataYear( item, property )
-- Kiểm tra độ sạch sẽ.
if item == nil or string.sub( property, 1, 1 ) ~= 'P' then
return ''
end
local type = 'sinh'
if property == 'P570' then
type = 'mất'
end
-- Lấy thông tin thuộc tính.
local statements = item:getBestStatements( property )
if #statements == 0 then
-- Nếu không có thông tin nào cả, thêm thể loại 'thiếu'.
if type == 'sinh' or type == 'mất' then
addCategory( 'Tác gia không rõ năm ' .. type )
end
local isHuman = item:formatPropertyValues( 'P31' ).value == 'người'
if type == 'mất' and isHuman then
-- Nếu không có thông tin ngày mất, cho là còn sống.
addCategory( 'Tác gia còn sống' )
end
end
-- Soạn danh sách năm, mỗi cái từ mỗi thông tin.
local years = {}
for _, statement in pairs( statements ) do
local year = getYearStringFromSingleStatement( statement, type )
table.insert( years, year )
end
years = tableToolsModule.removeDuplicates( tableToolsModule.compressSparseArray( years ) )
-- Nếu không tìm thấy năm nào, thử tìm sống vào khoảng.
if #years == 0 or table.concat( years, '/' ) == '?' then
floruitStatements = item:getBestStatements( 'P1317' )
for _, statement in pairs( floruitStatements ) do
-- Nếu tất cả những gì có là 'không rõ', thay nó.
if table.concat( years, '/' ) == '?' then
years = {}
end
addCategory( 'Tác gia có khoảng thời gian sống' )
year = getYearStringFromSingleStatement( statement, 'sống' )
table.insert( years, year )
end
end
years = tableToolsModule.removeDuplicates( tableToolsModule.compressSparseArray( years ) )
-- sắp xếp theo năm( years );
return table.concat( years, '/' )
end
--------------------------------------------------------------------------------
-- Lấy một thông tin về một thuộc tính cung cấp và tạo ra một dãy năm dễ đọc
-- thêm thể loại phù hợp khi làm.
-- @param table statement Phần thông tin.
-- @param string type Một trong 'sinh' hoặc 'mất'.
function getYearStringFromSingleStatement( statement, type )
local snak = statement.mainsnak
-- Chúng không dùng mw.wikibase.formatValue vì chỉ muốn lấy năm.
-- Không có giá trị. Sai cho năm sinh (nên là 'giá trị nào đó')
-- và ghi 'còn sống' cho năm mất.
if snak.snaktype == 'novalue' and type == 'sinh' then
addCategory( 'Tác gia thiếu năm sinh' )
return ''
end
if snak.snaktype == 'novalue' and type == 'mất' then
addCategory( 'Tác gia còn sống' )
return ''
end
-- Giá trị không rõ
if snak.snaktype == 'somevalue' then
addCategory( 'Tác gia không rõ năm ' .. type )
return '?'
end
-- Lấy năm từ giá trị thời gian.
local _,_, extractedYear = string.find( snak.datavalue.value.time, '([%+%-]%d%d%d+)%-' )
year = math.abs( tonumber( extractedYear ) )
addCategory( 'Tác gia ' .. dateModule.era( extractedYear ) )
-- Độ chính xác thế kỷ và thiên niên kỷ.
if snak.datavalue.value.precision == 6 or snak.datavalue.value.precision == 7 then
local ceilfactor = 100
local precisionName = 'thế kỷ'
if snak.datavalue.value.precision == 6 then
ceilfactor = 1000
precisionName = 'thiên niên kỷ'
end
local cent = math.max( math.ceil( year / ceilfactor ), 1 )
-- @TODO: extract this to use something like [[en:wikipedia:Module:Ordinal]]
year = precisionName .. ' ' .. cent
addCategory( 'Tác gia có năm ' .. type .. ' xấp xỉ' )
end
if snak.datavalue.value.precision == 8 then -- decade precision
year = 'thập niên ' .. math.floor( tonumber( year ) / 10 ) * 10
addCategory( 'Tác gia có năm ' .. type .. ' xấp xỉ' )
end
if tonumber( extractedYear ) < 0 then
year = year .. ' TCN'
end
-- Bỏ ra khỏi 'Tác gia còn sống' khi điều đó là vô lý.
if tonumber( extractedYear ) < tonumber( os.date( '%Y' ) - 110 ) then
removeCategory( 'Tác gia còn sống' )
end
-- Thêm vào thể loại 'Sinh YYYY' (trước khi thêm tiền tố 'khoảng ' hay 'sống vào khoảng').
if type == 'sinh' or type == 'mất' then
addCategory( type .. ' ' .. year )
end
-- Lấy xấp xỉ (P1480 = mức độ chính xác, Q5727902 = khoảng)
if statement.qualifiers ~= nil and statement.qualifiers.P1480 ~= nil then
for _,qualifier in pairs(statement.qualifiers.P1480) do
if qualifier.datavalue.value.id == 'Q5727902' then
addCategory( 'Tác gia có năm ' .. type .. ' xấp xỉ' )
year = 'khoảng ' .. year
end
end
end
-- Add floruit abbreviation.
if type == 'sống' then
year = 'sống ' .. year
end
return year
end
--------------------------------------------------------------------------------
-- Thêm thể loại vào danh sách thể loại hiện tại. Không ghi tiền tố Thể loại.
function addCategory( category )
for _, cat in pairs( categories ) do
if cat == category then
-- Đã có rồi
return
end
end
table.insert( categories, category )
end
--------------------------------------------------------------------------------
-- Xóa thể loại. Không ghi tiền tố Thể loại.
function removeCategory( category )
for catPos, cat in pairs( categories ) do
if cat == category then
table.remove( categories, catPos )
end
end
end
--------------------------------------------------------------------------------
-- Lấy mã wiki của các thể loại dùng addCategory.
function getCategories()
table.sort( categories )
local out = ''
for _, cat in pairs( categories ) do
out = out .. '[[Thể loại:' .. cat .. ']]'
end
return out
end
--------------------------------------------------------------------------------
-- Kiểm tra tựa trang hiện tại có năm đúng làm hậu tố định hướng.
function checkTitleDatesAgainstWikidata( title, wikidata_id )
-- Tất cả trang tác gia định hướng đều có ngoặc đơn trong tên.
local titleHasParentheses = string.find( tostring( title ), '%d%)' )
if titleHasParentheses == nil then
return
end
-- Tựa trang nên kết thúc bằng năm có cùng định dạng như trong tiêu đề
-- trang nhưng với dấu gạch thông thường thay vì gạch dài.
local birthYear = date( { type = 'sinh'; wikidata_id = wikidata_id } )
local deathYear = date( { type = 'mất'; wikidata_id = wikidata_id } )
local dates = '(' .. birthYear .. '-' .. deathYear .. ')'
if string.sub( tostring( title ), -string.len( dates ) ) ~= dates then
addCategory( 'Tác gia có tiêu đề năm không khớp' )
end
end
--------------------------------------------------------------------------------
-- Lấy chuỗi định dạng năm mà tác gia đã sống,
-- sau đó xếp vào thể loại phù hợp.
-- Chuỗi trả về bắt đầu bằng xuống hàng (<br />).
function dates( args )
local item = mw.wikibase.getEntity()
if args.wikidata_id ~= nil and args.wikidata_id ~= '' then
-- Kiểm tra này là cần thiết vì getEntity không chép được chuỗi trống.
item = mw.wikibase.getEntity( args.wikidata_id )
end
local outHtml = mw.html.create()
-- Kiểm tra trang định hướng có tiêu đề đúng chưa.
checkTitleDatesAgainstWikidata( args.pagetitle or mw.title.getCurrentTitle(), args.wikidata_id )
-- Lấy năm (năm mất trước, để sau đó năm sinh có ghi đè thể loại khi cần):
-- Mất.
local wikidataDeathyear = formatWikidataYear( item, 'P570' ) -- P570 Ngày mất
local wikisourceDeathyear = formatWikisourceYear( args.deathyear, 'mất' )
if args.deathyear == nil or args.deathyear == '' then
args.deathyear = wikidataDeathyear
else
-- Đối với năm mất do Wikisource tự ghi.
args.deathyear = wikisourceDeathyear
addCategory( 'Tác gia có năm mất bị ghi đè' )
if item ~= nil and wikisourceDeathyear ~= wikidataDeathyear then
addCategory( 'Tác gia có năm mất khác với Wikidata' )
end
if tonumber( args.deathyear ) ~= nil then
addCategory( 'Tác gia ' .. dateModule.era( args.deathyear ))
end
end
if args.deathyear == '' and item == nil then
addCategory( 'Tác gia thiếu năm mất' )
end
-- Sinh.
local wikidataBirthyear = formatWikidataYear( item, 'P569' ) -- P569 Ngày sinh
local wikisourceBirthyear = formatWikisourceYear( args.birthyear, 'sinh' )
if args.birthyear == nil or args.birthyear == '' then
args.birthyear = wikidataBirthyear
else
-- Đối với năm sinh do Wikisource tự ghi.
args.birthyear = wikisourceBirthyear
addCategory( 'Tác gia có năm sinh bị ghi đè' )
if item ~= nil and wikisourceBirthyear ~= wikidataBirthyear then
addCategory( 'Tác gia có năm sinh khác với Wikidata' )
end
if tonumber( args.birthyear ) ~= nil then
addCategory( 'Tác gia ' .. dateModule.era( args.birthyear ))
end
end
if args.birthyear == '' then
addCategory( 'Tác gia thiếu năm sinh' )
end
-- Ghép chúng lại, gồm cả ghi đè năm.
local dates = ''
if args.dates ~= nil and args.dates ~= '' then
-- Ngoặc được lặp lại ở đây và trong getFormattedDates()
addCategory( 'Tác gia có năm bị ghi đè' )
dates = '<br />(' .. args.dates .. ')'
else
dates = getFormattedDates( args.birthyear, args.deathyear )
end
outHtml:wikitext( dates .. getCategories() )
return tostring( outHtml )
end
--------------------------------------------------------------------------------
-- Lấy ngày định dạng đơn, không có thể loại.
-- args.year, args.type, args.wikidata_id
function date( args )
if args.type == nil then
args.type = 'sinh'
end
if args.year == nil or args.year == '' then
if args.wikidata_id == '' then
-- Nil nếu không ghi.
args.wikidata_id = nil
end
local item = mw.wikibase.getEntity( args.wikidata_id )
local property = 'P570' -- P570 Ngày mất
if args.type == 'sinh' then
property = 'P569' -- P569 Ngày sinh
end
return formatWikidataYear( item, property )
else
return formatWikisourceYear( args.year, args.type )
end
end
--------------------------------------------------------------------------------
-- Lấy chuỗi HTML đóng trong ngoặc thật sự để hiển thị ngày.
function getFormattedDates( birthyear, deathyear )
local dates = ''
if birthyear ~= '' or deathyear ~= '' then
dates = dates .. '<br />('
end
if birthyear ~= '' then
dates = dates .. birthyear
end
if ( birthyear ~= '' or deathyear ~= '' ) and birthyear ~= deathyear then
-- Thêm khoảng trống nếu có khoảng trống giữa các năm.
local spaces = ''
if string.match( birthyear .. deathyear, ' ' ) then
spaces = ' '
end
dates = dates .. spaces .. '–' .. spaces
end
if deathyear ~= '' and birthyear ~= deathyear then
dates = dates .. deathyear
end
if birthyear ~= '' or deathyear ~= '' then
dates = dates .. ')'
end
return dates
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Export all public functions.
return {
header = function( frame ) return header( frame.args ) end;
dates = function( frame ) return dates( frame.args ) end;
date = function( frame ) return date( frame.args ) end;
}