Wikisumber mswikisource https://ms.wikisource.org/wiki/Laman_Utama MediaWiki 1.46.0-wmf.23 first-letter Media Khas Perbincangan Pengguna Perbincangan pengguna Wikisumber Perbincangan Wikisumber Fail Perbincangan fail MediaWiki Perbincangan MediaWiki Templat Perbincangan templat Bantuan Perbincangan bantuan Kategori Perbincangan kategori Gerbang Perbincangan gerbang Pengarang Perbincangan pengarang Karya Perbincangan karya Terjemahan Perbincangan terjemahan Laman Perbincangan laman Indeks Perbincangan indeks TimedText TimedText talk Modul Perbincangan modul Acara Perbincangan acara Modul:Arguments 828 986 22790 16216 2026-04-14T13:22:32Z Hakimi97 9 Dilindungi "[[Modul:Arguments]]": Laman berimpak tinggi ([Sunting=Benarkan penyelia sahaja] (tak terbatas) [Pindahkan=Benarkan penyelia sahaja] (tak terbatas)) 16215 Scribunto text/plain --[=[ This module provides easy processing of arguments passed to Scribunto from #invoke. It is intended for use by other Lua modules, and should not be called from #invoke directly. ]=] local libraryUtil = require('libraryUtil') local checkType = libraryUtil.checkType local arguments = {} -- Generate four different tidyVal functions, so that we don't have to check the options every time we call it. local function tidyValDefault(key, val) if type(val) == 'string' then val = val:match('^%s*(.-)%s*$') if val == '' then return nil else return val end else return val end end local function tidyValTrimOnly(key, val) if type(val) == 'string' then return val:match('^%s*(.-)%s*$') else return val end end local function tidyValRemoveBlanksOnly(key, val) if type(val) == 'string' then if val:find('%S') then return val else return nil end else return val end end local function tidyValNoChange(key, val) return val end local function matchesTitle(given, title) local tp = type( given ) return (tp == 'string' or tp == 'number') and mw.title.new( given ).prefixedText == title end local translate_mt = { __index = function(t, k) return k end } function arguments.getArgs(frame, options) checkType('getArgs', 1, frame, 'table', true) checkType('getArgs', 2, options, 'table', true) frame = frame or {} options = options or {} --[[ -- Set up argument translation. --]] options.translate = options.translate or {} if getmetatable(options.translate) == nil then setmetatable(options.translate, translate_mt) end if options.backtranslate == nil then options.backtranslate = {} for k,v in pairs(options.translate) do options.backtranslate[v] = k end end if options.backtranslate and getmetatable(options.backtranslate) == nil then setmetatable(options.backtranslate, { __index = function(t, k) if options.translate[k] ~= k then return nil else return k end end }) end --[[ -- Get the argument tables. If we were passed a valid frame object, get the -- frame arguments (fargs) and the parent frame arguments (pargs), depending -- on the options set and on the parent frame's availability. If we weren't -- passed a valid frame object, we are being called from another Lua module -- or from the debug console, so assume that we were passed a table of args -- directly, and assign it to a new variable (luaArgs). --]] local fargs, pargs, luaArgs if type(frame.args) == 'table' and type(frame.getParent) == 'function' then if options.wrappers then --[[ -- The wrappers option makes Module:Arguments look up arguments in -- either the frame argument table or the parent argument table, but -- not both. This means that users can use either the #invoke syntax -- or a wrapper template without the loss of performance associated -- with looking arguments up in both the frame and the parent frame. -- Module:Arguments will look up arguments in the parent frame -- if it finds the parent frame's title in options.wrapper; -- otherwise it will look up arguments in the frame object passed -- to getArgs. --]] local parent = frame:getParent() if not parent then fargs = frame.args else local title = parent:getTitle():gsub('/sandbox$', '') local found = false if matchesTitle(options.wrappers, title) then found = true elseif type(options.wrappers) == 'table' then for _,v in pairs(options.wrappers) do if matchesTitle(v, title) then found = true break end end end -- We test for false specifically here so that nil (the default) acts like true. if found or options.frameOnly == false then pargs = parent.args end if not found or options.parentOnly == false then fargs = frame.args end end else -- options.wrapper isn't set, so check the other options. if not options.parentOnly then fargs = frame.args end if not options.frameOnly then local parent = frame:getParent() pargs = parent and parent.args or nil end end if options.parentFirst then fargs, pargs = pargs, fargs end else luaArgs = frame end -- Set the order of precedence of the argument tables. If the variables are -- nil, nothing will be added to the table, which is how we avoid clashes -- between the frame/parent args and the Lua args. local argTables = {fargs} argTables[#argTables + 1] = pargs argTables[#argTables + 1] = luaArgs --[[ -- Generate the tidyVal function. If it has been specified by the user, we -- use that; if not, we choose one of four functions depending on the -- options chosen. This is so that we don't have to call the options table -- every time the function is called. --]] local tidyVal = options.valueFunc if tidyVal then if type(tidyVal) ~= 'function' then error( "bad value assigned to option 'valueFunc'" .. '(function expected, got ' .. type(tidyVal) .. ')', 2 ) end elseif options.trim ~= false then if options.removeBlanks ~= false then tidyVal = tidyValDefault else tidyVal = tidyValTrimOnly end else if options.removeBlanks ~= false then tidyVal = tidyValRemoveBlanksOnly else tidyVal = tidyValNoChange end end --[[ -- Set up the args, metaArgs and nilArgs tables. args will be the one -- accessed from functions, and metaArgs will hold the actual arguments. Nil -- arguments are memoized in nilArgs, and the metatable connects all of them -- together. --]] local args, metaArgs, nilArgs, metatable = {}, {}, {}, {} setmetatable(args, metatable) local function mergeArgs(tables) --[[ -- Accepts multiple tables as input and merges their keys and values -- into one table. If a value is already present it is not overwritten; -- tables listed earlier have precedence. We are also memoizing nil -- values, which can be overwritten if they are 's' (soft). --]] for _, t in ipairs(tables) do for key, val in pairs(t) do if metaArgs[key] == nil and nilArgs[key] ~= 'h' then local tidiedVal = tidyVal(key, val) if tidiedVal == nil then nilArgs[key] = 's' else metaArgs[key] = tidiedVal end end end end end --[[ -- Define metatable behaviour. Arguments are memoized in the metaArgs table, -- and are only fetched from the argument tables once. Fetching arguments -- from the argument tables is the most resource-intensive step in this -- module, so we try and avoid it where possible. For this reason, nil -- arguments are also memoized, in the nilArgs table. Also, we keep a record -- in the metatable of when pairs and ipairs have been called, so we do not -- run pairs and ipairs on the argument tables more than once. We also do -- not run ipairs on fargs and pargs if pairs has already been run, as all -- the arguments will already have been copied over. --]] metatable.__index = function (t, key) --[[ -- Fetches an argument when the args table is indexed. First we check -- to see if the value is memoized, and if not we try and fetch it from -- the argument tables. When we check memoization, we need to check -- metaArgs before nilArgs, as both can be non-nil at the same time. -- If the argument is not present in metaArgs, we also check whether -- pairs has been run yet. If pairs has already been run, we return nil. -- This is because all the arguments will have already been copied into -- metaArgs by the mergeArgs function, meaning that any other arguments -- must be nil. --]] if type(key) == 'string' then key = options.translate[key] end local val = metaArgs[key] if val ~= nil then return val elseif metatable.donePairs or nilArgs[key] then return nil end for _, argTable in ipairs(argTables) do local argTableVal = tidyVal(key, argTable[key]) if argTableVal ~= nil then metaArgs[key] = argTableVal return argTableVal end end nilArgs[key] = 'h' return nil end metatable.__newindex = function (t, key, val) -- This function is called when a module tries to add a new value to the -- args table, or tries to change an existing value. if type(key) == 'string' then key = options.translate[key] end if options.readOnly then error( 'could not write to argument table key "' .. tostring(key) .. '"; the table is read-only', 2 ) elseif options.noOverwrite and args[key] ~= nil then error( 'could not write to argument table key "' .. tostring(key) .. '"; overwriting existing arguments is not permitted', 2 ) elseif val == nil then --[[ -- If the argument is to be overwritten with nil, we need to erase -- the value in metaArgs, so that __index, __pairs and __ipairs do -- not use a previous existing value, if present; and we also need -- to memoize the nil in nilArgs, so that the value isn't looked -- up in the argument tables if it is accessed again. --]] metaArgs[key] = nil nilArgs[key] = 'h' else metaArgs[key] = val end end local function translatenext(invariant) local k, v = next(invariant.t, invariant.k) invariant.k = k if k == nil then return nil elseif type(k) ~= 'string' or not options.backtranslate then return k, v else local backtranslate = options.backtranslate[k] if backtranslate == nil then -- Skip this one. This is a tail call, so this won't cause stack overflow return translatenext(invariant) else return backtranslate, v end end end metatable.__pairs = function () -- Called when pairs is run on the args table. if not metatable.donePairs then mergeArgs(argTables) metatable.donePairs = true end return translatenext, { t = metaArgs } end local function inext(t, i) -- This uses our __index metamethod local v = t[i + 1] if v ~= nil then return i + 1, v end end metatable.__ipairs = function (t) -- Called when ipairs is run on the args table. return inext, t, 0 end return args end return arguments ojpf6n6krtbq2o9ezlxv201kqkc2udp Templat:Border 10 1016 22814 7376 2026-04-14T15:50:52Z Hakimi97 9 Hakimi97 telah memindahkan laman [[Templat:Bingkai]] ke [[Templat:Border]] melalui lencongan 7375 wikitext text/x-wiki <includeonly>{{#invoke:Bingkai|border}}</includeonly><noinclude>{{pendokumenan}}</noinclude> 0vevfu4q0vbz5tgqzl8gf9geyq9ym5z Modul:Category handler 828 1344 22791 10174 2026-04-14T13:23:15Z Hakimi97 9 Dilindungi "[[Modul:Category handler]]": Laman berimpak tinggi ([Sunting=Benarkan penyelia sahaja] (tak terbatas) [Pindahkan=Benarkan penyelia sahaja] (tak terbatas)) 6786 Scribunto text/plain -------------------------------------------------------------------------------- -- -- -- CATEGORY HANDLER -- -- -- -- This module implements the {{category handler}} template in Lua, -- -- with a few improvements: all namespaces and all namespace aliases -- -- are supported, and namespace names are detected automatically for -- -- the local wiki. This module requires [[Module:Namespace detect]] -- -- and [[Module:Yesno]] to be available on the local wiki. It can be -- -- configured for different wikis by altering the values in -- -- [[Module:Category handler/config]], and pages can be blacklisted -- -- from categorisation by using [[Module:Category handler/blacklist]]. -- -- -- -------------------------------------------------------------------------------- -- Load required modules local yesno = require('Module:Yesno') -- Lazily load things we don't always need local mShared, mappings local p = {} -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function trimWhitespace(s, removeBlanks) if type(s) ~= 'string' then return s end s = s:match('^%s*(.-)%s*$') if removeBlanks then if s ~= '' then return s else return nil end else return s end end -------------------------------------------------------------------------------- -- CategoryHandler class -------------------------------------------------------------------------------- local CategoryHandler = {} CategoryHandler.__index = CategoryHandler function CategoryHandler.new(data, args) local obj = setmetatable({ _data = data, _args = args }, CategoryHandler) -- Set the title object do local pagename = obj:parameter('demopage') local success, titleObj if pagename then success, titleObj = pcall(mw.title.new, pagename) end if success and titleObj then obj.title = titleObj if titleObj == mw.title.getCurrentTitle() then obj._usesCurrentTitle = true end else obj.title = mw.title.getCurrentTitle() obj._usesCurrentTitle = true end end -- Set suppression parameter values for _, key in ipairs{'nocat', 'categories'} do local value = obj:parameter(key) value = trimWhitespace(value, true) obj['_' .. key] = yesno(value) end do local subpage = obj:parameter('subpage') local category2 = obj:parameter('category2') if type(subpage) == 'string' then subpage = mw.ustring.lower(subpage) end if type(category2) == 'string' then subpage = mw.ustring.lower(category2) end obj._subpage = trimWhitespace(subpage, true) obj._category2 = trimWhitespace(category2) -- don't remove blank values end return obj end function CategoryHandler:parameter(key) local parameterNames = self._data.parameters[key] local pntype = type(parameterNames) if pntype == 'string' or pntype == 'number' then return self._args[parameterNames] elseif pntype == 'table' then for _, name in ipairs(parameterNames) do local value = self._args[name] if value ~= nil then return value end end return nil else error(string.format( 'invalid config key "%s"', tostring(key) ), 2) end end function CategoryHandler:isSuppressedByArguments() return -- See if a category suppression argument has been set. self._nocat == true or self._categories == false or ( self._category2 and self._category2 ~= self._data.category2Yes and self._category2 ~= self._data.category2Negative ) -- Check whether we are on a subpage, and see if categories are -- suppressed based on our subpage status. or self._subpage == self._data.subpageNo and self.title.isSubpage or self._subpage == self._data.subpageOnly and not self.title.isSubpage end function CategoryHandler:shouldSkipBlacklistCheck() -- Check whether the category suppression arguments indicate we -- should skip the blacklist check. return self._nocat == false or self._categories == true or self._category2 == self._data.category2Yes end function CategoryHandler:matchesBlacklist() if self._usesCurrentTitle then return self._data.currentTitleMatchesBlacklist else mShared = mShared or require('Module:Category handler/shared') return mShared.matchesBlacklist( self.title.prefixedText, mw.loadData('Module:Category handler/blacklist') ) end end function CategoryHandler:isSuppressed() -- Find if categories are suppressed by either the arguments or by -- matching the blacklist. return self:isSuppressedByArguments() or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist() end function CategoryHandler:getNamespaceParameters() if self._usesCurrentTitle then return self._data.currentTitleNamespaceParameters else if not mappings then mShared = mShared or require('Module:Category handler/shared') mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData end return mShared.getNamespaceParameters( self.title, mappings ) end end function CategoryHandler:namespaceParametersExist() -- Find whether any namespace parameters have been specified. -- We use the order "all" --> namespace params --> "other" as this is what -- the old template did. if self:parameter('all') then return true end if not mappings then mShared = mShared or require('Module:Category handler/shared') mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData end for ns, params in pairs(mappings) do for i, param in ipairs(params) do if self._args[param] then return true end end end if self:parameter('other') then return true end return false end function CategoryHandler:getCategories() local params = self:getNamespaceParameters() local nsCategory for i, param in ipairs(params) do local value = self._args[param] if value ~= nil then nsCategory = value break end end if nsCategory ~= nil or self:namespaceParametersExist() then -- Namespace parameters exist - advanced usage. if nsCategory == nil then nsCategory = self:parameter('other') end local ret = {self:parameter('all')} local numParam = tonumber(nsCategory) if numParam and numParam >= 1 and math.floor(numParam) == numParam then -- nsCategory is an integer ret[#ret + 1] = self._args[numParam] else ret[#ret + 1] = nsCategory end if #ret < 1 then return nil else return table.concat(ret) end elseif self._data.defaultNamespaces[self.title.namespace] then -- Namespace parameters don't exist, simple usage. return self._args[1] end return nil end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- Used for testing purposes. return { CategoryHandler = CategoryHandler } end function p._main(args, data) data = data or mw.loadData('Module:Category handler/data') local handler = CategoryHandler.new(data, args) if handler:isSuppressed() then return nil end return handler:getCategories() end function p.main(frame, data) data = data or mw.loadData('Module:Category handler/data') local args = require('Module:Arguments').getArgs(frame, { wrappers = data.wrappers, valueFunc = function (k, v) v = trimWhitespace(v) if type(k) == 'number' then if v ~= '' then return v else return nil end else return v end end }) return p._main(args, data) end return p letwavu3yvlayfzew66uuwixmwebq5b Modul:If empty 828 1553 22805 7221 2026-04-14T15:45:49Z Hakimi97 9 Hakimi97 telah memindahkan laman [[Modul:Kalau kosong]] ke [[Modul:Module:If empty]]: Penyelarasan nama dengan Wikisumber Bahasa Inggeris, untuk memudahkan tujuan penyelenggaraan 7221 Scribunto text/plain local p = {} function p.main(frame) local args = require('Modul:Arguments').getArgs(frame, {wrappers = 'Templat:Kalau kosong', removeBlanks = false}) local lastk = 0 for k,v in ipairs(args) do if v ~= '' then return v end lastk = k end end return p m9up657q88je92puwpoobbrvczx3t0z 22807 22805 2026-04-14T15:46:56Z Hakimi97 9 Hakimi97 telah memindahkan laman [[Modul:Module:If empty]] ke [[Modul:If empty]]: Penyelarasan nama dengan Wikisumber Bahasa Inggeris, untuk memudahkan tujuan penyelenggaraan 7221 Scribunto text/plain local p = {} function p.main(frame) local args = require('Modul:Arguments').getArgs(frame, {wrappers = 'Templat:Kalau kosong', removeBlanks = false}) local lastk = 0 for k,v in ipairs(args) do if v ~= '' then return v end lastk = k end end return p m9up657q88je92puwpoobbrvczx3t0z 22813 22807 2026-04-14T15:49:53Z Hakimi97 9 22813 Scribunto text/plain local p = {} function p.main(frame) local args = require('Modul:Arguments').getArgs(frame, {wrappers = 'Templat:If empty', removeBlanks = false}) local lastk = 0 for k,v in ipairs(args) do if v ~= '' then return v end lastk = k end end return p 1du48xao11yhyvrd6n83gajzfc3vo8c Templat:If empty 10 1554 22810 7223 2026-04-14T15:48:26Z Hakimi97 9 Hakimi97 telah memindahkan laman [[Templat:Kalau kosong]] ke [[Templat:If empty]]: Penyelarasan nama dengan Wikisumber Bahasa Inggeris, untuk memudahkan tujuan penyelenggaraan 7223 wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#invoke:Kalau kosong|main}}<noinclude>{{pendokumenan}}</noinclude> 9ysr4ys0ftw4zexwxcccg51ur4nnymp 22812 22810 2026-04-14T15:48:48Z Hakimi97 9 22812 wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#invoke:If empty|main}}<noinclude>{{pendokumenan}}</noinclude> mea1d3d3gr93aa5x6xmfqtnwgpradua Modul:HTML attribute 828 1567 22799 7256 2026-04-14T15:43:34Z Hakimi97 9 Hakimi97 telah memindahkan laman [[Modul:Atribut HTML]] ke [[Modul:HTML attribute]]: Penyelarasan nama dengan Wikisumber Bahasa Inggeris, untuk memudahkan tujuan penyelenggaraan 7256 Scribunto text/plain require('strict') local p = {} local getArgs = require('Modul:Arguments').getArgs function p._attribute(args) local attribs = {} for k, v in pairs(args) do table.insert(attribs, k .. '="' .. v .. '"') end return table.concat(attribs, ' ') end function p.attribute(frame) return p._attribute(getArgs(frame)) end return p 4q2v4vth839d5myulrl2ql6ap3x773g Templat:HTML attribute 10 1568 22797 7258 2026-04-14T15:42:17Z Hakimi97 9 Hakimi97 telah memindahkan laman [[Templat:Atribut HTML]] ke [[Templat:HTML attribute]]: Penyelarasan nama dengan Wikisumber Bahasa Inggeris, untuk memudahkan tujuan penyelenggaraan 7258 wikitext text/x-wiki {{#invoke:Atribut HTML|attribute}}<noinclude>{{pendokumenan}}</noinclude> 4mewzpvikiuasur2egqlmdv1zh45v5d Modul:Border 828 1620 22801 7398 2026-04-14T15:44:24Z Hakimi97 9 Hakimi97 telah memindahkan laman [[Modul:Bingkai]] ke [[Modul:Border]]: Penyelarasan nama dengan Wikisumber Bahasa Inggeris, untuk memudahkan tujuan penyelenggaraan 7398 Scribunto text/plain require('strict') local p = {} --p stands for package local getArgs = require('Modul:Arguments').getArgs local make_style_string = require('Modul:Optional style').make_style_string local CSS_unit = require('Modul:Unit CSS')._CSS_unit function p.border_start(frame) local args = getArgs(frame) -- style args local maxwidth = args['max-width'] or args.maxwidth or args[2] or 'none' local display = args.display or 'block' local bstyle = args.bstyle or args[3] or 'solid' local bthickness = args.bthickness or args[4] or '1px' local color = args.color or args[5] or '#000000' local bgcolor = args.bgcolor or args[6] or '#FFFFFF' local align = args.align or args[7] or 'left' local position = args.position or args[8] local padding = args.padding or args[9] or '5px' local style = args.style or '' local positionStyle if position == 'left' then positionStyle = '' elseif position == 'right' then positionStyle = 'position:relative;margin-left:auto;' else positionStyle = 'margin-left:auto;margin-right:auto;' end local styleArgs = { ['max-width'] = maxwidth, ['display'] = display, ['box-sizing'] = 'border-box', ['border'] = bstyle .. " " .. bthickness .. " " .. color, ['background-color'] = bgcolor, ['text-align'] = align, ['padding'] = padding, ['style'] = positionStyle .. " " .. style } local styleParam = make_style_string(styleArgs) local divOpen = '<div class="wst-border" ' .. styleParam .. '>' local trackingCat if CSS_unit({maxwidth}) == 'px' then trackingCat = '[[Kategori:Laman menggunakan lebar piksel (bingkai)]]' else trackingCat = '' end return divOpen .. trackingCat end local function border_end() return '</div>' end function p.border(frame) return p.border_start(frame) .. getArgs(frame)[1] .. border_end() end return p dzcpfx91baai42jrhzf5soa5ggxf6mo Templat:Border/kotak pasir 10 1627 22816 7393 2026-04-14T15:50:53Z Hakimi97 9 Hakimi97 telah memindahkan laman [[Templat:Bingkai/kotak pasir]] ke [[Templat:Border/kotak pasir]] 7393 wikitext text/x-wiki <includeonly>{{#invoke:Bingkai/kotak_pasir|border}}</includeonly><noinclude>{{pendokumenan}}</noinclude> p0zj4a5t2lfoj1s15uk5w9hago3b544 Indeks:Hikayat Pelanduk Jenaka Or. 1932.pdf 252 1717 22780 18719 2026-04-14T12:32:43Z Hakimi97 9 22780 proofread-index text/x-wiki {{:MediaWiki:Proofreadpage_index_template |Type=book |wikidata_item= |Title=[[Hikayat Pelanduk Jenaka (Or. 1932)|حكاية فلندوق جناک]] |Language=ms-arab |Volume= |Author=عبد الحكيم |Translator= |Editor= |Illustrator= |School= |Publisher= |Address=بتاوي |Year=1718 |Key= |ISBN= |OCLC= |LCCN= |BNF_ARK= |ARC= |DOI= |Source=pdf |Image=9 |Progress=C |Transclusion=yes |Validation_date= |Pages=<pagelist /> |Volumes= |Remarks= |Width=Kelebaran imbasan |Header= |Footer= |tmplver= }} efwn0eskqps9rbkd0y8cnx2dwyx9lpq Pengguna:Hadithfajri/Laman utama 2 1848 22786 17979 2026-04-14T13:08:37Z Hadithfajri 36 22786 wikitext text/x-wiki __NOTOC____NOEDITSECTION__ <templatestyles src="Laman_utama/styles.css" /> {{/Pengepala}}<!-------Kanan---------> <div class="LU-kolom"><div class="LU-kolom-kiri"> {{Kotak berhias |logo=Nuvola apps kpdf recolored.png |tajuk=Jelajahi Wikisumber |isi='''[[:Kategori:Kategori|Berdasarkan Kategori]]'''<br> *[[:Kategori:Agama|Agama]] : [[:Kategori:Islam|Islam]], [[:Kategori:Kristian|Kristian]] *[[:Kategori:Bahasa|Bahasa]] : [[:Kategori:Tatabahasa|Tatabahasa]], [[:Kategori:Kamus|Kamus]] *[[:Kategori:Sastera|Sastera]] : [[:Kategori:Hikayat|Hikayat]], [[:Kategori:Syair|Syair]] *[[:Kategori:Undang-undang Malaysia|Undang-undang Malaysia]] '''[[:Kategori:Pengarang|Berdasarkan Pengarang]]'''}} {{Kotak berhias| |nombor=2 |logo=Foliate icon 2019.svg |tajuk=Kerjasama Penyuntingan |isi=Beberapa projek transkripsi yang sedang dijalankan: ===Projek transkripsi Wikisumber Cinta Bahasa Melayu=== * [[Index:The customs of the Malay kings especially concerning child birth.pdf|The customs of the Malay kings especially concerning child birth]] (1837) * [[Index:Sesuatu yang disebutkan di dalam Quran darihal kitab Injil dan Taurat.pdf|Sesuatu yang disebutkan di dalam Quran darihal kitab Injil dan Taurat]] (1891) * [[Index:Puji-pujian dan segala zabur Daud. The Psalter, or Psalms of David, with the Order for Morning and Evening Prayer daily throughout the year. Third edition.djvu|Puji-pujian dan segala zabur Daud. The Psalter, or Psalms of David, with the Order for Morning and Evening Prayer daily throughout the year. Third edition.]] (1836) ===Projek transkripsi (ruang nama Indeks dan Laman)=== * [[Index:Malaysia Act 1963.pdf|Akta Malaysia Tahun 1963]] (1963) * [[Index:Agreement Relating to Malaysia between UK, N. Borneo, Sarawak and Singapore.djvu|Persetujuan berkenaan dengan penubuhan perlembagaan Malaysia]] (1963) * [[Index:Ikhtisar Ceritera Daripada Raja-raja di Negeri Siam Or. 2011.pdf| Ikhtisar Ceritera Daripada Raja-raja di Negeri Siam Or. 2011]] (1823) * [[Index:Manila Accord (31 July 1963).djvu|Manila Accord]] (1963) * [[Index:Anchaman Komunis kapada Persekutuan Tanah Melayu.djvu|Anchaman Komunis kapada Persekutuan Tanah Melayu]] (1959) * [[Index:Ukpga 19570060 en.djvu|Akta kemerdekaan Persekutuan Tanah Melayu]] (1957) * [[Index:Hikayat Bayan Budiman.djvu|Hikayat Bayan Budiman]] (1371) * [[Index:Hikayat Hang Tuah.djvu|Hikayat Hang Tuah]] * [[Index:Malay-English vocabulary.djvu|Malay-English vocabulary]] (1912) * [[Index:Vocabulary of the English and Malay languages.djvu|Vocabulary of the English and Malay languages]] (1837) * [[Index:Bustan al-Katibin li as-Shibyan al-Mutaallimin.pdf|Bustan al-Katibin]] (1850) * [[Index:Kitab Injil al-Kudus daripada Tuhan Isa al-Masih.pdf|Kitab Injil al-Kudus daripada Tuhan Isa al-Masih]] (1856) * [[Index:Turjuman al-Mustafid.pdf|Turjuman al-Mustafid]] (1952) * [[Index:Hikayat_Abdullah_(1880 version).pdf|Hikayat Abdullah]] (1880) * [[Index:Pr_Terengganu.jpg|Batu Bersurat Terengganu]] (1303) * [[Index:Sejarah_Melayu_Or._1703.pdf|Sulalatus Salatin]] (1834) * [[Index:MSS Malay A2 Syair Perahu 1700.pdf|Syair Perahu (1700)]]}} </div></div> <!-------Kiri---------> <div class="LU-kolom"><div class="LU-kolom-kanan"> {{Kotak berhias |logo=Books_Flat_Icon_Vector.svg |tajuk=Naskhah Yang Selesai Dibacaprufkan |isi=<gallery heights=165 mode="packed"> Fail:The customs of the Malay kings especially concerning child birth.pdf|page=9|link=Adat Segala Raja-Raja Melayu|'''[[Pengarang:Abdullah_bin_Abdulkadir_Munsyi|Abdullah bin Abdulkadir Munsyi]]''',<br /> ''[[Adat Segala Raja-Raja Melayu]]'',<br /> 1837<br /> Fail:A practical Malay grammar (IA practicalmalaygr00sheliala).pdf|page=3|link=A Practical Malay Grammar|'''[[Pengarang:William Girdlestone Shellabear|W.G Shellabear]]''',<br /> ''[[A Practical Malay Grammar]]'',<br /> 1912<br /> Fail:Bustan al-Katibin li as-Shibyan al-Mutaallimin.pdf|page=7|link=Bustan al-Katibin|'''[[Pengarang:Raja Ali Haji|Raja Ali Haji]]''', <br /> ''[[Bustan al-Katibin|Bustan al-Katibin li as-Shibyan al-Mutaallimin]]'',<br />1850<br /> Fail:Collective volume with texts in Malay, Or. 3346.pdf|page=3|link=Syair Kampung Gelam Terbakar|'''[[Pengarang:Abdullah_bin_Abdulkadir_Munsyi|Abdullah bin Abdulkadir Munsyi]]''', <br /> ''[[Syair Kampung Gelam Terbakar]]'',<br />1847<br /> </gallery>}} {{Kotak berhias |nombor=2 |tajuk=Kenali Wikisumber |isi=[[Image:Biblioteket, rummet Stockholm. Polonika. Polsk skrift - Skoklosters slott - 87713.tif|left|120px]] '''Wikisumber''' ialah sebuah perpustakaan dalam talian yang mengandungi koleksi teks bebas dan dipelihara oleh sebuah komuniti yang aktif. Anda boleh membantu kami mengembangkan perpustakaan ini. Kami menerima semua jenis teks '''[[w:Kandungan bebas|bebas]]''' (termasuk daripada [[w:Domain awam|domain awam]], yang diterbitkan dengan [[w:Lesen Dokumentasi Bebas GNU|Lesen Dokumentasi Bebas GNU]], dan yang diterbitkan dengan [[w:Creative Commons|Lesen Creative Commons Pengiktirafan-Perkongsian Serupa]]). Untuk mengetahui bagaimana anda boleh menyumbang, sila kunjungi [[Wikisource:Bantuan|laman bantuan]]. Untuk menanyakan soalan, sila kunjungi laman [[Wikisource:Kedai Kopi|Kedai Kopi]].}} </div></div> <p style="clear: both;"></p> {{kotak berhias |nombor=3 |warna=merah |kanan=3.5em |tajuk=Wikisumber Dalam Bahasa Lain |isi={{BahasaLain}} }} {{kotak berhias |kanan=3.5em |nombor=3 |warna=hijau |logo=Wikimedia-logo.svg |tajuk=Projek Wikimedia yang lain |isi={{Projek saudara}} }} {{DISPLAYTITLE:<span style="position: absolute; clip: rect(1px 1px 1px 1px); clip: rect(1px, 1px, 1px, 1px);">{{FULLPAGENAME}}</span>}} m07bi9rnza6jssvm79wfe1l2nfwkg3v Indeks:Hikayat Iskandar Zulkarnain - volume 1 Or. 1696 1, Or. 1696 1.pdf 252 4001 22783 18716 2026-04-14T12:35:39Z Hakimi97 9 22783 proofread-index text/x-wiki {{:MediaWiki:Proofreadpage_index_template |Type=book |wikidata_item= |Title=[[Hikayat Iskandar Zulkarnain|حکاية سلطان اسکندر ذوالکرنين]] |Language=ms-arab |Volume= |Author= |Translator= |Editor= |Illustrator= |School= |Publisher= |Address= |Year= |Key= |ISBN= |OCLC= |LCCN= |BNF_ARK= |ARC= |DOI= |Source=pdf |Image=10 |Progress=X |Transclusion=no |Validation_date= |Pages=<pagelist /> |Volumes= |Remarks=‌ |Width= |Header= |Footer= |tmplver= }} nd8wrqropvto5l7ncl1lv48eg1qgvyo 22784 22783 2026-04-14T12:35:53Z Hakimi97 9 22784 proofread-index text/x-wiki {{:MediaWiki:Proofreadpage_index_template |Type=book |wikidata_item= |Title=[[Hikayat Iskandar Zulkarnain|حکاية سلطان اسکندر ذوالکرنين]] |Language=ms-arab |Volume= |Author= |Translator= |Editor= |Illustrator= |School= |Publisher= |Address= |Year= |Key= |ISBN= |OCLC= |LCCN= |BNF_ARK= |ARC= |DOI= |Source=pdf |Image=10 |Progress=X |Transclusion=no |Validation_date= |Pages=<pagelist /> |Volumes= |Remarks= |Width= |Header= |Footer= |tmplver= }} l1gme64iwftnak24xemucehjs85dslm Laman:Collective volume with texts in Malay, Or. 1722.pdf/55 250 4350 22794 14294 2026-04-14T13:55:13Z Hadithfajri 36 22794 proofread-page text/x-wiki <noinclude><pagequality level="1" user="Hadithfajri" /></noinclude>{{rangkap| ادا کفد سواة هاري \\ فرݢي برجالن راج بهري دکاراڠ مسکين سواة فري \\ بوليه دبوة فنتون دان ڽاڽي شعير دسکراڠ اورڠيڠ هينا \\ بوة ماين تيدق ݢون باڽق چڠݢل تيدق کنا \\ جاڠن دباوا کسيني سنا بوکنڽ سهيا فوڽ سوک \\ سبب دسوره سري فادک مک شعير سهيا نن ريک \\ بوة ايبور هاتي يڠ دوک اين سوره بيت کاراڠ \\ دفڽاڠة کوتا کاراڠ سورڽ اودوه باڽق کوراڠ \\ تيدق ݢون فد اورڠ تڠکو فتري سوره بيت \\ کاراڠ شعير سوره کات بݢند هندق بوة چريت \\ کاران ادند فرݢي فيت دري تيته توان فڠهول \\ سبب تکوة سرة مالو دي مڽوره سده سلالو \\ تيدق بوله ننتي دهول اف عقل بودي بيت \\ تيدق دافة لاݢ کات تيک کالي سده فينت \\ سوره جوݢ بوة چريت}} }}<noinclude></noinclude> n9jnheaujqtnur4unhlbo6ow1k5k2gg Indeks:Daftar Ejaan Melayu Za'ba AA0001098.pdf 252 5507 22821 17290 2026-04-15T03:28:13Z Hakimi97 9 Percubaan 22821 proofread-index text/x-wiki {{:MediaWiki:Proofreadpage_index_template |Type=book |wikidata_item=Q134106972 |Title= |Language=ms-arab |Volume= |Author= |Translator= |Editor= |Illustrator= |School= |Publisher= |Address= |Year= |Key= |ISBN= |OCLC= |LCCN= |BNF_ARK= |ARC= |DOI= |Source=pdf |Image=1 |Progress=C |Transclusion=no |Validation_date=April 2026 |Pages={{remove pages|pages=18,19,164,165|marked=yes}} <pagelist 1="Tajuk" 2="–" 3="٣" 4="٤" 5="٥" 6="٦" 7="کندوڠن" 8="–" 9="٩" 10="١٠" 11="١١" 12="١٢" 13="١٣" 14="١٤" 15="١٥" 16="١٦" 17="١٧" 18to19="➔" 20="١٨" 21="١٩" 22="٢٠" 23="٢١" 24="٢٢" 25="٢٣" 26="٢٤" 27="٢٥" 28="٢٦" 29="٢٧" 30="٢٨" 31="٢٩" 32="٣٠" 33="٣١" 34="٣٢" 35="٣٣" 36="٣٤" 37="٣٥" 38="٣٦" 39="٣٧" 40="٣٨" 41="٣٩" 42="٤٠" 43="٤١" 44="٤٢" 45="٤٣" 46="٤٤" 47="٤٥" 48="٤٦" 49="٤٧" 50="٤٨" 51="٤٩" 52="٥٠" 53="٥١" 54="٥٢" 55="٥٣" 56="٥٤" 57="٥٥" 58="٥٦" 59="٥٧" 60="٥٨" 61=1 164to165="➔" 166=104 755=1 755to779=roman 776to779=– /> |Volumes= |Remarks= |Width= |Header= |Footer= |tmplver= }} 4xcm4cvatuwfkwb7bz9aelms8b2aewk 22822 22821 2026-04-15T03:28:50Z Hakimi97 9 22822 proofread-index text/x-wiki {{:MediaWiki:Proofreadpage_index_template |Type=book |wikidata_item=Q134106972 |Title= |Language=ms-arab |Volume= |Author= |Translator= |Editor= |Illustrator= |School= |Publisher= |Address= |Year= |Key= |ISBN= |OCLC= |LCCN= |BNF_ARK= |ARC= |DOI= |Source=pdf |Image=1 |Progress=C |Transclusion=no |Validation_date= |Pages={{remove pages|pages=18,19,164,165|marked=yes}} <pagelist 1="Tajuk" 2="–" 3="٣" 4="٤" 5="٥" 6="٦" 7="کندوڠن" 8="–" 9="٩" 10="١٠" 11="١١" 12="١٢" 13="١٣" 14="١٤" 15="١٥" 16="١٦" 17="١٧" 18to19="➔" 20="١٨" 21="١٩" 22="٢٠" 23="٢١" 24="٢٢" 25="٢٣" 26="٢٤" 27="٢٥" 28="٢٦" 29="٢٧" 30="٢٨" 31="٢٩" 32="٣٠" 33="٣١" 34="٣٢" 35="٣٣" 36="٣٤" 37="٣٥" 38="٣٦" 39="٣٧" 40="٣٨" 41="٣٩" 42="٤٠" 43="٤١" 44="٤٢" 45="٤٣" 46="٤٤" 47="٤٥" 48="٤٦" 49="٤٧" 50="٤٨" 51="٤٩" 52="٥٠" 53="٥١" 54="٥٢" 55="٥٣" 56="٥٤" 57="٥٥" 58="٥٦" 59="٥٧" 60="٥٨" 61=1 164to165="➔" 166=104 755=1 755to779=roman 776to779=– /> |Volumes= |Remarks= |Width= |Header= |Footer= |tmplver= }} ohindvnxp4evoraihbhhvstmni2z21c Indeks:Collection des principales chroniques malayes publiée par Éd. Dulaurier.pdf 252 5759 22785 22551 2026-04-14T12:37:33Z Hakimi97 9 22785 proofread-index text/x-wiki {{:MediaWiki:Proofreadpage_index_template |Type=collection |wikidata_item= |Title=[[Hikayat Pasai]] dan [[Sulalatus Salatin]] |Language=ms-arab |Volume= |Author= |Translator= |Editor= |Illustrator= |School= |Publisher= |Address= |Year= |Key= |ISBN= |OCLC= |LCCN= |BNF_ARK= |ARC= |DOI= |Source=pdf |Image=10 |Progress=C |Transclusion=no |Validation_date= |Pages=Muqaddimah - Hikayat Pasai <pagelist from=10 to=133/> Sulalatus Salatin <pagelist from=134 to=402/> |Volumes= |Remarks= |Width= |Header= |Footer= |tmplver= }} odrr07unk625j79cq64k6k9z8rbhf51 Indeks:Hikayat Pelanduk Jinaka, and other texts in Malay and Bugis texts MSS Malay B 10.pdf 252 5784 22831 22605 2026-04-15T05:14:46Z Hakimi97 9 22831 proofread-index text/x-wiki {{:MediaWiki:Proofreadpage_index_template |Type=book |wikidata_item= |Title=حكاية ڤلندوق جناک |Language=ms-arab |Volume= |Author= |Translator= |Editor= |Illustrator= |School= |Publisher= |Address= |Year= |Key= |ISBN= |OCLC= |LCCN= |BNF_ARK= |ARC= |DOI= |Source=pdf |Image=https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Hikayat_Pelanduk_Jinaka%2C_and_other_texts_in_Malay_and_Bugis_texts_MSS_Malay_B_10.pdf/page1-500px-Hikayat_Pelanduk_Jinaka%2C_and_other_texts_in_Malay_and_Bugis_texts_MSS_Malay_B_10.pdf.jpg |Progress=X |Transclusion=no |Validation_date= |Pages=<pagelist /> |Volumes= |Remarks= |Width= |Header= |Footer= |tmplver= }} 1116libbbkgtdfaeua8plr0dhymq0sb 22832 22831 2026-04-15T05:15:02Z Hakimi97 9 22832 proofread-index text/x-wiki {{:MediaWiki:Proofreadpage_index_template |Type=book |wikidata_item= |Title=حكاية ڤلندوق جناک |Language=ms-arab |Volume= |Author= |Translator= |Editor= |Illustrator= |School= |Publisher= |Address= |Year= |Key= |ISBN= |OCLC= |LCCN= |BNF_ARK= |ARC= |DOI= |Source=pdf |Image=1 |Progress=X |Transclusion=no |Validation_date= |Pages=<pagelist /> |Volumes= |Remarks= |Width= |Header= |Footer= |tmplver= }} tpq7nh9dmy2y2yxppd2s9f6vdagktf1 22833 22832 2026-04-15T05:15:56Z Hakimi97 9 22833 proofread-index text/x-wiki {{:MediaWiki:Proofreadpage_index_template |Type=book |wikidata_item= |Title=حكاية ڤلندوق جناک |Language=ms-arab |Volume= |Author= |Translator= |Editor= |Illustrator= |School= |Publisher= |Address= |Year= |Key= |ISBN= |OCLC= |LCCN= |BNF_ARK= |ARC= |DOI= |Source=pdf |Image=1 |Progress=OCR |Transclusion=no |Validation_date= |Pages=<pagelist /> |Volumes= |Remarks= |Width= |Header= |Footer= |tmplver= }} eunkuje9pk3wqjqgytmfydlhurz89ta Modul:Index template/data 828 5997 22788 22770 2026-04-14T13:21:10Z Hakimi97 9 Utilize Modul:Arguments for getArgs 22788 Scribunto text/plain -- Modul:Index template/data -- Fetches and merges Wikidata into template arguments for Malay Wikisource index pages. local cfg = require('Modul:Index template/config') local getArgs = require('Modul:Arguments').getArgs local trim = mw.text.trim -- Static mappings -- Maps Wikidata instance-of (P31) entity IDs to index type strings. local WIKIDATA_TYPE_MAP = { ['Q3331189'] = 'book', ['Q1238720'] = 'journal', ['Q28869365'] = 'journal', ['Q191067'] = 'journal', ['Q23622'] = 'dictionary', ['Q187685'] = 'phdthesis', } -- Maps index parameter names → Wikidata property IDs used for auto-population. -- Comment out a line to disable auto-population for that field. local INDEX_TO_WIKIDATA = { subtitle = 'P1680', language = 'P407', volume = 'P478', edition = 'P393', author = 'P50', translator = 'P655', editor = 'P98', illustrator = 'P110', publisher = 'P123', printer = 'P872', address = 'P276', publishedin = 'P291', year = 'P577', inception = 'P571', parts = 'P747', } -- Argument normalisation -- Build the translate map once at module load (inverts cfg.param_map). -- cfg.param_map is { ['Title'] = 'title', ... } -- translate must be { ['title'] = 'Title', ... } (lua-key → wikitext-key) local TRANSLATE = {} for titleCase, lowerCase in pairs(cfg.param_map) do TRANSLATE[lowerCase] = titleCase end -- Wikidata helpers -- Returns the datavalue.value of the first best statement for `propertyId`, -- or nil if no statement with a datavalue exists. local function getBestStatementValue(item, propertyId) for _, statement in pairs(item:getBestStatements(propertyId)) do local dv = statement.mainsnak.datavalue if dv ~= nil then return dv.value end end return nil end -- Main data builder local function indexDataWithWikidata(frame) local args = getArgs(frame, { parentOnly = true, -- template args live in the parent frame translate = TRANSLATE, }) -- Resolve Wikidata item (if wikidata_item parameter was supplied). local item = nil if args.wikidata_item then item = mw.wikibase.getEntity(args.wikidata_item) if not item then mw.addWarning( 'The Wikidata entity identifier [[d:' .. args.wikidata_item .. '|' .. args.wikidata_item .. ']] put in the "Wikidata entity" parameter of the Book page: ' .. 'does not seem valid.' ) end end if not item then return { args = args, item = nil } end -- Type: derived from instance-of (P31). Stop at the first recognised value. if not args.type then for _, statement in pairs(item:getBestStatements('P31')) do local dv = statement.mainsnak.datavalue if dv ~= nil then local mapped = WIKIDATA_TYPE_MAP[dv.value] if mapped then args.type = mapped break end end end end -- Cover image (P18). if not args.image then local imgValue = getBestStatementValue(item, 'P18') if imgValue then args.image = imgValue end end -- Title: prefer P1476 (title), fall back to label, then sitelink display name. if not args.title then local value = item:formatStatements('P1476').value or '' if value == '' then value = item:getLabel() or '' end if value ~= '' then local siteLink = item:getSitelink() if siteLink then value = '[[' .. siteLink .. '|' .. value .. ']]' end -- Append an edit-on-Wikidata icon. args.title = value .. '&nbsp;[[File:OOjs UI icon edit-ltr.svg' .. '|Lihat dan sunting data pada Wikidata' .. '|10px|baseline|class=noviewer' .. '|link=d:' .. item.id .. '#P1476]]' end end -- Publication date (P577): extract the four-digit year from the timestamp. if not args.year then local timeValue = getBestStatementValue(item, 'P577') if timeValue then args.year = mw.ustring.sub(timeValue.time, 2, 5) end end -- Remaining fields: bulk-populate from Wikidata when not already set. for arg, propertyId in pairs(INDEX_TO_WIKIDATA) do if not args[arg] then local value = item:formatStatements(propertyId).value if value and value ~= '' then args[arg] = value end end end return { args = args, item = item } end -- Public API local p = {} function p.indexDataWithWikidata(frame) return indexDataWithWikidata(frame) end return p pnjd26dtha6xycuf1la3j74kftc747t 22818 22788 2026-04-15T03:23:58Z Hakimi97 9 Code update 22818 Scribunto text/plain -- Modul:Index template/data -- Fetches and merges Wikidata into template arguments for Malay Wikisource index pages. local cfg = require('Modul:Index template/config') local getArgs = require('Modul:Arguments').getArgs -- Static mappings -- Maps Wikidata instance-of (P31) entity IDs to index type strings. local WIKIDATA_TYPE_MAP = { ['Q3331189'] = 'book', ['Q1238720'] = 'journal', ['Q28869365'] = 'journal', ['Q191067'] = 'journal', ['Q23622'] = 'dictionary', ['Q187685'] = 'phdthesis', } -- Maps index parameter names → Wikidata property IDs used for auto-population. -- Comment out a line to disable auto-population for that field. local INDEX_TO_WIKIDATA = { subtitle = 'P1680', language = 'P407', volume = 'P478', edition = 'P393', author = 'P50', translator = 'P655', editor = 'P98', illustrator = 'P110', publisher = 'P123', printer = 'P872', address = 'P276', publishedin = 'P291', year = 'P577', inception = 'P571', parts = 'P747', } -- Argument normalisation -- Build the translate map once at module load (inverts cfg.param_map). -- cfg.param_map is { ['Title'] = 'title', ... } (wikitext-key → lua-key) -- TRANSLATE must be { ['title'] = 'Title', ... } (lua-key → wikitext-key) -- Modul:Arguments uses this to look up Title-Case wikitext params by lua key. local TRANSLATE = {} for titleCase, lowerCase in pairs(cfg.param_map) do TRANSLATE[lowerCase] = titleCase end -- Wikidata helpers -- Returns the datavalue.value of the first best statement for `propertyId`, -- or nil if no statement with a datavalue exists. local function getBestStatementValue(item, propertyId) for _, statement in pairs(item:getBestStatements(propertyId)) do local dv = statement.mainsnak.datavalue if dv ~= nil then return dv.value end end return nil end -- Main data builder local function indexDataWithWikidata(frame) local args = getArgs(frame, { parentOnly = true, -- template args live in the parent frame translate = TRANSLATE, }) -- Resolve Wikidata item (if wikidata_item parameter was supplied). local item = nil if args.wikidata_item then item = mw.wikibase.getEntity(args.wikidata_item) if not item then mw.addWarning( 'The Wikidata entity identifier [[d:' .. args.wikidata_item .. '|' .. args.wikidata_item .. ']] put in the "Wikidata entity" parameter of the Book page: ' .. 'does not seem valid.' ) end end if not item then return { args = args, item = nil } end -- Type: derived from instance-of (P31). Stop at the first recognised value. if not args.type then for _, statement in pairs(item:getBestStatements('P31')) do local dv = statement.mainsnak.datavalue if dv ~= nil then local mapped = WIKIDATA_TYPE_MAP[dv.value] if mapped then args.type = mapped break end end end end -- Cover image (P18). if not args.image then local imgValue = getBestStatementValue(item, 'P18') if imgValue then args.image = imgValue end end -- Title: prefer P1476 (title), fall back to label, then sitelink display name. if not args.title then local value = item:formatStatements('P1476').value or '' if value == '' then value = item:getLabel() or '' end if value ~= '' then local siteLink = item:getSitelink() if siteLink then value = '[[' .. siteLink .. '|' .. value .. ']]' end -- Append an edit-on-Wikidata icon. args.title = value .. '&nbsp;[[File:OOjs UI icon edit-ltr.svg' .. '|Lihat dan sunting data pada Wikidata' .. '|10px|baseline|class=noviewer' .. '|link=d:' .. item.id .. '#P1476]]' end end -- Publication date (P577): extract the four-digit year from the timestamp. if not args.year then local timeValue = getBestStatementValue(item, 'P577') if timeValue then args.year = mw.ustring.sub(timeValue.time, 2, 5) end end -- Remaining fields: bulk-populate from Wikidata when not already set. for arg, propertyId in pairs(INDEX_TO_WIKIDATA) do if not args[arg] then local value = item:formatStatements(propertyId).value if value and value ~= '' then args[arg] = value end end end return { args = args, item = item } end -- Public API local p = {} function p.indexDataWithWikidata(frame) return indexDataWithWikidata(frame) end return p cgjdp1tx0igw94l6bdbes1a2s1up5hx 22829 22818 2026-04-15T05:08:55Z Hakimi97 9 Code consolidation 22829 Scribunto text/plain -- Modul:Index template/data -- Fetches and merges Wikidata into template arguments for Malay Wikisource index pages. local cfg = require('Modul:Index template/config') local getArgs = require('Modul:Arguments').getArgs -- Static mappings -- Maps Wikidata instance-of (P31) entity IDs to index type strings. local WIKIDATA_TYPE_MAP = { ['Q3331189'] = 'book', ['Q1238720'] = 'journal', ['Q28869365'] = 'journal', ['Q191067'] = 'journal', ['Q23622'] = 'dictionary', ['Q187685'] = 'phdthesis', } -- Maps index parameter names → Wikidata property IDs used for auto-population. -- Comment out a line to disable auto-population for that field. local INDEX_TO_WIKIDATA = { subtitle = 'P1680', language = 'P407', volume = 'P478', edition = 'P393', author = 'P50', translator = 'P655', editor = 'P98', illustrator = 'P110', publisher = 'P123', printer = 'P872', address = 'P276', publishedin = 'P291', year = 'P577', inception = 'P571', parts = 'P747', } -- Wikidata helpers -- Returns the datavalue.value of the first best statement for `propertyId`, -- or nil if no statement with a datavalue exists. local function getBestStatementValue(item, propertyId) for _, statement in pairs(item:getBestStatements(propertyId)) do local dv = statement.mainsnak.datavalue if dv ~= nil then return dv.value end end return nil end -- Main data builder local function indexDataWithWikidata(frame) local args = getArgs(frame, { parentOnly = true, -- template args live in the parent frame translate = cfg.translate, }) -- Resolve Wikidata item (if wikidata_item parameter was supplied). local item = nil if args.wikidata_item then item = mw.wikibase.getEntity(args.wikidata_item) if not item then mw.addWarning( 'The Wikidata entity identifier [[d:' .. args.wikidata_item .. '|' .. args.wikidata_item .. ']] put in the "Wikidata entity" parameter of the Book page: ' .. 'does not seem valid.' ) end end if not item then return { args = args, item = nil } end -- Type: derived from instance-of (P31). Stop at the first recognised value. if not args.type then for _, statement in pairs(item:getBestStatements('P31')) do local dv = statement.mainsnak.datavalue if dv ~= nil then local mapped = WIKIDATA_TYPE_MAP[dv.value] if mapped then args.type = mapped break end end end end -- Cover image (P18). if not args.image then local imgValue = getBestStatementValue(item, 'P18') if imgValue then args.image = imgValue end end -- Title: prefer P1476 (title), fall back to label, then sitelink display name. if not args.title then local value = item:formatStatements('P1476').value or '' if value == '' then value = item:getLabel() or '' end if value ~= '' then local siteLink = item:getSitelink() if siteLink then value = '[[' .. siteLink .. '|' .. value .. ']]' end -- Append an edit-on-Wikidata icon. args.title = value .. '&nbsp;[[File:OOjs UI icon edit-ltr.svg' .. '|Lihat dan sunting data pada Wikidata' .. '|10px|baseline|class=noviewer' .. '|link=d:' .. item.id .. '#P1476]]' end end -- Publication date (P577): extract the four-digit year from the timestamp. if not args.year then local timeValue = getBestStatementValue(item, 'P577') if timeValue then args.year = mw.ustring.sub(timeValue.time, 2, 5) end end -- Remaining fields: bulk-populate from Wikidata when not already set. for arg, propertyId in pairs(INDEX_TO_WIKIDATA) do if not args[arg] then local value = item:formatStatements(propertyId).value if value and value ~= '' then args[arg] = value end end end return { args = args, item = item } end -- Public API local p = {} function p.indexDataWithWikidata(frame) return indexDataWithWikidata(frame) end return p so5lpvj1avocz6koq97xw4pkepm68wk Modul:Index template 828 5998 22789 22775 2026-04-14T13:21:26Z Hakimi97 9 Utilize Modul:Arguments for getArgs 22789 Scribunto text/plain --[=[ Latest update: 14th April 2026 This is a module to implement logic for [[MediaWiki:Proofreadpage index template]], to render the book/index metadata panel for Malay Wikisource index pages. ]=] local ISO_639 = require('Modul:ISO 639') local messageBox = require('Module:Message box') local category_handler = require('Module:Category handler')._main local cfg = require('Modul:Index template/config') local getArgs = require('Modul:Arguments').getArgs -- Low-level markup helpers local function construct_cat(cat) return '[[Kategori:' .. cat .. ']]' end local function construct_cat_link(cat, text) return '[[:Kategori:' .. cat .. '|' .. (text or cat) .. ']]' end -- Builds a single labelled metadata row. local function construct_field(id, content) if id == nil or content == nil then return nil end if not cfg.headings[id] then error(cfg.missing_heading_id(id)) end return mw.html.create('tr') :attr('id', 'ws-index-' .. id .. '-row') :addClass('ws-index-row') :tag('th') :attr('scope', 'row') :attr('id', 'ws-index-' .. id .. '-label') :addClass('ws-index-label') :wikitext(cfg.headings[id].txt) :done() :tag('td') :attr('id', 'ws-index-' .. id .. '-value') :addClass('ws-index-value') :wikitext(content) :allDone() end -- Conditionally adds a metadata row and the appropriate tracking category. -- If `content` is truthy the row is added plus `with_cat` (if given). -- Otherwise only `without_cat` is emitted (if given). local function add_field(tbl, html, id, content, with_cat, without_cat) if content then tbl:node(construct_field(id, content)) if with_cat then html:wikitext(construct_cat(with_cat)) end elseif without_cat then html:wikitext(construct_cat(without_cat)) end end -- Wikidata link helpers local function addWikidataToLink(page, label, category) local title = mw.title.new(page) if title == nil then return '[[' .. page .. '|' .. label .. ']]' end if title.isRedirect then title = title.redirectTarget end local tag = mw.html.create('span') local itemId = mw.wikibase.getEntityIdForTitle(title.fullText) tag:wikitext('[[' .. page .. '|' .. label .. ']]') if itemId then tag:wikitext( ' [[Image:Wikidata.svg|10px|link=d:' .. itemId .. '|Lihat maklumat di Wikidata]]' ) if category then tag:wikitext('[[Kategori:' .. category .. ']]') end end return tostring(tag) end -- Walks wikilinks inside `wikitext` and augments each with a Wikidata icon -- when the linked page has a Wikidata entity. local function withWikidataLink(wikitext, category) if wikitext == nil then return nil end -- Try bare [[Page]] links first … local result = mw.ustring.gsub(wikitext, '%[%[([^|%]]*)%]%]', function(page) return addWikidataToLink(page, mw.ustring.gsub(page, '%.*/', ''), category) end) if result ~= wikitext then return result end -- … then [[Page|Label]] links. return mw.ustring.gsub(wikitext, '%[%[([^|]*)|([^|%]]*)%]%]', function(page, link) return addWikidataToLink(page, link, category) end) end -- Formats a contributor field (author / translator / editor). -- With a Wikidata item: augments links with Wikidata icons. -- Without: wraps bare (non-wikilinked) names in {{Al|}}. local function format_person(value, item) if item then return withWikidataLink(value) end if value:find('%[%[') then return value end return '{{Al|' .. value .. '}}' end -- Progress / transclusion status rows local function construct_status_field(args, statusArgs) local key = statusArgs.key local config_key = statusArgs.config_key or key local index_status = args[key] or '_missing' local sd = cfg[config_key][index_status] or cfg[config_key]['_default'] local txt = sd.txt if type(txt) == 'function' then txt = txt(index_status) end local display = sd.error and ('<span class="error">' .. txt .. '</span>') or construct_cat_link(sd.cat, txt) return { row = construct_field(key, display), cat = construct_cat(sd.cat), } end -- Indicator builder local function construct_indicator(frame, iData) local parts = { iData.image, iData.width or '20px' } if iData.alt then table.insert(parts, 'alt=' .. iData.alt) end if iData.link then table.insert(parts, 'link=' .. iData.link) end if iData.caption then table.insert(parts, iData.caption) end return frame:extensionTag{ name = 'indicator', content = '[[' .. table.concat(parts, '|') .. ']]', args = { name = iData.name }, } end -- Talk-page remarks local p = {} function p._index_talk_remarks(args) if not args.talkPageTitle then args.talkPageTitle = mw.title.getCurrentTitle().talkPageTitle end local text = cfg.talkremarks.text(args) local cat = category_handler({ construct_cat(cfg.talkremarks.cat) }) or '' local notes = '' if args.notes then notes = mw.html.create('div') :addClass('ombox-content') :css({ ['text-align'] = 'left', ['max-height'] = '5.5em', ['overflow'] = 'scroll', ['padding'] = '0.25em', ['margin'] = '0.25em', ['border-style'] = 'dashed', }) :newline() :wikitext(args.notes .. cat) :newline() :allDone() end return messageBox.main('ombox', { type = 'content', image = '[[File:Ambox important.svg|24px]]', style = 'box-sizing:border-box;margin:-0.93em auto 0.0em;text-align:center;width:100%;', textstyle = 'font-size:93%;text-decoration:none;', text = text .. tostring(notes), }) end function p.index_talk_remarks(frame) local args = getArgs(frame) -- trim + blank-removal handled automatically args.talkPageTitle = mw.title.getCurrentTitle().talkPageTitle return p._index_talk_remarks(args) end -- Language resolution -- Resolves the display language string and emits language-related tracking -- categories onto `html`. Returns the display string, or nil if unavailable. local function resolve_language(args, item, html) local displayLang = nil local languageCount = 0 if item then local languages = item:formatPropertyValues( 'P407', { mw.wikibase.entity.claimRanks.RANK_NORMAL } ).value if languages and mw.text.trim(languages) ~= '' then displayLang = languages for language in languages:gmatch('([^,]+)') do language = mw.text.trim(language) if language ~= '' then languageCount = languageCount + 1 html:wikitext(construct_cat( 'Laman indeks karya yang asal dalam ' .. language )) end end end end if not displayLang and args.language then local displayLangs = {} for _, l in ipairs(mw.text.split(args.language, ',%s*', false)) do local lang = mw.text.trim(l) if lang ~= '' then local langName = ISO_639.language_name(lang, lang) table.insert(displayLangs, langName) languageCount = languageCount + 1 html:wikitext(construct_cat( 'Laman indeks karya yang asal dalam bahasa ' .. langName )) end end if #displayLangs > 0 then displayLang = table.concat(displayLangs, ', ') end end if displayLang then html:wikitext(construct_cat('Karya dengan maklumat bahasa')) if languageCount > 1 then html:wikitext(construct_cat('Laman indeks karya yang asal dalam pelbagai bahasa')) end else html:wikitext(construct_cat('Laman indeks karya tanpa maklumat bahasa')) end return displayLang end -- Metadata table -- File formats that should render as a link to the index file page. local LINKABLE_SOURCES = { djvu=true, pdf=true, png=true, gif=true, tif=true, ogg=true, ogv=true, webm=true, } local function build_metadata(args, item, html) local t = mw.html.create('table'):attr('id', 'ws-index-metadata') -- Title if args.title then local titleContent if item then titleContent = withWikidataLink(args.title) elseif args.title:find('%[%[') then titleContent = args.title else titleContent = '[[' .. args.title .. ']]' end t:node(construct_field('title', titleContent)) else mw.addWarning('Anda perlu isi medan tajuk borang.') end -- Subtitle add_field(t, html, 'subtitle', withWikidataLink(args.subtitle)) -- Language (complex; categories emitted inside resolve_language) add_field(t, html, 'language', resolve_language(args, item, html)) -- Simple bibliographic fields add_field(t, html, 'volume', args.volume, 'Karya dengan maklumat nombor jilid', 'Karya tanpa maklumat nombor jilid') add_field(t, html, 'edition', args.edition, 'Karya dengan maklumat edisi', 'Karya tanpa maklumat edisi') -- Author (also emits per-author categories from Wikidata) if args.author then t:node(construct_field('author', format_person(args.author, item))) html:wikitext(construct_cat('Karya dengan maklumat pengarang')) if item then local authors = item:formatPropertyValues( 'P50', { mw.wikibase.entity.claimRanks.RANK_NORMAL } ).value or '' for author in authors:gmatch('([^,]+)') do html:wikitext(construct_cat('Karya ' .. mw.text.trim(author))) end end else html:wikitext(construct_cat('Karya tanpa maklumat pengarang')) end -- Contributor fields add_field(t, html, 'translator', args.translator and format_person(args.translator, item), 'Karya dengan maklumat penterjemah', 'Karya tanpa maklumat penterjemah') add_field(t, html, 'editor', args.editor and format_person(args.editor, item), 'Karya dengan maklumat penyunting', 'Karya tanpa maklumat penyunting') add_field(t, html, 'illustrator', args.illustrator and withWikidataLink(args.illustrator), 'Karya dengan maklumat pengilustrasi', 'Karya tanpa maklumat pengilustrasi') add_field(t, html, 'publisher', args.publisher and withWikidataLink(args.publisher), 'Karya dengan maklumat penerbit', 'Karya tanpa maklumat penerbit') -- Address / Published-in (mutually exclusive) if args.address then t:node(construct_field('address', withWikidataLink(args.address))) html:wikitext(construct_cat('Karya dengan maklumat alamat')) elseif args.publishedin then t:node(construct_field('publishedin', withWikidataLink(args.publishedin))) html:wikitext(construct_cat('Karya dengan maklumat alamat penerbitan')) else html:wikitext(construct_cat('Karya tanpa maklumat alamat penerbitan')) end -- Year / Inception (mutually exclusive) if args.year then t:node(construct_field('year', withWikidataLink(args.year))) html:wikitext(construct_cat('Karya dengan maklumat tarikh')) html:wikitext(construct_cat('Karya tahun ' .. args.year)) elseif args.inception then t:node(construct_field('inception', withWikidataLink(args.inception))) html:wikitext(construct_cat('Karya dengan maklumat tarikh terawal')) else html:wikitext(construct_cat('Karya tanpa maklumat tarikh')) end add_field(t, html, 'printer', args.printer and withWikidataLink(args.printer), 'Karya dengan maklumat pencetak', 'Karya tanpa maklumat pencetak') -- Source (linkable formats get a file-page link) local src = args.source t:node(construct_field('source', src and LINKABLE_SOURCES[src] and '[[:Fail:' .. mw.title.getCurrentTitle().text .. '|' .. src .. ']]' or src )) -- Progress & transclusion status local progress_data = construct_status_field(args, { key = 'progress', config_key = 'status' }) local transclusion_data = construct_status_field(args, { key = 'transclusion' }) t:node(progress_data.row); html:wikitext(progress_data.cat) t:node(transclusion_data.row); html:wikitext(transclusion_data.cat) -- Validation date local vdate = args.validation_date if vdate then local vcat = cfg.validation_cats.dated(vdate) t:node(construct_field('validation_date', construct_cat_link(vcat, vdate))) html:wikitext(construct_cat(vcat)) elseif args.progress == 'T' then html:wikitext(construct_cat(cfg.validation_cats.undated)) end -- Standard identifiers for _, id in ipairs({ 'isbn', 'oclc', 'lccn', 'ark', 'doi' }) do local val = args[id] if val then local link_fn = cfg.url_gens[id] t:node(construct_field(id, link_fn and link_fn(val, val) or val)) end end add_field(t, html, 'volumes', args.volumes) return t end -- Cover image --[=[ Decision tree (evaluated in order): 1. Full [[...]] wikilink spec supplied → use as-is 2. Bare filename (has extension) → strip namespace prefix, rewrap 3. Audiovisual timestamp string → treat as thumbtime= value (→ case 5) 4. Multipage (DjVu/PDF) + file exists → page= thumbnail 5. Audiovisual + file exists → thumbtime= thumbnail 6. Any other type + file exists → plain file link 7. File does not exist → placeholder + missing category --]=] local function build_cover(args) local image_number = tonumber(args.image) -- Treat a bare timestamp string (e.g. "83" or "1:23") as a thumbtime value. if args.image and not image_number and args.source_type == 'audiovisual' and mw.ustring.match(args.image, '^%d+[%d:]*$') then image_number = args.image end local image_spec local cats = {} if not image_number and args.image and mw.ustring.find(args.image, '^%[%[') then -- Case 1: full wikilink spec image_spec = args.image if args.source_type ~= 'image' then table.insert(cats, construct_cat(cfg.cover_cats.fullspec)) end elseif not image_number and args.image and mw.ustring.find(args.image, '%.%w+$') then -- Case 2: bare filename — strip any recognised File namespace prefix local image_name = args.image local file_ns = mw.site.namespaces[6] local prefixes = { file_ns.name, file_ns.canonicalName } for _, alias in ipairs(file_ns.aliases) do table.insert(prefixes, alias) end for _, prefix in ipairs(prefixes) do image_name = mw.ustring.gsub(image_name, '^' .. prefix .. ':', '') image_name = mw.ustring.gsub(image_name, '^' .. prefix:lower() .. ':', '') end image_spec = '[[' .. mw.title.makeTitle('Fail', image_name).prefixedText .. '|' .. cfg.cover.width .. '|class=ws-cover]]' if args.source_type ~= 'image' then table.insert(cats, construct_cat(cfg.cover_cats.fullspec)) end elseif args.source_type == 'multipage' and args.file_exists then -- Case 4: DjVu / PDF page thumbnail image_spec = '[[' .. args.fileTitle.prefixedText .. '|' .. cfg.cover.width .. '|page=' .. (image_number or 1) .. '|class=ws-cover]]' elseif args.source_type == 'audiovisual' and args.file_exists then -- Case 5: audio / video timestamp thumbnail image_spec = '[[' .. args.fileTitle.prefixedText .. '|' .. cfg.cover.width .. '|thumbtime=' .. (image_number or 0) .. '|class=ws-cover]]' elseif args.file_exists then -- Case 6: image or unknown type image_spec = '[[' .. args.fileTitle.prefixedText .. '|' .. cfg.cover.width .. '|class=ws-cover]]' else -- Case 7: file missing — fall back to placeholder local image_link = args.fileTitle.prefixedText if not mw.ustring.find(args.fileTitle.rootText, '^.*%.%w+') then image_link = 'Special:Upload' end image_spec = '[[' .. cfg.cover.image .. '|' .. cfg.cover.width .. '|link=' .. image_link .. '|class=ws-cover]]' table.insert(cats, construct_cat(cfg.cover_cats.missing)) end return image_spec .. table.concat(cats) end -- Argument setup -- Resolves all derived values and performs every expensive DB lookup exactly -- once. Anything that touches the DB (file.exists, title.exists) lives here -- and nowhere else, making the cost immediately visible to maintainers. local function process_args(args) local pageTitle = mw.title.getCurrentTitle() args.talkPageTitle = pageTitle.talkPageTitle args.fileTitle = mw.title.makeTitle('Fail', pageTitle.rootText) args.source_type = cfg.cover_cats.file_types[args.source] args.file_exists = args.fileTitle.file.exists -- expensive: DB lookup args.talk_exists = args.talkPageTitle.exists -- expensive: DB lookup return args end -- Main entry point local INDICATOR_ORDER = { 'pagegame', 'purge', 'book2scroll', 'bookreader' } local function indexTemplate(frame) local styles = frame:extensionTag{ name = 'templatestyles', args = { src = 'Modul:Index template/styles.css' }, } local data = (require 'Modul:Index_template/data').indexDataWithWikidata(frame) local args, item = data.args, data.item args = process_args(args) -- Scan the talk page for formatting notes unless notes were supplied directly. local talkremarks = '' local talk_page_exists = args.talk_exists if talk_page_exists and not args.notes then local content = args.talkPageTitle.content for _, keyword in ipairs(cfg.talkremarks.keywords) do local pattern = keyword.alone and '==( *' .. keyword.pattern .. ' *)==' or '==([^=%n]*' .. keyword.pattern .. '[^=%n]*)==' local section = mw.ustring.match(content, pattern) if section then args.notes = mw.getCurrentFrame():callParserFunction( '#lsth', args.talkPageTitle.prefixedText, mw.text.trim(section) ) break end end end if talk_page_exists then talkremarks = p._index_talk_remarks(args) end local html = mw.html.create() -- Wikidata indicator if item then html:wikitext('[[Kategori:Karya dengan ID Wikidata]]') html:wikitext( '<indicator name="wikidata">[[File:Wikidata.svg|20px|ID Wikidata|link=d:' .. item.id .. ']]</indicator>' ) else html:wikitext('[[Kategori:Karya tanpa ID Wikidata]]') end -- Tool indicators local indicators_cfg = require('Modul:Index template/indicators') for _, key in ipairs(INDICATOR_ORDER) do html:wikitext(construct_indicator(frame, indicators_cfg[key])) end local metadataTable = build_metadata(args, item, html) local coverImage = build_cover(args) -- Outer layout: [cover + metadata + pagelist] | [remarks] local outerRow = html:tag('table') :attr('id', 'ws-index-container') :tag('tr') outerRow:tag('td') :attr('id', 'ws-index-main-cell') :tag('table') :attr('id', 'ws-index-main-table') :tag('tr'):tag('td') :tag('div') :attr('id', 'ws-index-cover-container') :wikitext(coverImage) :done() :node(metadataTable) :done() :tag('tr'):tag('td') :tag('div') :attr('id', 'ws-index-pagelist-container') :addClass('mw-collapsible') :tag('em'):wikitext(cfg.pagelist.pages.txt):done() :wikitext(' ') :tag('span') :attr('id', 'ws-index-pagelist-legend') :wikitext(cfg.pagelist.legend.txt) :done() :tag('div') :attr('id', 'ws-index-pagelist') :addClass('index-pagelist mw-collapsible-content') :newline() :wikitext(args.pages and mw.text.trim(args.pages)) :newline() if args.remarks then outerRow:tag('td') :attr('id', 'ws-index-remarks') :newline() :wikitext(frame:preprocess(args.remarks)) else outerRow:tag('td'):attr('id', 'ws-index-remarks-empty') end -- Notes block if args.notes then html:tag('div'):attr('id', 'ws-index-notes'):wikitext(args.notes) end -- Tracking categories if cfg.type_cats[args.type] then html:wikitext(construct_cat(cfg.type_cats[args.type])) end if cfg.source_cats[args.source] then html:wikitext(construct_cat(cfg.source_cats[args.source])) elseif args.source ~= 'lain-lain' then html:wikitext(construct_cat('Indeks fail format lain')) end html:wikitext(construct_cat('Indeks')) if not args.remarks then html:wikitext(construct_cat('Laman berindeks')) end return talkremarks .. styles .. tostring(html) end function p.indexTemplate(frame) return indexTemplate(frame) end return p toa7dam8dih3f77h8rlosuoxbvm5a5g 22820 22789 2026-04-15T03:24:28Z Hakimi97 9 Code update 22820 Scribunto text/plain --[=[ Latest update: 15th April 2026 This is a module to implement logic for [[MediaWiki:Proofreadpage index template]], to render the book/index metadata panel for Malay Wikisource index pages. ]=] local ISO_639 = require('Modul:ISO 639') local messageBox = require('Module:Message box') local category_handler = require('Module:Category handler')._main local cfg = require('Modul:Index template/config') -- Low-level markup helpers local function construct_cat(cat) return '[[Kategori:' .. cat .. ']]' end local function construct_cat_link(cat, text) return '[[:Kategori:' .. cat .. '|' .. (text or cat) .. ']]' end -- Builds a single labelled metadata row. local function construct_field(id, content) if id == nil or content == nil then return nil end if not cfg.headings[id] then error(cfg.missing_heading_id(id)) end return mw.html.create('tr') :attr('id', 'ws-index-' .. id .. '-row') :addClass('ws-index-row') :tag('th') :attr('scope', 'row') :attr('id', 'ws-index-' .. id .. '-label') :addClass('ws-index-label') :wikitext(cfg.headings[id].txt) :done() :tag('td') :attr('id', 'ws-index-' .. id .. '-value') :addClass('ws-index-value') :wikitext(content) :allDone() end -- Conditionally adds a metadata row and the appropriate tracking category. -- If `content` is truthy the row is added plus `with_cat` (if given). -- Otherwise only `without_cat` is emitted (if given). local function add_field(tbl, html, id, content, with_cat, without_cat) if content then tbl:node(construct_field(id, content)) if with_cat then html:wikitext(construct_cat(with_cat)) end elseif without_cat then html:wikitext(construct_cat(without_cat)) end end -- Wikidata link helpers local function addWikidataToLink(page, label, category) local title = mw.title.new(page) if title == nil then return '[[' .. page .. '|' .. label .. ']]' end if title.isRedirect then title = title.redirectTarget end local tag = mw.html.create('span') local itemId = mw.wikibase.getEntityIdForTitle(title.fullText) tag:wikitext('[[' .. page .. '|' .. label .. ']]') if itemId then tag:wikitext( ' [[Image:Wikidata.svg|10px|link=d:' .. itemId .. '|Lihat maklumat di Wikidata]]' ) if category then tag:wikitext('[[Kategori:' .. category .. ']]') end end return tostring(tag) end -- Walks wikilinks inside `wikitext` and augments each with a Wikidata icon -- when the linked page has a Wikidata entity. local function withWikidataLink(wikitext, category) if wikitext == nil then return nil end -- Try bare [[Page]] links first … local result = mw.ustring.gsub(wikitext, '%[%[([^|%]]*)%]%]', function(page) return addWikidataToLink(page, mw.ustring.gsub(page, '%.*/', ''), category) end) if result ~= wikitext then return result end -- … then [[Page|Label]] links. return mw.ustring.gsub(wikitext, '%[%[([^|]*)|([^|%]]*)%]%]', function(page, link) return addWikidataToLink(page, link, category) end) end -- Formats a contributor field (author / translator / editor). -- With a Wikidata item: augments links with Wikidata icons. -- Without: wraps bare (non-wikilinked) names in {{Al|}}. local function format_person(value, item) if item then return withWikidataLink(value) end if value:find('%[%[') then return value end return '{{Al|' .. value .. '}}' end -- Progress / transclusion status rows local function construct_status_field(args, statusArgs) local key = statusArgs.key local config_key = statusArgs.config_key or key local index_status = args[key] or '_missing' local sd = cfg[config_key][index_status] or cfg[config_key]['_default'] local txt = sd.txt if type(txt) == 'function' then txt = txt(index_status) end local display = sd.error and ('<span class="error">' .. txt .. '</span>') or construct_cat_link(sd.cat, txt) return { row = construct_field(key, display), cat = construct_cat(sd.cat), } end -- Indicator builder -- Builds one <indicator> tag from an indicator config entry. -- `link` and `caption` may be plain strings or functions called with `args`. -- An optional `include` predicate (also called with `args`) gates rendering; -- defaults to always-show when absent. local function construct_indicator(args, iData) local include = iData.include or function() return true end if not include(args) then return '' end local parts = { iData.image, iData.width or '20px' } if iData.alt then table.insert(parts, 'alt=' .. iData.alt) end local link = iData.link if type(link) == 'function' then link = link(args) end if link then table.insert(parts, 'link=' .. link) end local caption = iData.caption if type(caption) == 'function' then caption = caption(args) end if caption then table.insert(parts, caption) end return mw.getCurrentFrame():extensionTag{ name = 'indicator', content = '[[' .. table.concat(parts, '|') .. ']]', args = { name = iData.name }, } end -- Talk-page remarks local p = {} function p._index_talk_remarks(args) if not args.talkPageTitle then args.talkPageTitle = mw.title.getCurrentTitle().talkPageTitle end local text = cfg.talkremarks.text(args) local cat = category_handler({ construct_cat(cfg.talkremarks.cat) }) or '' local notes = '' if args.notes then notes = mw.html.create('div') :addClass('ombox-content') :css({ ['text-align'] = 'left', ['max-height'] = '5.5em', ['overflow'] = 'scroll', ['padding'] = '0.25em', ['margin'] = '0.25em', ['border-style'] = 'dashed', }) :newline() :wikitext(args.notes .. cat) :newline() :allDone() end return messageBox.main('ombox', { type = 'content', image = '[[File:Ambox important.svg|24px]]', style = 'box-sizing:border-box;margin:-0.93em auto 0.0em;text-align:center;width:100%;', textstyle = 'font-size:93%;text-decoration:none;', text = text .. tostring(notes), }) end function p.index_talk_remarks(frame) local args = {} for k, v in pairs(frame.args) do args[k] = v end args.talkPageTitle = mw.title.getCurrentTitle().talkPageTitle return p._index_talk_remarks(args) end -- Language resolution -- Resolves the display language string and emits language-related tracking -- categories onto `html`. Returns the display string, or nil if unavailable. local function resolve_language(args, item, html) local displayLang = nil local languageCount = 0 if item then local languages = item:formatPropertyValues( 'P407', { mw.wikibase.entity.claimRanks.RANK_NORMAL } ).value if languages and mw.text.trim(languages) ~= '' then displayLang = languages for language in languages:gmatch('([^,]+)') do language = mw.text.trim(language) if language ~= '' then languageCount = languageCount + 1 html:wikitext(construct_cat( 'Laman indeks karya yang asal dalam ' .. language )) end end end end if not displayLang and args.language then local displayLangs = {} for _, l in ipairs(mw.text.split(args.language, ',%s*', false)) do local lang = mw.text.trim(l) if lang ~= '' then local langName = ISO_639.language_name(lang, lang) table.insert(displayLangs, langName) languageCount = languageCount + 1 html:wikitext(construct_cat( 'Laman indeks karya yang asal dalam bahasa ' .. langName )) end end if #displayLangs > 0 then displayLang = table.concat(displayLangs, ', ') end end if displayLang then html:wikitext(construct_cat('Karya dengan maklumat bahasa')) if languageCount > 1 then html:wikitext(construct_cat('Laman indeks karya yang asal dalam pelbagai bahasa')) end else html:wikitext(construct_cat('Laman indeks karya tanpa maklumat bahasa')) end return displayLang end -- Metadata table -- File formats that should render as a link to the index file page. local LINKABLE_SOURCES = { djvu=true, pdf=true, png=true, gif=true, tif=true, ogg=true, ogv=true, webm=true, } local function build_metadata(args, item, html) local t = mw.html.create('table'):attr('id', 'ws-index-metadata') -- Title if args.title then local titleContent if item then titleContent = withWikidataLink(args.title) elseif args.title:find('%[%[') then titleContent = args.title else titleContent = '[[' .. args.title .. ']]' end t:node(construct_field('title', titleContent)) else mw.addWarning('Anda perlu isi medan tajuk borang.') end -- Subtitle add_field(t, html, 'subtitle', withWikidataLink(args.subtitle)) -- Language (complex; categories emitted inside resolve_language) add_field(t, html, 'language', resolve_language(args, item, html)) -- Simple bibliographic fields add_field(t, html, 'volume', args.volume, 'Karya dengan maklumat nombor jilid', 'Karya tanpa maklumat nombor jilid') add_field(t, html, 'edition', args.edition, 'Karya dengan maklumat edisi', 'Karya tanpa maklumat edisi') -- Author (also emits per-author categories from Wikidata) if args.author then t:node(construct_field('author', format_person(args.author, item))) html:wikitext(construct_cat('Karya dengan maklumat pengarang')) if item then local authors = item:formatPropertyValues( 'P50', { mw.wikibase.entity.claimRanks.RANK_NORMAL } ).value or '' for author in authors:gmatch('([^,]+)') do html:wikitext(construct_cat('Karya ' .. mw.text.trim(author))) end end else html:wikitext(construct_cat('Karya tanpa maklumat pengarang')) end -- Contributor fields add_field(t, html, 'translator', args.translator and format_person(args.translator, item), 'Karya dengan maklumat penterjemah', 'Karya tanpa maklumat penterjemah') add_field(t, html, 'editor', args.editor and format_person(args.editor, item), 'Karya dengan maklumat penyunting', 'Karya tanpa maklumat penyunting') add_field(t, html, 'illustrator', args.illustrator and withWikidataLink(args.illustrator), 'Karya dengan maklumat pengilustrasi', 'Karya tanpa maklumat pengilustrasi') add_field(t, html, 'publisher', args.publisher and withWikidataLink(args.publisher), 'Karya dengan maklumat penerbit', 'Karya tanpa maklumat penerbit') -- Address / Published-in (mutually exclusive) if args.address then t:node(construct_field('address', withWikidataLink(args.address))) html:wikitext(construct_cat('Karya dengan maklumat alamat')) elseif args.publishedin then t:node(construct_field('publishedin', withWikidataLink(args.publishedin))) html:wikitext(construct_cat('Karya dengan maklumat alamat penerbitan')) else html:wikitext(construct_cat('Karya tanpa maklumat alamat penerbitan')) end -- Year / Inception (mutually exclusive) if args.year then t:node(construct_field('year', withWikidataLink(args.year))) html:wikitext(construct_cat('Karya dengan maklumat tarikh')) html:wikitext(construct_cat('Karya tahun ' .. args.year)) elseif args.inception then t:node(construct_field('inception', withWikidataLink(args.inception))) html:wikitext(construct_cat('Karya dengan maklumat tarikh terawal')) else html:wikitext(construct_cat('Karya tanpa maklumat tarikh')) end add_field(t, html, 'printer', args.printer and withWikidataLink(args.printer), 'Karya dengan maklumat pencetak', 'Karya tanpa maklumat pencetak') -- Source (linkable formats get a file-page link) local src = args.source t:node(construct_field('source', src and LINKABLE_SOURCES[src] and '[[:Fail:' .. mw.title.getCurrentTitle().text .. '|' .. src .. ']]' or src )) -- Progress & transclusion status local progress_data = construct_status_field(args, { key = 'progress', config_key = 'status' }) local transclusion_data = construct_status_field(args, { key = 'transclusion' }) t:node(progress_data.row); html:wikitext(progress_data.cat) t:node(transclusion_data.row); html:wikitext(transclusion_data.cat) -- Validation date local vdate = args.validation_date if vdate then local vcat = cfg.validation_cats.dated(vdate) t:node(construct_field('validation_date', construct_cat_link(vcat, vdate))) html:wikitext(construct_cat(vcat)) elseif args.progress == 'T' then html:wikitext(construct_cat(cfg.validation_cats.undated)) end -- Standard identifiers for _, id in ipairs({ 'isbn', 'oclc', 'lccn', 'ark', 'doi' }) do local val = args[id] if val then local link_fn = cfg.url_gens[id] t:node(construct_field(id, link_fn and link_fn(val, val) or val)) end end add_field(t, html, 'volumes', args.volumes) return t end -- Cover image --[=[ Decision tree (evaluated in order): 1. Full [[...]] wikilink spec supplied → use as-is 2. Bare filename (has extension) → strip namespace prefix, rewrap 3. Audiovisual timestamp string → treat as thumbtime= value (→ case 5) 4. Multipage (DjVu/PDF) + file exists → page= thumbnail 5. Audiovisual + file exists → thumbtime= thumbnail 6. Any other type + file exists → plain file link 7. File does not exist → placeholder + missing category --]=] local function build_cover(args) local image_number = tonumber(args.image) -- Treat a bare timestamp string (e.g. "83" or "1:23") as a thumbtime value. if args.image and not image_number and args.source_type == 'audiovisual' and mw.ustring.match(args.image, '^%d+[%d:]*$') then image_number = args.image end local image_spec local cats = {} if not image_number and args.image and mw.ustring.find(args.image, '^%[%[') then -- Case 1: full wikilink spec image_spec = args.image if args.source_type ~= 'image' then table.insert(cats, construct_cat(cfg.cover_cats.fullspec)) end elseif not image_number and args.image and mw.ustring.find(args.image, '%.%w+$') then -- Case 2: bare filename — strip any recognised File namespace prefix local image_name = args.image local file_ns = mw.site.namespaces[6] local prefixes = { file_ns.name, file_ns.canonicalName } for _, alias in ipairs(file_ns.aliases) do table.insert(prefixes, alias) end for _, prefix in ipairs(prefixes) do image_name = mw.ustring.gsub(image_name, '^' .. prefix .. ':', '') image_name = mw.ustring.gsub(image_name, '^' .. prefix:lower() .. ':', '') end image_spec = '[[' .. mw.title.makeTitle('Fail', image_name).prefixedText .. '|' .. cfg.cover.width .. '|class=ws-cover]]' if args.source_type ~= 'image' then table.insert(cats, construct_cat(cfg.cover_cats.fullspec)) end elseif args.source_type == 'multipage' and args.file_exists then -- Case 4: DjVu / PDF page thumbnail image_spec = '[[' .. args.fileTitle.prefixedText .. '|' .. cfg.cover.width .. '|page=' .. (image_number or 1) .. '|class=ws-cover]]' elseif args.source_type == 'audiovisual' and args.file_exists then -- Case 5: audio / video timestamp thumbnail image_spec = '[[' .. args.fileTitle.prefixedText .. '|' .. cfg.cover.width .. '|thumbtime=' .. (image_number or 0) .. '|class=ws-cover]]' elseif args.file_exists then -- Case 6: image or unknown type image_spec = '[[' .. args.fileTitle.prefixedText .. '|' .. cfg.cover.width .. '|class=ws-cover]]' else -- Case 7: file missing — fall back to placeholder local image_link = args.fileTitle.prefixedText if not mw.ustring.find(args.fileTitle.rootText, '^.*%.%w+') then image_link = 'Special:Upload' end image_spec = '[[' .. cfg.cover.image .. '|' .. cfg.cover.width .. '|link=' .. image_link .. '|class=ws-cover]]' table.insert(cats, construct_cat(cfg.cover_cats.missing)) end return image_spec .. table.concat(cats) end -- Argument setup -- Resolves all derived values and performs every expensive DB lookup exactly -- once. Anything that touches the DB (file.exists, title.exists) lives here -- and nowhere else, making the cost immediately visible to maintainers. local function process_args(args) -- Apply config defaults for any args not supplied by the template. for k, v in pairs(cfg.defaults or {}) do if args[k] == nil then args[k] = v end end -- Allow pageTitle to be pre-set (e.g. from a sandbox or test harness). -- In normal template rendering it is always nil, so getCurrentTitle() is used. args.pageTitle = (args.pageTitle and mw.title.new(args.pageTitle)) or mw.title.getCurrentTitle() args.talkPageTitle = args.pageTitle.talkPageTitle args.fileTitle = mw.title.makeTitle('Fail', args.pageTitle.rootText) args.source_type = cfg.cover_cats.file_types[args.source] args.file_exists = args.fileTitle.file.exists -- expensive: DB lookup args.talk_exists = args.talkPageTitle.exists -- expensive: DB lookup return args end -- Main entry point local INDICATOR_ORDER = { 'pagegame', 'purge', 'book2scroll', 'bookreader', 'validated' } local function indexTemplate(frame) local styles = frame:extensionTag{ name = 'templatestyles', args = { src = 'Modul:Index template/styles.css' }, } local data = (require 'Modul:Index_template/data').indexDataWithWikidata(frame) local args, item = data.args, data.item args = process_args(args) -- Sort index pages correctly in categories (falls back to page title). local sortkey = mw.getCurrentFrame():callParserFunction( 'DEFAULTSORT', { args.pageTitle.text } ) -- Scan the talk page for formatting notes unless notes were supplied directly. local talkremarks = '' local talk_page_exists = args.talk_exists if talk_page_exists and not args.notes then local content = args.talkPageTitle.content for _, keyword in ipairs(cfg.talkremarks.keywords) do local pattern = keyword.alone and '==( *' .. keyword.pattern .. ' *)==' or '==([^=%n]*' .. keyword.pattern .. '[^=%n]*)==' local section = mw.ustring.match(content, pattern) if section then args.notes = mw.getCurrentFrame():callParserFunction( '#lsth', args.talkPageTitle.prefixedText, mw.text.trim(section) ) break end end end if talk_page_exists then talkremarks = p._index_talk_remarks(args) end local html = mw.html.create() -- Wikidata indicator if item then html:wikitext('[[Kategori:Karya dengan ID Wikidata]]') html:wikitext( '<indicator name="wikidata">[[File:Wikidata.svg|20px|ID Wikidata|link=d:' .. item.id .. ']]</indicator>' ) else html:wikitext('[[Kategori:Karya tanpa ID Wikidata]]') end -- Tool indicators local indicators_cfg = require('Modul:Index template/indicators') for _, key in ipairs(INDICATOR_ORDER) do html:wikitext(construct_indicator(args, indicators_cfg[key])) end local metadataTable = build_metadata(args, item, html) local coverImage = build_cover(args) -- Outer layout: [cover + metadata + pagelist] | [remarks] local outerRow = html:tag('table') :attr('id', 'ws-index-container') :tag('tr') outerRow:tag('td') :attr('id', 'ws-index-main-cell') :tag('table') :attr('id', 'ws-index-main-table') :tag('tr'):tag('td') :tag('div') :attr('id', 'ws-index-cover-container') :wikitext(coverImage) :done() :node(metadataTable) :done() :tag('tr'):tag('td') :tag('div') :attr('id', 'ws-index-pagelist-container') :addClass('mw-collapsible') :tag('em'):wikitext(cfg.pagelist.pages.txt):done() :wikitext(' ') :tag('span') :attr('id', 'ws-index-pagelist-legend') :wikitext(cfg.pagelist.legend.txt) :done() :tag('div') :attr('id', 'ws-index-pagelist') :addClass('index-pagelist mw-collapsible-content') :newline() :wikitext(args.pages and mw.text.trim(args.pages)) :newline() if args.remarks then outerRow:tag('td') :attr('id', 'ws-index-remarks') :newline() :wikitext(frame:preprocess(args.remarks)) else outerRow:tag('td'):attr('id', 'ws-index-remarks-empty') end -- Notes block if args.notes then html:tag('div'):attr('id', 'ws-index-notes'):wikitext(args.notes) end -- Tracking categories if cfg.type_cats[args.type] then html:wikitext(construct_cat(cfg.type_cats[args.type])) end if cfg.source_cats[args.source] then html:wikitext(construct_cat(cfg.source_cats[args.source])) elseif args.source ~= 'lain-lain' then html:wikitext(construct_cat('Indeks fail format lain')) end html:wikitext(construct_cat('Indeks')) if not args.remarks then html:wikitext(construct_cat('Laman berindeks')) end return talkremarks .. styles .. tostring(html) .. sortkey end function p.indexTemplate(frame) return indexTemplate(frame) end return p emklx555ci0ze4sluqj3fn8kega398e 22823 22820 2026-04-15T04:33:43Z Hakimi97 9 Merge Modul:Index template/indicators into Modul:Index template/config 22823 Scribunto text/plain --[=[ Latest update: 15th April 2026 This is a module to implement logic for [[MediaWiki:Proofreadpage index template]], to render the book/index metadata panel for Malay Wikisource index pages. ]=] local ISO_639 = require('Modul:ISO 639') local messageBox = require('Module:Message box') local category_handler = require('Module:Category handler')._main local cfg = require('Modul:Index template/config') -- Low-level markup helpers local function construct_cat(cat) return '[[Kategori:' .. cat .. ']]' end local function construct_cat_link(cat, text) return '[[:Kategori:' .. cat .. '|' .. (text or cat) .. ']]' end -- Builds a single labelled metadata row. local function construct_field(id, content) if id == nil or content == nil then return nil end if not cfg.headings[id] then error(cfg.missing_heading_id(id)) end return mw.html.create('tr') :attr('id', 'ws-index-' .. id .. '-row') :addClass('ws-index-row') :tag('th') :attr('scope', 'row') :attr('id', 'ws-index-' .. id .. '-label') :addClass('ws-index-label') :wikitext(cfg.headings[id].txt) :done() :tag('td') :attr('id', 'ws-index-' .. id .. '-value') :addClass('ws-index-value') :wikitext(content) :allDone() end -- Conditionally adds a metadata row and the appropriate tracking category. -- If `content` is truthy the row is added plus `with_cat` (if given). -- Otherwise only `without_cat` is emitted (if given). local function add_field(tbl, html, id, content, with_cat, without_cat) if content then tbl:node(construct_field(id, content)) if with_cat then html:wikitext(construct_cat(with_cat)) end elseif without_cat then html:wikitext(construct_cat(without_cat)) end end -- Wikidata link helpers local function addWikidataToLink(page, label, category) local title = mw.title.new(page) if title == nil then return '[[' .. page .. '|' .. label .. ']]' end if title.isRedirect then title = title.redirectTarget end local tag = mw.html.create('span') local itemId = mw.wikibase.getEntityIdForTitle(title.fullText) tag:wikitext('[[' .. page .. '|' .. label .. ']]') if itemId then tag:wikitext( ' [[Image:Wikidata.svg|10px|link=d:' .. itemId .. '|Lihat maklumat di Wikidata]]' ) if category then tag:wikitext('[[Kategori:' .. category .. ']]') end end return tostring(tag) end -- Walks wikilinks inside `wikitext` and augments each with a Wikidata icon -- when the linked page has a Wikidata entity. local function withWikidataLink(wikitext, category) if wikitext == nil then return nil end -- Try bare [[Page]] links first … local result = mw.ustring.gsub(wikitext, '%[%[([^|%]]*)%]%]', function(page) return addWikidataToLink(page, mw.ustring.gsub(page, '%.*/', ''), category) end) if result ~= wikitext then return result end -- … then [[Page|Label]] links. return mw.ustring.gsub(wikitext, '%[%[([^|]*)|([^|%]]*)%]%]', function(page, link) return addWikidataToLink(page, link, category) end) end -- Formats a contributor field (author / translator / editor). -- With a Wikidata item: augments links with Wikidata icons. -- Without: wraps bare (non-wikilinked) names in {{Al|}}. local function format_person(value, item) if item then return withWikidataLink(value) end if value:find('%[%[') then return value end return '{{Al|' .. value .. '}}' end -- Progress / transclusion status rows local function construct_status_field(args, statusArgs) local key = statusArgs.key local config_key = statusArgs.config_key or key local index_status = args[key] or '_missing' local sd = cfg[config_key][index_status] or cfg[config_key]['_default'] local txt = sd.txt if type(txt) == 'function' then txt = txt(index_status) end local display = sd.error and ('<span class="error">' .. txt .. '</span>') or construct_cat_link(sd.cat, txt) return { row = construct_field(key, display), cat = construct_cat(sd.cat), } end -- Indicator builder -- Builds one <indicator> tag from an indicator config entry. -- `link` and `caption` may be plain strings or functions called with `args`. -- An optional `include` predicate (also called with `args`) gates rendering; -- defaults to always-show when absent. local function construct_indicator(args, iData) local include = iData.include or cfg.indicator_defaults.include if not include(args) then return '' end local parts = { iData.image, iData.width or cfg.indicator_defaults.width } if iData.alt then table.insert(parts, 'alt=' .. iData.alt) end local link = iData.link if type(link) == 'function' then link = link(args) end if link then table.insert(parts, 'link=' .. link) end local caption = iData.caption if type(caption) == 'function' then caption = caption(args) end if caption then table.insert(parts, caption) end return mw.getCurrentFrame():extensionTag{ name = 'indicator', content = '[[' .. table.concat(parts, '|') .. ']]', args = { name = iData.name }, } end -- Talk-page remarks local p = {} function p._index_talk_remarks(args) if not args.talkPageTitle then args.talkPageTitle = mw.title.getCurrentTitle().talkPageTitle end local text = cfg.talkremarks.text(args) local cat = category_handler({ construct_cat(cfg.talkremarks.cat) }) or '' local notes = '' if args.notes then notes = mw.html.create('div') :addClass('ombox-content') :css({ ['text-align'] = 'left', ['max-height'] = '5.5em', ['overflow'] = 'scroll', ['padding'] = '0.25em', ['margin'] = '0.25em', ['border-style'] = 'dashed', }) :newline() :wikitext(args.notes .. cat) :newline() :allDone() end return messageBox.main('ombox', { type = 'content', image = '[[File:Ambox important.svg|24px]]', style = 'box-sizing:border-box;margin:-0.93em auto 0.0em;text-align:center;width:100%;', textstyle = 'font-size:93%;text-decoration:none;', text = text .. tostring(notes), }) end function p.index_talk_remarks(frame) local args = {} for k, v in pairs(frame.args) do args[k] = v end args.talkPageTitle = mw.title.getCurrentTitle().talkPageTitle return p._index_talk_remarks(args) end -- Language resolution -- Resolves the display language string and emits language-related tracking -- categories onto `html`. Returns the display string, or nil if unavailable. local function resolve_language(args, item, html) local displayLang = nil local languageCount = 0 if item then local languages = item:formatPropertyValues( 'P407', { mw.wikibase.entity.claimRanks.RANK_NORMAL } ).value if languages and mw.text.trim(languages) ~= '' then displayLang = languages for language in languages:gmatch('([^,]+)') do language = mw.text.trim(language) if language ~= '' then languageCount = languageCount + 1 html:wikitext(construct_cat( 'Laman indeks karya yang asal dalam ' .. language )) end end end end if not displayLang and args.language then local displayLangs = {} for _, l in ipairs(mw.text.split(args.language, ',%s*', false)) do local lang = mw.text.trim(l) if lang ~= '' then local langName = ISO_639.language_name(lang, lang) table.insert(displayLangs, langName) languageCount = languageCount + 1 html:wikitext(construct_cat( 'Laman indeks karya yang asal dalam bahasa ' .. langName )) end end if #displayLangs > 0 then displayLang = table.concat(displayLangs, ', ') end end if displayLang then html:wikitext(construct_cat('Karya dengan maklumat bahasa')) if languageCount > 1 then html:wikitext(construct_cat('Laman indeks karya yang asal dalam pelbagai bahasa')) end else html:wikitext(construct_cat('Laman indeks karya tanpa maklumat bahasa')) end return displayLang end -- Metadata table -- File formats that should render as a link to the index file page. local LINKABLE_SOURCES = { djvu=true, pdf=true, png=true, gif=true, tif=true, ogg=true, ogv=true, webm=true, } local function build_metadata(args, item, html) local t = mw.html.create('table'):attr('id', 'ws-index-metadata') -- Title if args.title then local titleContent if item then titleContent = withWikidataLink(args.title) elseif args.title:find('%[%[') then titleContent = args.title else titleContent = '[[' .. args.title .. ']]' end t:node(construct_field('title', titleContent)) else mw.addWarning('Anda perlu isi medan tajuk borang.') end -- Subtitle add_field(t, html, 'subtitle', withWikidataLink(args.subtitle)) -- Language (complex; categories emitted inside resolve_language) add_field(t, html, 'language', resolve_language(args, item, html)) -- Simple bibliographic fields add_field(t, html, 'volume', args.volume, 'Karya dengan maklumat nombor jilid', 'Karya tanpa maklumat nombor jilid') add_field(t, html, 'edition', args.edition, 'Karya dengan maklumat edisi', 'Karya tanpa maklumat edisi') -- Author (also emits per-author categories from Wikidata) if args.author then t:node(construct_field('author', format_person(args.author, item))) html:wikitext(construct_cat('Karya dengan maklumat pengarang')) if item then local authors = item:formatPropertyValues( 'P50', { mw.wikibase.entity.claimRanks.RANK_NORMAL } ).value or '' for author in authors:gmatch('([^,]+)') do html:wikitext(construct_cat('Karya ' .. mw.text.trim(author))) end end else html:wikitext(construct_cat('Karya tanpa maklumat pengarang')) end -- Contributor fields add_field(t, html, 'translator', args.translator and format_person(args.translator, item), 'Karya dengan maklumat penterjemah', 'Karya tanpa maklumat penterjemah') add_field(t, html, 'editor', args.editor and format_person(args.editor, item), 'Karya dengan maklumat penyunting', 'Karya tanpa maklumat penyunting') add_field(t, html, 'illustrator', args.illustrator and withWikidataLink(args.illustrator), 'Karya dengan maklumat pengilustrasi', 'Karya tanpa maklumat pengilustrasi') add_field(t, html, 'publisher', args.publisher and withWikidataLink(args.publisher), 'Karya dengan maklumat penerbit', 'Karya tanpa maklumat penerbit') -- Address / Published-in (mutually exclusive) if args.address then t:node(construct_field('address', withWikidataLink(args.address))) html:wikitext(construct_cat('Karya dengan maklumat alamat')) elseif args.publishedin then t:node(construct_field('publishedin', withWikidataLink(args.publishedin))) html:wikitext(construct_cat('Karya dengan maklumat alamat penerbitan')) else html:wikitext(construct_cat('Karya tanpa maklumat alamat penerbitan')) end -- Year / Inception (mutually exclusive) if args.year then t:node(construct_field('year', withWikidataLink(args.year))) html:wikitext(construct_cat('Karya dengan maklumat tarikh')) html:wikitext(construct_cat('Karya tahun ' .. args.year)) elseif args.inception then t:node(construct_field('inception', withWikidataLink(args.inception))) html:wikitext(construct_cat('Karya dengan maklumat tarikh terawal')) else html:wikitext(construct_cat('Karya tanpa maklumat tarikh')) end add_field(t, html, 'printer', args.printer and withWikidataLink(args.printer), 'Karya dengan maklumat pencetak', 'Karya tanpa maklumat pencetak') -- Source (linkable formats get a file-page link) local src = args.source t:node(construct_field('source', src and LINKABLE_SOURCES[src] and '[[:Fail:' .. mw.title.getCurrentTitle().text .. '|' .. src .. ']]' or src )) -- Progress & transclusion status local progress_data = construct_status_field(args, { key = 'progress', config_key = 'status' }) local transclusion_data = construct_status_field(args, { key = 'transclusion' }) t:node(progress_data.row); html:wikitext(progress_data.cat) t:node(transclusion_data.row); html:wikitext(transclusion_data.cat) -- Validation date local vdate = args.validation_date if vdate then local vcat = cfg.validation_cats.dated(vdate) t:node(construct_field('validation_date', construct_cat_link(vcat, vdate))) html:wikitext(construct_cat(vcat)) elseif args.progress == 'T' then html:wikitext(construct_cat(cfg.validation_cats.undated)) end -- Standard identifiers for _, id in ipairs({ 'isbn', 'oclc', 'lccn', 'ark', 'doi' }) do local val = args[id] if val then local link_fn = cfg.url_gens[id] t:node(construct_field(id, link_fn and link_fn(val, val) or val)) end end add_field(t, html, 'volumes', args.volumes) return t end -- Cover image --[=[ Decision tree (evaluated in order): 1. Full [[...]] wikilink spec supplied → use as-is 2. Bare filename (has extension) → strip namespace prefix, rewrap 3. Audiovisual timestamp string → treat as thumbtime= value (→ case 5) 4. Multipage (DjVu/PDF) + file exists → page= thumbnail 5. Audiovisual + file exists → thumbtime= thumbnail 6. Any other type + file exists → plain file link 7. File does not exist → placeholder + missing category --]=] local function build_cover(args) local image_number = tonumber(args.image) -- Treat a bare timestamp string (e.g. "83" or "1:23") as a thumbtime value. if args.image and not image_number and args.source_type == 'audiovisual' and mw.ustring.match(args.image, '^%d+[%d:]*$') then image_number = args.image end local image_spec local cats = {} if not image_number and args.image and mw.ustring.find(args.image, '^%[%[') then -- Case 1: full wikilink spec image_spec = args.image if args.source_type ~= 'image' then table.insert(cats, construct_cat(cfg.cover_cats.fullspec)) end elseif not image_number and args.image and mw.ustring.find(args.image, '%.%w+$') then -- Case 2: bare filename — strip any recognised File namespace prefix local image_name = args.image local file_ns = mw.site.namespaces[6] local prefixes = { file_ns.name, file_ns.canonicalName } for _, alias in ipairs(file_ns.aliases) do table.insert(prefixes, alias) end for _, prefix in ipairs(prefixes) do image_name = mw.ustring.gsub(image_name, '^' .. prefix .. ':', '') image_name = mw.ustring.gsub(image_name, '^' .. prefix:lower() .. ':', '') end image_spec = '[[' .. mw.title.makeTitle('Fail', image_name).prefixedText .. '|' .. cfg.cover.width .. '|class=ws-cover]]' if args.source_type ~= 'image' then table.insert(cats, construct_cat(cfg.cover_cats.fullspec)) end elseif args.source_type == 'multipage' and args.file_exists then -- Case 4: DjVu / PDF page thumbnail image_spec = '[[' .. args.fileTitle.prefixedText .. '|' .. cfg.cover.width .. '|page=' .. (image_number or 1) .. '|class=ws-cover]]' elseif args.source_type == 'audiovisual' and args.file_exists then -- Case 5: audio / video timestamp thumbnail image_spec = '[[' .. args.fileTitle.prefixedText .. '|' .. cfg.cover.width .. '|thumbtime=' .. (image_number or 0) .. '|class=ws-cover]]' elseif args.file_exists then -- Case 6: image or unknown type image_spec = '[[' .. args.fileTitle.prefixedText .. '|' .. cfg.cover.width .. '|class=ws-cover]]' else -- Case 7: file missing — fall back to placeholder local image_link = args.fileTitle.prefixedText if not mw.ustring.find(args.fileTitle.rootText, '^.*%.%w+') then image_link = 'Special:Upload' end image_spec = '[[' .. cfg.cover.image .. '|' .. cfg.cover.width .. '|link=' .. image_link .. '|class=ws-cover]]' table.insert(cats, construct_cat(cfg.cover_cats.missing)) end return image_spec .. table.concat(cats) end -- Argument setup -- Resolves all derived values and performs every expensive DB lookup exactly -- once. Anything that touches the DB (file.exists, title.exists) lives here -- and nowhere else, making the cost immediately visible to maintainers. local function process_args(args) -- Apply config defaults for any args not supplied by the template. for k, v in pairs(cfg.defaults or {}) do if args[k] == nil then args[k] = v end end -- Allow pageTitle to be pre-set (e.g. from a sandbox or test harness). -- In normal template rendering it is always nil, so getCurrentTitle() is used. args.pageTitle = (args.pageTitle and mw.title.new(args.pageTitle)) or mw.title.getCurrentTitle() args.talkPageTitle = args.pageTitle.talkPageTitle args.fileTitle = mw.title.makeTitle('Fail', args.pageTitle.rootText) args.source_type = cfg.cover_cats.file_types[args.source] args.file_exists = args.fileTitle.file.exists -- expensive: DB lookup args.talk_exists = args.talkPageTitle.exists -- expensive: DB lookup return args end -- Main entry point local function indexTemplate(frame) local styles = frame:extensionTag{ name = 'templatestyles', args = { src = 'Modul:Index template/styles.css' }, } local data = (require 'Modul:Index_template/data').indexDataWithWikidata(frame) local args, item = data.args, data.item args = process_args(args) -- Sort index pages correctly in categories (falls back to page title). local sortkey = mw.getCurrentFrame():callParserFunction( 'DEFAULTSORT', { args.pageTitle.text } ) -- Scan the talk page for formatting notes unless notes were supplied directly. local talkremarks = '' local talk_page_exists = args.talk_exists if talk_page_exists and not args.notes then local content = args.talkPageTitle.content for _, keyword in ipairs(cfg.talkremarks.keywords) do local pattern = keyword.alone and '==( *' .. keyword.pattern .. ' *)==' or '==([^=%n]*' .. keyword.pattern .. '[^=%n]*)==' local section = mw.ustring.match(content, pattern) if section then args.notes = mw.getCurrentFrame():callParserFunction( '#lsth', args.talkPageTitle.prefixedText, mw.text.trim(section) ) break end end end if talk_page_exists then talkremarks = p._index_talk_remarks(args) end local html = mw.html.create() -- Wikidata indicator if item then html:wikitext('[[Kategori:Karya dengan ID Wikidata]]') html:wikitext( '<indicator name="wikidata">[[File:Wikidata.svg|20px|ID Wikidata|link=d:' .. item.id .. ']]</indicator>' ) else html:wikitext('[[Kategori:Karya tanpa ID Wikidata]]') end -- Tool indicators for _, v in ipairs(cfg.indicators) do html:wikitext(construct_indicator(args, v)) end local metadataTable = build_metadata(args, item, html) local coverImage = build_cover(args) -- Outer layout: [cover + metadata + pagelist] | [remarks] local outerRow = html:tag('table') :attr('id', 'ws-index-container') :tag('tr') outerRow:tag('td') :attr('id', 'ws-index-main-cell') :tag('table') :attr('id', 'ws-index-main-table') :tag('tr'):tag('td') :tag('div') :attr('id', 'ws-index-cover-container') :wikitext(coverImage) :done() :node(metadataTable) :done() :tag('tr'):tag('td') :tag('div') :attr('id', 'ws-index-pagelist-container') :addClass('mw-collapsible') :tag('em'):wikitext(cfg.pagelist.pages.txt):done() :wikitext(' ') :tag('span') :attr('id', 'ws-index-pagelist-legend') :wikitext(cfg.pagelist.legend.txt) :done() :tag('div') :attr('id', 'ws-index-pagelist') :addClass('index-pagelist mw-collapsible-content') :newline() :wikitext(args.pages and mw.text.trim(args.pages)) :newline() if args.remarks then outerRow:tag('td') :attr('id', 'ws-index-remarks') :newline() :wikitext(frame:preprocess(args.remarks)) else outerRow:tag('td'):attr('id', 'ws-index-remarks-empty') end -- Notes block if args.notes then html:tag('div'):attr('id', 'ws-index-notes'):wikitext(args.notes) end -- Tracking categories if cfg.type_cats[args.type] then html:wikitext(construct_cat(cfg.type_cats[args.type])) end if cfg.source_cats[args.source] then html:wikitext(construct_cat(cfg.source_cats[args.source])) elseif args.source ~= 'lain-lain' then html:wikitext(construct_cat('Indeks fail format lain')) end html:wikitext(construct_cat('Indeks')) if not args.remarks then html:wikitext(construct_cat('Laman berindeks')) end return talkremarks .. styles .. tostring(html) .. sortkey end function p.indexTemplate(frame) return indexTemplate(frame) end return p c7xm26fd2fd5z7nqa8bzsbr6oojxnkv 22828 22823 2026-04-15T05:08:52Z Hakimi97 9 Code consolidation 22828 Scribunto text/plain --[=[ Latest update: 15th April 2026 This is a module to implement logic for [[MediaWiki:Proofreadpage index template]], to render the book/index metadata panel for Malay Wikisource index pages. ]=] local ISO_639 = require('Modul:ISO 639') local messageBox = require('Module:Message box') local category_handler = require('Module:Category handler')._main local cfg = require('Modul:Index template/config') -- Low-level markup helpers local function construct_cat(cat) return '[[Kategori:' .. cat .. ']]' end local function construct_cat_link(cat, text) return '[[:Kategori:' .. cat .. '|' .. (text or cat) .. ']]' end -- Builds a single labelled metadata row. local function construct_field(id, content) if id == nil or content == nil then return nil end if not cfg.headings[id] then error(cfg.missing_heading_id(id)) end return mw.html.create('tr') :attr('id', 'ws-index-' .. id .. '-row') :addClass('ws-index-row') :tag('th') :attr('scope', 'row') :attr('id', 'ws-index-' .. id .. '-label') :addClass('ws-index-label') :wikitext(cfg.headings[id].txt) :done() :tag('td') :attr('id', 'ws-index-' .. id .. '-value') :addClass('ws-index-value') :wikitext(content) :allDone() end -- Conditionally adds a metadata row and the appropriate tracking category. -- If `content` is truthy the row is added plus `with_cat` (if given). -- Otherwise only `without_cat` is emitted (if given). local function add_field(tbl, html, id, content, with_cat, without_cat) if content then tbl:node(construct_field(id, content)) if with_cat then html:wikitext(construct_cat(with_cat)) end elseif without_cat then html:wikitext(construct_cat(without_cat)) end end -- Wikidata link helpers local function addWikidataToLink(page, label, category) local title = mw.title.new(page) if title == nil then return '[[' .. page .. '|' .. label .. ']]' end if title.isRedirect then title = title.redirectTarget end local tag = mw.html.create('span') local itemId = mw.wikibase.getEntityIdForTitle(title.fullText) tag:wikitext('[[' .. page .. '|' .. label .. ']]') if itemId then tag:wikitext( ' [[Image:Wikidata.svg|10px|link=d:' .. itemId .. '|Lihat maklumat di Wikidata]]' ) if category then tag:wikitext('[[Kategori:' .. category .. ']]') end end return tostring(tag) end -- Walks wikilinks inside `wikitext` and augments each with a Wikidata icon -- when the linked page has a Wikidata entity. local function withWikidataLink(wikitext, category) if wikitext == nil then return nil end -- Try bare [[Page]] links first … local result = mw.ustring.gsub(wikitext, '%[%[([^|%]]*)%]%]', function(page) return addWikidataToLink(page, mw.ustring.gsub(page, '%.*/', ''), category) end) if result ~= wikitext then return result end -- … then [[Page|Label]] links. return mw.ustring.gsub(wikitext, '%[%[([^|]*)|([^|%]]*)%]%]', function(page, link) return addWikidataToLink(page, link, category) end) end -- Formats a contributor field (author / translator / editor). -- With a Wikidata item: augments links with Wikidata icons. -- Without: wraps bare (non-wikilinked) names in {{Al|}}. local function format_person(value, item) if item then return withWikidataLink(value) end if value:find('%[%[') then return value end return '{{Al|' .. value .. '}}' end -- Progress / transclusion status rows local function construct_status_field(args, statusArgs) local key = statusArgs.key local config_key = statusArgs.config_key or key local index_status = args[key] or '_missing' local sd = cfg[config_key][index_status] or cfg[config_key]['_default'] local txt = sd.txt if type(txt) == 'function' then txt = txt(index_status) end local display = sd.error and ('<span class="error">' .. txt .. '</span>') or construct_cat_link(sd.cat, txt) return { row = construct_field(key, display), cat = construct_cat(sd.cat), } end -- Indicator builder -- Builds one <indicator> tag from an indicator config entry. -- `link` and `caption` may be plain strings or functions called with `args`. -- An optional `include` predicate (also called with `args`) gates rendering; -- defaults to always-show when absent. local function construct_indicator(args, iData) local include = iData.include or cfg.indicator_defaults.include if not include(args) then return '' end local parts = { iData.image, iData.width or cfg.indicator_defaults.width } if iData.alt then table.insert(parts, 'alt=' .. iData.alt) end local link = iData.link if type(link) == 'function' then link = link(args) end if link then table.insert(parts, 'link=' .. link) end local caption = iData.caption if type(caption) == 'function' then caption = caption(args) end if caption then table.insert(parts, caption) end return mw.getCurrentFrame():extensionTag{ name = 'indicator', content = '[[' .. table.concat(parts, '|') .. ']]', args = { name = iData.name }, } end -- Talk-page remarks local p = {} function p._index_talk_remarks(args) if not args.talkPageTitle then args.talkPageTitle = mw.title.getCurrentTitle().talkPageTitle end local text = cfg.talkremarks.text(args) local cat = category_handler({ construct_cat(cfg.talkremarks.cat) }) or '' local notes = '' if args.notes then notes = mw.html.create('div') :addClass('ombox-content') :css({ ['text-align'] = 'left', ['max-height'] = '5.5em', ['overflow'] = 'scroll', ['padding'] = '0.25em', ['margin'] = '0.25em', ['border-style'] = 'dashed', }) :newline() :wikitext(args.notes .. cat) :newline() :allDone() end return messageBox.main('ombox', { type = 'content', image = '[[File:Ambox important.svg|24px]]', style = 'box-sizing:border-box;margin:-0.93em auto 0.0em;text-align:center;width:100%;', textstyle = 'font-size:93%;text-decoration:none;', text = text .. tostring(notes), }) end function p.index_talk_remarks(frame) local args = {} for k, v in pairs(frame.args) do args[k] = v end args.talkPageTitle = mw.title.getCurrentTitle().talkPageTitle return p._index_talk_remarks(args) end -- Language resolution -- Resolves the display language string and emits language-related tracking -- categories onto `html`. Returns the display string, or nil if unavailable. local function resolve_language(args, item, html) local displayLang = nil local languageCount = 0 if item then local languages = item:formatPropertyValues( 'P407', { mw.wikibase.entity.claimRanks.RANK_NORMAL } ).value if languages and mw.text.trim(languages) ~= '' then displayLang = languages for language in languages:gmatch('([^,]+)') do language = mw.text.trim(language) if language ~= '' then languageCount = languageCount + 1 html:wikitext(construct_cat( 'Laman indeks karya yang asal dalam ' .. language )) end end end end if not displayLang and args.language then local displayLangs = {} for _, l in ipairs(mw.text.split(args.language, ',%s*', false)) do local lang = mw.text.trim(l) if lang ~= '' then local langName = ISO_639.language_name(lang, lang) table.insert(displayLangs, langName) languageCount = languageCount + 1 html:wikitext(construct_cat( 'Laman indeks karya yang asal dalam bahasa ' .. langName )) end end if #displayLangs > 0 then displayLang = table.concat(displayLangs, ', ') end end if displayLang then html:wikitext(construct_cat('Karya dengan maklumat bahasa')) if languageCount > 1 then html:wikitext(construct_cat('Laman indeks karya yang asal dalam pelbagai bahasa')) end else html:wikitext(construct_cat('Laman indeks karya tanpa maklumat bahasa')) end return displayLang end -- Metadata table local function build_metadata(args, item, html) local t = mw.html.create('table'):attr('id', 'ws-index-metadata') -- Title if args.title then local titleContent if item then titleContent = withWikidataLink(args.title) elseif args.title:find('%[%[') then titleContent = args.title else titleContent = '[[' .. args.title .. ']]' end t:node(construct_field('title', titleContent)) else mw.addWarning('Anda perlu isi medan tajuk borang.') end -- Subtitle add_field(t, html, 'subtitle', withWikidataLink(args.subtitle)) -- Language (complex; categories emitted inside resolve_language) add_field(t, html, 'language', resolve_language(args, item, html)) -- Simple bibliographic fields add_field(t, html, 'volume', args.volume, 'Karya dengan maklumat nombor jilid', 'Karya tanpa maklumat nombor jilid') add_field(t, html, 'edition', args.edition, 'Karya dengan maklumat edisi', 'Karya tanpa maklumat edisi') -- Author (also emits per-author categories from Wikidata) if args.author then t:node(construct_field('author', format_person(args.author, item))) html:wikitext(construct_cat('Karya dengan maklumat pengarang')) if item then local authors = item:formatPropertyValues( 'P50', { mw.wikibase.entity.claimRanks.RANK_NORMAL } ).value or '' for author in authors:gmatch('([^,]+)') do html:wikitext(construct_cat('Karya ' .. mw.text.trim(author))) end end else html:wikitext(construct_cat('Karya tanpa maklumat pengarang')) end -- Contributor fields add_field(t, html, 'translator', args.translator and format_person(args.translator, item), 'Karya dengan maklumat penterjemah', 'Karya tanpa maklumat penterjemah') add_field(t, html, 'editor', args.editor and format_person(args.editor, item), 'Karya dengan maklumat penyunting', 'Karya tanpa maklumat penyunting') add_field(t, html, 'illustrator', args.illustrator and withWikidataLink(args.illustrator), 'Karya dengan maklumat pengilustrasi', 'Karya tanpa maklumat pengilustrasi') add_field(t, html, 'publisher', args.publisher and withWikidataLink(args.publisher), 'Karya dengan maklumat penerbit', 'Karya tanpa maklumat penerbit') -- Address / Published-in (mutually exclusive) if args.address then t:node(construct_field('address', withWikidataLink(args.address))) html:wikitext(construct_cat('Karya dengan maklumat alamat')) elseif args.publishedin then t:node(construct_field('publishedin', withWikidataLink(args.publishedin))) html:wikitext(construct_cat('Karya dengan maklumat alamat penerbitan')) else html:wikitext(construct_cat('Karya tanpa maklumat alamat penerbitan')) end -- Year / Inception (mutually exclusive) if args.year then t:node(construct_field('year', withWikidataLink(args.year))) html:wikitext(construct_cat('Karya dengan maklumat tarikh')) html:wikitext(construct_cat('Karya tahun ' .. args.year)) elseif args.inception then t:node(construct_field('inception', withWikidataLink(args.inception))) html:wikitext(construct_cat('Karya dengan maklumat tarikh terawal')) else html:wikitext(construct_cat('Karya tanpa maklumat tarikh')) end add_field(t, html, 'printer', args.printer and withWikidataLink(args.printer), 'Karya dengan maklumat pencetak', 'Karya tanpa maklumat pencetak') -- Source (linkable formats get a file-page link) local src = args.source t:node(construct_field('source', src and cfg.linkable_sources[src] and '[[:Fail:' .. mw.title.getCurrentTitle().text .. '|' .. src .. ']]' or src )) -- Progress & transclusion status local progress_data = construct_status_field(args, { key = 'progress', config_key = 'status' }) local transclusion_data = construct_status_field(args, { key = 'transclusion' }) t:node(progress_data.row); html:wikitext(progress_data.cat) t:node(transclusion_data.row); html:wikitext(transclusion_data.cat) -- Validation date local vdate = args.validation_date if vdate then local vcat = cfg.validation_cats.dated(vdate) t:node(construct_field('validation_date', construct_cat_link(vcat, vdate))) html:wikitext(construct_cat(vcat)) elseif args.progress == 'T' then html:wikitext(construct_cat(cfg.validation_cats.undated)) end -- Standard identifiers for _, id in ipairs({ 'isbn', 'oclc', 'lccn', 'ark', 'doi' }) do local val = args[id] if val then local link_fn = cfg.url_gens[id] t:node(construct_field(id, link_fn and link_fn(val, val) or val)) end end add_field(t, html, 'volumes', args.volumes) return t end -- Cover image --[=[ Decision tree (evaluated in order): 1. Full [[...]] wikilink spec supplied → use as-is 2. Bare filename (has extension) → strip namespace prefix, rewrap 3. Audiovisual timestamp string → treat as thumbtime= value (→ case 5) 4. Multipage (DjVu/PDF) + file exists → page= thumbnail 5. Audiovisual + file exists → thumbtime= thumbnail 6. Any other type + file exists → plain file link 7. File does not exist → placeholder + missing category --]=] local function build_cover(args) local image_number = tonumber(args.image) -- Treat a bare timestamp string (e.g. "83" or "1:23") as a thumbtime value. if args.image and not image_number and args.source_type == 'audiovisual' and mw.ustring.match(args.image, '^%d+[%d:]*$') then image_number = args.image end local image_spec local cats = {} if not image_number and args.image and mw.ustring.find(args.image, '^%[%[') then -- Case 1: full wikilink spec image_spec = args.image if args.source_type ~= 'image' then table.insert(cats, construct_cat(cfg.cover_cats.fullspec)) end elseif not image_number and args.image and mw.ustring.find(args.image, '%.%w+$') then -- Case 2: bare filename — strip any recognised File namespace prefix local image_name = args.image local file_ns = mw.site.namespaces[6] local prefixes = { file_ns.name, file_ns.canonicalName } for _, alias in ipairs(file_ns.aliases) do table.insert(prefixes, alias) end for _, prefix in ipairs(prefixes) do image_name = mw.ustring.gsub(image_name, '^' .. prefix .. ':', '') image_name = mw.ustring.gsub(image_name, '^' .. prefix:lower() .. ':', '') end image_spec = '[[' .. mw.title.makeTitle('Fail', image_name).prefixedText .. '|' .. cfg.cover.width .. '|class=ws-cover]]' if args.source_type ~= 'image' then table.insert(cats, construct_cat(cfg.cover_cats.fullspec)) end elseif args.source_type == 'multipage' and args.file_exists then -- Case 4: DjVu / PDF page thumbnail image_spec = '[[' .. args.fileTitle.prefixedText .. '|' .. cfg.cover.width .. '|page=' .. (image_number or 1) .. '|class=ws-cover]]' elseif args.source_type == 'audiovisual' and args.file_exists then -- Case 5: audio / video timestamp thumbnail image_spec = '[[' .. args.fileTitle.prefixedText .. '|' .. cfg.cover.width .. '|thumbtime=' .. (image_number or 0) .. '|class=ws-cover]]' elseif args.file_exists then -- Case 6: image or unknown type image_spec = '[[' .. args.fileTitle.prefixedText .. '|' .. cfg.cover.width .. '|class=ws-cover]]' else -- Case 7: file missing — fall back to placeholder local image_link = args.fileTitle.prefixedText if not mw.ustring.find(args.fileTitle.rootText, '^.*%.%w+') then image_link = 'Special:Upload' end image_spec = '[[' .. cfg.cover.image .. '|' .. cfg.cover.width .. '|link=' .. image_link .. '|class=ws-cover]]' table.insert(cats, construct_cat(cfg.cover_cats.missing)) end return image_spec .. table.concat(cats) end -- Argument setup -- Resolves all derived values and performs every expensive DB lookup exactly -- once. Anything that touches the DB (file.exists, title.exists) lives here -- and nowhere else, making the cost immediately visible to maintainers. local function process_args(args) -- Apply config defaults for any args not supplied by the template. for k, v in pairs(cfg.defaults or {}) do if args[k] == nil then args[k] = v end end -- Allow pageTitle to be pre-set (e.g. from a sandbox or test harness). -- In normal template rendering it is always nil, so getCurrentTitle() is used. args.pageTitle = (args.pageTitle and mw.title.new(args.pageTitle)) or mw.title.getCurrentTitle() args.talkPageTitle = args.pageTitle.talkPageTitle args.fileTitle = mw.title.makeTitle('Fail', args.pageTitle.rootText) args.source_type = cfg.cover_cats.file_types[args.source] args.file_exists = args.fileTitle.file.exists -- expensive: DB lookup args.talk_exists = args.talkPageTitle.exists -- expensive: DB lookup return args end -- Main entry point local function indexTemplate(frame) local styles = frame:extensionTag{ name = 'templatestyles', args = { src = 'Modul:Index template/styles.css' }, } local data = (require 'Modul:Index_template/data').indexDataWithWikidata(frame) local args, item = data.args, data.item args = process_args(args) -- Sort index pages correctly in categories (falls back to page title). local sortkey = mw.getCurrentFrame():callParserFunction( 'DEFAULTSORT', { args.pageTitle.text } ) -- Scan the talk page for formatting notes unless notes were supplied directly. local talkremarks = '' local talk_page_exists = args.talk_exists if talk_page_exists and not args.notes then local content = args.talkPageTitle.content for _, keyword in ipairs(cfg.talkremarks.keywords) do local pattern = keyword.alone and '==( *' .. keyword.pattern .. ' *)==' or '==([^=%n]*' .. keyword.pattern .. '[^=%n]*)==' local section = mw.ustring.match(content, pattern) if section then args.notes = mw.getCurrentFrame():callParserFunction( '#lsth', args.talkPageTitle.prefixedText, mw.text.trim(section) ) break end end end if talk_page_exists then talkremarks = p._index_talk_remarks(args) end local html = mw.html.create() -- Wikidata indicator if item then html:wikitext('[[Kategori:Karya dengan ID Wikidata]]') html:wikitext( '<indicator name="wikidata">[[File:Wikidata.svg|20px|ID Wikidata|link=d:' .. item.id .. ']]</indicator>' ) else html:wikitext('[[Kategori:Karya tanpa ID Wikidata]]') end -- Tool indicators for _, v in ipairs(cfg.indicators) do html:wikitext(construct_indicator(args, v)) end local metadataTable = build_metadata(args, item, html) local coverImage = build_cover(args) -- Outer layout: [cover + metadata + pagelist] | [remarks] local outerRow = html:tag('table') :attr('id', 'ws-index-container') :tag('tr') outerRow:tag('td') :attr('id', 'ws-index-main-cell') :tag('table') :attr('id', 'ws-index-main-table') :tag('tr'):tag('td') :tag('div') :attr('id', 'ws-index-cover-container') :wikitext(coverImage) :done() :node(metadataTable) :done() :tag('tr'):tag('td') :tag('div') :attr('id', 'ws-index-pagelist-container') :addClass('mw-collapsible') :tag('em'):wikitext(cfg.pagelist.pages.txt):done() :wikitext(' ') :tag('span') :attr('id', 'ws-index-pagelist-legend') :wikitext(cfg.pagelist.legend.txt) :done() :tag('div') :attr('id', 'ws-index-pagelist') :addClass('index-pagelist mw-collapsible-content') :newline() :wikitext(args.pages and mw.text.trim(args.pages)) :newline() if args.remarks then outerRow:tag('td') :attr('id', 'ws-index-remarks') :newline() :wikitext(frame:preprocess(args.remarks)) else outerRow:tag('td'):attr('id', 'ws-index-remarks-empty') end -- Notes block if args.notes then html:tag('div'):attr('id', 'ws-index-notes'):wikitext(args.notes) end -- Tracking categories if cfg.type_cats[args.type] then html:wikitext(construct_cat(cfg.type_cats[args.type])) end if cfg.source_cats[args.source] then html:wikitext(construct_cat(cfg.source_cats[args.source])) elseif args.source ~= 'lain-lain' then html:wikitext(construct_cat('Indeks fail format lain')) end html:wikitext(construct_cat('Indeks')) if not args.remarks then html:wikitext(construct_cat('Laman berindeks')) end return talkremarks .. styles .. tostring(html) .. sortkey end function p.indexTemplate(frame) return indexTemplate(frame) end return p 31b556w1fymb6cqb2mvp7yhwwdaxb5t Pengguna:Hadithfajri/Laman utama/Pengepala 2 6178 22787 17938 2026-04-14T13:10:30Z Hadithfajri 36 22787 wikitext text/x-wiki <templatestyles src="Laman_utama/styles.css" /> <!----baru------> <div class="LU-outer-wrapper"> <div class="LU-logo" > [[File:Wikisource-logo-ms.svg|150px]] </div> <div class="LU-content"> <div style="flex-direction: row;display: flex; justify-content: space-around;"> <div class="LU-rumi"> <div> <div class="LU-selamat-datang"> Selamat Datang ke <span class="LU-tulisan-wiki">Wiki</span><span class="LU-tulisan-sumber">sumber</span> </div> <div style="margin-top: -1em; font-variant: small-caps;"> Perpustakaan [[w:Kandungan bebas|bebas]] dalam talian yang [[Wikisumber:Apa itu Wikisumber?|boleh diselenggara oleh sesiapa sahaja]]. </div> <div style="margin-top: -0.5em; font-variant: small-caps;"> <span class="plainlinks">[//ms.m.wikisource.org Versi mudah alih] − [https://ms.wikisource.org/wiki/Laman_Utama Capaian selamat]</span> </div> </div> </div> <div class="LU-kanan-jawi"> <div class="LU-jawi" > سلامة داتڠ <span class="LU-tulisan-jawi-wiki">کويکي</span><span class="LU-tulisan-jawi-sumber">سومبر</span> </div> <div style="margin-top: -1em; font-variant: small-caps;"> kini, terdapat '''[[{{ns:special}}:Statistik|{{NUMBEROFARTICLES}}]]''' koleksi teks bebas di [[w:Wikisumber|Wikisumber]]. </div> <div style="margin-top: -0.5em; font-variant: small-caps;"> {{CURRENTDAYNAME}}, {{CURRENTDAY}} {{CURRENTMONTHNAME}} {{CURRENTYEAR}}, {{CURRENTTIME}} ([[:w:UTC|UTC]]) </div> </div> </div> <!-- Bottom Navigation --> <div class="LU-bottom-nav"> [[Wikisumber:Indeks|<span style="color:#0645AD">Indeks</span>]] '''·''' [[Wikisumber:Gerbang komuniti|<span style="color:#0645AD">Gerbang Komuniti</span>]] '''·''' [[Wikisumber:Kedai Kopi/Pengumuman|<span style="color:#0645AD">Pengumuman</span>]] '''·''' [[Wikisumber:Kotak Pasir|<span style="color:#0645AD">Kotak Pasir</span>]] '''·''' <span class="plainlinks">[http://wikimediafoundation.org/wiki/DonateNonJS/en <span style="color:#0645AD">derma</span>]</span><br> [[:Kategori:Kategori|<span style="color:#0645AD">Kategori</span>]] ''':''' [[:Kategori:Karya|<span style="color:#0645AD">Karya</span>]] '''·''' [[:Kategori:Pengarang|<span style="color:#0645AD">Pengarang</span>]] '''·''' [[:Kategori:Sumber|<span style="color:#0645AD">Sumber</span>]] </div> </div> </div><p style="clear: both;"></p> <noinclude> [[Kategori:Laman Utama|Laman Utama]] </noinclude> g1t3caxyra6e3t1nh5gm51szlh7xast Indeks:Sjaïr Kén Tamboehan, een oorspronkelijk maleisch Gedicht, met aanteekeningen uitgegeven door J.J. de Hollander; Kén Tamboehan, 1856.pdf 252 6406 22830 22687 2026-04-15T05:09:55Z Hakimi97 9 22830 proofread-index text/x-wiki {{:MediaWiki:Proofreadpage_index_template |Type=book |wikidata_item= |Title=Sjaïr Kén Tamboehan |Language=ms |Volume= |Author= |Translator= |Editor= |Illustrator= |School= |Publisher= |Address= |Year= |Key= |ISBN= |OCLC= |LCCN= |BNF_ARK= |ARC= |DOI= |Source=pdf |Image=9 |Progress=X |Transclusion=no |Validation_date= |Pages=<pagelist /> |Volumes= |Remarks= |Width= |Header= |Footer= |tmplver= }} hfhn6mmaysrres7gvpj1bj8z0vncuno Indeks:Mawlid al-Nabi Or. 3289.pdf 252 7446 22781 22642 2026-04-14T12:33:56Z Hakimi97 9 22781 proofread-index text/x-wiki {{:MediaWiki:Proofreadpage_index_template |Type=book |wikidata_item= |Title=Mawlid al-Nabi |Language=ms-arab |Volume= |Author= |Translator= |Editor= |Illustrator= |School= |Publisher= |Address= |Year= |Key= |ISBN= |OCLC= |LCCN= |BNF_ARK= |ARC= |DOI= |Source=pdf |Image=2 |Progress=X |Transclusion=no |Validation_date= |Pages=<pagelist /> |Volumes= |Remarks= |Width= |Header= |Footer= |tmplver= }} lkpv3ocbx4rps1n03kq6e4xb0p5km66 Indeks:Het Nieuwe Testament in het Maleisch.pdf 252 7805 22782 21783 2026-04-14T12:34:47Z Hakimi97 9 22782 proofread-index text/x-wiki {{:MediaWiki:Proofreadpage_index_template |Type=book |wikidata_item= |Title=Perjanjian Baru |Language=ms-arab |Volume= |Author= |Translator=Klinkert |Editor= |Illustrator= |School= |Publisher= |Address= |Year= |Key= |ISBN= |OCLC= |LCCN= |BNF_ARK= |ARC= |DOI= |Source=pdf |Image=1 |Progress=X |Transclusion=no |Validation_date= |Pages=<pagelist 1="Cover" 2to4="–" 5="Cover" 6="–" 7="Title" 8=4 688to692="–" /> |Volumes= |Remarks= |Width= |Header= |Footer= |tmplver= }} s08tv5q86ov5hj3g3fh67l30lwv0v6d Modul:Index template/config 828 7955 22824 22765 2026-04-15T04:33:46Z Hakimi97 9 Merge Modul:Index template/indicators into Modul:Index template/config 22824 Scribunto text/plain local function any_case(str) return str:gsub('.', function(chr) if chr:match('%a') then return '[' .. chr:lower() .. chr:upper() .. ']' else return chr end end) end local validation_cats = { ['dated'] = function(vdate) return 'Indeks disahkan pada ' .. vdate end, ['undated'] = 'Indeks disahkan tanpa tarikh', } return { ['param_map'] = { ['Type'] = 'type', ['Title'] = 'title', ['Subtitle'] = 'subtitle', ['Language'] = 'language', ['Volume'] = 'volume', ['Edition'] = 'edition', ['Author'] = 'author', ['Translator'] = 'translator', ['Editor'] = 'editor', ['Illustrator'] = 'illustrator', ['Publisher'] = 'publisher', ['Address'] = 'address', ['Printer'] = 'printer', ['Year'] = 'year', ['Source'] = 'source', ['Image'] = 'image', ['Progress'] = 'progress', ['Transclusion'] = 'transclusion', ['Validation_date'] = 'validation_date', ['ISBN'] = 'isbn', ['OCLC'] = 'oclc', ['LCCN'] = 'lccn', ['ARK'] = 'ark', ['DOI'] = 'doi', ['Volumes'] = 'volumes', ['Notes'] = 'notes', ['Pages'] = 'pages', ['Remarks'] = 'remarks', ['wikidata_item'] = 'wikidata_item', }, ['headings'] = { ['title'] = { ['txt'] = 'Tajuk' }, ['subtitle'] = { ['txt'] = 'Subtajuk' }, ['language'] = { ['txt'] = 'Bahasa' }, ['volume'] = { ['txt'] = 'Jilid' }, ['edition'] = { ['txt'] = 'Edisi' }, ['author'] = { ['txt'] = 'Pengarang' }, ['translator'] = { ['txt'] = 'Penterjemah' }, ['editor'] = { ['txt'] = 'Penyunting' }, ['illustrator'] = { ['txt'] = 'Pengilustrasi' }, ['publisher'] = { ['txt'] = 'Penerbit' }, ['address'] = { ['txt'] = 'Alamat' }, ['publishedin'] = { ['txt'] = 'Alamat penerbitan' }, ['year'] = { ['txt'] = 'Tahun' }, ['inception'] = { ['txt'] = 'Tarikh terawal' }, ['printer'] = { ['txt'] = 'Pencetak' }, ['source'] = { ['txt'] = 'Sumber' }, ['progress'] = { ['txt'] = 'Kemajuan' }, ['transclusion'] = { ['txt'] = 'Transklusi' }, ['validation_date'] = { ['txt'] = 'Tarikh pengesahan' }, ['isbn'] = { ['txt'] = 'ISBN' }, ['oclc'] = { ['txt'] = 'OCLC' }, ['lccn'] = { ['txt'] = 'LCCN' }, ['ark'] = { ['txt'] = 'ARK' }, ['doi'] = { ['txt'] = 'DOI' }, ['volumes'] = { ['txt'] = 'Siri' }, }, ['status'] = { ['T'] = { ['cat'] = 'Indeks disahkan', ['txt'] = 'Selesai disahkan', }, ['V'] = { ['cat'] = 'Indeks telah dibacaprufkan', ['txt'] = 'Akan disahkan', }, ['C'] = { ['cat'] = 'Indeks belum dibacaprufkan', ['txt'] = 'Akan dibacaprufkan', }, ['OCR'] = { ['cat'] = 'Indeks - Lapisan Teks Diperlukan', ['txt'] = 'Perlu tambah lapisan teks OCR', }, ['L'] = { ['cat'] = 'Indeks - Fail yang perlu dibaiki', ['txt'] = 'Fail sumber cacat', ['error'] = true, }, ['X'] = { ['cat'] = 'Indeks - Fail untuk disemak', ['txt'] = 'Semak kesemua muka surat pada fail sumber sebelum memulakan proses baca pruf (untuk mengesahkan fail tersebut tidak ada masalah)', ['error'] = true, }, ['_missing'] = { ['cat'] = 'Indeks - Kemajuan tidak diketahui', ['txt'] = 'Kemajuan tidak diketahui (ralat templat)', ['error'] = true, }, ['_default'] = { ['cat'] = 'Indeks - Kemajuan tidak diketahui', ['txt'] = function(index_status) return 'Kemajuan tidak diketahui: ' .. index_status .. ' (ralat templat)' end, ['error'] = true, } }, ['transclusion'] = { ['yes'] = { ['cat'] = 'Ditransklusi sepenuhnya', ['txt'] = 'Ditransklusi sepenuhnya', }, ['notimg'] = { ['cat'] = 'Imej belum ditransklusi sepenuhnya', ['txt'] = 'Imej belum ditransklusi sepenuhnya', }, ['notadv'] = { ['cat'] = 'Bahan pengiklanan belum ditransklusi', ['txt'] = 'Bahan pengiklanan belum ditransklusi', }, ['held'] = { ['cat'] = 'Transklusi ditangguhkan', ['txt'] = 'Transklusi ditangguhkan', }, ['check'] = { ['cat'] = 'Semakan transklusi diperlukan', ['txt'] = 'Semakan transklusi diperlukan', }, ['no'] = { ['cat'] = 'Indeks belum ditransklusi', ['txt'] = 'Indeks belum ditransklusi mahupun diperiksa', }, ['_missing'] = { ['cat'] = 'Indeks belum ditransklusi', ['txt'] = 'Status transklusi tiada (ralat templat)', ['error'] = true, }, ['_default'] = { ['cat'] = 'Indeks belum ditransklusi', ['txt'] = function(index_status) return 'Status transklusi tidak diketahui: ' .. index_status .. ' (ralat templat)' end, ['error'] = true, } }, ['validation_cats'] = validation_cats, ['url_gens'] = { ['isbn'] = function(id, text) return require('Module:ISBN')._ISBN({id}) end, ['oclc'] = function(id, text) return '[https://www.worldcat.org/oclc/' .. mw.uri.encode(id, 'PATH') .. ' ' .. text .. ']' end, ['lccn'] = function(id, text) return '[https://lccn.loc.gov/' .. mw.uri.encode(id, 'PATH') .. ' ' .. text .. ']' end, ['ark'] = function(id, text) return '[https://n2t.net/' .. mw.uri.encode(id, 'QUERY') .. ' ' .. text .. ']' end, ['doi'] = function(id, text) return '[https://doi.org/' .. mw.uri.encode(id, 'PATH') .. ' ' .. text .. ']' end, }, ['cover'] = { ['width'] = '250px', ['image'] = 'File:Placeholder book.svg' }, ['cover_cats'] = { ['file_types'] = { ['jpg'] = 'image', ['png'] = 'image', ['gif'] = 'image', ['tif'] = 'image', ['ogg'] = 'audiovisual', ['ogv'] = 'audiovisual', ['webm'] = 'audiovisual', ['pdf'] = 'multipage', ['djvu'] = 'multipage', ['_empty_'] = 'unknown', }, ['image'] = 'Indeks fail imej', ['audiovisual'] = 'Indeks fail audiovizual', ['unknown'] = 'Indeks jenis tidak diketahui', ['missing'] = 'Indeks dengan fail hilang', ['fullspec'] = 'Indeks bukan imej dengan imej kulit ditentukan sepenuhnya', }, ['type_cats'] = { ['book'] = 'Indeks - Buku', ['journal'] = 'Indeks - Jurnal', ['collection'] = 'Indeks - Koleksi', ['dictionary'] = 'Indeks - Kamus', ['phdthesis'] = 'Indeks - Tesis', }, ['source_cats'] = { ['djvu'] = 'Indeks fail DjVu', ['pdf'] = 'Indeks fail PDF', ['jpg'] = 'Indeks fail JPG', ['png'] = 'Indeks fail PNG', ['gif'] = 'Indeks fail GIF', ['tif'] = 'Indeks fail TIF', ['ogg'] = 'Indeks fail OGG', ['ogv'] = 'Indeks fail OGV', ['webm'] = 'Indeks fail WebM', }, ['pagelist'] = { ['pages'] = { ['txt'] = 'Senarai muka surat' }, ['legend'] = { ['txt'] = '(kunci kepada [[Bantuan:Status_laman|Status Laman]])' } }, ['missing_heading_id'] = function(id) return 'Tidak jumpa tajuk untuk ID: ' .. id end, ['indicator_defaults'] = { ['width'] = '20px', ['include'] = function(args) return true end, }, ['indicators'] = { { name = 'pagegame', image = 'File:OOjs UI icon page number.svg', width = '20px', link = function(args) return tostring(mw.uri.fullUrl('toolforge:ws-page-game', { wikisource = 'ms', index = mw.uri.encode(args.fileTitle.rootText), lang = 'ms', })) end, caption = 'Permainan Laman Wikisumber (pembina senarai muka surat langkah-demi-langkah)', }, { name = 'purge file', image = 'File:OOjs UI icon reload.svg', width = '20px', link = function(args) return tostring(mw.uri.fullUrl( 'Indeks:' .. args.pageTitle.text, { action = 'purge' } )) end, caption = 'Bersihkan fail', }, { name = 'book2scroll', image = 'File:Library-logo-blue-outline.png', width = '18px', link = function(args) return tostring(mw.uri.fullUrl( 'toolforge:book2scrollv2/read/ms/' .. mw.uri.encode(args.fileTitle.rootText) )) end, caption = 'Buka pada Book2Scroll', }, { name = 'bookreader', image = 'File:BookReader-favicon.svg', width = '18px', link = function(args) return tostring(mw.uri.fullUrl( 'toolforge:bookreader/ms/' .. mw.uri.encode(args.fileTitle.rootText) )) end, caption = 'Buka fail pada BookReader', }, { name = 'validated-index-date', image = 'File:Yes Check Circle.svg', width = '15px', alt = 'Laman indeks yang disahkan.', link = function(args) local vdate = args.validation_date return vdate and tostring(mw.uri.fullUrl( 'Kategori:' .. validation_cats.dated(vdate) )) or '' end, caption = function(args) local vdate = args.validation_date return vdate and 'Disahkan pada ' .. vdate or nil end, include = function(args) return args.validation_date ~= nil end, }, }, ['talkremarks'] = { ['text'] = function(args) return 'Garis panduan pemformatan khusus untuk karya ini mungkin telah ditetapkan. Sila semak [[' .. args.talkPageTitle.prefixedText .. '|laman perbincangan Indeks ini]] dan patuhi sebarang kelaziman yang berkaitan.' end, ['cat'] = 'Laman yang menggunakan catatan perbincangan indeks dengan parameter nota', ['keywords'] = { -- Kata kunci Melayu { ['pattern'] = any_case('nota?'), ['alone'] = true, }, { ['pattern'] = any_case('nota? ringkas'), ['alone'] = false, }, { ['pattern'] = any_case('nota? bacapruf'), ['alone'] = false, }, { ['pattern'] = any_case('nota? gaya'), ['alone'] = false, }, { ['pattern'] = any_case('nota? tataletak'), ['alone'] = false, }, { ['pattern'] = any_case('konvensyen? pemformatan'), ['alone'] = false, }, { ['pattern'] = any_case('pemformatan'), ['alone'] = true, }, { ['pattern'] = any_case('konvensyen?'), ['alone'] = true, }, { ['pattern'] = any_case('tataletak'), ['alone'] = true, }, { ['pattern'] = any_case('petikan'), ['alone'] = true, }, { ['pattern'] = any_case('tanda petikan'), ['alone'] = false, }, { ['pattern'] = any_case('tipografi'), ['alone'] = false, }, { ['pattern'] = any_case('ejaan'), ['alone'] = false, }, { ['pattern'] = any_case('panduan gaya'), ['alone'] = false, }, { ['pattern'] = any_case('garis? panduan?'), ['alone'] = false, }, { ['pattern'] = any_case('laman? hilang'), ['alone'] = true, }, -- Kata kunci Inggeris (untuk keserasian) { ['pattern'] = any_case('notes?'), ['alone'] = true, }, { ['pattern'] = any_case('formatting conventions?'), ['alone'] = false, }, { ['pattern'] = any_case('formatt?i?n?g?'), ['alone'] = true, }, { ['pattern'] = any_case('conventions?'), ['alone'] = true, }, { ['pattern'] = any_case('guidelines?'), ['alone'] = false, }, { ['pattern'] = any_case('style guide'), ['alone'] = false, }, { ['pattern'] = any_case('spelling'), ['alone'] = false, }, { ['pattern'] = any_case('typography'), ['alone'] = false, }, { ['pattern'] = any_case('long[ %-]s'), ['alone'] = true, }, }, }, } ib7jttigz6fv1p8ke949w6y70jcrl6r 22827 22824 2026-04-15T05:08:50Z Hakimi97 9 Code consolidation 22827 Scribunto text/plain local function any_case(str) return str:gsub('.', function(chr) if chr:match('%a') then return '[' .. chr:lower() .. chr:upper() .. ']' else return chr end end) end -- Inverted param_map: maps lua-key → Title-Case wikitext key. -- Used by Modul:Arguments in the data module to resolve template parameters. local param_map = { ['Type'] = 'type', ['Title'] = 'title', ['Subtitle'] = 'subtitle', ['Language'] = 'language', ['Volume'] = 'volume', ['Edition'] = 'edition', ['Author'] = 'author', ['Translator'] = 'translator', ['Editor'] = 'editor', ['Illustrator'] = 'illustrator', ['Publisher'] = 'publisher', ['Address'] = 'address', ['Printer'] = 'printer', ['Year'] = 'year', ['Source'] = 'source', ['Image'] = 'image', ['Progress'] = 'progress', ['Transclusion'] = 'transclusion', ['Validation_date'] = 'validation_date', ['ISBN'] = 'isbn', ['OCLC'] = 'oclc', ['LCCN'] = 'lccn', ['ARK'] = 'ark', ['DOI'] = 'doi', ['Volumes'] = 'volumes', ['Notes'] = 'notes', ['Pages'] = 'pages', ['Remarks'] = 'remarks', ['wikidata_item'] = 'wikidata_item', } local translate = {} for titleCase, lowerCase in pairs(param_map) do translate[lowerCase] = titleCase end local validation_cats = { ['dated'] = function(vdate) return 'Indeks disahkan pada ' .. vdate end, ['undated'] = 'Indeks disahkan tanpa tarikh', } return { ['param_map'] = param_map, ['translate'] = translate, ['headings'] = { ['title'] = { ['txt'] = 'Tajuk' }, ['subtitle'] = { ['txt'] = 'Subtajuk' }, ['language'] = { ['txt'] = 'Bahasa' }, ['volume'] = { ['txt'] = 'Jilid' }, ['edition'] = { ['txt'] = 'Edisi' }, ['author'] = { ['txt'] = 'Pengarang' }, ['translator'] = { ['txt'] = 'Penterjemah' }, ['editor'] = { ['txt'] = 'Penyunting' }, ['illustrator'] = { ['txt'] = 'Pengilustrasi' }, ['publisher'] = { ['txt'] = 'Penerbit' }, ['address'] = { ['txt'] = 'Alamat' }, ['publishedin'] = { ['txt'] = 'Alamat penerbitan' }, ['year'] = { ['txt'] = 'Tahun' }, ['inception'] = { ['txt'] = 'Tarikh terawal' }, ['printer'] = { ['txt'] = 'Pencetak' }, ['source'] = { ['txt'] = 'Sumber' }, ['progress'] = { ['txt'] = 'Kemajuan' }, ['transclusion'] = { ['txt'] = 'Transklusi' }, ['validation_date'] = { ['txt'] = 'Tarikh pengesahan' }, ['isbn'] = { ['txt'] = 'ISBN' }, ['oclc'] = { ['txt'] = 'OCLC' }, ['lccn'] = { ['txt'] = 'LCCN' }, ['ark'] = { ['txt'] = 'ARK' }, ['doi'] = { ['txt'] = 'DOI' }, ['volumes'] = { ['txt'] = 'Siri' }, }, ['status'] = { ['T'] = { ['cat'] = 'Indeks disahkan', ['txt'] = 'Selesai disahkan', }, ['V'] = { ['cat'] = 'Indeks telah dibacaprufkan', ['txt'] = 'Akan disahkan', }, ['C'] = { ['cat'] = 'Indeks belum dibacaprufkan', ['txt'] = 'Akan dibacaprufkan', }, ['OCR'] = { ['cat'] = 'Indeks - Lapisan Teks Diperlukan', ['txt'] = 'Perlu tambah lapisan teks OCR', }, ['L'] = { ['cat'] = 'Indeks - Fail yang perlu dibaiki', ['txt'] = 'Fail sumber cacat', ['error'] = true, }, ['X'] = { ['cat'] = 'Indeks - Fail untuk disemak', ['txt'] = 'Semak kesemua muka surat pada fail sumber sebelum memulakan proses baca pruf (untuk mengesahkan fail tersebut tidak ada masalah)', ['error'] = true, }, ['_missing'] = { ['cat'] = 'Indeks - Kemajuan tidak diketahui', ['txt'] = 'Kemajuan tidak diketahui (ralat templat)', ['error'] = true, }, ['_default'] = { ['cat'] = 'Indeks - Kemajuan tidak diketahui', ['txt'] = function(index_status) return 'Kemajuan tidak diketahui: ' .. index_status .. ' (ralat templat)' end, ['error'] = true, } }, ['transclusion'] = { ['yes'] = { ['cat'] = 'Ditransklusi sepenuhnya', ['txt'] = 'Ditransklusi sepenuhnya', }, ['notimg'] = { ['cat'] = 'Imej belum ditransklusi sepenuhnya', ['txt'] = 'Imej belum ditransklusi sepenuhnya', }, ['notadv'] = { ['cat'] = 'Bahan pengiklanan belum ditransklusi', ['txt'] = 'Bahan pengiklanan belum ditransklusi', }, ['held'] = { ['cat'] = 'Transklusi ditangguhkan', ['txt'] = 'Transklusi ditangguhkan', }, ['check'] = { ['cat'] = 'Semakan transklusi diperlukan', ['txt'] = 'Semakan transklusi diperlukan', }, ['no'] = { ['cat'] = 'Indeks belum ditransklusi', ['txt'] = 'Indeks belum ditransklusi mahupun diperiksa', }, ['_missing'] = { ['cat'] = 'Indeks belum ditransklusi', ['txt'] = 'Status transklusi tiada (ralat templat)', ['error'] = true, }, ['_default'] = { ['cat'] = 'Indeks belum ditransklusi', ['txt'] = function(index_status) return 'Status transklusi tidak diketahui: ' .. index_status .. ' (ralat templat)' end, ['error'] = true, } }, ['validation_cats'] = validation_cats, ['url_gens'] = { ['isbn'] = function(id, text) return require('Module:ISBN')._ISBN({id}) end, ['oclc'] = function(id, text) return '[https://www.worldcat.org/oclc/' .. mw.uri.encode(id, 'PATH') .. ' ' .. text .. ']' end, ['lccn'] = function(id, text) return '[https://lccn.loc.gov/' .. mw.uri.encode(id, 'PATH') .. ' ' .. text .. ']' end, ['ark'] = function(id, text) return '[https://n2t.net/' .. mw.uri.encode(id, 'QUERY') .. ' ' .. text .. ']' end, ['doi'] = function(id, text) return '[https://doi.org/' .. mw.uri.encode(id, 'PATH') .. ' ' .. text .. ']' end, }, ['cover'] = { ['width'] = '250px', ['image'] = 'File:Placeholder book.svg' }, ['cover_cats'] = { ['file_types'] = { ['jpg'] = 'image', ['png'] = 'image', ['gif'] = 'image', ['tif'] = 'image', ['ogg'] = 'audiovisual', ['ogv'] = 'audiovisual', ['webm'] = 'audiovisual', ['pdf'] = 'multipage', ['djvu'] = 'multipage', ['_empty_'] = 'unknown', }, ['image'] = 'Indeks fail imej', ['audiovisual'] = 'Indeks fail audiovizual', ['unknown'] = 'Indeks jenis tidak diketahui', ['missing'] = 'Indeks dengan fail hilang', ['fullspec'] = 'Indeks bukan imej dengan imej kulit ditentukan sepenuhnya', }, ['type_cats'] = { ['book'] = 'Indeks - Buku', ['journal'] = 'Indeks - Jurnal', ['collection'] = 'Indeks - Koleksi', ['dictionary'] = 'Indeks - Kamus', ['phdthesis'] = 'Indeks - Tesis', }, ['linkable_sources'] = { djvu=true, pdf=true, png=true, gif=true, tif=true, ogg=true, ogv=true, webm=true, }, ['source_cats'] = { ['djvu'] = 'Indeks fail DjVu', ['pdf'] = 'Indeks fail PDF', ['jpg'] = 'Indeks fail JPG', ['png'] = 'Indeks fail PNG', ['gif'] = 'Indeks fail GIF', ['tif'] = 'Indeks fail TIF', ['ogg'] = 'Indeks fail OGG', ['ogv'] = 'Indeks fail OGV', ['webm'] = 'Indeks fail WebM', }, ['pagelist'] = { ['pages'] = { ['txt'] = 'Senarai muka surat' }, ['legend'] = { ['txt'] = '(kunci kepada [[Bantuan:Status_laman|Status Laman]])' } }, ['missing_heading_id'] = function(id) return 'Tidak jumpa tajuk untuk ID: ' .. id end, ['indicator_defaults'] = { ['width'] = '20px', ['include'] = function(args) return true end, }, ['indicators'] = { { name = 'pagegame', image = 'File:OOjs UI icon page number.svg', width = '20px', link = function(args) return tostring(mw.uri.fullUrl('toolforge:ws-page-game', { wikisource = 'ms', index = mw.uri.encode(args.fileTitle.rootText), lang = 'ms', })) end, caption = 'Permainan Laman Wikisumber (pembina senarai muka surat langkah-demi-langkah)', }, { name = 'purge file', image = 'File:OOjs UI icon reload.svg', width = '20px', link = function(args) return tostring(mw.uri.fullUrl( 'Indeks:' .. args.pageTitle.text, { action = 'purge' } )) end, caption = 'Bersihkan fail', }, { name = 'book2scroll', image = 'File:Library-logo-blue-outline.png', width = '18px', link = function(args) return tostring(mw.uri.fullUrl( 'toolforge:book2scrollv2/read/ms/' .. mw.uri.encode(args.fileTitle.rootText) )) end, caption = 'Buka pada Book2Scroll', }, { name = 'bookreader', image = 'File:BookReader-favicon.svg', width = '18px', link = function(args) return tostring(mw.uri.fullUrl( 'toolforge:bookreader/ms/' .. mw.uri.encode(args.fileTitle.rootText) )) end, caption = 'Buka fail pada BookReader', }, { name = 'validated-index-date', image = 'File:Yes Check Circle.svg', width = '15px', alt = 'Laman indeks yang disahkan.', link = function(args) local vdate = args.validation_date return vdate and tostring(mw.uri.fullUrl( 'Kategori:' .. validation_cats.dated(vdate) )) or '' end, caption = function(args) local vdate = args.validation_date return vdate and 'Disahkan pada ' .. vdate or nil end, include = function(args) return args.validation_date ~= nil end, }, }, ['talkremarks'] = { ['text'] = function(args) return 'Garis panduan pemformatan khusus untuk karya ini mungkin telah ditetapkan. Sila semak [[' .. args.talkPageTitle.prefixedText .. '|laman perbincangan Indeks ini]] dan patuhi sebarang kelaziman yang berkaitan.' end, ['cat'] = 'Laman yang menggunakan catatan perbincangan indeks dengan parameter nota', ['keywords'] = { -- Kata kunci Melayu { ['pattern'] = any_case('nota?'), ['alone'] = true, }, { ['pattern'] = any_case('nota? ringkas'), ['alone'] = false, }, { ['pattern'] = any_case('nota? bacapruf'), ['alone'] = false, }, { ['pattern'] = any_case('nota? gaya'), ['alone'] = false, }, { ['pattern'] = any_case('nota? tataletak'), ['alone'] = false, }, { ['pattern'] = any_case('konvensyen? pemformatan'), ['alone'] = false, }, { ['pattern'] = any_case('pemformatan'), ['alone'] = true, }, { ['pattern'] = any_case('konvensyen?'), ['alone'] = true, }, { ['pattern'] = any_case('tataletak'), ['alone'] = true, }, { ['pattern'] = any_case('petikan'), ['alone'] = true, }, { ['pattern'] = any_case('tanda petikan'), ['alone'] = false, }, { ['pattern'] = any_case('tipografi'), ['alone'] = false, }, { ['pattern'] = any_case('ejaan'), ['alone'] = false, }, { ['pattern'] = any_case('panduan gaya'), ['alone'] = false, }, { ['pattern'] = any_case('garis? panduan?'), ['alone'] = false, }, { ['pattern'] = any_case('laman? hilang'), ['alone'] = true, }, -- Kata kunci Inggeris (untuk keserasian) { ['pattern'] = any_case('notes?'), ['alone'] = true, }, { ['pattern'] = any_case('formatting conventions?'), ['alone'] = false, }, { ['pattern'] = any_case('formatt?i?n?g?'), ['alone'] = true, }, { ['pattern'] = any_case('conventions?'), ['alone'] = true, }, { ['pattern'] = any_case('guidelines?'), ['alone'] = false, }, { ['pattern'] = any_case('style guide'), ['alone'] = false, }, { ['pattern'] = any_case('spelling'), ['alone'] = false, }, { ['pattern'] = any_case('typography'), ['alone'] = false, }, { ['pattern'] = any_case('long[ %-]s'), ['alone'] = true, }, }, }, } clrzkn7oi5jojq8kwry66y2lrfddi0p Modul:Index template/doc 828 7960 22792 22773 2026-04-14T13:26:03Z Hakimi97 9 Document the module 22792 wikitext text/x-wiki {{lua|Modul:Arguments|Modul:ISO 639|Modul:Category handler|Modul:File link|Modul:Message box|Modul:Index template/config|Modul:Index template/indicators|Modul:Index template/data|Modul:Index template/styles.css|Templat:Author link|Templat:Index talk remarks}} This is the current module to implement logic for [[MediaWiki:Proofreadpage index template]], based on [[:mediawikiwiki:Wikidata - Wikisource Integration Modules|Wikidata - Wikisource Integration Modules]] on MediaWiki with significant changes: # Reconfiguration of index page panel structure (which includes image, metadata, pagelist, and remarks/notes sections) to follow the structure on [[:en:Module:Proofreadpage index template|Module:Proofreadpage index template]]. # Adaptation new metadata fields from [[:en:Module:Proofreadpage index template|Module:Proofreadpage index template]]: (1) language parameter and categorization, ensuring manually-entered language code would return language canonical names; (2) transclusion status; (3) validation date; (4) ISBN/OCLC/LCCN/ARK/DOI; (5) talk page remark related functionality; (6) missing file tracking category; (7) full image spec tracking category; and (8) audiovisual thumbtime cover # Sufficient gap between image and metadata # Sufficient gap between labels and values of metadata # Author property value changed to P50 instead of P253075 # Ensured all file types under the source parameter could be wikilinked. # The wikilinks for title, author, translator and editor fields could be generated automatically or manually # Simplified the invocation of the module at MediaWiki:Proofreadpage index template so that no explicit mentioning of parameters and indicators. # Integration of Modul:Index data into Modul:Index template, with the new name Modul:Index template/data. # Replaced the usage of transclusion_checker indicator (external toolforge link) to [[MediaWiki:Gadget-transclusion-check|transclusion check gadget]]. # Utilized the [[Modul:Arguments]] for getArgs. <noinclude>[[Category:External links on protected pages]]</noinclude> 45utd2wedyfcgvpfa1rrj7j5xhe3sxw 22826 22792 2026-04-15T04:35:27Z Hakimi97 9 22826 wikitext text/x-wiki {{lua|Modul:Arguments|Modul:ISO 639|Modul:Category handler|Modul:File link|Modul:Message box|Modul:Index template/config|Modul:Index template/data|Modul:Index template/styles.css|Templat:Author link|Templat:Index talk remarks}} This is the current module to implement logic for [[MediaWiki:Proofreadpage index template]], based on [[:mediawikiwiki:Wikidata - Wikisource Integration Modules|Wikidata - Wikisource Integration Modules]] on MediaWiki with significant changes: # Reconfiguration of index page panel structure (which includes image, metadata, pagelist, and remarks/notes sections) to follow the structure on [[:en:Module:Proofreadpage index template|Module:Proofreadpage index template]]. # Adaptation new metadata fields from [[:en:Module:Proofreadpage index template|Module:Proofreadpage index template]]: (1) language parameter and categorization, ensuring manually-entered language code would return language canonical names; (2) transclusion status; (3) validation date; (4) ISBN/OCLC/LCCN/ARK/DOI; (5) talk page remark related functionality; (6) missing file tracking category; (7) full image spec tracking category; and (8) audiovisual thumbtime cover # Sufficient gap between image and metadata # Sufficient gap between labels and values of metadata # Author property value changed to P50 instead of P253075 # Ensured all file types under the source parameter could be wikilinked. # The wikilinks for title, author, translator and editor fields could be generated automatically or manually # Simplified the invocation of the module at MediaWiki:Proofreadpage index template so that no explicit mentioning of parameters and indicators. # Integration of Modul:Index data into Modul:Index template, with the new name Modul:Index template/data. # Replaced the usage of transclusion_checker indicator (external toolforge link) to [[MediaWiki:Gadget-transclusion-check|transclusion check gadget]]. # Utilized the [[Modul:Arguments]] for getArgs. <noinclude>[[Category:External links on protected pages]]</noinclude> 725x2nyyru4kyhtv7eysz1isgkoanvf Laman:Syair Lampung Karam.pdf/19 250 7962 22793 2026-04-14T13:33:39Z Hadithfajri 36 /* Belum dibaca pruf */ Mencipta laman baru dengan kandungan '{{رڠکڤ|سده دفريقسا کونن سموا \\ دسوره تڠکل فول دتمفتڽ منا يڠ سوک دتڠکوڽ \\ ادا يڠ ستڠه منجادي صحابتڽ سفأروه برکات کفد سکلين \\ دودق دتمفة کيت دکسيه ماکن بيسؤله هاري دفريقساکن \\ فرسيدين داتڠ دوا سکاوان ستڠه اوراڠ منتأ فرميسي \\ فرکي کفد صحبة دان هندي بيسؤ ها...' 22793 proofread-page text/x-wiki <noinclude><pagequality level="1" user="Hadithfajri" /></noinclude>{{رڠکڤ|سده دفريقسا کونن سموا \\ دسوره تڠکل فول دتمفتڽ منا يڠ سوک دتڠکوڽ \\ ادا يڠ ستڠه منجادي صحابتڽ سفأروه برکات کفد سکلين \\ دودق دتمفة کيت دکسيه ماکن بيسؤله هاري دفريقساکن \\ فرسيدين داتڠ دوا سکاوان ستڠه اوراڠ منتأ فرميسي \\ فرکي کفد صحبة دان هندي بيسؤ هاري داتڠ کسيني \\ منڠکو فرنته دباوه دولي فاکي هاري ڽتله توان \\ اداله کيرا٢ دوکل دلافن داتڠ برکومفول برکاوان٢ \\ مندافتکن سکاوة اي سکلين فوکل سمبيلن ڽتاله تنتو \\ داتڠ سقاوة ملهتکن ايت}}<noinclude></noinclude> c92mz85otgf13oq3k8pmmqvzbwim9xv Laman:Pelita Brunei-1 Januari 1959.pdf/7 250 7963 22795 2026-04-14T14:17:10Z Rombituon 510 /* Belum dibaca pruf */ Mencipta laman baru dengan kandungan 'RANCHANGAN PERHIASAN KUALA BLAIT-SERIA. JAWATAN Kuasa Lawatan Diraja, Kuala Belait telah menerima lukisan2 dan chadangan yang di-sampaikan oleh Tuan ".B.H.Rackham kerana per- hiasan sa-panjang jalan yang akan di-lalui oleh Yang Amat Mulia Duke of Edinburgh apabila beliau melawat ka-Kuala Belait dan Seria hari Sabtu 28 February yang akan datang ini. {{inden teks|2em|Pada am-nya perhiasan2 itu akan berasaskan pada ka-Dirajaan.}} {... 22795 proofread-page text/x-wiki <noinclude><pagequality level="1" user="Rombituon" /></noinclude>RANCHANGAN PERHIASAN KUALA BLAIT-SERIA. JAWATAN Kuasa Lawatan Diraja, Kuala Belait telah menerima lukisan2 dan chadangan yang di-sampaikan oleh Tuan ".B.H.Rackham kerana per- hiasan sa-panjang jalan yang akan di-lalui oleh Yang Amat Mulia Duke of Edinburgh apabila beliau melawat ka-Kuala Belait dan Seria hari Sabtu 28 February yang akan datang ini. {{inden teks|2em|Pada am-nya perhiasan2 itu akan berasaskan pada ka-Dirajaan.}} {{inden teks|2em|Sa-keping panji2 besar dengan ayat "Selamat Datang ka-Daerah Kuala Belait, Negeri Brunei" akan di-kibarkan di-lapangan terbang Anduki tempat Duke of Edinburgh turun ke-bumi Negeri Brunei pada pagi hari itu dari Sarawak. Sa-lepas itu beliau akan menaiki kende- raan melalui Jalan Tengah ka-Seria.}} {{inden teks|2em|Dalam perjalanan itu perarakan motokar2 akan melalui sa-buah pintu gerbang yang akan di-bena di-simpang Jalan Tengah dengan Lorong Tengah.}} {{inden teks|2em|Di-padang Marina, Duke of Edinburgh akan meme eksa perbarisan yang terdiri dari murid2 sekolah tempatan, pengakap dan lain2 per- tubohan kaum. Beberapa lukisan menggambarkan kebesaran Diraja akan di-pertunjokkan di-padang itu.}} {{inden teks|2em|Sa-masa memereksa perbarisan itu Duke of "inburgh akan berjalan i-bawah empat buah pintu gerbang yang akan di-bena oleh kaum Melayu, China, Indian dan Dayak dan Dusun di-aerah Kuala Belait.}} {{inden teks|2em|Dalam perjalanan-nya ka-Penaga Club kerana ha hir dalam majlis jamuan kerajaan Duke of Edinburgh akan berjalan dekat tiga batang tiang besi 30 kaki tinggi menjunjong sa-buah mahkota.}} {{inden teks|2em|Jalan2 yang akan di-lalui oleh Duke di-kawasan padang minyak itu akan di-hiasi dengan bendera 2 Negeri Brunei an negeri2 Commonwealth.}} ******************* PERHUBONGAN TALIPON BRUNEI-LABILAN. {{inden teks|2em|Perkhidmatan talipon V.H.F. di-antara Brunei engan Labuan akan di-mulakan eri hari ini saperti berikut:}} {{inden teks|2em|Hari Ahad dan hari kelepasan dari pukul 7.30 pagi hingga pukul 12.30 tengah hari.}} {{inden teks|2em|Lain2 hari termasok Juma'at dan Sabtu dari pukul 7.30 pagi hingga pukul 6 petang.}} ********************** WAYANG GAMBAR PEJABAT PENERANGAN. {{inden teks|2em|Jadual pertunjókan wayang gambar Pejabat Penerangan, Kuala Belait bagi bulan ini in-leh saperti di-bawah ini:}} {{inden teks|2em|7 January, Labi; 6 Jenuery, Rampayoh; 7 January, Raten; 8 January Bukit Punn; 12 January, Lorong 14, Polis Serie; 13 January, Penage Field Force; 14 January, Padang Kechil, Kuala Belait; 15 January, Rumah Orang Miskin, Seria; 16 January, Sungai Teraban, Kuala Belait; 26 January, Danau; 27 January, Telisi; 28 January Liang dan 29 January, Lumut.}} ************************* {{inden teks|2em|Hakim Besar, Brunei, Sir Ernest Williams, telah i-perkenankan oleh Baginda Queen Can Duli Yang Maha Mulia berhenti eri perkhid- matan sa-telah habis chuti yang akan di-ambil-nyr pada hujong bulan March hadapan ini.}}<noinclude></noinclude> dg041ar6wo1mlrc7tzyp6jj41tbel8a Laman:Pelita Brunei-1 Januari 1959.pdf/8 250 7964 22796 2026-04-14T14:20:11Z Rombituon 510 /* Belum dibaca pruf */ Mencipta laman baru dengan kandungan 'ISTI'ADAT PEMBUKAAN ANTHONY. ABELL COLLEGE {{inden teks|2em|Yang Terutama Pesuroh Jaya Tinggi Brunei, Dato Paduka Sir Anthony Abell, telah mengistiharkan pembukaan rasmi sekolah menengah Brunei yang kedua, di-Seria pada 18 December, yang lalu.}} {{inden teks|2em|Sekolah itu di-namakan Anthony Abell College kerana meng- ambil sempena dari nama Pesuroh Jaya Tinggi itu.}} {{inden teks|2em|Sekolah itu belum siap lagi. Sa-banyak $1,5... 22796 proofread-page text/x-wiki <noinclude><pagequality level="1" user="Rombituon" /></noinclude>ISTI'ADAT PEMBUKAAN ANTHONY. ABELL COLLEGE {{inden teks|2em|Yang Terutama Pesuroh Jaya Tinggi Brunei, Dato Paduka Sir Anthony Abell, telah mengistiharkan pembukaan rasmi sekolah menengah Brunei yang kedua, di-Seria pada 18 December, yang lalu.}} {{inden teks|2em|Sekolah itu di-namakan Anthony Abell College kerana meng- ambil sempena dari nama Pesuroh Jaya Tinggi itu.}} {{inden teks|2em|Sekolah itu belum siap lagi. Sa-banyak $1,580,000 akan di- belanjakan dalam tahun ini kerana pembenaan peringkat pengha- bisan.}} {{inden teks|2em|Apabila sekolah itu siap kelak Sir Anthony berharap moga2 ia-nya akan di-akui di-seluroh Borneo sa-bagai sa-buah seko- lah yang mengeluarkan pemimpin2 yang chekap dan berani dan perempuan yang jauh pemandangan dan chenderong kapada sim- pati international dalam menjalankan tugas mereka memimpin anak2 negeri.}} {{inden teks|2em|Dalam uchapan-nya sa-jurus sa-belum mendedahkan kain tu- dong papan peringatan pembenaan sekolah itu Sir Anthony telah mengingatkan bahawa satu perkara yang sangat di-perlukan oleh Brunei pada masa ini dan di-masa hadapan ia-lah pemimpin2.}} {{inden teks|2em|Pemimpin2 ada-lah di-kehendaki kerana Duli Yang Maha Mulia berchi ta2 hendak memberi satu perlembagaan baharu kapada Bru- nei supaya dapat anak2 Brunei memikul beban pemerentahan yang lebeh berat dari yang sudah2.}} {{inden teks|2em|Pemimpin yang baik dan sehat hanya-lah dapat di-berikan oleh mereka yang waras fikiran-nya dan tidak memikirkan kepen- tingan dan keuntongan diri sendiri dan mereka itu hendak-lah berani, yakin dan mahu merintis jalan.}} {{inden teks|2em|Sir Anthony telah menegaskan bahawa kemudahan2 pelajaran yang di-beri oleh Negeri Brunei kapada anak2 Brunei ada-lah lebeh maju dari lain2 negeri di-Borneo ini dan barangkali juga dari lain2 negeri di-Tenggara Asia.}} {{inden teks|2em|Ini memberi harapan baik kapada Brunei dan satu chabaran besar kapada anak2 Brunei yang cherdek dan berusaha. Mahu-kah pemuda pemudi Brunei itu mengambil peluang ini untok mensesu- aikan diri mereka menjadi pemimpin2? Sir Anthony bertanya.}} {{inden teks|2em|Di-antara lain2 Sir Anthony telah mengingatkan murid2 se- kolah itu bahawa Negeri Brunei berkehendakkan ramai pegawai2 pertanian, ahli2 sains, pegawai2 hutan, doktor2, jurutera2 dan lain2 pegawai yang berkelulusan.}} {{inden teks|2em|"Saya perchaya satu perkara yang penting dalam didekan pelaja- ran ia-lah sa-saorang itu hendak-lah bersedia melateh diri-nya}} - bersambong di-muke -<noinclude></noinclude> tjix05v63j4j3f0pb5v4nndtf05wd3i Templat:Atribut HTML 10 7965 22798 2026-04-14T15:42:18Z Hakimi97 9 Hakimi97 telah memindahkan laman [[Templat:Atribut HTML]] ke [[Templat:HTML attribute]]: Penyelarasan nama dengan Wikisumber Bahasa Inggeris, untuk memudahkan tujuan penyelenggaraan 22798 wikitext text/x-wiki #LENCONG [[Templat:HTML attribute]] iwrb5lfmwc3esw6j9s1w4juvg6qwvgh Modul:Atribut HTML 828 7966 22800 2026-04-14T15:43:34Z Hakimi97 9 Hakimi97 telah memindahkan laman [[Modul:Atribut HTML]] ke [[Modul:HTML attribute]]: Penyelarasan nama dengan Wikisumber Bahasa Inggeris, untuk memudahkan tujuan penyelenggaraan 22800 Scribunto text/plain return require [[Modul:HTML attribute]] qlf0taj9fp9eoyq7ujfqqlny8yv0fzw Modul:Bingkai 828 7967 22802 2026-04-14T15:44:24Z Hakimi97 9 Hakimi97 telah memindahkan laman [[Modul:Bingkai]] ke [[Modul:Border]]: Penyelarasan nama dengan Wikisumber Bahasa Inggeris, untuk memudahkan tujuan penyelenggaraan 22802 Scribunto text/plain return require [[Modul:Border]] dnxkwpgn307o6aqewqe8evasu6g93w0 Modul:Bingkai/kotak pasir 828 7968 22804 2026-04-14T15:44:24Z Hakimi97 9 Hakimi97 telah memindahkan laman [[Modul:Bingkai/kotak pasir]] ke [[Modul:Border/kotak pasir]]: Penyelarasan nama dengan Wikisumber Bahasa Inggeris, untuk memudahkan tujuan penyelenggaraan 22804 Scribunto text/plain return require [[Modul:Border/kotak pasir]] 5lsv10lyy7z3eg06u5eml1wb44vbq42 Modul:Kalau kosong 828 7969 22806 2026-04-14T15:45:49Z Hakimi97 9 Hakimi97 telah memindahkan laman [[Modul:Kalau kosong]] ke [[Modul:Module:If empty]]: Penyelarasan nama dengan Wikisumber Bahasa Inggeris, untuk memudahkan tujuan penyelenggaraan 22806 Scribunto text/plain return require [[Modul:Module:If empty]] fy665it0z3n40tzyooplejw1wqiaymx 22809 22806 2026-04-14T15:47:32Z Hakimi97 9 Mengubah sasaran lencongan dari [[Modul:Module:If empty]] ke [[Modul:If empty]] 22809 Scribunto text/plain return require [[Modul:If empty]] s12txo4ovu25cpdi5pxvw85u23bzk9b Templat:Kalau kosong 10 7971 22811 2026-04-14T15:48:26Z Hakimi97 9 Hakimi97 telah memindahkan laman [[Templat:Kalau kosong]] ke [[Templat:If empty]]: Penyelarasan nama dengan Wikisumber Bahasa Inggeris, untuk memudahkan tujuan penyelenggaraan 22811 wikitext text/x-wiki #LENCONG [[Templat:If empty]] 278jsj8u3t7cb4riank238l6izu47i5 Templat:Bingkai 10 7972 22815 2026-04-14T15:50:52Z Hakimi97 9 Hakimi97 telah memindahkan laman [[Templat:Bingkai]] ke [[Templat:Border]] melalui lencongan 22815 wikitext text/x-wiki #LENCONG [[Templat:Border]] 2ug5rg9do7x2ffnnfnhhe1w6l0npfis Templat:Bingkai/kotak pasir 10 7973 22817 2026-04-14T15:50:53Z Hakimi97 9 Hakimi97 telah memindahkan laman [[Templat:Bingkai/kotak pasir]] ke [[Templat:Border/kotak pasir]] 22817 wikitext text/x-wiki #LENCONG [[Templat:Border/kotak pasir]] cs8c99jb0gc39x0g6b7w2o0gndma85v MediaWiki:Deletereason-dropdown 8 7974 22825 2026-04-15T04:34:45Z Hakimi97 9 Mencipta laman baru dengan kandungan '* Sebab-sebab lazim ** Spam ** Vandalisme ** Melanggar hak cipta ** Permintaan pengarang ** Lencongan terputus ** Kod skrip yang usang' 22825 wikitext text/x-wiki * Sebab-sebab lazim ** Spam ** Vandalisme ** Melanggar hak cipta ** Permintaan pengarang ** Lencongan terputus ** Kod skrip yang usang q1mw4xyi9cexsmai5xqpzmh0adqmy8w