Viewlet Overrides Layout

47 views
Skip to first unread message

Laksma

unread,
Nov 7, 2014, 9:52:07 PM11/7/14
to col...@googlegroups.com
Could someone help me with viewlets? I was trying to implement a viewlet on my ColdBox-based app. Basically, I followed the steps explained on http://wiki.coldbox.org/wiki/Layouts-Views.cfm#Viewlets_(Portable_Events). When I ran it, the existing layout that calls the viewlet was not displayed. Instead, it got replaced by the viewlet.

Enviroment:
  • Windows 7 Professional
  • Railo 4.2.1
  • ColdBox 3.8.1

Code:
/handlers/viewlets.cfc
component {
 
function home(event, rc, prc) {
   
event.setView("viewlets/home");
 
}

 
function userinfo(event, rc, prc) {
   prc
.data.username = "jsmith";
   
return renderView("viewlets/userinfo");
 
}
}


/views/viewlets/home.cfm
<cfoutput>#runEvent("viewlets.userinfo")#</cfoutput>


/views/viewlets/userinfo.cfm
<cfoutput>
 
<div>Username: #prc.data.username#</div>
</cfoutput>


/layouts/main.cfm
<html>
<head></head>
<body>
 
<div>I am Layout.</div>
 
<div><cfoutput>#renderView()#</cfoutput></div>
</body>
</html>


The way I called: http://test/index.cfm?event=viewlets.home and it redirected to http://test/index.cfm?event=viewlets.userinfo. Is this behavior correct? And, how to make the viewlet displayed inside the existing layout? Thank you.





Andrew Scott

unread,
Nov 7, 2014, 10:22:57 PM11/7/14
to col...@googlegroups.com
Viewlets CAN NOT be called on other event handlers like this, because it will use that view instead.

If you want to provide logic to a viewlet you will need to use a handler that doesn't override the view itself, in other words you're doing it wrong!!


Regards,
Andrew Scott
WebSite: http://www.andyscott.id.au/


--
--
You received this message because you are subscribed to the Google Groups "ColdBox Platform" group.
For News, visit http://blog.coldbox.org
For Documentation, visit http://wiki.coldbox.org
For Bug Reports, visit https://ortussolutions.atlassian.net/browse/COLDBOX
---
You received this message because you are subscribed to the Google Groups "ColdBox Platform" group.
To unsubscribe from this group and stop receiving emails from it, send an email to coldbox+u...@googlegroups.com.
To post to this group, send email to col...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Laksma

unread,
Nov 8, 2014, 3:53:45 AM11/8/14
to col...@googlegroups.com
I am lost. Here's another attempt from what I understand based on http://wiki.coldbox.org/wiki/Layouts-Views.cfm#Viewlets_(Portable_Events).

/handlers/main.cfc
component {
 
function index(event, rc, prc) {
   prc
.message = "Welcome!";
 
}
}

/handlers/viewlets.cfc
component {
 
function userinfo(event, rc, prc) {
   prc
.username = "jsmith";
   
return renderView(view="viewlets/userinfo");
 
}
}

/views/main/index.cfm
I am main.index view. <cfoutput>#prc.message#</cfoutput>

/views/viewlets/userinfo.cfm
Your username is <cfoutput>#prc.username#</cfoutput>.

/layouts/main.cfm
<html>
<head>
 
<title>main layout</title>
</head>
<body>
<cfoutput>
 
<div>#renderView()#</div>
 
<div>#runEvent("viewlets.userinfo")#</div>
</cfoutput>
</body>
</html>

What am I missing? A sample working code to demonstrate viewlets would be helpful. Thank you.


Andrew Scott

unread,
Nov 8, 2014, 5:39:20 AM11/8/14
to col...@googlegroups.com
This part

<div>#runEvent("viewlets.userinfo")#</div>

and this part

component {
 
function userinfo(event, rc, prc) {
   prc
.username = "jsmith";
   
return renderView(view="viewlets/userinfo");
 
}
}

When you call a handler with runEvent() and use event.setView or renderView() you can end up with views that you don't want.

If you want to do something like this, create an API that is only accessible to anything that isn't going to set a view, then refactor your code to do something like this.

component {
 
function userinfo(event, rc, prc) {

   wrapperToGetUserInfo();
   return renderView(view="viewlets/userinfo");
 
}

 function wrapperToGetUserInfo(event, rc, prc) {

   prc.userinfo = wrapperToGetUserInfo();
 }
}

Then in your viewlett

<div>#runEvent("viewlets.wrapperToGetUserInfo")#</div>

Notice how I have refactored the event handler to remove the renderview()!!!


Regards,
Andrew Scott
WebSite: http://www.andyscott.id.au/


Andrew Scott

unread,
Nov 8, 2014, 5:43:31 AM11/8/14
to col...@googlegroups.com
Also it might help to think of viewletts like widgets, no matter what the widgte becomes the container and then they do Ajax calls to get the data they need, viewletts are the same they already contain the view all they need now is to retrieve the data, either via models or other events.

It is also maybe good practice to refactor your code in this manner, especially if you plan to support Restful or other RPC type calls, that would allow you to keep your code duplication to a state of zero duplication.




Regards,
Andrew Scott
WebSite: http://www.andyscott.id.au/


Laksma

unread,
Nov 9, 2014, 7:45:28 PM11/9/14
to col...@googlegroups.com
Andrew, thanks for answering my questions and giving some advanced techniques. Would you mind take a look viewlets description on http://wiki.coldbox.org/wiki/Layouts-Views.cfm#Viewlets_(Portable_Events)? It seems pretty straight forward, but I couldn't make the sample code work as I posted on https://groups.google.com/d/msg/coldbox/fow9lYo_cM4/Hp7Dld2Rn1EJ. Thanks again!

Andrew Scott

unread,
Nov 9, 2014, 8:05:11 PM11/9/14
to col...@googlegroups.com
You know, I can't actually see anything wrong with that!

Luis, Brad & Joel might need to pipe in here. My guess something has changed since the docs where written, could you tell us what version of ColdBox you're using?

Regards,
Andrew Scott
WebSite: http://www.andyscott.id.au/


On Mon, Nov 10, 2014 at 11:45 AM, Laksma <lak...@gmail.com> wrote:
Andrew, thanks for answering my questions and giving some advanced techniques. Would you mind take a look viewlets description on http://wiki.coldbox.org/wiki/Layouts-Views.cfm#Viewlets_(Portable_Events)? It seems pretty straight forward, but I couldn't make the sample code work as I posted on https://groups.google.com/d/msg/coldbox/fow9lYo_cM4/Hp7Dld2Rn1EJ. Thanks again!

--

Laksma

unread,
Nov 9, 2014, 8:23:45 PM11/9/14
to col...@googlegroups.com
I am running ColdBox 3.8.1 on Railo 4.2.1.
Would you make your solution on https://groups.google.com/d/msg/coldbox/fow9lYo_cM4/jYpRDPGYD7EJ a bit clear? The wrapper looks like a recursive to me. :)

Andrew Scott

unread,
Nov 9, 2014, 10:34:00 PM11/9/14
to col...@googlegroups.com
There is no recursive going on there, all I am doing is this for the real event handler.

 function userinfo(event, rc, prc) {

   wrapperToGetUserInfo();
   return renderView(view="viewlets/userinfo");
 
}

All I have done, is remove the code that is going to be duplicated to a separate method/function and called it in the handler above. Then the method looks like this, it is bare bones but has enough to understand it.

 function wrapperToGetUserInfo(event, rc, prc) {
   prc.userinfo = wrapperToGetUserInfo();
 }

​Then in the view you do this.​

<div>#runEvent("viewlets.wrapperToGetUserInfo")#</div>

Now as this calls the new function, it removes the need to run all that other code if you don't need it to be included, this is usually the case for RPC type calls, where all you want to do is return json or the data in another format. There might be other security things you may want to wrap it up in etc., so therefore by removing the user info from the handler it is able to be re-used.

However having said that, if you plan to use a service to return that information, it might be neither here nor there if you go down that route.

But there is certainly no recursion going on there, what part makes you thin that?

As for your original issue, I believe it should work as that is what is mean for the nature of viewlets. So what I would do is turn on the logger, set it up if you haven't and begin placing logs in the places to log certain expected information. Then compare the logs with what you truly should be expecting, even the work flow execution.

I can't stress enough, how important switching the logger on is. It will show what the actual issue might end up being, it could be as simple as a configuration is wrong and its doing what you tell it. But without logging that information, you looking for a needle in a hay stack for the cause.


Regards,
Andrew Scott
WebSite: http://www.andyscott.id.au/

On Mon, Nov 10, 2014 at 12:23 PM, Laksma <lak...@gmail.com> wrote:
I am running ColdBox 3.8.1 on Railo 4.2.1.
Would you make your solution on https://groups.google.com/d/msg/coldbox/fow9lYo_cM4/jYpRDPGYD7EJ a bit clear? The wrapper looks like a recursive to me. :)

--

Brad Wood

unread,
Nov 10, 2014, 11:20:25 AM11/10/14
to col...@googlegroups.com
You might need to share your code.  I just tried the exact code sample that's in our docs and it worked perfectly.  There is nothing wrong with it.

I posted my sample app on GitHub and ForgeBox so you can easily try it out.  Install CommandBox if you are not already using it ( http://www.ortussolutions.com/#download )

Run the following commands from the interactive shell to download and and install my viewlet sample app and run it on your local machine (no web or CF server setup is necessary)

ComandBox> mkdir testsite
ComandBox> cd testsite
ComandBox> install coldbox-viewlet-sample
ComandBox> start

Let me know if you have more questions.  

Thanks!

~Brad

Laksma

unread,
Nov 10, 2014, 1:55:51 PM11/10/14
to col...@googlegroups.com
Brad,

Thanks for the complete viewlet sample code. When I compared mine with yours, the only difference is you use composition in the bootstrapper; and mine used inheritance. So, the viewlet is working properly on with composition, but not with inheritance.

Anyway, thanks again everyone for helping me!

br...@bradwood.com

unread,
Nov 10, 2014, 2:47:58 PM11/10/14
to col...@googlegroups.com
Hi Laksma, that shouldn't make any difference at all.  In fact, I just tested it using inheritance and my example site still runs fine.  You can do it yourself.  Just edit the Application.cfc and replace the contents of the entire file with this text:
 
component extends='coldbox.system.Coldbox' { }
 
If you code is behaving differently, there must be something else different with your code.  Perhaps, you can create a sample application of your own that exhibits this behavior so we can see it.

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

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

Laksma

unread,
Nov 10, 2014, 6:58:57 PM11/10/14
to col...@googlegroups.com
Brad,

I was able to narrow down the problem. My bootstrapper extends from:

component extends='coldbox.system.mvc.Bootstrap' { }

I got this from /ApplicationTemplates/lite/Application.cfc (inheritance version).

br...@bradwood.com

unread,
Nov 10, 2014, 8:57:14 PM11/10/14
to col...@googlegroups.com
Ahh, you're on ColdBox Lite-- that makes sense.  Your behavior definitely seems like a bug, but to be honest ColdBox Lite has now gone away since ColdBox 4.0 is the new stripped-down core and everything has been extracted into modules.  If I were you, I would just change the bootstrap over to use the full ColdBox framework.  
 
Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: br...@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com 
 
 
--------- Original Message ---------
Subject: Re: [coldbox:22760] Re: Viewlet Overrides Layout
From: "Laksma" <lak...@gmail.com>
--
Reply all
Reply to author
Forward
0 new messages