HomePortals/ColdBox Integration Revisited

A while ago I wrote a post about how to integrate the HomePortals layout rendering features into an a ColdBox application. Since then a lot has changed on both the HomePortals and ColdBox camps so I've been wanting to revisit that experiment and see if it could be made in an easier way now, using the advances on both frameworks. Read on for the findings.

[More]

BugLog Update and News

I wanted to share a couple of news about the BugLog project.

First if you are using ColdBox, Tom Demanincor wrote a very nice tutorial on how to integrate bugLog as a ColdBox plugin. Check out his blog post here, it is very detailed and shows the code needed to make it work.

Also he raised an interesting point if you are modifying buglog to use per-application mappings. The BugLog distribution contains basically two independent applications. The main one is the server/listener part, which is the part that receives the bug reports from the applications. This is on the main bugLog directory and has its own Application.cfc. This application does not have a user interface.

The second application is the HQ application, which is the part that has the user interface and is where you get redirected if you just go to /bugLog in your browser. This is where you can see the bug reports and look at the pretty charts. This one also has its own Application.cfc and is located in /bugLog/HQ

So if you are defining per-application mappings programmatically on the Application.cfc don't forget that you need to set them up on both Application.cfc files otherwise you gonna find some weird errors.

Additionally a couple of people in the community reported a few minor bugs that needed to be corrected. The first one dealing with some component references not being created with the full path to the CFC and resulting in some errors. And the second one was that sending of bug reports via email was not working due to a missing setting.

To enable emailing a bug report that has been received you need to edit the /buglog/hq/config/config.xml.cfm file and set the contactEmail setting to the email address you wish to use as the sender.

I have updated the project in RiaForge with these fixes, so you can get the latest release from there. Here is the link.

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:

<?xml version="1.0" encoding="UTF-8"?>
<homePortals>
   <appRoot>/hpcoldbox/</appRoot>
   <accountsRoot>/hpcoldbox/accounts/</accountsRoot>
</homePortals>

accounts-config.xml.cfm

<?xml version="1.0" encoding="UTF-8"?>
<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:

<?xml version="1.0" encoding="UTF-8"?>
<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:

<cfinclude template="/Home/Common/Templates/gateway.cfm">

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

<cffunction name="onAppInit" access="public" returntype="void" output="false">
   <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

<cfcomponent name="general" extends="coldbox.system.eventhandler" output="false">
   <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:

<cfoutput>#renderView()#</cfoutput>

The last piece was updating the view (views/home.cfm) in the same way.

<cfset html = Event.getValue("html")>
<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!

Colbox 2.5 New Features

My good friend Luis Majano has published an article listing all the features of the upcoming new version of his open-source framework ColdBox, and I just have to say that this stuff is IMPRESSIVE. Whatever your preferences regarding frameworks and architecture are, you have to give it to Luis, this is TOP LEVEL software engineering. I guess I'd say my favorite new features are the Interceptors and the Air/Flex Proxy.

Here is the link to the full document: http://ortus.svnrepository.com/coldbox/trac.cgi/wiki/cbWhatsNew2.50

BlogCFC was created by Raymond Camden. This blog is running version 5.9. Contact Blog Owner