Some questions starting with Coldbox

Hi cbUsers!

For a new project, I started using Coldbox (v. 6.6.1) intensively. I have a few questions to ask:

#1

Oops! Seems ColdBox is still not ready to serve requests, please try again.

Using a suggest (or press F5 F5 F5…), I noticed that - every now and then - Coldbox returns this error. I don’t restart Coldbox on every request, but my environment is “development”.
I guess it depends on this.

#2

post( "/login/do" )
    .toHandler( "AuthController.doLogin" );

get( "/login" )
    .toHandler( "AuthController.login" );

In Router, I have to write the entries in this order.
Because looking for “/login/do” in the url, the “/login” event fires before “/login/do”.

Is that correct or am I doing something wrong?

#3
I tried to render an external view in a controller, but if I write like this (with extension):

renderExternalView("/apps/utils/404.cfm") 

but i get this error:

ROOT\apps\utils\404.cfm.cfm] not found

without extension I get:

ROOT\apps\manager\views[method-not-found].cfm not found

the file with the same name as the method in the url is loaded.

Can’t I use renderExternalView() in a controller, but only in the view?
I’m trying to use this method in my param “invalidEventHandler” function.

#4
I found that I can write:

event.setView( "firstDir/secondDir/myFile" );

Is it a bug or a features? (I have never found any such example) :sweat_smile:
This allows me to organize my code much better.

#5
this code:

event.setView( view="main/login", layout="login" )

gets this error:

ROOT\apps\manager\views\AuthController\login.cfm] not found

… same for (chaining + inline):

event.setView( view="main/login" ).setLayout( "login" );

It works if i use chaining:

event.setView( "main/login" ).setLayout( "login" );

Same for:

event.setView( view="main/login", noLayout=true );

ROOT\apps\manager\views\AuthController\login.cfm] not found

I must write:

event.setView( "main/login" ).noLayout();

Likewise I can’t use any other event arguments (like args, cache …)
I guess I’m doing something wrong …

#6
I can’t use “relocate()”
For any value (url, uri or event) i get this error:

relocate( uri="/manager/dashboard" );  <-- my phisical url
relocate( "/dashboard" );
relocate( event="MainController.dashboard" );

image

(I attach stacktrace error.htm.pdf (241.9 KB) )

this is entry in my Router:

get( "/dashboard" )
	.to( "MainController.dashboard" ).end();

#7
Finally, a piece of advice.
In this project have got a “public” part and a “admin” part.
The UIs are completely different. They use the same services.

I made two Coldbox applications, like this:

/apps
     /admin
         /config/Coldbox.cfc
         /controllers
         /views
/apps
     /public
         /config/Coldbox.cfc
         /controllers
         /views

It seems to work well, but do you think it is a good choice?
Or I may need to load view of the other app or share the UserController between the two applications.

The only problem I see in unifying the apps is the folder that contains the controllers.

While for the views I can write (using only one “views” directory):

setView ('public/shipment/new')

or

setView ('admin/shipment/list')

… how can i organize my controllers well?
Should I write this?

AdminShipmentController.cfc

and

PublicShipmentController.cfc

too long … :stuck_out_tongue:
Some advice?

.
.

Sorry for the long post. Thanks if you want to answer me.

Apart from these small problems, I’m using Coldbox intensively for the first time. I’m finding very well!

Thank you guys! :heart:

Wow, what great list! Before we dive in, a couple questions

  • What CF engine/version
  • Do you have full null support enabled? A couple of your errors seem like they may be related to that (It’s supported, but rarely used so sometimes buggy)

I’m not exactly sure what your question is. Yes, that is a feature of ColdBox, and it’s presumably working as designed. Basically, if the framework is in the process of reloading, it will return this as a “fail fast” approach. You can customize the message that appears in this case, or you can disable the fail-fast feature entirely which will cause new requests to wait, but can also easily take down a production server if it reinits under heavy load :slight_smile: Read more here:

That looks correct. I see the /login/do route ONLY respponds to a POST. Are you testing it with a POST, or are you testig it with a GET? Also ensure you have these custom routes above any convention routes like :handler/:action? in your router.

Firstly, note that method name as been deprecated in favor of externalView()

What I think is happening is you are confusing renderView() with event.setView() The first function immediately returns the HTML of the view in question and outputs it from the function, not modifying the request at all. The second one just makes an internal note of the view you’d like to render, then later, when the request is finished, that view is rendered.

  • If you don’t call event.setView() or event.noRender() or return render data in the controller, Coldbox will automatically attempt to run the default covention view, which is going to be /handlername/actionname.cfm which is what your error is showing.
  • I’m not super familiar with the external view method, but I don’t think there is an equivalent event.setExternalView() sort of method.

I think what you need to do is simply return the results of the external view method directly from your handler action method. This will short circuit ColdBox’s default convention view rendering. You may also need to set the render format so it doesn’t try to JSON serialize it.

THAT SAID, if all this is an attempt to share views between apps, forget everything you’re doing as you’re making it too hard IMO :slight_smile: You should be able to just set the external view folder and let event.setView() find it in the lookup order. But I don’t even recommend that-- I’d combine your apps and use modules. More on that later.

Absolutely a feature! Handlers, and views alike can be organized in folders, or “packages” as we call them. The convention is to put views for a handler named Foo.cfc in a folder called foo inside the views dir. But you can put them wherever you like so long as you explicitly set the view you want to render.

I’m not quite following what you have going on without seeing the whole setup working. The fact taht the error is referencing a view file in a totally different folder tells me ColdBox is not setting the view properly and it looks as though it’s trying to just render the default convention view. Without knowing what handler/action you’re hitting, it’s hard to tell.

This is very odd and feels like it may be related to your null settings. I also found this syntax error in the relocate() method declaration in Controller.cfc that may be affecting it.

		persist              = "",
		struct persistStruct = structNew()
		boolean ssl,

notice the missing comma after the struct new. Please add that comma in and see if it makes any difference. (@lmajano I assume this is a bug?)

I highly recommend you use modules to do this. The folder structure is very similar and each module can still have its own

  • settings
  • router
  • handlers/views/models/layouts

But the modules can live in the same application so they can still share

  • app level settings
  • app level models
  • views and handlers from other modules
  • app level interceptors

I think this strikes a perfect mix of easy re-usability between the modules, but still contained in a single top level app.

I don’t tend to put the word “handler” or “controller” or “view” on my files. The folder they live in is already enough information for me to know it’s a handler or a view, etc. So, I’d just have this:

/modules_app/admin/handlers/Shipment.cfc
/modules_app/public/handlers/Shipment.cfc

And the out-of-the box convention routes for both of them would simply be

localhost/admin/shipment
localhost/public/shipment

And ColdBox will also allow you to put one of the modules in “take over” mode so it latches onto the / route so it gets all the default routes and then you can delegate just the /admin routes to the admin module.

Your models will also self-organize with modules. Consider:

/modules_app/admin/models/ShipmentService.cfc
/modules_app/public/models/FooBarDAO.cfc

The default names of these models will be

ShipmentService@admin
FooBarDAO@public
2 Likes

Sorry for the long wait in the reply.

Lucee last version, on Tomcat 9.5, with Coldbox last version

yes

:sweat_smile: ok, sorry. In truth I can’t quite tell when Coldbox is reload.

I have this line in my code:

public Boolean function onRequestStart (string targetPage) {

    url.fwreinit = 1;
    
    application.cbBootstrap.onRequestStart( arguments.targetPage );
    
    return true;
}

I expect it to reset on every request, but I’m not sure.
I have to investigate, and I’ll tell you better

Ok, I add the coma but I keep getting the same error.

Seems the error in Controller.cfc, line 1145

flash.putAll( map = arguments.persistStruct, saveNow = true );

that arguments.persistStruct is Null
If I can help you debug please ask without problems.

Ok Brad. This is all very, very interesting.
I need to find some hours to change all my code.
Thanks for the invaluable advice! :heart:

Yes. You are right. But all of my files all have a suffix “namespace” (AuthService, ShipmentController, DriverDAO, ServiceCommand and so on).
Only “beans” (data carriers, I don’t know the nomenclature in Java, maybe “pojo”) don’t have the suffix.
So I confused Coldbox controllers with beans: I was going crazy … :grin:

I’m having some other problem with Coldbox, maybe I’ll write on this forum in a while.
In the meantime, thank you very much for your exhaustive answer! :blush:

Yes, it would. I would be rather cautious doing this as it can make your server very unstable. Basically a reinit is a complete destruction and re-creation of the entire framework in memory. Any sort of async requests or Ajax calls with have troubles due to the framework constantly reinitting.

Keep in mind there is a CommandBox command that will watch your source for changes and reinit automatically for you:

coldbox watch-reinit

Tail the console logs and it will be rather easy. A default ColdBox template like you get from coldbox create app has a Console logger enabled by default and you’ll see messages in the console every time the framework reinit.

server log --follow

I am almost entirely sure your error is coming from your full null support. Like i said, we support this, but not many people even use it, so it can be buggy from time to time. It would appear the default values of function arguments are not being applied when the argument is already coming in as null.

When you call relocate() in your handler, this is actually the method that is being called:

You can see there are no default values here so every argument you don’t pass is going to be defined as null. You can see we then just pass the entire argument scope via argumentCollection into the actual method in the Contorller class, which provides default values for all the arguments:

When null support is off, the default values kick in here and persistStruct is set to an empty struct, however when full null support is enabled, Lucee leaves the argument with a value of null. I assume Lucee would say this is working as designed, but it presents a problem for sure in ColdBox when we try to use argumentCollection in proxy methods and attempt to default the arguments in the inner method.

Can you please put in a ticket for this in our JIRA so we can fix it:
https://ortussolutions.atlassian.net/browse/COLDBOX

In the mean time, you could add some code like this to the inside of the controller’s relocate method

arguments.persistStruct = arguments.persistStruct ?: {};
arguments.addToken= arguments.addToken?: false;
arguments.queryString = arguments.queryString ?: "";
etc..

ColdBox needs to examine all of our uses of argumentCollection that calls a method with default params to see where else this issue may be lurking.

Ooh, interesting-- I also just discovered Lucee only ignores the default attribute when null support is enabled AND named arguments are being used.

Ok Brad, thanks for your feedback.
I’m having other problems with the “pdfArgs” in renderData() and “args” of event.setView().
I believe the problem is always the same.

Tonight I tried to correct the problem, but I got lost in the maze of Coldbox. :sweat_smile:
I’ll try again this evening.
I’d like to at least be able to fix the problem with “args”.

I would like to be able to help you.
If you think I can write some code and / or test, please ask. I will be happy to help you.

Now I open the ticket on Jira.

Many thanks again.

Filled:
https://ortussolutions.atlassian.net/browse/COLDBOX-1114

1 Like

I have also entered this ticket as I think there’s some bugginess going on in Lucee as well:

https://luceeserver.atlassian.net/browse/LDEV-4020

1 Like