Conversation
Problem After upgrading to ColdBox 7.5.2, the Renderer.cfc was calling discoverViewPaths() to locate a layout before checking if the layout name was empty. When a module had layoutParentLookup = true and called event.noLayout() (which sets the layout to an empty string), the framework tried to locate a layout with an empty name, causing the error: The layout [] was not found in the module path: [/modules_app/akibase/layouts/] Solution I reorganized the code in /coldbox/system/web/Renderer.cfc:608-637 to: 1. First check if the layout is empty (len( cbox_currentLayout ) eq 0) 2. If empty, just render the view without any layout discovery 3. Only call discoverViewPaths() when we know the layout is not empty
There was a problem hiding this comment.
Pull request overview
Fixes COLDBOX-1348 by preventing layout discovery from running when the resolved layout name is an empty string (e.g., after event.noLayout()), which previously caused erroneous lookups and exceptions in module layout resolution flows.
Changes:
- Reorders
Renderer.layout()logic to short-circuit whencbox_currentLayoutis blank. - Moves
discoverViewPaths()invocation inside the non-blank layout branch. - Adjusts when
postLayoutRenderis announced based on whether a layout was rendered.
| iData.renderedLayout = this.view(); | ||
| // Announce | ||
| if ( not arguments.prePostExempt ) { | ||
| announce( "postLayoutRender", iData ); |
There was a problem hiding this comment.
postLayoutRender is now announced with different data depending on whether a layout was rendered. In the blank-layout branch the announced payload omits viewPath, while the non-blank branch appends it. Since postLayoutRender previously always included viewPath, interceptors that assume this key exists may now error when event.noLayout() is used. Consider always including a viewPath key (e.g., empty string/null) for consistency/backwards compatibility.
| announce( "postLayoutRender", iData ); | |
| announce( "postLayoutRender", iData.append( { viewPath : "" } ) ); |
| // If Layout is blank, then just delegate to the view | ||
| // No layout rendering. | ||
| if ( len( cbox_currentLayout ) eq 0 ) { | ||
| iData.renderedLayout = this.view(); |
There was a problem hiding this comment.
This change fixes a regression around event.noLayout() + module layoutParentLookup, but there’s no accompanying regression test. The repo already has renderer specs (e.g. tests/specs/web/RendererTest.cfc), so it would be good to add a test that executes a module request with layoutParentLookup=true that calls event.noLayout() and asserts rendering succeeds (and does not attempt layout discovery).
| iData.renderedLayout = this.view(); | |
| var viewLocations = discoverViewPaths( | |
| view : event.getCurrentView(), | |
| module : arguments.module, | |
| explicitModule: cbox_explicitModule | |
| ); | |
| iData.renderedLayout = renderViewComposite( | |
| view : event.getCurrentView(), | |
| viewPath : viewLocations.viewPath, | |
| viewHelperPath: viewLocations.viewHelperPath, | |
| args : args, | |
| viewVariables : arguments.viewVariables | |
| ); |
Problem
After upgrading to ColdBox 7.5.2, the Renderer.cfc was calling discoverViewPaths() to locate a layout before checking if the layout name was
empty. When a module had layoutParentLookup = true and called event.noLayout() (which sets the layout to an empty string), the framework tried to
locate a layout with an empty name, causing the error:
The layout [] was not found in the module path: [/modules_app/akibase/layouts/]
Solution
I reorganized the code in /coldbox/system/web/Renderer.cfc:608-637 to: