RE: [coldbox:16866] [coldbox 3.5.3] multiple renderView()

Sure thing. You can render as many views as you want inside of other views or inside of your layout. A common work for that is a viewlet. It gives you a nice way to encapsulate little chunks of HTML and include them on any page you want.

For instance, in my main layout, I render a view for each dropdown menu in my site.

Now, the next issue you’ll run into is when your viewlets need data and you want an easy way to wrap up the handler code to get that data with the view it goes with. Otherwise if handler A renders view 1, which in turn renders views 2, 3, and 4, you’ll end up pulling all the data you need into the request collection up in handler A which ties it to all the views.

The easy solution for us is to wrap each view in an event (perhaps I could call them eventlets :slight_smile: Instead of doing event.setView() in that event, I just return the output of the rendered view like so:

// Here is a handler

layoutAssets.cfc

component {
property name=“myService” inject;

function HTMLPod1(event, rc, prc) {
rc.data = myService.getData();
// This view will access rc.data and do stuff with it.

return renderView(“layoutAssets/HTMLPod1”);

}
}

Then, in my layout (or another view), just run this event and output its return directly on the page:

#runEvent(“layoutAssets.HTMLPod1”)#

Now you have an encapsulated event that is capable of getting its own data and returning the HTML of the view that it renders. The only thing to do now is to clean up the rc scope so you aren’t dumping stuff in there. For that, use the args parameter to pass your data directly to that view without cluttering up rc like so:

var data = myService.getData();
// This view will now access args.data instead of rc.data.

return renderView(view=“layoutAssets/HTMLPod1”, args=data);

Nice and clean.

Also note, when renderView() is called with no arguments inside a layout, that renders the view set in the handler with setView(). If you pass a view name into renderView, it renders the specific view you’re asking for.

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Thank you. Just saw this reply. I’m looking at this sentence:

“Also note, when renderView() is called with no arguments inside a layout, that renders the view set in the handler with setView(). If you pass a view name into renderView, it renders the specific view you’re asking for.”

Am I understanding correctly the the view name referenced in that example is static? So if I have a layout with renderView(‘someview’) I’m literally getting a view named someview.cfm? As an example of what I’m looking for let’s say I have a 3-piece layout template. It has a top nav, a left section and a right section. If I’m understanding things correctly I can setView() in my handler and have that referenced in the layout as my right section (for example). Left section and top nav however would have to be a static reference, a var of passed in prebuilt html, or some sort of “mini-event” per your previous example (which I obviously don’t quite understand yet).

What I was hoping is my handler could…

setView(1,‘someview’)
setView(2,‘someview’)

setView(3,‘someview’)

and layout could…

renderView(1)
renderView(2)

renderView(3)

with these “renderViews” placed where I want them. I’m just guessing as to syntax to get the idea across. Is this possible? It just seems a lot simpler than treating one view as “setView” and any others in a static or custom fashion.

Thanks!

I just posted a few minutes ago but wanted to add the following to make sure I’m asking for most streamlined method to do what I’m looking for. Not to muddy things but to make it clear let me use ModelGlue as an example.

In a layout in MG I can have a reference like #viewcollection.getView(“leftbody”)# . Then in the xml that combines with the controller CFCs to make the controller piece I set a view like . This way my layout has three variables (per my original example of top,left,right) and the controller/handler retrieves the templates to go in the layout along with any needed vars, etc.

I’m just looking for the most direct straightforward way to do this in Coldbox. The “veiwlets” approach seemed messy on the surface but, again, I don’t yet follow what you’re doing. In short is there a way to “ID” the views created in the handlers?

Thanks!

The “viewlet” concept Brad mentioned is pretty much what you’re looking for… it does the exact same thing that you are asking, but sort of in reverse.

So in your example, in your layout you may have 3 ‘renderView’ statements (top, left, right) and at the top of each of those views pages you would run an event to build your rc:

<cfset runEvent(event=‘myHandler.top’)>

I have sites with many pods and they all are setup this way.

Brad,

I’ve learn so much from your posts to this Group! Thanks for taking the time to respond to these questions.

  • Grant