Module:URL: Difference between revisions

From NvWiki
Jump to navigation Jump to search
m 1 revision imported: Import modules used with Template:Infobox software
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{Permanently protected}}
--
{{oldtfdfull|date=2016 October 8|result=no consensus to merge|disc=Template:Official_URL }}
-- This module implements {{URL}}
{{User:MiszaBot/config
--
|archiveheader = {{talkarchivenav}}
-- See unit tests at [[Module:URL/testcases]]
|maxarchivesize = 75K
|counter = 2
|minthreadsleft = 3
|minthreadstoarchive = 1
|algo = old(28d)
|archive = Template talk:URL/Archive %(counter)d
}}
{{WikiProject banner shell|
{{WikiProject Microformats}}
}}
{{archives|search=yes}}


== Is there any reason to trim "www" from the displayed URL? ==
local p = {}
local function safeUri(s)
local success, uri = pcall(function()
return mw.uri.new(s)
end)
if success then
return uri
end
end
 
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


Template:URL is designed to display the "www" as part of the link displayed and is clear that "Parameter 2 (<nowiki>{{URL|url name|optional display text}}</nowiki>) is deprecated"; I certainly don't see any reason to manually remove the "www" using parameter 2. Is there any reason to make edits such as [https://en.wikipedia.org/w/index.php?title=Wildwood,_New_Jersey&diff=prev&oldid=1239773656 this one], one example of many, whose only purpose is to trim the "www"? There was [https://en.wikipedia.org/w/index.php?title=Template_talk:URL&oldid=950508753 this discussion from 2020] that leaned against removal of the "www". Does this still stand and if so should there be a clearer admonition in Template:URL discouraging the practice? [[User:Alansohn|Alansohn]] ([[User talk:Alansohn|talk]]) 17:21, 12 August 2024 (UTC)
function p._url(url, text, msg)
:I would describe [https://en.wikipedia.org/w/index.php?title=Wildwood,_New_Jersey&diff=prev&oldid=1239773656 that edit] as mildly negative, not helpful. It made the displayed URL longer, wrapping it in my display. The previous, shorter URL did not wrap. Since {{para|2}} is deprecated, a better edit would have been to remove "www" from {{para|1}} while removing {{para|2}}, after checking that the resulting URL worked, of course. – [[User:Jonesey95|Jonesey95]] ([[User talk:Jonesey95|talk]]) 21:18, 12 August 2024 (UTC)
url = mw.text.trim(url or '')
text = mw.text.trim(text or '')
-- Check for pre-formatted url. Catches '{{url|{{url|google.com}}}}' that can occur via template
if (mw.ustring.match(url, '^<span class="url">')) then
return url, text, msg
end
local nomsg = (msg or ''):sub(1,1):lower() == "n" or msg == 'false' -- boolean: true if msg is "false" or starts with n or N


== URL template, capitalization and screenreaders ==
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


[[User:ChirpingEmu]] has changed a few dozen articles, including [https://en.wikipedia.org/w/index.php?title=Emerson_Junior-Senior_High_School&diff=prev&oldid=1314864291 this edit], in which links were taken out of the URL template, with the edit summary "reformatted URL for screenreader accessibility". On their talk page, the user stated that they are "using Apple’s built-in screenreader to ensure that the URL is spoken correctly. Usually, changing the capitalization of parts of the URL does the trick" but that "The issue with the URL template is that it’s not case-sensitive." [[User:Alansohn|Alansohn]] ([[User talk:Alansohn|talk]]) 21:44, 3 October 2025 (UTC)
-- 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)


== Edit request 10 November 2025 ==
-- 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, '%?$', '')


{{Edit template-protected|answered=yes|Module: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')


'''Please sync code from [[Module:URL/sandbox|sandbox]]:''' This inserts a check for a pre-formatted url. This will allow the use of {{tl|url}} in a template. So for example if {{tl|infobox settlement}} has:
local uri = safeUri(url)
<pre>
| data1 = {{url|{{{website|}}}}}
</pre>


You can now safely pass:
-- Handle URL's without a protocol and URL's that are protocol-relative,
<pre>
-- e.g. www.example.com/foo or www.example.com:8080/foo, and //www.example.com/foo
| website = {{url|google.com}}
if uri and (not uri.protocol or (uri.protocol and not uri.host)) and url:sub(1, 2) ~= '//' then
</pre>
url = 'http://' .. url
uri = safeUri(url)
end


without the template blowing up. Technically I can make this change myself, but would like a 2nd set of eyes to review it. Note that [[Module talk:URL/testcases]] had a failing test case before I made my change to the sandbox. It is unrelated to my changes. The other failing test, at the top of the page, is expected as it specifically tests the case that I am trying to fix. The sandbox version handles it correctly, the live version does not.  
if text == '' then
if uri then
if uri.path == '/' then uri.path = '' end


local port = ''
if uri.port then port = ':' .. uri.port end


'''Diff:'''
text = mw.ustring.lower(uri.host or '') .. port .. (uri.relativePath or '')
{{Text diff
 
|1=
-- Add <wbr> before _/.-# sequences
|2=
text = mw.ustring.gsub(text,"(/+)","<wbr/>%1")      -- This entry MUST be the first. "<wbr/>" has a "/" in it, you know.
if (mw.ustring.match(url, '^<span class="url">')) then
text = mw.ustring.gsub(text,"(%.+)","<wbr/>%1")
return url, text, msg
-- text = mw.ustring.gsub(text,"(%-+)","<wbr/>%1") -- DISABLED for now
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
end
}}
 
'''[[User:Zackmann08|<span style="color:#00ced1">Zack</span><span style="color:#007F94">mann</span>]]''' (<sup>[[User_talk:Zackmann08|Talk to me]]</sup>/<sub>[[Special:Contributions/Zackmann08|<span style="color:orange;">What I been doing</span>]]</sub>) 20:03, 10 November 2025 (UTC)
return mw.ustring.format('<span class="url">[%s %s]</span>', url, text)
:The testcases look like an improvement to me. Since this module is used in 647,000 pages, I wouldn't mind having a module editor review the code changes. If nothing happens in a few days, I will be happy to implement the changes and see if any bugs crop up. I anticipate finding more edge cases that would need to be added to the testcases page, but sometimes the best way to find those is by making errors appear in the wild (unfortunately). [[User:Jonesey95|Jonesey95]] ([[User talk:Jonesey95|talk]]) 00:29, 11 November 2025 (UTC)
end
::Going to go ahead and implement this. Hopefully it doesn't blow up... If it does, we revert! --'''[[User:Zackmann08|<span style="color:#00ced1">Zack</span><span style="color:#007F94">mann</span>]]''' (<sup>[[User_talk:Zackmann08|Talk to me]]</sup>/<sub>[[Special:Contributions/Zackmann08|<span style="color:orange;">What I been doing</span>]]</sub>) 22:06, 12 November 2025 (UTC)
 
--[[
The main entry point for calling from Template:URL.
--]]
function p.url(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 ''
local msg = templateArgs.msg or parentArgs.msg or ''
url = url or extractUrl(templateArgs) or extractUrl(parentArgs) or ''
return p._url(url, text, msg)
end
 
--[[
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, "(.*)(&nbsp;<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
 
return p

Latest revision as of 16:58, 26 December 2025

Template:Used in system Template:Module rating

This module implements {{URL}} and {{URL2}}. Please see the template page for documentation.

Lua interface

The p._url(url, text, msg) function may be used by other Lua modules. It returns a formatted Wikitext for the given URL, made suitable for line wrapping using Template:Tag. It takes the following parameters:

url
REQUIRED. The URL to format.
text
OPTIONAL. Display text to put in the Wikitext link. Defaults to a pretty version of the URL.
msg
OPTIONAL. String. If content is false, n or N, do not emit a help message (using {{tlx}}) when URL is not given.

Example

The following module emits a prettified link to log the user out. It will wrap correctly to most widths.

local url = require('Module:URL')._url
local p = {}

p.main = function(frame)
    return url("https://en.wikipedia.org/wiki/Special:UserLogout")
end

return p

See also

  • Template:Ml – a simpler version which only allows one value

--
-- This module implements {{URL}}
--
-- See unit tests at [[Module:URL/testcases]]

local p = {}
 
local function safeUri(s)
	local success, uri = pcall(function()
		return mw.uri.new(s)
	end)
	if success then
		return uri
	end
end

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

function p._url(url, text, msg)
	url = mw.text.trim(url or '')
	text = mw.text.trim(text or '')
	
	-- Check for pre-formatted url. Catches '{{url|{{url|google.com}}}}' that can occur via template
	if (mw.ustring.match(url, '^<span class="url">')) then
		return url, text, msg
	end
	
	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
			text = mw.ustring.gsub(text,"(/+)","<wbr/>%1")      -- This entry MUST be the first. "<wbr/>" has a "/" in it, you know.
			text = mw.ustring.gsub(text,"(%.+)","<wbr/>%1")
			-- text = mw.ustring.gsub(text,"(%-+)","<wbr/>%1") 	-- DISABLED for now
			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

--[[
The main entry point for calling from Template:URL.
--]]
function p.url(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 ''
	local msg = templateArgs.msg or parentArgs.msg or ''
	url = url or extractUrl(templateArgs) or extractUrl(parentArgs) or ''
	return p._url(url, text, msg)
end

--[[
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, "(.*)(&nbsp;<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

return p