Difference between revisions of "Template talk:Navbox items"

From GodWiki
Jump to: navigation, search
(A recursive call in the template calls a recursive call in the template calls a recursive call in the template calls a recursive call in the template call: new section)
m (A recursive call in the template calls a recursive call in the template calls a recursive call in the template calls a recursive call in the template call: Yeah, depth limit is 40)
Line 159: Line 159:
  
 
It'll need to be done in a sandbox and tested thoroughly (recursion is a bitch is recursion is a bitch) and I don't have the time right now, but if nobody else gets it done I'll do this in the next... kinda... mañana. Soonish. (I actually ''like'' recursive programming because it's <s>hard</s> fun, so I'll probably do it, y'know. Soonish.) -- [[User:Djonni|Djonni]] ([[User talk:Djonni|talk]]) 04:51, 18 November 2019 (UTC)
 
It'll need to be done in a sandbox and tested thoroughly (recursion is a bitch is recursion is a bitch) and I don't have the time right now, but if nobody else gets it done I'll do this in the next... kinda... mañana. Soonish. (I actually ''like'' recursive programming because it's <s>hard</s> fun, so I'll probably do it, y'know. Soonish.) -- [[User:Djonni|Djonni]] ([[User talk:Djonni|talk]]) 04:51, 18 November 2019 (UTC)
 +
 +
:Okay, yep, according to [[metawikipedia:Help:Expansion depth]], there's a depth limit of 40. And since this template is called from {{tlf|Navbox}} and {{tlf|Navbox group}}, and itself calls {{tlf|Yesno-yes}}, which calls {{tlf|Yesno}} in turn (and we should allow a future editor to add a couple of levels of depth to this without having to test all ''n'' parameters laboriously) let's say we limit ourselves to 35 deep. Then, a template which handles 21 parameters at a time (remembering that recursive calls skip {{para|1}}) can cope with 20*35+1=701 items. That's definitely more than we need, but is a healthy upper limit. Seems reasonable to code this up to about ''n''=200 for now and if it needs expansion in future then our future selves can easily expand it. -- [[User:Djonni|Djonni]] ([[User talk:Djonni|talk]]) 05:12, 18 November 2019 (UTC)

Revision as of 05:12, 18 November 2019

Simplify

This:

{{#if: {{yesno|yes=|blank=|def=|no=no|{{{wrap|}}}}}{{{item-style|}}}|<span style{{=}}"white-space: {{yesno|yes=normal|blank=normal|def=normal|no=nowrap|{{{wrap|}}}}}; {{{item-style|}}}">}}{{#ifeq:{{{mode|wikilink}}}|wikilink|{{!(}}{{!(}}}}{{{1|}}}{{#ifeq:{{{mode|wikilink}}}|wikilink|]]}}{{#if: {{yesno|yes=|blank=|def=|no=no|{{{wrap|}}}}}{{{item-style|}}}|</span>}}

Can all be reduced to simply:

<span style{{=}}"{{#ifeq:{{yesno-yes|{{{wrap|}}}}}|no|white-space:nowrap;|white-space:normal;}} {{{item-style|}}}">{{#ifeq:{{{mode|wikilink}}}|wikilink|{{!(}}{{!(}}}}{{{1|}}}{{#ifeq:{{{mode|wikilink}}}|wikilink|]]}}</span>

(In other words, unconditionally include the span, and unconditionally insert the contents of {{{item-style}}} in its styleattribute. If those contents are blank, then great.) -- FeRDNYC (talk) 09:29, 9 January 2019 (UTC)

Also, instead of
{{#ifeq:{{{mode|wikilink}}}|wikilink|{{!(}}{{!(}}}}{{{1|}}}{{#ifeq:{{{mode|wikilink}}}|wikilink|]]}}
wouldn't this work?
{{#ifeq:{{{mode|wikilink}}}|wikilink|[[{{{1}}}]]|{{{1}}}}}
(No point in doing {{{1|}}} because you've already tested that at the beginning.) -- FeRDNYC (talk) 09:43, 9 January 2019 (UTC)
So in toto, my suggestion for e.g. #2 is:
{{#if: {{{2|}}}|&nbsp;{{{bullet|{{Navbox list/Bullet}}}}}&#32;<span style{{=}}"{{#ifeq:{{yesno-yes|{{{wrap|}}}}}|no|white-space:nowrap;|white-space:normal;}} {{{item-style|}}}">{{#ifeq:{{{mode|wikilink}}}|wikilink|[[{{{2}}}]]|{{{2}}}}}</span>}}
-- FeRDNYC (talk) 09:48, 9 January 2019 (UTC)
I see the value in the simplicity of it, but I was hoping to avoid unnecessarily bloating the HTML... Since I expect relatively few navboxes will use |wrap=no or |list-style=, I'm not sure which is the greater sin: having the GodWiki server parse a whole bunch of extra {{#if:s with each cache refresh, or having the server send a stack of unnecessary bytes to each client with each page load. Or if worrying about either of those epsilons of difference is silly, and code simplicity should win.
Sigh. I've had a tough day or two, and I'm a bit brain dead and unfocussed. Simplicity is king, I'll make the changes. :) -- Djonni (talk) 16:17, 10 January 2019 (UTC)
Here's my take: Template code is ugly enough, and so skirts the edges of readability anyway, that code simplicity and maintainability always win out. Sure, don't unnecessarily waste bytes. But a change is necessary if it makes the code more readable to other people, or means even the person who wrote it doesn't have to spend 5 minutes parsing it out when they come back to it after 6 months.
Besides, the current output of that 4-item {{Navbox items}} invocation above below is 970 characters. With |wrap=no added in, that becomes 1145 characters — a less than 20% increase. Granted, those are relatively long items, but let's even say a more realistic increase is maybe 30%. That means that, since the current navbox is 27.5K in its entirety, adding spans to every item might grow it by something like 10K. The wiki's Google Analytics tracking JavaScript alone is 16.8K.
And as far as parsing complexity goes, well, the current {{Navbox list}} code is... not lightweight, as templates go. But it's also not anything I'm really worried about. Here's the comment-embedded result of loading Template:Navbox JanuWiki 2019:
CPU time usage: 0.817 seconds
Real time usage: 0.819 seconds
Preprocessor visited node count: 45965/1000000
Preprocessor generated node count: 31150/1000000
Post‐expand include size: 123523/2097152 bytes
Template argument size: 113732/2097152 bytes
Highest expansion depth: 17/40
Expensive parser function count: 0/100

Transclusion expansion time report (%,ms,calls,template)
143.58% 1129.881      2 Template:Navbox
100.00%  786.932      1 -total
 95.12%  748.536      9 Template:Navbox_list
 58.80%  462.682   1263 Template:Yesno
 52.61%  414.041    901 Template:Yesno-no
 43.91%  345.508      1 Template:Navbox_subgroup
 14.20%  111.747    235 Template:Yesno-yes
  1.27%   10.008      1 Template:Navbox_items
  0.45%    3.510      1 Template:Navbar
  0.42%    3.312    214 Template:Navbox_list/Space
{{Navbox items}} is already looking lighter, though again that may be misleading since it's one list of 5 items. Some of the {{Navbox list}} invocations have to process almost 30 arguments.
It's definitely important to always consider things like output size and parsing complexity, I agree. But I'm not really worried about parser complexity except when it becomes obscene enough to cause real problems. And I'm not losing sleep over anything that grows the output size by less than, say, 50K. Possibly-extraneous spans are insignificant enough to be lost in the noise, and worth the extra bytes if the code is clearer and more readable. At least, IMHO. -- FeRDNYC (talk) 09:02, 11 January 2019 (UTC)
Tick.png Done Simplified span and wikilink handling done, and {{Navbox items}} now supports 99 unnamed parameters, ready to roll out.
Awesome! \o/ -- FeRDNYC (talk) 15:42, 11 January 2019 (UTC)
Just implemented it at Template:Navbox JanuWiki 2019 (with |mode=nolink, but I wonder if including the <span>...</span> icons in the touch target area wouldn't help mobile users anyway) and it looks good. -- Djonni (talk) 11:17, 11 January 2019 (UTC)
Perhaps, but that's sort of orthogonal. The spans certainly can be included in the links, but even in that case I'd argue that it should be done with |mode=nolink, because this:
{{Navbox items|mode=nolink
| [[Thingy|Thingy <span>...</span>]]
| [[OtherThingy|Otherthingy <span>...</span>]]
}}
is a lot more readable than:
{{Navbox items
| Thingy{{!}}Thingy <span>...</span>
| OtherThingy{{!}}Otherthingy <span>...</span>
}}
as the latter is basically unreadable to non-template-coders. I feel like autolink mode is a handy shortcut only for when the list is just a simple list of names to be linked; no piping or anything fancy. If any of that is needed, it should be done with |mode=nolink. -- FeRDNYC (talk) 15:42, 11 January 2019 (UTC)
(In fact... come to think of it, if the <span> is inside a piped wikilink, it might even be possible to write it as [[Foo|Foo <span style="blah">]] instead of having to do the {{=}} thing. Which would be cool. I should test that.) -- FeRDNYC (talk) 16:23, 11 January 2019 (UTC)
Results of the conversion to {{Navbox items}}:
CPU time usage: 0.256 seconds
Real time usage: 0.261 seconds
Preprocessor visited node count: 11972/1000000
Preprocessor generated node count: 39543/1000000
Post‐expand include size: 106074/2097152 bytes
Template argument size: 82042/2097152 bytes
Highest expansion depth: 17/40
Expensive parser function count: 0/100

Transclusion expansion time report (%,ms,calls,template)
131.72%  304.179      2 Template:Navbox
100.00%  230.925      1 -total
 54.12%  124.972      9 Template:Navbox_items
 33.55%   77.483    240 Template:Yesno
 32.99%   76.180      1 Template:Navbox_list
 32.96%   76.109      1 Template:Navbox_subgroup
 21.18%   48.903    127 Template:Yesno-yes
 20.73%   47.868    109 Template:Yesno-no
  1.59%    3.680      1 Template:Navbar
  1.14%    2.624    160 Template:=
Wow! I honestly didn't expect it to make that much of a difference. Sweet. -- FeRDNYC (talk) 16:23, 11 January 2019 (UTC)

(In fact... come to think of it, if the <span> is inside a piped wikilink, it might even be possible to write it as [[Foo|Foo <span style="blah">]] instead of having to do the {{=}} thing.

Yes! Confirmed, [[Beer Mugger|Beer Mugger <span style="font-size: x-small; display: inline-block; vertical-align: middle;">📷</span>]] is perfectly legal as a template argument, without the {{=}} #WIN -- FeRDNYC (talk) 16:26, 11 January 2019 (UTC)

Expansion of unnamed parameters

So, I decided to use this in the JanuWiki navbox, just for the Quests list (for now), to get it wrapping and act as a test. I hit an issue that led to my making the second change I'd suggested, to:

{{#ifeq:{{{mode|wikilink}}}|wikilink|[[{{{1}}}]]|{{{1}}}}}

as an attempted fix. It still didn't do what I wanted, so I had to change it again, to:

{{#ifeq:{{{mode|wikilink}}}|wikilink|[[{{#if:{{{1|}}}|{{{1}}}}}]]|{{{1}}}}}

because, even though that seems redundant, as MediaWiki's help explains:

Spaces, tabs and newlines are stripped from: [...] the start and end of the expanded wikitext of the value of a parameter of a parser function
Spaces, tabs and newlines are preserved: [...] at the start and end of the expanded wikitext of the value of an unnamed template parameter

So, before my second change, both your version and my first version turned this:

{{Navbox items|bullet=🍻
| Brew a storm in a teacup
| Deliver some sour gnomish beer to the dark elves
| Find out how to turn a golden brick into a pint of beer
| Sing all of “99 bottles of beer on the wall!”
}}

into this:

[[ Brew a storm in a teacup ]] 🍻 [[ Deliver some sour gnomish beer to the dark elves ]] 🍻 [[ Find out how to turn a golden brick into a pint of beer ]] 🍻 [[ Sing all of “99 bottles of beer on the wall!” ]]

...The seemingly-redundant {{#if...}} causes the newline and spaces to be stripped inside the square braces, and makes the magic happen:

Brew a storm in a teacup 🍻 Deliver some sour gnomish beer to the dark elves 🍻 Find out how to turn a golden brick into a pint of beer 🍻 Sing all of “99 bottles of beer on the wall!”

(Fun with MediaWiki parsers, eh?) -- FeRDNYC (talk) 14:57, 9 January 2019 (UTC)

(And the irony is that I ended up switching back to |mode=nolink, simply because it feels like the easier method of specifying the list when some items contain <span>...</span> additions. But, at least the autolinking code is tested now, the newlines issue has been encountered and dealt with, and the navbox is now wrapping and fitting on the mobile page. Woo!) -- FeRDNYC (talk) 15:04, 9 January 2019 (UTC)
Oooh, good changes and good thinking, I doubt I'd have thought of using a redundant {{#if: to strip whitespace. Elegantly done! -- Djonni (talk) 16:04, 10 January 2019 (UTC)

A recursive call in the template calls a recursive call in the template calls a recursive call in the template calls a recursive call in the template call

So, Emptysora pointed out during this Talk:Main Page#Modification_to_navboxes discussion that this template bumps up against a hard limit of 99 items (from memory). After I explained why this was the case (no Lua, all parameters must be hard-coded, no handling of arbitrary parameters) I was unsatisfied with my own answer. And there is a way to allow the template to handle much longer lists, taking advantage of this clever little hack that Emptysora added to the docs. Originally, I was thinking something like this at the end would do the trick:

{{#if:{{{100|}}}|{{Navbox items|mode={{{mode|}}}|wrap={{{wrap|}}}|item-style={{{item-style|}}}|bullet={{{bullet|}}}|<!--Unnamed parameter 1 left blank-->|{{{100}}}|{{{101|}}}|...|{{{201|}}}}}}}

And then I realised that recursion would allow this template to be dramatically simplified and shortened, by handling just, say, 10 or 20 unnamed parameters and then calling itself again. This would mean we simply decide how many parameters to support, and if at some point we ever want to expand that, it's trivial. So, whatever the max {{{n|}}} we extend the recursive call's list to will be the total number of parameters supported. And whenever we want to make a change to the way list items are handled, instead of changing it in 99 places, we change it in 10-20.

(I mean, strictly speaking through recursion we could just handle the first two parameters and pass the rest, but that would mean that any accidental double-bars (||) in the list would prematurely truncate it, and would mean that to render each navbox the wiki would have to call a bajillion nested templates and I think there's a depth limit. We actually do need to check that for this.)

It'll need to be done in a sandbox and tested thoroughly (recursion is a bitch is recursion is a bitch) and I don't have the time right now, but if nobody else gets it done I'll do this in the next... kinda... mañana. Soonish. (I actually like recursive programming because it's hard fun, so I'll probably do it, y'know. Soonish.) -- Djonni (talk) 04:51, 18 November 2019 (UTC)

Okay, yep, according to metawikipedia:Help:Expansion depth, there's a depth limit of 40. And since this template is called from {{Navbox}} and {{Navbox group}}, and itself calls {{Yesno-yes}}, which calls {{Yesno}} in turn (and we should allow a future editor to add a couple of levels of depth to this without having to test all n parameters laboriously) let's say we limit ourselves to 35 deep. Then, a template which handles 21 parameters at a time (remembering that recursive calls skip |1=) can cope with 20*35+1=701 items. That's definitely more than we need, but is a healthy upper limit. Seems reasonable to code this up to about n=200 for now and if it needs expansion in future then our future selves can easily expand it. -- Djonni (talk) 05:12, 18 November 2019 (UTC)