How to dynamically render views from controller?

15 views
Skip to first unread message

marc

unread,
Mar 28, 2012, 12:41:20 PM3/28/12
to model...@googlegroups.com
Hi,

Currently I send an email by specifying an e-mail template in the <view> section of my event-handler xml.
This email-template contains my html, links to graphics,css includes etc in a <cfsavecontent> block. Below that block I use a <cfmail> tag that has the value of the <cfsavecontent> as the emailbody. So trhe email gets sent from a view. Rather kludgy but it works.

Now I want to send e-mails from within a loop, that is in a controller. The previous method is not usable here. Is the following possible:

within every the loop iteration
set text in the event scope - event.setvalue("text",<emailtext>);
render a view (or multiple views in case of layouts) The views access the keys set in the loop;
use that rendered html as the body of the <cfmail> tag

So I can send multiple emails from within the controller, just have to specify a special email layout.

I hope this is clear.

Most likely this is possible but I can't find examples or entries in the howto that describe this.

Thanks,

Marc

Dan Wilson

unread,
Mar 28, 2012, 12:51:02 PM3/28/12
to model...@googlegroups.com
Hmm.. this is an interesting use case. The ModelGlue framework handles everything in a Post/Response manner, meaning the output of the request fills the buffer with content to go back to the client.

What you are trying to do is use the views of Model Glue in a way in which they were not intended. Sure you could do this in a service, but I'm assuming there is some value to using the results to add the right content to the view.

I'm not in a position to work up a model for how to do this, but if you are sure this is what you want to do, you may consider using some of the view methods on the EventContext (Event) object.

Look at:

getView
AddView
renderView
getViewCollection  

I'm sure you can piece these together to do something programmatic for your use case. Please report back your findings or any questions you have.


DW



--
Model-Glue Sites:
Home Page: http://www.model-glue.com
Documentation: http://docs.model-glue.com
Bug Tracker: http://bugs.model-glue.com
Blog: http://www.model-glue.com/blog
 
You received this message because you are subscribed to the Google
Groups "model-glue" group.
To post to this group, send email to model...@googlegroups.com
To unsubscribe from this group, send email to
model-glue+...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/model-glue?hl=en



--
Plutarch - "The mind is not a vessel to be filled but a fire to be kindled."

Nando

unread,
Apr 3, 2012, 4:15:56 AM4/3/12
to model...@googlegroups.com
In this case, I simply render the view in an EmailService component - yes, within a method called renderEmail.
Nando M. Breiter
The CarbonZero Project
CP 234
6934 Bioggio
Switzerland

+41 91 606 6372

na...@carbonzero.ch
www.carbonzero.ch

Chris Blackwell

unread,
Apr 14, 2012, 10:36:11 AM4/14/12
to model...@googlegroups.com
Hi Marc,

I'm a little late to this but thought i'd share my solution in case its of any help.

First, I create a component that extends ModelGlue's event context to provide a renderTemplate method.

component extends="ModelGlue.gesture.eventrequest.EventContext" {
/**
* renders a view template and returns its html, 
* template: the view template to render 
* values: struct of values passed to the view, in addition to the eventcontext
* name: if provided the output will be added to the viewcollection
*/
function renderTemplate(template, values={}, name="") {
   var view = new ModelGlue.gesture.eventhandler.View();
view.template = arguments.template;
for(var key in values) {
var value = new ModelGlue.gesture.eventhandler.Value();
value.name = key;
value.value = values[key];
view.addValue(value);
var content = variables._viewRenderer.renderView(this, view, variables._helpers);
if(len(name)) {
this.getViewCollection().addRenderedView(name, content);
return content;
}
}

Then tell ModelGlue to use your component using a little bit of config in your apps ColdSpring.xml

<bean id="modelglue.eventContextFactory" class="ModelGlue.gesture.eventrequest.EventContextFactory">
<property name="modelGlue"><ref bean="modelglue.ModelGlue"/></property>
<property name="statePersister"><ref bean="modelglue.statePersister"/></property>
<property name="viewRenderer"><ref bean="modelglue.viewRenderer"/></property>
<property name="beanPopulator"><ref bean="modelglue.beanPopulator"/></property>
<property name="logWriter"><ref bean="modelglue.logWriter"/></property>
<property name="objectPath"><value>com.myapp.MyEventContext</value></property>
</bean>

Replacing com.myapp.MyEventContext with the path to your new component.

Then in your controller you can call renderTemplate, heres a contrived example.

function sendSomeEmails(event) {
  var users = beans.userservice.getSomeUsersAsArray();
  for(var user in users) {
    var html = event.renderTemplate("emails/some_notification.cfm", {user=user});
    beans.emailservice.send(body=html, to=user.getEMail());
  }
}

I've found this to be a useful solution allowing you to reuse views for emails
Cheers, Chris


--
Reply all
Reply to author
Forward
0 new messages