Editing Module:URL
Appearance
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 2: | Line 2: | ||
-- This module implements {{URL}} | -- This module implements {{URL}} | ||
-- | -- | ||
-- See unit tests at [[Module:URL/ | -- See unit tests at [[Module:URL/testcases]] | ||
local p = {} | local p = {} | ||
function | local function safeUri(s) | ||
local success, uri = pcall(function() | |||
return mw.uri.new(s) | |||
end) | |||
if success then | |||
return uri | |||
end | |||
end | end | ||
function | local function extractUrl(args) | ||
for name, val in pairs(args) do | |||
if name ~= 2 and name ~= "msg" then | |||
local url = name .. "=" .. val; | |||
url = mw.ustring.gsub(url, '^[Hh][Tt][Tt][Pp]([Ss]?):(/?)([^/])', 'http%1://%3') | |||
local uri = safeUri(url); | |||
if uri and uri.host then | |||
return url | |||
end | |||
end | |||
end | |||
end | end | ||
function p._url(url, text) | function p._url(url, text, msg) | ||
url = mw.text.trim(url or '') | |||
text = mw.text.trim(text or '') | |||
local nomsg = (msg or ''):sub(1,1):lower() == "n" or msg == 'false' -- boolean: true if msg is "false" or starts with n or N | |||
if url == '' then | |||
if text == '' then | |||
if nomsg then | |||
return nil | |||
else | |||
return mw.getCurrentFrame():expandTemplate{ title = 'tlx', args = { 'URL', "''example.com''", "''optional display text''" } } | |||
end | |||
else | |||
return text | |||
end | |||
end | |||
-- If the URL contains any unencoded spaces, encode them, because MediaWiki will otherwise interpret a space as the end of the URL. | |||
url = mw.ustring.gsub(url, '%s', function(s) return mw.uri.encode(s, 'PATH') end) | |||
-- If there is an empty query string or fragment id, remove it as it will cause mw.uri.new to throw an error | |||
url = mw.ustring.gsub(url, '#$', '') | |||
url = mw.ustring.gsub(url, '%?$', '') | |||
-- If it's an HTTP[S] URL without the double slash, fix it. | |||
url = mw.ustring.gsub(url, '^[Hh][Tt][Tt][Pp]([Ss]?):(/?)([^/])', 'http%1://%3') | |||
local uri = safeUri(url) | |||
-- Handle URL's without a protocol and URL's that are protocol-relative, | |||
-- e.g. www.example.com/foo or www.example.com:8080/foo, and //www.example.com/foo | |||
if uri and (not uri.protocol or (uri.protocol and not uri.host)) and url:sub(1, 2) ~= '//' then | |||
url = 'http://' .. url | |||
uri = safeUri(url) | |||
end | |||
if text == '' then | |||
if uri then | |||
if uri.path == '/' then uri.path = '' end | |||
local port = '' | |||
if uri.port then port = ':' .. uri.port end | |||
text = mw.ustring.lower(uri.host or '') .. port .. (uri.relativePath or '') | |||
-- Add <wbr> before _/.-# sequences | -- Add <wbr> before _/.-# sequences | ||
Line 68: | Line 79: | ||
text = mw.ustring.gsub(text,"(%#+)","<wbr/>%1") | text = mw.ustring.gsub(text,"(%#+)","<wbr/>%1") | ||
text = mw.ustring.gsub(text,"(_+)","<wbr/>%1") | text = mw.ustring.gsub(text,"(_+)","<wbr/>%1") | ||
else -- URL is badly-formed, so just display whatever was passed in | |||
text = url | |||
end | |||
end | |||
return mw.ustring.format('<span class="url">[%s %s]</span>', url, text) | |||
end | end | ||
--[[ | |||
The main entry point for calling from Template:URL. | |||
--]] | |||
function p.url(frame) | function p.url(frame) | ||
local templateArgs = frame.args | |||
local parentArgs = frame:getParent().args | local parentArgs = frame:getParent().args | ||
local url = templateArgs[1] or parentArgs[1] | |||
local text = templateArgs[2] or parentArgs[2] or '' | |||
local msg = templateArgs.msg or parentArgs.msg or '' | |||
url = url or extractUrl(templateArgs) or extractUrl(parentArgs) or '' | |||
return p._url(url, text, msg) | |||
end | end | ||
function | |||
--[[ | |||
The entry point for calling from the forked Template:URL2. | |||
This function returns no message by default. | |||
It strips out wiki-link markup, html tags, and everything after a space. | |||
--]] | |||
function p.url2(frame) | |||
local templateArgs = frame.args | |||
local parentArgs = frame:getParent().args | |||
local url = templateArgs[1] or parentArgs[1] | |||
local text = templateArgs[2] or parentArgs[2] or '' | |||
-- default to no message | |||
local msg = templateArgs.msg or parentArgs.msg or 'no' | |||
url = url or extractUrl(templateArgs) or extractUrl(parentArgs) or '' | |||
-- if the url came from a Wikidata call, it might have a pen icon appended | |||
-- we want to keep that and add it back at the end. | |||
local u1, penicon = mw.ustring.match( url, "(.*)( <span class='penicon.*)" ) | |||
if penicon then url = u1 end | |||
-- strip out html tags and [ ] from url | |||
url = (url or ''):gsub("<[^>]*>", ""):gsub("[%[%]]", "") | |||
-- truncate anything after a space | |||
url = url:gsub("%%20", " "):gsub(" .*", "") | |||
return (p._url(url, text, msg) or "") .. (penicon or "") | |||
end | end | ||
return p | return p |