RE: [coldbox:15634] [CB 3.5.X] Disable Implict View Feature

in a SaaS environment there would be a custom “accounts” directory that contains a mimic structure of a CB application directory (handlers, interceptors, views, etc, etc) which would be pointed to (at a request or session level) as the externals so that when the user does

That sounds an awful lot like a module. The only issue is, I don’t think it would work to have different modules loaded on each request. The external locations can actually be a list of locations to check. I haven’t tried this, but but what if you had no local assets, and everything was externals? Set up two external locations, the first one would be the “overrides” and the second would be the “default” which would be checked next. I don’t know if you can change app mappings on a per-request basis, or if that would overwrite itself on concurrent requests. Even if you did, the next problem you would run into would be that ColdBox caches handler and view lookups so it doesn’t have to do it every request.
Honestly, I think you need to look into having a separate instance of the ColdBox application in memory for each client. Whether you set up separate web roots, or just dynamically change the ColdFusion application name based on the domain, I’m not sure how you can get a single ColdBox instance to have many different lookup locations for hundreds of clients without modifying the core and disabling all caching of those lookups.

Even if we reversed the order of lookups, you really still have the same problems-- just reversed. You either need 250 site roots (or at least 250 different application scopes), or the ability to have ColdBox load one of 250 different settings (not really possible).

The only way I think that might work is if you built your own layer on top of ColdBox, where you always hit a generic handler which based on logged in user or something would in turn decide which handler to run or which views to render. You’d basically be building the override functionality yourself. We sort of do this where I work where we have a content table in the database that defines different pieces of content as well as the package, handler, action, and layout required to render that content. We send everything through a route that looks like site.com/go/pageSlug and then turn around and run the appropriate event and set the layout based on what we get out of the database (video, audio, article, etc). We don’t do that to have different companies use the app though, we just do that because we built a database-driven CMS on top of ColdBox.

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, correct me if I am wrong as I never had issues doing this.

But everything is cached on the application scope, so if the application name is changed then how would this be a problem?

For example

site1.com.au would load up in externalview and cache what it needs against an application name defined for it.

site2.com.au would load up in local view and cahce everything needed for it.

Sorry either I am missing something, or I got around this another way!

I’d agree with Brad,

Either you have separate virtualhosts (as I’ve alluded to in the past using symlinks), or you do as Brad has suggested and dynamically change the appname based on the hostname. The only issue with that is that you can’t handle multiple hosts per client (i.e www.client1.myapp.com and client1.myapp.com). That only really would matter in a CMS environment though I imagine. You’d also not have the ability to change other settings, such as enabling debugging for client1 and disabling it for client2 (as you wouldn’t have separate Coldbox.cfc files for each client). However, Brad’s suggestion does seem the best fit for you, as you mentioned you’d prefer to keep the app in “one place”, and not have to fiddle too much with files.

Unless all 250 clients will be accessing the system at exactly the same time, then I’m not sure having this many separate CB instances will be too bad if your server has a decent amount of RAM – especially if wirebox and cachebox are setup properly to expire objects in a reasonable way.

Also, you’re still getting the conventions and externals the wrong way around. The externals should never change (that’s where your core app lives), it’s the conventions that would need to change.

To give you an example of how Brad’s suggestion would work:

In your application.cfc you’d have:

(That will create a “unique” CB instance for each host).

And you conventions should be something like:

conventions = {

handlersLocation = “custom/handlers/#cgi.http_host#”,

pluginsLocation = “custom/plugins/#cgi.http_host#”,

viewsLocation = " custom/views/#cgi.http_host#",

layoutsLocation = “custom/layouts/#cgi.http_host#”,

modelsLocation = “custom/models/#cgi.http_host#”,

modulesLocation = “modules”,

eventAction = “index”

};

You’ll have to ensure those directories exist – otherwise it will throw an error. So if you have a “client creation” script, ensure it creates those directories automatically (they can be empty, as long as they exist). You might have to run a script initially to create those directories for your existing clients.

Thanks,

Tom.

That was more very helpful discussion on this. I see what you mean about externals and did not realize that was the way the logic should go. I think Brad was trying to get this point across but I just did not catch it.

So, if I then create a unique named application and the custom directories for each unique client (base url / domain), the core code exists in the root, still, but is referenced as the “externallocation” source and the unique client directories become the convention.

Am I understanding that correctly? Let’s assume it is.

So now let’s assume I use a home.login handler/action and one client that diverges from the norm. Any other client issues that command, it’s NOT going to exist in their unique directory structure so the “externals” will kick in…because the convention is unique to the client and external is the default. Then, for the client that does have a custom one, their directory structure would have a home handler with a login action and login view…and that WOULD trigger first because it exists in convention (the unique directories)?

Close?

Mike

Yep that’s right.

Let’s say you do event.setView(“user/home”).

If custom/views/client1.myapp.com/user/home.cfm exists, that’s the view that will be rendered, otherwise /views/user/home.cfm will be rendered instead.

Regarding handlers, Brad seemed to suggest that they’re class based – I wasn’t aware of that, so I’ve always cloned the entire handler – but if that’s true it’s v.cool as your unique handler only needs the customised actions. I’d get Brad or someone else to confirm that….