HomePhabricator
Why does building a skin require PHP knowledge?
Most UX developers only know CSS, JS and HTML

One of my longstanding pet peeves is that skin development for MediaWiki is so hard. I propose a radical change to how skins are installed and ask for feedback.

Having watched teenagers use Myspace.com and then tumblr.com and watching Wikimedians build all sorts of things using wikitext templating it's clear that skinning anything should be possible with a mixture of basic knowledge of web technology (HTML,CSS maybe JSON) and/or cargo cult programming. The MediaWiki skin ecosystem is pretty sparse and when skins are created they don't tend to be published for wider consumption or are lost in github repos that are never linked to. Some never even get built. After almost 10 years in this movement it's easy to see why.

At a recent offsite I got all my team to stand up in a room and asked them to sit down if they felt comfortable with HTML. A few sat down and I told them unfortunately they couldn't build a skin. When I asked them if they felt comfortable editing CSS, a few more sat down and I told them the same thing. Eventually everyone sat down. What was interesting was who sat down and when. The designers sat down at the mention of PHP (while comfortable with CSS and JS) as did many frontend engineers. Meanwhile backend engineers sat down at the mention of PHP.

Our skin code is pretty complicated. We currently encourage skin development by guiding users to the ExampleSkin. This extension is pretty scary to many developers not already in our ecosystem and many designers who are in it. There is an extreme amount of PHP and knowledge of folder structure and MediaWiki-concepts such as ResourceLoader is needed before someone can even start.

Currently to create a skin at minimum you must

  • Download and setup MediaWiki
  • Learn git and clone the ExampleSkin repo
  • Understand ResourceLoader
  • Understand our i18n system
  • Understand how skin.json works
  • Edit PHP to generate HTML
  • Edit CSS

To encourage a healthy skin system we need to lower many of the barriers to implementing a skin. It should be as simple as:

  • Clone a repo
  • Edit some CSS and HTML
  • Run some npm commands

During the implementation of MobileFrontend and MinervaNeue many changes were made to the skin system to help build the new skin whilst maintain the old skin. It also intentionally made some breaking changes from traditional skin - for example no longer were languages or categories part of the HTML of an article. JavaScript and CSS shipped by all skins was turned off in preference for its own versions. In my opinion this was the skin's right. A good skinning system allows you to create radically different skins and innovate. If our skin system was healthy we'd likely have skins of all sorts of shapes and sizes. A good skin system also makes maintenance easier. Right now because of class inheritance, it's very difficult to make changes to our existing skins or our core skin PHP without worrying about breaking something elsewhere. Similar changes and challenges happened with Timeless that I'm sure Isarra can attest to!

Exploring different approaches

I've been lamenting this situation for some time. A while back I created an extension called SimpleSkins that reduced the Minerva skin to 2 files with some ambitious and breaking changes to the PHP skin code that I dreamed of one day upstreaming.

At a recent hackathon, with this idea still in mind, I took a slightly different approach. Instead of trying to make a skin a folder of several files I thought - what if the skin folder was an output of a build step? Similar to the SimpleSkin approach I again focused on a folder of frontend friendly technologies and reduced Vector to 3 files - Mustache (template), JS (with require support), LESS(css) however the generation of skin.json, PHP was left to a build script. Remarkably this worked and was relatively straightforward. One interesting insight I had this time however was that no skin developer should require a MediaWiki install to build the skin - with templates a lot of data can be stubbed or come from an API endpoint. Not having to install a MediaWiki install is a big deal!

With a good architecture a lot of our skin system can be abstracted away. A skin without qqq codes is still useful provided en.json has been generated. ResourceLoader module config is much easier to auto-generate now we have packageFiles provided we enforce a common entry point e.g. index.js and index.css/less. The PHP skin class should and can do more. Instead of having skins that extend SkinTemplate e.g. SkinVector we should have a skin rendering class that renders folders that contain skin meta data....

How we do it.

Forgetting about existing technology choices and working with what we've got, I'd propose automating most of the skin registration process - to the point that PHP is irrelevant and JS and JSON files are optional.

I strongly believe the following is possible:

  • An online skin builder that saves and exports skin folders to download folder or github similar to jsfiddle
  • A valid skin is a folder with at minimum 2 files - index.mustache and index.(css/less)
  • You should be able to copy and paste an existing skin and get a new skin without any modification except the folder name.

To achieve such a goal we would need a SkinRenderer class that locates a skin directory and renders the template inside it (Mustache is currently the template language we support in core). SkinRenderer when passed the skin key skinnew for example would find the folder skinnew in the skins folder and the files index.less, index.js and skin.mustache. It would pass skin.mustache data (which is subject to deprecation policy and well documented and it would register a ResourceLoader module using index.less and index.js and packageFiles. qqq.json and en.json if needed could live in the i18n folder as they currently do but their absence would not cause any problems.

A developer would fork a new version of the ExampleSkin which provides the basic file components, run npm install and then npm start. This would pull our core frontend technologies - mustache and LESS from npm and then pass the skin through a tool such as parceljs that allows live updating, the workflow of which is demonstrated in this video. However unlike in my hack experiment, installing the skin would be as simple as copying that folder into mediawiki's skin folder rather than running a build step :)

What do I do next?

Am I alone in thinking it should be possible to build skins without PHP? Do you have different opinions on what the skin system should be? Do you have concerns about how such a system would scale or whether such a system would get adoption? What do you think of my skin builder tool and should I work on it more? If so I'd love to hear more from you. Any feedback you can provide would be helpful to decide whether I should prepare and push and RFC.

Thank you for your time!

Written by Jdlrobson on Feb 3 2020, 6:37 AM.
User
Projects
Subscribers
Demian, alistair3149, mmodell and 3 others
Tokens
"Love" token, awarded by Lens0021."Yellow Medal" token, awarded by mmodell."Love" token, awarded by Ammarpad.

Event Timeline

Am I alone in thinking it should be possible to build skins without PHP? Do you have different opinions on what the skin system should be?

You're not alone. First and foremost I feel the skin system should be modernized. Requiring passing raw HTML to a (mustache) template because the QuickTemplate abstraction generates raw HTML or require elements to be built with methods like makeListItem should be the exception, not the norm.
It would certainly help if there was a document describing what elements a skin is expected to provide, with which classes/ids, and what hierarchical order is required (for say VisualEditor).

Do you have concerns about how such a system would scale or whether such a system would get adoption?

Extension registration has been adopted in pretty much every modern extension (and skin), and it allowed the simplification of registering extensions, removing the need for PHP knowledge, which in turn allowed volunteers with limited (or none at all) knowledge of PHP to do maintenance work on them. I think that, when the proposed system provides a clean and, more important, an easier way of skinning, adoption would follow. That does require good documentation and a good example (e.g. converting Vector/Minerva).

Any feedback you can provide would be helpful to decide whether I should prepare and push and RFC.

Please create an RFC, I'd love to help out. The existing skinning system is in dire need of improvement, with many parts appearing to have come right out of the late PHP 4 era.

In my opinion this was the skin's right.

I think it could be valuable to separate the ideas of application entry points and UI appearance-only changes. (I'm not sure if it makes sense in MediaWiki for the latter to include content styling too.)

Currently to create a skin at minimum you must

Probably good to add what's typical as well. For example, heavy MediaWiki integration in the form of PHP hook lifecycles, extension integration, and OOUI, and then defining an API for gadgets to use.

A valid skin is a folder with at minimum 2 files - index.mustache and index.(css/less)

It might be neat to experiment with a skin based entirely on user styles.

To achieve such a goal we would need a SkinRenderer class that locates a skin directory and renders the template inside it

Is mediawiki-dali-skin-builder a kind of wrapper skin? That is, a new repo that's technically a MediaWiki skin in itself but really just provides the glue needed to achieve the structure you want for "simple skins.

Great post! By "online skin builder" do you mean something like mwstew but for skins? Ignore that, I just looked at Dali. :)

(By the way there's a syntax error after "friendly technologies and".)

There are so many ways that MediaWiki shows it's age and skinning is definitely one of the most visible 😁

I think everything proposed here is very sensible, though I'm not that familiar with MediaWiki skinning and I can't offer much mw knowledge, I would definitely support such an RFC.

@Samwilson I've gone one step further
https://skinomatic.wmflabs.org/

If you click build in the top right it will generate you a zip that contains a working skin repo.

Is mediawiki-dali-skin-builder a kind of wrapper skin? That is, a new repo that's technically a MediaWiki skin in itself but really just provides the glue needed to achieve the structure you want for "simple skins.

In my away, but my hope would be to not need an extension/wrapper skin because the core code is flexible enough and aware of templates.

Hopefully the https://skinomatic.wmflabs.org/ is a powerful demonstration of what's possible here.
My hope would be to make this file which is outputted in the end skin unnecessary:
https://github.com/wikimedia/skinomatic/blob/master/scaffolding/ScaffoldingTemplate.php.txt

Please create an RFC, I'd love to help out.

Flagging issues with https://skinomatic.wmflabs.org/ would be helpful - one obvious one is how to add icons to the interface without using absolute URIs.