Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to render nested array of data into the same partial multiple times? #190

Closed
Integralist opened this issue Nov 7, 2016 · 1 comment

Comments

@Integralist
Copy link

Integralist commented Nov 7, 2016

Hi

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 the x 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?

@Integralist
Copy link
Author

So I've managed to resolve this issue myself with a change in code design and nesting 'Presenter' classes (but would be interesting to see how others are doing this)...

+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 the Presenter 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 inside self.post.results from the top level Feed presenter

Our code starts at the top level presenter (Feed) and starts recursively rendering each nested Presenter it finds

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant