Page MenuHomePhabricator

TemplateStyles don't work when the template is inside a link
Open, Needs TriagePublicBUG REPORT

Description

When a TemplateStyles invocation is inside a piped internal link [[Foo|{{bar_with_tstyles|baz}}]], and when that invocation is the first invocation on the wiki page, TemplateStyles will apply to that specific invocation but no others on the page.

This inhibits the use of TemplateStyles inside inline templates, for example ru.wp Template:Comment and en.wp Template:Fraction.

Sometimes the use can be inverted as a workaround e.g. {{bar_with_tstyles|[[Foo|baz]]}}, but sometimes uses want to provide a link around the whole template e.g. Template:Fraction and linking to some named fractions.

Original report

[[A|{{comment|text|comment}}]] doesn't work properly in ruwiki: {{comment}} template contains a <templatestyles> tag, but no template styles are applied.

<templatestyles> expands into this code:

<style data-mw-deduplicate="TemplateStyles:r93295199">'"`UNIQ--templatestyles-00000001-QINU`"'</style>

(note the strip marker).

{{comment|text|comment}} works fine, and <templatestyles> expands correctly:

<style data-mw-deduplicate="TemplateStyles:r93295199">.mw-parser-output .ts-comment-commentedText{border-bottom:1px dotted;cursor:help}@media(hover:none){.mw-parser-output .ts-comment-commentedText:not(.rt-commentedText){border-bottom:0;cursor:auto}}</style>

The problem occurs because the template is used inside a link. The point of using this template inside a link is to provide a tooltip other than the standard tooltip for links.

An example without templates:

[[A|<templatestyles src="Шаблон:Comment/styles.css" /><span class="ts-comment-commentedText">text</span>]]

Related tasks:

Event Timeline

TemplateStyles generates a "general" marker (to, among other things, prevent T67258) that contains the style tags, with the actual content inside the style tags being hidden inside a "nowiki" marker (to prevent it from being mangled by Parser->doBlockLevels()).

Normally this is handled fine: Parser::internalParseHalfParsed() unstrips the "general" marker, does some stuff, and then unstrips the "nowiki" marker.

But in the case where the "general" marker is inside a link's text, the link is hidden by a LinkHolderArray marker. The first unstrip of "general" markers therefore doesn't see it. There's a second "general" unstrip, but that doesn't happen until after the "nowiki" unstrip so the contained "nowiki" marker never gets unstripped.

There are a few fixes I can think of, but I don't know whether any of them might break other assumptions.

  • Have LinkHolderArray unstrip general markers when replacing the link holders.
  • Have LinkHolderArray take an option to unstrip general markers when replacing the link holders, and use that option from Parser::internalParseHalfParsed().
  • Replace either the unstripNowiki or the second unstripGeneral call with unstripBoth.

Thanks to @Jonesey95's report at en:Template talk:Noitalic: The same thing is happening inside navboxes at en. Apparently, whether the noitalic is inside a link or not.

Edit: never mind, bug occurs if first instance of inner templatestyled template is in a link.

This doesn't happen with plain external links like [https://example.com {{sfrac|3|2|1}}] which was surprising to me.

For some reason, the bug isn't present here: https://es.wikisource.org/wiki/Usuario:Ignacio_Rodr%C3%ADguez/Testpage2

Despite being inside a link and all.
I haven't been able to reproduce it

This is really annoying for the Wikisourcen since their formatting needs follow whatever the text they are reproducing used, rather than a project-specific manual of style. It is very common to have typical linkable phrases (names of authors, say) formatted with multiple styles (i.e. multiple formatting templates) such that the template(s) cannot be moved outside the link.

Random contrived example: [[Author:William Shakespeare|{{all-small-caps|Shakespeare,}} {{letter-spacing|.2em|William}}]].

The workarounds being employed is stuff like {{all-small-caps|[[Author:William Shakespeare|Shakespeare,]] {{letter-spacing|.2em|[[Author:William Shakespeare|William]]}}, which… EWWW!

If one of the possible fixes Anomie sketched out above are feasible, even if not entirely architecturally clean, it would be very helpful to have that fix for now while we wait for the "perfect and correct" fix down the road.

The workarounds being employed is stuff like {{all-small-caps|[[Author:William Shakespeare|Shakespeare,]] {{letter-spacing|.2em|[[Author:William Shakespeare|William]]}}, which… EWWW!

Yeah, that's one work around. The other is something like this currently-unused monstrosity.

If one of the possible fixes Anomie sketched out above are feasible, even if not entirely architecturally clean, it would be very helpful to have that fix for now while we wait for the "perfect and correct" fix down the road.

I was thinking this might be something that could be fixed when the extension is "fixed" for T272941: Make TemplateStyles extension compatible with Parsoid as the ideal point, since I assume these qualities will be looked at in that context.

If one of the possible fixes Anomie sketched out above are feasible, even if not entirely architecturally clean, it would be very helpful to have that fix for now while we wait for the "perfect and correct" fix down the road.

The issue isn't that it's not architecturally clean (it's not really possible to do architecturally clean changes to the parser anyway), but whether it create new breakage because something somewhere implicitly relies on the current sequence of unstrips.

  • Have LinkHolderArray take an option to unstrip general markers when replacing the link holders, and use that option from Parser::internalParseHalfParsed().

I guess this would be the least risky of the three options.

I was thinking this might be something that could be fixed when the extension is "fixed" for T272941: Make TemplateStyles extension compatible with Parsoid as the ideal point, since I assume these qualities will be looked at in that context.

This bug is an artiface of the exact way stripping/unstripping is used in the parser. AFAIK Parsoid has no concept of stripping/unstripping (not being regex-based, it does not have a need to hide non-wikitext that matches regexes targeting wikitext syntax behind text markers). So I guess one way to fix this is to just wait for parser unification.

I guess one way to fix this is to just wait for parser unification.

Given this problem is currently being used to veto conversion of templates to use TemplateStyles on-wiki, I would really rather not wait for The Great Parser Unification™ (real soon now, I'm sure).

Real-world occurrence at en-wiki here; css font-variant:small-caps (diff) is an effective workaround. Discussion at Template talk:Smallcaps#Unaccountable failure.

Izno changed the subtype of this task from "Task" to "Bug Report".Jan 2 2024, 10:19 PM