On Feb 3, 2012, at 7:33 PM, Daniel Friesen wrote:
Also, are you already working with Owen Davis
& the Wikia folks
regarding their skin rewrite proposal?
No one sent me any information about that
-- In fact this might be the
first I've even heard of it. Though I'd love to see their ideas.
~Daniel Friesen (Dantman, Nadir-Seen-Fire) [
http://daniel.friesen.name]
I haven't had time to respond to this, I've been a bit swamped… Here's a
summary...
The approach we took was to make a self contained and modular mini-framework for building
skins. It borrows a lot from Symfony. Typically with mediawiki skins, you have a giant
skin template file which defines an template object and contains bunch of html, which then
calls a bunch of helper functions to build more html. We felt it got pretty unmanageable
pretty quickly with our Monaco skin, which takes the same approach. What we did with
Oasis was basically reduce it to this:
class OasisTemplate extends QuickTemplate {
echo Module::get('Oasis', 'Index')->render();
// or echo wfRenderModule('Oasis', 'Index');
}
And then define a Data TransferObject + Controller hybrid. All public variables are
exported to the template, which reduces the amount of boilerplate PHP syntax to a
minimum:
class OasisModule extends Module {
public $foo;
public $bar;
public $wgGlobalVar; // any global reference is auto-copied to the template
public function executeIndex() { // any function called executeX is
"dispatchable", the rest are helpers
// controller logic goes here
$this->foo = FooService::getSomeFoo();
$this->bar = BarService::getSomeBar();
}
}
And the template/view is just a raw php file called Oasis_Index.php :
<div>
<div> <?php if (isset($wgGlobalVar)) echo $foo ?> </div>
<div> <?= $bar ?> </div>
<div> <?= Module::get('Something', 'Index')->render();
?>
<div> <?= wfRenderModule('OtherThing', 'Whatever'); ?>
</div>
As long as the names match up, the Module class matches up the controller method and the
view template (Index, in this case). Of course, when we got to really building the skin,
it got a lot more complicated, and now it's undergone a bit of a transformation into a
more formal MVVC framework which obscures the simplicity of the original approach. But
that was the idea. We have something like 40+ modules in the skin itself, and who knows
how many more in extensions.
The nice thing about this was that doing Module::get("Thing",
"Index")->getData() will just give you a raw array of data, which means any
controller methods can double as an ajax call (after transforming it to json) or a service
class for some other piece of PHP, which is a shortcut we use a lot.
At this point, the Oasis skin has been stretched (ha) far beyond it's initial design
and it's holding up… okay, I guess. It's easy for people to find one small
section of the code and just work on that, and you can test individual components
separately and see the raw data or the raw html for any module directly in the browser,
which was the goal. The modules actually got converted to something more like full blown
controllers with a dispatcher framework a while ago. You can see the current version of
the entry point here:
http://trac.wikia-code.com/browser/wikia/trunk/skins/Oasis.php
And an example of how the modules can get pretty complex, and how you DON'T want that
logic in a template:
http://trac.wikia-code.com/browser/wikia/trunk/skins/oasis/modules/LatestAc…
http://trac.wikia-code.com/browser/wikia/trunk/skins/oasis/modules/template…
and an example of the raw data for that exact bit of code on a live wiki:
http://community.wikia.com/wikia.php?controller=LatestActivity&method=I…
and the html without the rest of the skin:
http://community.wikia.com/wikia.php?controller=LatestActivity&method=I…
It's really not MUCH more complicated, and I think the basic concept could be
extracted and simplified and open sourced pretty easily. Oasis at this point depends on a
LOT of other wikia code, but the design itself doesn't. And it's all one step
closer to a more formal web services framework, which is I guess where we are going in the
long run…? I'm not sure if this is something anybody else is interested in, but
I'm happy to provide more details.
owen(a)wikia-inc.com