Page MenuHomePhabricator

RFC: Skin templating
Closed, DeclinedPublic

Description

  • Affected components: TBD.
  • Engineer(s) or team for initial implementation: TBD.
  • Code steward: TBD.

Motivation

(Define the problem you are seeking to solve.)

Requirements

(Specify the features or criteria that need to be met.)


Exploration

(Use this space for data gathering, status quo, proposals, other considerations etc.)

This RFC aims to revamp how skins are created, to improve usability in creating skins, extending skins with new UI (in Extensions), and giving more power and flexibility for system administrators to customise skins for their own sites without causing undue burden on upgrades.

Link to RFC on mediawiki.org

Event Timeline

Unless anyone has any lingering concerns or questions they'd like addressed before the RFC is submitted for TechCom perusal, I'm going to be moving this RFC along to the next step of the process in a few days (requesting an IRC meeting).

To be honest I'm still very confused about this RFC. We had an RFC about using templates in MediaWiki across client and server and settled on Mustache for better or worse in Requests_for_comment/HTML_templating_library.

it was resolved that Mustache be used as the recommended template processor in core and extensions, for both JavaScript and PHP code.

The proposal in Skin templating seems identical to the one MinervaNeue has been using happily for many years and I'd support it. I don't understand what our hopes are for having an RFC discussion about this and I have little to add apart from JDI!

This RFC aims to deprecate BaseTemplate and as such make backwards-incompatible changes to the entire skinning system as a whole. This does not open up the option of using Mustache to generate parts of skins with PHP code to glue those parts together, it makes using Mustache mandatory for skins and eliminates PHP from the presentation logic entirely.

This RFC is not about picking the template library, that work is already complete. This RFC is about dragging our skinning system into the 21st century without legacy baggage or compromises on vision.

All skins (WMF-deployed and 3rd party) would need to be modified to conform to this new scheme. No existing skin, not even MinervaNeue, is currently compatible. That being said, MinervaNeue serves as a good example of the direction I want to take with this RFC, with its multiple hierarchical mustache templates.

Given the scope of changes, an RFC is necessary. The RFC page states "The Wikimedia RFC Process is used to track technical decisions and more complex changes that are strategic, cross-cutting, and/or hard to undo."

Strategic? Yes, this proposal aims to rip out and re-write the current skinning system with something that is sane and maintainable
Cross-cutting? Yes, this proposal impacts every skin, both WMF and 3rd party. No existing skin will be compatible with the new system without modification
Hard to undo? Not as much, we can always just roll back the change. New skins made with the new system would need some sort of shim to work, but could otherwise (mostly) function with the old BaseTemplate.

That said, I think the proposal is ready for an IRC meeting to finish discussing it. There are still some unresolved things such as how to handle caching of skins, which I can't entirely qualify by myself.

tstarling subscribed.

That said, I think the proposal is ready for an IRC meeting to finish discussing it. There are still some unresolved things such as how to handle caching of skins, which I can't entirely qualify by myself.

Moving on the RFC workboard accordingly.

This RFC aims to deprecate BaseTemplate and as such make backwards-incompatible changes to the entire skinning system as a whole.

Thanks for this clarification! FWIW any skin could copy BaseTemplate into their repo and/or we could leave it registered but deprecated and unused for several releases if need be. I do think templates serve a better purpose than this PHP class. Thanks for your patience with me!

@Skizzerz TechCom is trying to shift weight from IRC meetings to discussion here on phabricator. For this purpose, I suggest to copy the essential parts of the RFC from the wiki to the task description and writing an email to wikitech-l, asking for input. This would mean moving the RFC to "under discussion" on the RFC board for now. If it appears like there is consensus forming in the discussion on this ticket, we could perhaps move the RFC directly to last call without the need for an IRC meeting (or you could request an IRC meeting again, if you think it would be useful).

Thanks for this clarification! FWIW any skin could copy BaseTemplate into their repo and/or we could leave it registered but deprecated and unused for several releases if need be. I do think templates serve a better purpose than this PHP class. Thanks for your patience with me!

The current plan is to leave BaseTemplate in-place, but deprecated and unused by core, for at least 3-4 releases before it is removed. This gives 3rd parties ample time to re-work their skins which use BaseTemplate to use the new system instead. Depending on feedback from 3rd parties, that may or may not be extended. I'm hoping to provide good documentation for how to do things under the new system (once built) to ease the process for the 3rd parties, in addition to doing work to convert WMF-deployed skins as well as a couple of 3rd party skins in Gerrit (which can be used as examples).

@Skizzerz TechCom is trying to shift weight from IRC meetings to discussion here on phabricator. For this purpose, I suggest to copy the essential parts of the RFC from the wiki to the task description and writing an email to wikitech-l, asking for input. This would mean moving the RFC to "under discussion" on the RFC board for now. If it appears like there is consensus forming in the discussion on this ticket, we could perhaps move the RFC directly to last call without the need for an IRC meeting (or you could request an IRC meeting again, if you think it would be useful).

A wikitech-l thread for this RFC was sent on February 27, https://lists.wikimedia.org/pipermail/wikitech-l/2019-February/091594.html

No responses were made to that thread. If needed, I could bump it to add a last call for input and point at this thread. I wanted to avoid duplicating info between the ticket and the wiki, as edits to one won't necessarily be reflected in the other source.

I could perhaps work on some components of the RFC as a proof-of-concept, but I don't want to put too much effort into development which would possibly be thrown away in case this discussion leads to a change in direction.

An elephant in the room is what will be happening to the DOM as a result of this RFC. As one of the explicit goals of this RFC is to unify DOM across skins so that Gadget authors don't have to do skin-specific things if they don't have to. This means, however, that the overall DOM of most if not all skins will change in order to make them unified.

I was thinking about using Vector as the base DOM to adhere everything to, which would reduce the work needed to convert Gadgets and the like, but Vector's DOM can be charitably described as "not very flexible".

What are everyone's thoughts on how to address making a consistent DOM across all skins? In addition to the development effort involved, an outreach effort will almost certainly be required. In addition, deployment considerations need to be made. How do we get a smooth rollout of the changes in a way that doesn't just break everything?

What are everyone's thoughts on how to address making a consistent DOM across all skins?

If all skins are to share the same DOM structure, why have templating at all? If the DOM output is the same, the templates would be the same, no? In that case, skins would just consist of CSS...

It seems to me like these questions should be decoupled. 1) should we move the skin system to use (mustache) templates? And 2) should all skins share the same DOM strcucture (i.e. become styles)? And if not, what parts of the DOM structure should be the same for all skins?

Why does the DOM need to be consistent? It certainly isn't in Minerva. I would truly value having a proper API for accessing skins via gadgets rather than relying on CSS selectors.

I would truly value having a proper API for accessing skins via gadgets rather than relying on CSS selectors.

+1, though that's probably yet another RFC, and quite a bit of work...

Why does the DOM need to be consistent? It certainly isn't in Minerva. I would truly value having a proper API for accessing skins via gadgets rather than relying on CSS selectors.

Doesn't have to be! The goal listed is so that Gadgets can work well across skins without needing to resort to skin-specific hacks. A (mostly) consistent DOM is one way to achieve this, but is not the only way, as you've noted.

When I say "consistent DOM", I mean things like "use the same IDs / class names across skins where it makes sense to do so". So, the content container id will always be mainContent, content actions will always be p-cactions, and the like. Skins will almost certainly need to vary how they order things and lay things out by necessity in order to achieve whatever makes that skin work.

As an easy example, one skin may feature a left sidebar and content area, whereas another skin may have both a left and right sidebar area. These will by necessity have different elements composing that, and therefore a different overall DOM. I'm trying to address issues where a Gadget tries to work with both skins, say, to add something to the search bar. The search bar happens to be located in the left sidebar on skin 1, and the right sidebar on skin 2. It shouldn't have to jump through hoops to get to the search bar in each skin; they should use the same id or whatnot so the Gadget can directly drill to it in a skin-agnostic fashion. An API would serve this purpose as well, and would likely be a better way of going about it.

I think at this point I do need to work on an example just to get the idea across better and give people something concrete to look at in order to get an idea of the scope of changes I'm proposing here and what benefits those changes could have. I hope to have that ready in a week or so. In the meantime, please continue to comment on anything you notice :)

Consistent CSS classes and element IDs would indeed be great. This could go along with documentation stating explicitly what guarantees are (not) given.

I feel this RFC is focussing too much in a specific outcome, as such it is lacking a cohesive problem statement. This is, in my opinion, making it difficult for others to participate in a productive way.

There are a number of perceived problems presented in this RFC currently that I think do not have wide agreement, and as such would be very difficult to make progress on.

  • Why should a gadget be able to inspect the DOM equally and find no differences between skins? What is the end-user problem this is aiming to achieve? I feel that alone could be its own RFC.
  • Why should all skins use Mustache? It sounds like this is proposing that skins have no control over the HTML output. If that is so, then what would they be able to do with Mustache? If they are allowed to change the HTML output, why not allow them to continue to use BaseTemplate if they so desire?

I am all for consistency, but I am also a big supporter of boundaries between different components. I feel that MediaWiki core caring about how a skin produces its output crosses a boundary that shouldn't be crossed.

We can certainly impose conventions on what is found in the output. And if we want to codify that and make it impossible to breach, that's an interesting idea. But that leads me back to the question: If skins have no control over the output, what would they be using Mustache for?

I believe that the user stories mentioned in Goals adequately describe what this RFC is meant to tackle. If you disagree with some of the user stories, that is a valuable discussion to have. Many of these stories are things I have heard from other people across various channels. The "consistent DOM" point arose around VisualEditor rather than Gadgets, as VE expects certain elements to exist in order to power the editor interface. I mentioned Gadgets in the RFC to generalize it more as any js which would want to add things to a page needs to know where it should be adding it.

You are correct in that the RFC proposes an implementation in addition to saying "here is a problem, let's discuss it." This is because the problem is general and wide-reaching, and the proposed implementation has been done before to great success in other software. There are almost certainly problems with the proposal, however, and I am hoping that is what the RFC process will expose. If the end result becomes "the implementation proposed does not adequately solve the problems it needs to solve," then that discussion will be invaluable for tweaking and coming up with something that does work.

Why should a gadget be able to inspect the DOM equally and find no differences between skins? What is the end-user problem this is aiming to achieve? I feel that alone could be its own RFC.

I am not advocating that the DOM be exactly the same across every skin. Indeed, I don't believe that is even possible to achieve. Instead, certain key elements should be as consistent as possible between them so that things written for one skin will ideally work with others as well, if they all do things (mostly) similarly. In other words, I hope to establish a convention and get skins to mostly stick to it.

Should this go through, Core will be moving parts of its own HTML generation into templates, such as the sidebar and table of contents. I aim to also ship a base set of templates (to provide the mostly-consistent DOM mentioned above) as part of "Fallback." Skins can override as many or as few of these templates as they want in order to tweak things how they want them to be. This is an improvement over the status quo where a skin currently must override everything, even if it only wants to make 2 or 3 small tweaks.

Why should all skins use Mustache? It sounds like this is proposing that skins have no control over the HTML output. If that is so, then what would they be able to do with Mustache? If they are allowed to change the HTML output, why not allow them to continue to use BaseTemplate if they so desire?

We ship a set of base templates. Skins override as many or as few of these templates as they want in order to customize their generated HTML in a skin-specific way. The skin has complete control over the HTML output, even more than it currently does (for example, control over how the Table of Contents HTML is generated).

We can certainly impose conventions on what is found in the output. And if we want to codify that and make it impossible to breach, that's an interesting idea. But that leads me back to the question: If skins have no control over the output, what would they be using Mustache for?

It will not be impossible to breach the conventions. The conventions are shipped as part of the Fallback skin to provide new skins an easy base to start building from, but the expectation is that they will deviate from at least some templates to do their thing. However, by only overriding the bits they need to override, everything else remains the same and we achieve a higher level of cohesion between skins for their DOM.

Can you please let me know what lead you to believe that core would be stringently enforcing the rendered HTML, and preventing skins from doing their own thing? I would like to revise those sections of the RFC to make it more clear what the intent is. Alternatively, please feel free to edit it yourself, it's a wiki after all :)

TechCom is hosting an IRC meeting on this topic on March 27 at 11pm PST (March 28 06:00 UTC, 07:00 CET) in #wikimedia-office

Cancelled to be reschedule during the other IRC window at a later date

@kchapman Would it be possible to do this meeting at some other time/day? As one of the people most familiar with the current skinning system, it'd probably be good if I could make it, and that is not a time I will be able to make as I am going to be on a plane somewhere over the atlantic.

TechCom is hosting an IRC meeting on April 3rd at 2pm PST (22:00 UTC, 23:00 CET) in #wikimedia-office

Action items from the IRC discussion:

*<Skizzerz> 1. Expand upon the RFC to include a migration plan
*<Skizzerz> 2. Add a section for possible future expansion

So having experimented (very briefly) with some templating with the current mustache support in core, I note that MediaWiki seems to have some very heavy caching of anything after the initial level, evidently due to performance concerns. What this means in practice is that it can actually be somewhat difficult to work with - one needs to manually disable or reset the cache every time they make a change in order for the change to show up, which for frontend design and development work presents a major problem in terms of seeing what we're doing while we do it.

Do we have any good ways around this for doing the development itself?

Because the whole premise here was to make heavy use of layering and includes in order to allow maximal flexibility without requiring people to really implement a whole lot themselves. And that seems to be where our current mustache support quits working very well.

I note that MediaWiki seems to have some very heavy caching of anything after the initial level

Related: T113095. Maybe we can disable this caching in debug mode.

Here's the gist of what what we (mostly @Skizzerz) found regarding Mustache as it applies to this proposal:

Basically it falls flat in three areas: runtime performance, component reusability, and extensibility.

  1. Runtime performance: sub-templates or whatever they're called are processed at runtime, so we can't pre-cache or pre-expand them. This will likely kill performance on larger sites
  2. Component reusability: because there's no way to explicitly pass parameters to sub-tempates, we'd need to roll literally everything into the top-level context object passed to the skin. This simply isn't feasible for certain classes of components, such as a generic "sidebar block" widget
  3. Extensibility: the default parser expects everything in the same directory, which blocks any attempts at overwriting certain templates with other versions as described in the RfC

Points 1 and 3 can be solved via a custom parser, but point 2 requires extensions to the markup, and those required extensions look, well, pretty much exactly like what Handlebars already has. I think whatever syntax we end up going for will likely require a custom parser, just to add hook points, but I'd like to stick to the language spec for said parser. Avoids any surprises and the like.

Point 1 also raises some other issues, a the only way to get a template language-based skin to work well from a performance standpoint is to precompile it to PHP when the skin is installed, which introduces security questions about where those precompiled files are stored, and how to prevent malicious modifications to them.

More on this later, maybe.

I think the recently merged SkinMustache class provides an alternative to BaseTemplate which addresses the goals of T217158#5019573 with the exception that the new skin class is not mandatory but a recommended alternative. It's used to build CologneBlue and Modern, Vector and Minerva and this has led to a standard and simplified API that addresses the needs of all these skins in a generic way.

A new skin compatible with MediaWiki master can be made using the following tool: https://skins.wmflabs.org/#/add

@Skizzerz how would you feel about merging this RFC into https://phabricator.wikimedia.org/T249673 or calling it resolved?

I think the recently merged SkinMustache class provides an alternative to BaseTemplate which addresses the goals of T217158#5019573 with the exception that the new skin class is not mandatory but a recommended alternative. It's used to build CologneBlue and Modern, Vector and Minerva and this has led to a standard and simplified API that addresses the needs of all these skins in a generic way.

A new skin compatible with MediaWiki master can be made using the following tool: https://skins.wmflabs.org/#/add

@Skizzerz how would you feel about merging this RFC into https://phabricator.wikimedia.org/T249673 or calling it resolved?

@Jdlrobson I haven't had the motivation to move this RFC further along, so it's mostly stalled. SkinMustache meets some but not all of the points this RFC was designed to address, and in investigating what it would take to meet the rest of them, I actually learned that Mustache simply isn't powerful enough to do what I want. If I were to continue this RFC, I would push for replacing Mustache with Handlebars (via the LightnCandy library for PHP). Handlebars is a superset/extension of Mustache which adds a few template logic constructs required to sensibly offer system administrator customization of skins.

Looking at T249673, it looks like it touches on some (but not all) of the points of this RFC: notably, it completely disregards system administrators who want an easy way to tweak built-in skins without requiring development effort and extension developers who want to inject something across all skins where there is no targeted hook (using BeforePageDisplay to wrangle HTML strings isn't a good practice imo).

If you want to get in touch on IRC, I'd love to chat about my vision and see if we can possibly work together on a cohesive skin overhaul that serves the needs of the myriad consumers of skins (development, system administration, and end users). My nick there is Skizzerz.

would push for replacing Mustache with Handlebars (via the LightnCandy library for PHP). Handlebars is a superset/extension of Mustache which adds a few template logic constructs required to sensibly offer system administrator customization of skins.

I think longer term Vue.js would make sense given the move to adopt Vue.js in the frontend given https://phabricator.wikimedia.org/T241180 and that's what I've been working towards. The Mustache move is simply a step in making sure skins are rendered via templates and separating the rendering part from the data part.

If you want to get in touch on IRC, I'd love to chat about my vision and see if we can possibly work together on a cohesive skin overhaul that serves the needs of the myriad consumers of skins (development, system administration, and end users). My nick there is Skizzerz.

Sounds good!

notably, it completely disregards system administrators who want an easy way to tweak built-in skins without requiring development effort and extension developers who want to inject something across all skins where there is no targeted hook (using BeforePageDisplay to wrangle HTML strings isn't a good practice imo).

I've been advocating for making configuration easier and less hooks, and have been documenting use cases on https://mediawiki.org/wiki/User:Jdlrobson/Skins_for_extension_developers but it's not been my intention to disregard system administrators (quite the opposite!)

Could you give an example of where you might want to inject HTML where this is no targetted hook?

Untagging MediaWiki-Core-Skin-Architecture here as I'm not sure what I can do to help move this along at this current stage.

I guess that means either tech-decision-forum or status declined?

Looks like this has been abandoned two years ago. I'm closing it as declined for now, for lack of a more appropriate status. That doesn't mean the general idea doesn't have merit. If someone is up to it, they should feel free to revive this and send it through the new process.