So I’m having some problems wrapping my head around the best idiomatic way to deal with some complex html cases flexibly using Mustache.php
The first is a pre-selected select dropdown, e.g.
<select>
<option value=''></option>
<option value='bob'>Bob Williams</option>
<option value='james' selected>James Smith</option>
</select>
I have a way that I deal with this, but my way seems really inflexible:
- take an array in php,
- reformat it into multi-dimensional arrays with 3 elements; value, display, selected (boolean)
- pass it to the template where option, value, and selected are output in a loop
Is there an awesome approach for making preselected select dropdowns using partials or anonymous functions or methods or some other feature of mustache.php that I’m missing?
Edit: Pared down this question into separate parts to try to maximize clarity.
The idiomatic way to do this in Mustache would be to create a View (or ViewModel) rather than passing in a hash of data:
Then you could combine this with a
dropdownpartial…Which you can use in your template like this:
And render it:
… But you can do even better than that 🙂
With this:
And this:
And one of these:
Throw in a new
addresspartial:Update your main template:
And go!
Now you have modular, reusable, easily testable, extensible bits of code and partials to go with ’em.
Note that the classes we created are “Views” or “ViewModels”. They’re not your domain model objects… They don’t care about persistence, or validation, all they care about is preparing values for your templates. If you’re using Models as well, that makes it even easier, because things like our Address class can wrap your address model, and grab the values it needs directly off the model rather than requiring you to pass a bunch of things to the constructor.
The Zen of Mustache
If you take this approach to its logical conclusion, you end up with one top-level View or ViewModel class per action/template pair in your app — the View could internally delegate to sub-Views and partials, like we did with the Dropdowns from our Address View, but you’d have one first-class View or ViewModel responsible for rendering each action.
Meaning (in an MVC/MVVM world), your Controller action would do whatever “action” was required of it, then create the View or ViewModel class responsible for populating your template, hand it a couple of domain Model objects, and call render on the template. The Controller wouldn’t prepare any data, because that’s the responsibility of the View layer. It would simply hand it a couple of model objects.
Now all your logic for “rendering” is neatly encapsulated in the View layer, all your markup is neatly encapsulated in your template file, your Model is free from ugly formatting business, and your Controller is nice and light like it should be 🙂