mvvmviewmodelphptal

PHPTAL: Viewmodel Solution


I've picked up PHPTAL (after coming from PHPMustache), and I'm trying to inject a ViewModel class Mustache-style into my template. Let me explain ..

controller

$viewmodel = new \Viewmodel\Home();
$template = new \PHPTAL('application/views/home.html');
$template->viewmodel = $viewmodel;
echo $template->execute();

home.html <- template

<p>Hello <strong>${viewmodel/test}</strong>.</p>

Home.php <- viewmodel class

namespace Viewmodel;
class Home {
    function test() {
        return "world";
    }
}

The above works, but how do I avoid prefixing every variable reference with "viewmodel/"?

With Mustache, your variable context could be a single class. eg. echo $template->render($html, $viewmodel);. Prefixing is not necessary. All the meat is inside a loosely coupled viewmodel. I'd like to enforce this behaviour with PHPTAL without having to explicitly assign the whole class to a variable name.


Solution

  • In short, no.

    There's no equivalent to JavaScript's with(model){} operator. You're supposed to be explicit what variables you declare via $context->set() and use models explicitly, e.g. ${user/name} rather than ${name}. The latest version (in GitHub) supports closures, so you can use that for lazily computed variables.

    If you're not giving direct access to models and you want to proxy all data through the viewmodel, then that looks like impedance mismatch with Moustache design philosophy.

    In PHPTAL's approach to MVC you have business logic handled by model/controller (e.g. customer's account balance stored/manipulated) and any view-specific logic (e.g. if balance is negative then display it in red) goes into the template.

    There's no in-between object to mediate that communication to add expressiveness to the template, because the template language is more expressive, and can be extended with TALES expressions:

    <strong tal:condition="customer/isInDebt"/>
    
    <strong tal:condition="isNegative:customer/balance"/>