Template talk:Plural
| Template:Plural is permanently protected from editing as it is a heavily used or highly visible template. Substantial changes should first be proposed and discussed here on this page. If the proposal is uncontroversial or has been discussed and is supported by consensus, editors may use {{edit template-protected}} to notify an administrator or template editor to make the requested edit. Usually, any contributor may edit the template's documentation to add usage notes or categories.
Any contributor may edit the template's sandbox. Functionality of the template can be checked using test cases. |
Old discussion
[edit]I have fixed this template to correctly handle all plurals, even "ox/oxen". Anomie 19:59, 5 October 2007 (UTC)
Safesubst
[edit]{{editprotected}} Please make this edit to allow the template to give the expected output when substed. Anomie⚔ 17:28, 12 October 2010 (UTC)
- done —TheDJ (talk • contribs) 18:17, 12 October 2010 (UTC)
Edit request on 1 July 2013: add TemplateData for Visual Editor
[edit]This edit request has been answered. Set the |answered= parameter to no to reactivate your request. |
Provides the appropriate singular or plural form of a noun preceded by a number
| Parameter | Description | Type | Status | |
|---|---|---|---|---|
| Number | 1 | A non-negative number | Number | required |
| Name | 2 | A singular noun | String | required |
| Name (plural) | 3 | Plural form of Name (not needed if the plural is formed by adding -s) | String | optional |
ℜob C. alias ÀLAROB 00:07, 2 July 2013 (UTC)
Not done: {{edit protected}}is usually not required for edits to the documentation, categories, or interlanguage links of templates using a documentation subpage. Use the 'edit' link at the top of the green "Template documentation" box to edit the documentation subpage. --Redrose64 (talk) 08:58, 2 July 2013 (UTC)
Edit request on 30 September 2013
[edit]This edit request has been answered. Set the |answered= parameter to no to reactivate your request. |
I am requesting that this template be updated to allow the option of using a non-breaking space between the number and the text (in place of the current breaking space). The updated code can be found in Template:Plural/sandbox. The following shows an example of how it would work (the output was placed inside a narrow <div> to force a line break).
| Example | Current output | Sandbox output |
|---|---|---|
Non-breaking space: {{plural|20|year|nb=y}}
|
20 years
|
20 years
|
Breaking space (default): {{plural|20|year}}
|
20 years
|
20 years
|
Additional examples can be found at Template:Plural/testcases. -- Zyxw (talk) 01:58, 30 September 2013 (UTC)
Done Except I used {{yesno}} so {{plural|20|year|nb=no}}will do what the user probably expects. Anomie⚔ 02:06, 30 September 2013 (UTC)
- Thanks for the quick response and also for adding
nb=noto the test cases. -- Zyxw (talk) 04:03, 30 September 2013 (UTC)
- Thanks for the quick response and also for adding
Template-protected edit request on 17 September 2025
[edit]This edit request has been answered. Set the |answered= parameter to no to reactivate your request. |
Currently this template has two problems:
- It uses
 to express a space, which looks useless and ugly when the template is substituted - It uses
{{{{{|safesubst:}}}...}}to signal multilevel substitutions, but that is dangerous and deprecated in favour of{{safesubst:<noinclude />...}}, because the|=parameter (i.e. the parameter named with an empty string) sometimes might actually be passed as a real parameter.
Would you mind replacing the current code with this version?
<includeonly>{{{1}}}{{safesubst:<noinclude />P{{safesubst:<noinclude />yesno|{{{nb|no}}}|yes=1|no=2}}| | }}{{safesubst:<noinclude />plural:{{{1}}}|{{{2}}}|{{{3|{{{2}}}s}}}|{{{4}}}}}</includeonly><noinclude>{{Documentation}}</noinclude>
--Grufo (talk) 19:29, 17 September 2025 (UTC)
Not done: have you tested this without the  space code? When I tested it, the space between the{{{1}}} {{{2}}}sdisappears and it looks like this:{{{1}}}{{{2}}}s.
- Can't have that, can we? As for the method of safe substituting, it is used in many templates and works just fine as it is. Thank you for your concerns, though. Sorry, but I really don't see a problem here that needs solving. P.I. Ellsworth , ed. – welcome! – 19:50, 17 September 2025 (UTC)
- @Paine Ellsworth: Not sure what you tested. This is a test:
{{plural/sandbox|0|page}}returns "0 pages"{{plural/sandbox|1|page}}returns "1 page"{{plural/sandbox|2|page}}returns "2 pages"
- As for
{{{{{|safesubst:}}}...}}, please check this warning. In the best case scenario template creators will not be able to use {{plural}} within {{#invoke:params|call_for_each_group}}; in the worst case scenario, other bugs will emerge in other contexts as well and people will struggle to understand where they come from. Mediawiki too warns that the argument with an empty name “is sometimes used by modules that call templates or for inserting comments”. If it is true that “it is used in many templatesand works just fine as it is”, it should be updated everywhere is found. --Grufo (talk) 20:13, 17 September 2025 (UTC)- Likely the test continued to use
{{#if:}}instead of changing to {{P1}}/{{P2}}. Compare||(using #if) versus| |(using P2). Anomie⚔ 21:10, 17 September 2025 (UTC) "Not sure what you tested"
? Yes, I could have been more explicit, so sorry. I tested the live template's code without the| }}, as in|}}and| }}, and both tests yielded{{{1}}}{{{2}}}s(loss of space) in the sandbox. What we seem to be up against here is my ignorance, and the fact that the following is also true:{{plural|0|page}}returns "0 pages"{{plural|1|page}}returns "1 page"{{plural|2|page}}returns "2 pages"
- ...so I'm very sorry about that. You see, while TEs know how to edit templates and some modules, we are sometimes clueless as to the actual value of our edits when we try to help others who get posted to Category:Wikipedia template-protected edit requests. In cases like these we need more than obscure warnings in Module /doc pages (and the module is used in relatively few articles and templates) or equally obscure MW paragraphs – we like to see examples of where the actual problem(s) appear. Template {{Plural}} is used on 112,000 pages, which makes it a "high-risk" template. So without more context, for all we know we might be butchering the underlying WP server system with such edits (no offense meant – it's just that some of us have been badly burned before, and that makes us very careful). Might do this, might do that? Where is the actual problem? – examples, examples, examples... there's the ticket! P.I. Ellsworth , ed. – welcome! – 21:20, 17 September 2025 (UTC)
- @Paine Ellsworth: No problem for the misunderstanding. As for
{{{{{|safesubst:}}}...}}, the issue is that you are using the|=parameter explictly ignoring that it can actually be an existing parameter. To give you a concrete example, if you write {{plural | 1 = 103 | 2 = cat | = blabla }}
- you get:
- 103 cats
- You might be wondering why someone should use the
|=parameter, since it is not expected by the template. But:- It might not a human inserting it, it might be a module that calls {{plural}} (and that is what {{#invoke:params|call_for_each_group}} does)
- It might be that someone is using that parameter as a comment placeholder
- Writing
{{{{{|safesubst:}}}...}}is also slower to parse, since the parser needs to check if that parameter exists. And so you will relieve “112,000 pages” of a bad coding practice. --Grufo (talk) 21:59, 17 September 2025 (UTC)- On the surface that appears to be a very good example, especially since with...
{{plural/sandbox | 1 = 103 | 2 = cat | = blabla }}
- you get:
- 103 cats
- rather than the mess yielded by the live template you have shown. And yet, that is a theoretical situation rather than a working test-case example of the perceived problem. Would it be possible for you to actually show something on the [test cases] page, perhaps similar to my addition of your example given just above? Perhaps you can use {{#invoke:params|call_for_each_group}} since it calls this template? P.I. Ellsworth , ed. – welcome! – 01:10, 18 September 2025 (UTC)
- Module:Params is a general-purpose module; per se it does not call {{Plural}}, nor any other template, however it gives template creators the possibility to call any template under many scenarios. If a template creator tells {{#invoke:params|call_for_each_group}} to call {{Plural}}, it might be that the empty-name parameter is used, or it might not be, but the point is that it might not depend on the template creator at all but on the final user. So I have created {{Plural/testcases/empty-name parameter}} as a test. By default it calls {{plural}}, but if you specify
|#template=plural/sandboxit will call {{plural/sandbox}} instead. Now, if you write {{Plural/testcases/empty-name parameter | Hello | World | Foo | #template = plural/sandbox | item 1 = cat | amount 1 = 123 | item 2 = dog | amount 2 = 0 | item 3 = dinosaur | amount 3 = 1 }}
- it correctly yields
- 123 cats, 0 dogs, 1 dinosaur
- But if instead you write
{{Plural/testcases/empty-name parameter | Hello | World | Foo | #template = plural | item 1 = cat | amount 1 = 123 | item 2 = dog | amount 2 = 0 | item 3 = dinosaur | amount 3 = 1 }}
- you get a very ugly mess. Of course, the template creator can design {{Plural/testcases/empty-name parameter}} in such a way that all sequential parameters are discarded for this call, it's actually pretty easy to do with Module:Params; but how should the template creator be possibly able to foresight that this bug in {{plural}} exists? And why should we make life harder to template creators without any justified reason? I still haven't heard any argument about why, according to you, we should keep the bug-prone
{{{{{|safesubst:}}}...}}. --Grufo (talk) 03:15, 18 September 2025 (UTC)- Or, conversely, how should every template creator know that Module:Params has such weird behavior as to oddly provide the empty-named parameter that's used by other (mainly very old, pre-safesubst) templates for substing? Maybe the bug lies there. Anomie⚔ 11:41, 18 September 2025 (UTC)
- The {{#invoke:params|call_for_each_group}} function does only what is told to do: group parameters with the same numerical suffix and call a template for each group with the prefixes as parameters. In “item N” the prefix is “item”. In “N” the prefix is “”. It is as consequential as it can be. What is not consequential instead is a template that does undocumented things when called with an undocumented parameter. What is the reason according to you why we should keep
{{{{{|safesubst:}}}...}}? --Grufo (talk) 14:19, 18 September 2025 (UTC)- As I said, depends on how you look at things. Anomie⚔ 15:08, 18 September 2025 (UTC)
- Anomie, answering the question “
What is the reason according to you why we should keep
” does not depend on how you look at things. I am sincerely curious to understand why a relict syntax that is ugly, bug-prone and slower to parse can be attractive for some editors. --Grufo (talk) 15:13, 18 September 2025 (UTC){{{{{|safesubst:}}}...}}?- Easy questions. You ask
What is the reason according to you why we should keep (the current code)
and say furtherI am sincerely curious to understand why a relict syntax that is ugly, bug-prone and slower to parse can be attractive for some editors.
It's because I am unconvinced. And I think editor Anomie has made valid points. I don't find the code "ugly", and all we really have is your word that it's "bug-prone" and "slower to parse". You have not convinced me that such code that is still used extensively in templates cannot be worked around for the one and only module you seem to be worried about. If documented properly at Module:Params/doc, then it would appear that no change to this template or any other template that uses the current code is really necessary. I think the important question is why should all those templates be changed just to accomodate one module that has relatively limited usage? So sorry. I'm unconvinced. P.I. Ellsworth , ed. – welcome! – 15:54, 18 September 2025 (UTC)- Of course it can be worked around. It is very easy to call this template as it is with {{#invoke:params|call_for_each_group}}, without generating any weird behavior. But the whole point of a workaround is that the template creator has to know that {{Plural}} uses an undocumented parameter and that needs to be addressed. Without knowing it they will not address it. Therefore, if you want to keep using the empty-name parameter, I strongly suggest to write about it in the documentation, so that whoever uses this template can adjust accordingly. --Grufo (talk) 16:12, 18 September 2025 (UTC)
- And please do not reactivate the edit-request template without first garnering consensus for this change. P.I. Ellsworth , ed. – welcome! – 16:00, 18 September 2025 (UTC)
- Consensus on what?? The main reason I came here was to remove the HTML entity
 : Any news about that? I haven't read any answer except you testing the wrong code. If you don't want to answer it's fine, but you need to give other template editors the possibility to answer, so please stop writing|answered=yeswithout answering the request you say you are answering to. --Grufo (talk) 16:14, 18 September 2025 (UTC)- If the main reason you came here was to remove a space, then you might have said so in the beginning, which you didn't. And I think consensus is needed to remove the empty-name code, which will have broad implications for other templates that use it. And I'd tone it down if I were you. You'll catch a lot more flies with honey rather than vinegar. I'm done with it. Happy entrails :>) P.I. Ellsworth , ed. – welcome! – 16:48, 18 September 2025 (UTC)
- The edit request to remove the HTML entity
Not resolved to satisfaction of complainant: Really badly handled response. was closed despite total lack of objections against the request. Improvements without objections like these should be applied mechanically by any template editor who passes by. The invitation to template editors is still open to either- Apply this edit request
- Reject the edit request (with motivations)
- --Grufo (talk) 18:15, 6 October 2025 (UTC)
- If the main reason you came here was to remove a space, then you might have said so in the beginning, which you didn't. And I think consensus is needed to remove the empty-name code, which will have broad implications for other templates that use it. And I'd tone it down if I were you. You'll catch a lot more flies with honey rather than vinegar. I'm done with it. Happy entrails :>) P.I. Ellsworth , ed. – welcome! – 16:48, 18 September 2025 (UTC)
- Consensus on what?? The main reason I came here was to remove the HTML entity
- Easy questions. You ask
- Anomie, answering the question “
- As I said, depends on how you look at things. Anomie⚔ 15:08, 18 September 2025 (UTC)
- The {{#invoke:params|call_for_each_group}} function does only what is told to do: group parameters with the same numerical suffix and call a template for each group with the prefixes as parameters. In “item N” the prefix is “item”. In “N” the prefix is “”. It is as consequential as it can be. What is not consequential instead is a template that does undocumented things when called with an undocumented parameter. What is the reason according to you why we should keep
- Or, conversely, how should every template creator know that Module:Params has such weird behavior as to oddly provide the empty-named parameter that's used by other (mainly very old, pre-safesubst) templates for substing? Maybe the bug lies there. Anomie⚔ 11:41, 18 September 2025 (UTC)
- Module:Params is a general-purpose module; per se it does not call {{Plural}}, nor any other template, however it gives template creators the possibility to call any template under many scenarios. If a template creator tells {{#invoke:params|call_for_each_group}} to call {{Plural}}, it might be that the empty-name parameter is used, or it might not be, but the point is that it might not depend on the template creator at all but on the final user. So I have created {{Plural/testcases/empty-name parameter}} as a test. By default it calls {{plural}}, but if you specify
- @Paine Ellsworth: No problem for the misunderstanding. As for
- Likely the test continued to use
- @Paine Ellsworth: Not sure what you tested. This is a test: