Marko : async-fragment inside async-fragment

103 views
Skip to first unread message

Adrien Baumann

unread,
Jul 20, 2015, 9:25:59 AM7/20/15
to rapt...@googlegroups.com
Hello everyone,

I'm using Express and Marko (and I'm starting to really enjoy it). I want to progressively render the HTML and I have a common page template that could be summarized like this : 

<html>
  <async-fragment data-provider="data.header" var="header">${header}</async-fragment>
  <async-fragment data-provider="data.content" var="footer">${content}</async-fragment>
  <async-fragment data-provider="data.footer" var="footer">${footer}</async-fragment>
</html>

On some occasions, I would like my content to come from another marko template that would also contain some ordered <async-fragment>; is there a way to achieve this ? (If not exactly this, something similar).

Thanks for any help or tips you could give me. :)

Patrick Steele-Idem

unread,
Jul 20, 2015, 11:12:36 AM7/20/15
to rapt...@googlegroups.com, adrien....@gmail.com
Hi Adrien,

You could create a data provider that provides either raw content (as a String), but typically the data provider just provides the data and the template chooses how to render HTML for the data. However, for your use case, you could also have your data provider also provide both the data and the template that should be used to render the HTML. Probably easier to show in code:

<html>
    <async-fragment data-provider="data.header" var="header">${header}</async-fragment>
    <async-fragment data-provider="data.content" var="footer">
        <include template="data.content.template" template-data="data.content.data"/>
    </async-fragment>
    <async-fragment data-provider="data.footer" var="footer">${footer}</async-fragment>
</html>

In addition, the JavaScript code for your content data provider could look similar to the following:

var viewModel = {
    content: function(callback) {
        callback(null, {
            template: require('./my-content.marko'),
            data: myAsyncData
        });
    },
    ...
};

With that said, it might be considered bad practice for your common page template to make calls to data providers. Instead, I would strongly recommend taking advantage of the layout taglib: https://github.com/raptorjs/marko-layout

By using the layout taglib you would still have a common page template, but the user of the layout template can choose which content to inject into the various parts of the page.

I'm glad to hear that you are enjoying Marko. Please feel free to ask if you have any more questions or suggestions.

Thanks.

Adrien Baumann

unread,
Jul 22, 2015, 11:10:56 AM7/22/15
to RaptorJS
Hello Patrick,

Thanks a lot for your answer. It seems that a a mix of layout taglib and async fragments is exactly what I want to achieve. :)

I can't seem to be able to do <includes> in the layout though. But I think that's a normal thing, right ? 

So I ended up using 1 layout, 1 page template (to gather/render everything) using the layout, and various content templates (to be included in the page). Async-fragments can happen in the page template and/or in the content templates. That's perfect.

So, thank you again,I'm going back to my tinkering. :)

Patrick Steele-Idem

unread,
Jul 22, 2015, 12:36:36 PM7/22/15
to RaptorJS, adrien....@gmail.com
Hi Adrien,

I can't seem to be able to do <includes> in the layout though. But I think that's a normal thing, right ? 

That doesn't sound normal at all. Can you please share some code I can use to reproduce the problem? Probably best to create a Github issue: https://github.com/raptorjs/marko/issues

Glad you got it working. Happy coding :)
Reply all
Reply to author
Forward
0 new messages