Using HomePortals and ColdBox Together
This afternoon I have been experimenting with a somewhat interesting and funky idea: mixing the layout rendering engine of HomePortals with a full application framework like ColdBox.
Why? Because integrating these two engines would allow developers to create applications that can benefit from the modularity provided by HomePortals on the front end and at the same time enjoy all the swiss-army knife functionality provided by ColdBox, in particular the rich control over the lifecycle of the requests and the application.
For example, this could be great for developing dashboards or BI applications. HomePortals would make it easy to create a modular interface based on small widgets or pods, and ColdBox could handle the overall application structure and tasks (security, persistence, logging, etc).
In theory it sounded possible, so I just went ahead and see what I could get. Well, at the end I found that the two worked beautifully together.
I do not have yet a full working application that I can share, so for the time being this is just "proof-of-concept" type of stuff.
Here is what I did.
** For this I used ColdBox 2.5.2 and HomePortals 3.0.189, which are the current releases for both projects.
First I created a new coldbox application using the "ApplicationTemplate" found on the standard ColdBox distro. I named the new application "hpcoldbox" and put it on a directory under my web root so I could get to it by going to: http://localhost/hpcoldbox
The first part was setting up the HomePortals side, which was basically just modifying the newly created application to look like a HomePortals site and then writing a sample page to display. Let me describe this step by step.
Within the "config" directory I added the two main HomePortals configuration files: homePortals-config.xml and accounts-config.xml.cfm
homePortals-config.xml:
<homePortals>
<appRoot>/hpcoldbox/</appRoot>
<accountsRoot>/hpcoldbox/accounts/</accountsRoot>
</homePortals>
accounts-config.xml.cfm
<homePortalsAccounts version="1.0">
<!-- Root directory for account directories -->
<accountsRoot>/hpcoldbox/accounts/</accountsRoot>
<!-- storage type -->
<storageType>xml</storageType>
<storageFileHREF>/hpcoldbox/accounts/accounts.xml</storageFileHREF>
</homePortalsAccounts>
Those files provide a very basic configuration for HomePortals. The first one just states where the application is located and where will the account files be stored. The second one just expands a bit on some details about how we are going to store the account data.
Next I needed to create an account an a sample page. For that, under the root of the new application, I created a new directory named "accounts", with the following internal structure:

To make things easier I just copied the accounts.xml and site.xml from /Home/Accounts/accounts.xml and /Home/Accounts/default/site.xml since I was using pretty much a default setup.
For default.xml, which is our sample page, I used the following code:
<Page access="general" owner="default">
<title>HP+ColdBox</title>
<stylesheet href="/Home/resourceLibrary/Pagetemplates/layouts/layoutTemplates.css"/>
<skin id="boxy"/>
<layout>
<location class="column_small" id="h_location_column_2" name="left" type="column"/>
<location class="column" id="h_location_column_3" name="middle" type="column"/>
<location class="column_small" id="h_location_column_4" name="right" type="column"/>
</layout>
<modules>
<module displayMode="short" id="rssReader1" location="left" maxItems="10" name="RSSReader/RSSReader"
rss="http://www.coldfusionbloggers.org/rss.cfm" />
<module id="FlickrFeed1" location="middle" maxItems="10" name="flickrFeed/flickrFeed"
onClickGotoFlickr="true" showheader="true" tags="coldfusion" title="FlickrFeed1"/>
<module displayMode="short" id="rssReader2" location="right" maxItems="10" name="RSSReader/RSSReader"
rss="http://digg.com/rss/index.xml" title="Digg"/>
</modules>
</Page>
Nothing fancy, just display a couple of feeds and a flicker photo stream.
Finally I had to create a template to allow HomePortals modules to talk back to HomePortals in an asynchronous way. So I created a file named gateway.cfm in the root of the application with the following contents:
That was it for the HomePortals side. The next part was doing the ColdBox part.
HomePortals works basically as an API, that means that everything is object-based, so the crucial part is to have an instance of the HomePortals main object, which is Home.components.homePortals. The best practice is to instantiate it as a singleton and just leave it on the application scope. Since we need to do this only once for the lifetime of the application, I added the following code to /hpcoldbox/handlers/main.cfc
<cfargument name="Event" type="coldbox.system.beans.requestContext">
<!--- ON Application Start Here --->
<cfset application.homePortals = createObject("component","Home.components.homePortals").init("/hpcoldbox/")>
</cffunction>
I know ColdBox offers more options for these kind of things but for the purpose of the experiment this seemed like the quickest way to get up and running.
Then, I modified the default event (general.dspHome) in /hpcoldbox/handlers/general.cfc
<cfsetting enablecfoutputonly="false">
<cffunction name="dspHome" access="public" returntype="void" output="false">
<cfargument name="Event" type="coldbox.system.beans.requestContext">
<cfset var account = "default">
<cfset var page = "default">
<cfset var oPageRenderer = application.homePortals.loadPage(account, page)>
<cfset var html = oPageRenderer.renderPage()>
<cfset Event.setValue("html", html)>
<!--- Set the View To Display, after Logic --->
<cfset Event.setView("home")>
</cffunction>
</cfcomponent>
What this code does is get the homePortals instance and load the page named "default" on the account named "default". After the page has been loaded and parsed internally, it then asks for the rendered HTML corresponding to that page. Then we set that returned html content into a variable named "html" in the request collection. Finally we set the view to render.
Notice also the <cfsetting> tag that I had to add on top. This was needed because it seems that coldbox internally has it set to true and that affected the rendering of some parts of the output in HomePortals.
Next I modified the default layout file (/hpcoldbox/layouts/Layout.Main.cfm) to just limit itself to render the view. I did this because the output of the HomePortals rendering is already a full HTML document. However, you can modify your HomePortals settings to only a partial HTML page and use ColdBox layouts to handle the page's HTML structure.
This is what my Layout.Main.cfm looked like:
The last piece was updating the view (views/home.cfm) in the same way.
<cfoutput>#html#</cfoutput>
And that was it, when I went into my browser and fired up the application, the HomePortals page was rendered perfectly.
Again, this is a very simple proof-of-concept but I trust that if you are familiar with ColdBox you can see how this fully integrates into the application. You could have some pages rendered normally and some pages rendered with HomePortals; and thats without even going into further integration within custom HomePortals modules that you could write that could take advantage of the coldboxproxy to make even more interesting things.
I am really excited to have been able to find this out, as I said at the beginning, because I think it opens the door to very interesting opportunities. It would also be interesting to see if HomePortals can also be integrated in the same manner with Model-Glue, MachI, Fusebox, or other full application frameworks; however my practical knowledge of those is even less than what I know about ColdBox, so if anyone is willing to give it a try I'd love to hear how it went.
Thats it for now,
Happy coding!