[coldbox-3.7.1] onRequestEnd not working and legacy views

I am converting an older site to Coldbox and I am trying to cleanup the Application.cfc, to have as little as possible.
So I have been moving all the methods into my main.cfc, and have coldbox handle all the onAppInit, onRequestStart etc.

So far it has been working out alright, except for onRequestEnd.
When I move my onRequestEnd to main.cfc, the debug info shows that it ran, however, I get no output on the browser.
However, when I remove “main.onRequestEnd” from Coldbox.cfc, and move the method out to my Application.cfc, it works as it did on the legacy site without any problems.

That was part 1.

Second part of my question has to do with the legacy site conversion.

I am converting a huge legacy site and want to keep all the legacy files in a directory outside of views, so that there is no mixing of code and files between coldbox/mvc style coding and the old legacy coding.
However, I want to be able to leverage the functionality in Coldbox, where I don’t have to specify handlers for my old legacy files.

Is there an external view mapping I can add somewhere in Coldbox.cfc?

And by doing so can Coldbox by convention, know which view to render?

What I mean is for existing files without handlers I can call
index.cfm/aboutus/contact
for a file in
/views
/aboutus
contact.cfm

In addition to that I want a mapped location like
/LegacyAppName (this would be like an external view location)
/products
listing.cfm

I want to be able to call that like index.cfm/products/listing

Is Coldbox able to handle both?

I want the external view so that legacy files can remain as-is, until we get the time/budget to convert them over. However, I still want the coldbox configurations etc to run first, since there are global settings and certain interceptors that need to run, even before the legacy files get hit, so they can continue to access certain methods etc.

Thanks in advance,
cbfan

Short answer, I don’t think so.

The onRequestEnd in ColdBox, from what I can recall is actually run outside of the rendering of views and layouts. This would be a difficult task to do in ColdBox.

Your best bet, is to look into interceptors like postRequest or postEvent etc.

You could probably do the legacy stuff within onMissingEvent handler…

Sorry, onInvalidEvent (MONDAY!)

Hi cbfan,

Unfortunately, you cannot directly output to the page from inside of event handler code. The technical reason is because the Controller.runEvent() and Controller.invoker() methods inside the framework have output=false which kills anything you try to output. The more theoretical reason why output is not allowed from a handler (controller) is because ColdBox is an MVC framework and output should be defined in views.

There are many ways to include output at the end of a request. Please share what kind of code you are needing to output and we will help you. An interception point like preRender may help you here.

> Is there an external view mapping I can add somewhere in Coldbox.cfc?

Yes! It’s called viewsExternalLocation and you can set it to an external folder of views. It will be checked if the view doesn’t exist in the normal “views” convention folder. I just spent way too long playing with it, and here’s some interesting behaviors I found for you to keep in mind.

  • If you have the SES interceptor enabled, implicit view dispatch doesn’t work for views in the root of your views folder. I think this is a bug so I entered COLDBOX-245
  • The viewsExternalLocation setting actually defaults to “”, which means it searches your web root for views. I’m not entirely sure that’s intended, but works
    There is another way to route legacy files through ColdBox which can also work around my first bullet point. That is to simply create routes in your /config/routes.cfm file for whatever pages you want (Works with any external view). Imagine you had a file called “legacy.cfm” in your web root. Add this line to routes.cfm:

addRoute(pattern=“legacy”, view=“legacy”);

And hit the following URL:

example.com/index.cfm/legacy

of course, with a rewrite engine installed on Apache/IIS, it could be reduced to this:

example.com/legacy

Of course, once you use the route approach-- the route can be anything

addRoute(pattern=“foobar”, view=“legacy”);

will run your legacy.cfm file when you hit this URL:

example.com/foobar

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

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

Brad,

Thanks again!
Actually it was working without me knowing why or how.
But after your explanation, I understand completely.
So I had my legacy folder, and Coldbox was finding the files, but it’s due to what you said, if you leave the externalview mapping blank.

Quick question… If I add a specific mapping such as viewsExternalLocation="/legacy" does Coldbox still search the entire webroot, or just the specific location?
The reason for me asking, was I figured it might speed things up a bit if there’s an explicit reference, rather than just spidering the entire webroot.

So Brad, I have another question, which might merit its own topic now.
I’m having issues with URL rewriting.

Currently the rewrite is index.cfm/handler/event.
I’m running IIS7 and have written a rule to convert legacy urls as such
any path that’s not index.cfm gets rewritten to index.cfm/r0/r1

This is fine and all, but I’d like my coldbox URLs to be http://domainRoot/handler/event?queryString
How can I have IIS take out the index.cfm, but my app.cfc and coldbox app to still recognize that the script_name is still index.cfm even though it’s been removed from the URL.

Thanks,
cbfan

Right now you can only have one external view location. There is, however, a ticket in to allow it to be an array of locations:
https://ortussolutions.atlassian.net/browse/COLDBOX-29

Also, it’s worth noting, ColdBox doesn’t “spider” the views location-- there’s no recursive search or anything. You are required to reference the partial path to the view starting in the root of the view location. So if you have a folder called “products” and a file in that folder called “widget.cfm”, you cannot to renderView(“widget”) but you CAN do renderView(“products/widget”). It’s all relative to the root of the views location.

Regarding rewrites-- I’m confused-- is IIS taking out or adding in the index cfm? Remember, ColdFusion doesn’t see the URL in your browser-- it sees the URL that IIS hands it after the rewrites have been processed. Dump your CGI scope to confirm exactly what ColdFusion is seeing.

Here is documentation on the rewrite rules we recommend for ColdBox SES:
http://wiki.coldbox.org/wiki/URLMappings.cfm

Also regarding your desired URL structure of
http://domainRoot/handler/event?key=value

That will work, but the default SES format is like so:
http://domainRoot/handler/event/key/value

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

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

Brad,

For testing purposes, I have disabled whatever URL rewriting I had on IIS.
I followed the wiki instructions and have implemented the IIS7 rewriting rules as suggested.

So my company’s intranet app is a framed app, and each link opens in a frame.

Using the suggested rewrite rules from the wiki, the following link works:
Link A: http://BaseURL/index.cfm/templates/iconnav?module=eLearning&true

However I was hoping that the following URL would work:
Link B: http://BaseURL/templates/iconnav?module=eLearning&true

How can I get Link B to work? That’s my main question.
What it does is redirect to the default handler.

My routes.cfm only has this in it so far:

// Allow unique URL or combination of URLs, we recommend both enabled
setUniqueURLS(false);

// Base URL

if( len(getSetting(‘AppMapping’) ) lte 1){
setBaseURL(“http://#cgi.HTTP_HOST#/index.cfm”);
}
else{
setBaseURL(“http://#cgi.HTTP_HOST#/#getSetting(‘AppMapping’)#/index.cfm”);
}

// Your Application Routes
addRoute(pattern=":handler/:action?");
Best regards,
cbfan

If you are wanting ColdBox to generate all links (event.buildLink(), setNextEvent()) without the index.cfm, you will want to remove all occurrences of “index.cfm” from your routes.cfm file.

Now, as far as why your URL isn’t working-- I’m not sure. Can you dump the CGI scope out in Application.cfc to intercept the request and see exactly how it’s being passed from IIS to CF? I’m not as familiar with configuring IIS for rewrites as I usually use Apache.

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

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

Brad,

Thanks again for the suggestions. I haven’t tried them yet.

Meanwhile I had a sidebar question regarding implicit view rendering, for my employer’s legacy code.

Currently it’s working well. Where things tend to breakdown is when I have multiple subfolder levels within my legacy directory.

So let’s say I have an externalViewLocation of /legacy.
under there I have an /admin folder, which has things in the root of the folder, as well as subdirectories.

so like
/admin
adminHome.cfm
reloadTags.cfm
manageRelease.cfm
/security
/settings
/promotions
/contactus

I want to be able to call http://domainURL/index.cfm/admin/reloadTags - and run the legacy views on the top level implicitly.
As well as: http://domainURL/index.cfm/admin/security/someSecurityScript.cfm

What I have found is that if I have a blank admin folder in my handlers directory. Then the files in the subdirectories of admin, run implicitly.
However the files right under the root of /admin, don’t run. For example the url: index.cfm/admin/adminHome throws the error

Application Execution ExceptionError Type: HandlerService.EventHandlerNotRegisteredException : [N/A]

Error Messages: The event: admin.adminHome.index is not valid registered event.

Please help, since the viability of implementing coldbox at my company depends on the legacy files being able to run as is, for the moment. Which means that views in multiple folder levels still need to be able to run, without explicitly defining handlers for each of them.

Thanks,
cbfan

Based on a quick local test I just did, that behavior is fixed by this ticket:

https://ortussolutions.atlassian.net/browse/COLDBOX-245

You can:

  1. Wait for the next version of ColdBox to come out
  2. Download the development branch from GitHub
  3. Look at the commit and make the same local change to your ColdBox install

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

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

I just saw that Luis snuck out ColdBox 3.8.1 last night.
http://blog.coldbox.org/blog/coldbox-platform-v381-released

Update to our latest release and see if that fixes your issues.

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

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

Brad,

I have upgrade to version 3.8.1, and the multiple subdirectories are not working via implicit handler/view rendering.
This url is still failing for me: index.cfm/admin/Settings/listAllSettings

I’m still getting the error
The event: admin.Settings is not valid registered event.

However, the following url works:
index.cfm?event=admin.settings.listallSettings

We have several fortune 500 clients, that have legacy code with multiple levels of subdirectories. I cannot afford to switch them all over to the event=dir.subdir.filename url’s
We were relying on the friendly urls working at least with the index.cfm/dir1/dir2/filename.

Is there some kind of workaround you can think of to help me in this situation?
This is very critical to my business, so all your assistance is greatly appreciated.

cheers,
cbfan

That setup works for me on ColdBox 3.8.1. I have /views/admin/settings/listSettings.cfm and an empty “admin” folder in my “handlers” directory.

I hit this URL: /index.cfm/admin/settings/listSettings and it renders the view.

There must be more variables at play in your setup.

Also, we understand the importance of you getting this to work. You don’t need to remind us in every E-mail :slight_smile:

Don’t forget, if this doesn’t work, you always have the method of creating routes for each of your legacy pages. It might be more work for you but it’s easier for ColdBox to figure out and let’s you have more control over the URL.

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

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

Brad,

I’m sorry I misspoke, I think I just needed to give my server 3 swift kicks in the backside to realize it’s using a new[er] version of coldbox.
Thanks!!!

I think I posted that response to soon.

In an earlier response you mentioned an array of locations for external views. Do you have any idea on an ETA for that?

Once I have some more time I will test and check the url rewriting issue I spoke of earlier.
The path_info seems to be fine, however I think my IIS rule, is set to do a redirect of anything NOT prefixed with index.cfm, So like /admin/reloadSettings.cfm, gets an IIS redirect to index.cfm/admin/reloadSettings.

I did that because I could not figure any other way to make the server understand that I want this to be a coldbox request.

Do you think I should change that redirect to be like: anydirectory/anyfile.cfm to be redirected to anydirectory/anyfile ?

If I do that I am wondering, will this line work in Application.cfc? <cfif findNoCase(‘index.cfm’, listLast(arguments.targetPage, ‘/’))> to process it as a ColdBox request?

Thanks again for all the help.

Cheers,
cbfan

Brad,

So I dumped the CGI scope from Application.cfc

I’m entering a url, that should use implicit view rendering to display a legacy page: http://myAppURL/templates/iconnav
If I enter: http://myAppURL/index.cfm/templates/iconnav OR http://myAppURL/index.cfm?event=templates.iconnav then it’s fine.

However, the url http://myAppURL/templates/iconnav does not work.
Path_Info and Query_String are both blank.

There is another post on this forum, where a user “dehian”, I believe ran into similar issues, but used the same rewrite rules as displayed on the CB wiki.
I entered the same exact rules, and it doesn’t seem to work.

I have entered rules for media files, and for CFIDE, etc, and those all work fine.

Any help is appreciated:
CBFAN

Could this be another example to re-connect the connectors because of a CF update?

Hi Andrew,

Can you please elaborate?
I recently installed CF10 last month, and have not applied any updates.

Do I still need to re-connect the connectors?

Thanks,
cbfan

I would begin with the updates first, as there was an issue with CGI and was fixed in Update 1, any update that says please update the connectors means that you need to run the Web Configuration Tool.

So yes, I would be updating before coming back with any issues you are having. The amount of people who mention problems with CF 10 and the CGI either has not updated CF or has not updated the connectors correctly.

Hope that helps.

Agree with Andrew. Before you try anything else, update CF10 to the latest update and then use the webserver configuration tool to update the IIS connectors. You wouldn’t believe how many times that has fixed people’s problems.

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

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