I'm using Python's pystache (which is the standard Mustache api).
Here is an example of my data's structure:
{
"results": [
{
"user": "foo",
"flags": [
"a",
"b",
"c"
]
},
{ ... }
]
}
Now in my template I try to do this:
{{#results}}
{{> stuff}}
{{/results}}
Where stuff
is a partial, and that partial looks like this:
user: {{ user }}
isX: {{ flags.x }}
Now what provides the data to the template is a class that acts as a 'view model' so I can normalise some of the data and have the template interact with the normalised data rather than the raw json data shown above.
The problem is I don't know how to implement my view model to work with the fact we're looping through nested data.
Using the above as an example, my raw data uses an array of strings to represent the flags
value, where as I want the template to show true or false depending if the value x
appears in the flag array.
In code I might try to implement this like so:
class Feed(Presenter):
def prepare_view(self, **params):
self.view = View()
self.view.template_path = '/app/static/views/feed.mustache'
self.view.results = self.post.results
self.view.flags = namedtuple('_', ['x'])('true')
return self
just imagine the
namedtuple
was where I loop over the array looking for thex
string and I return true or false based on that
Now the issue here is that for me to write the namedtuple
code, I need to know which index of the results to be looping over.
Am I just missing something really obvious?
So I've managed to resolve this issue myself with a change in code design and nesting 'Presenter' classes (but I would be interested to see how others are doing this; as I tried multiple other ways trying pystache language features with no working solution)...
class Feed(Presenter):
def prepare_view(self, **params):
self.view = View()
self.view.template_path = '/app/static/views/feed.mustache'
self.view.teasers = self.prepare_teasers()
return self
def prepare_teasers(self):
return [Teaser(Context(result)) for result in self.post.results]
where
self.post
is set on thePresenter
and provides the raw data we're looking to consume
The Teaser
then works effectively the same as this top level Feed
presenter, the difference is it's given a different 'context' object (i.e. self.post
value) to use as its data source:
class Teaser(Presenter):
def prepare_view(self, **params):
self.view = View()
self.view.template_path = '/app/static/components/teaser/teaser.mustache'
self.view.username = self.post.author
self.view.uri = self.post.uri
self.view.title = self.post.name
return self
self.post
is now one of the elements from insideself.post.results
from the top levelFeed
presenter
Our code starts at the top level presenter (Feed
) and starts recursively rendering each nested Presenter it finds