@@ -71,7 +71,7 @@ public function renderMarkdown( HttpResponseStatus $responseCode, array $data =
7171 @http_response_code ( $ responseCode ->value );
7272
7373 $ view = new Markdown ()
74- ->setController ( new \ ReflectionClass ( static ::class )-> getShortName () )
74+ ->setController ( $ this -> getControllerViewPath () )
7575 ->setLayout ( $ layout )
7676 ->setPage ( $ page )
7777 ->setCacheEnabled ( $ cacheEnabled );
@@ -111,7 +111,7 @@ public function renderHtml( HttpResponseStatus $responseCode, array $data = [],
111111 @http_response_code ( $ responseCode ->value );
112112
113113 $ view = new Html ()
114- ->setController ( new \ ReflectionClass ( static ::class )-> getShortName () )
114+ ->setController ( $ this -> getControllerViewPath () )
115115 ->setLayout ( $ layout )
116116 ->setPage ( $ page )
117117 ->setCacheEnabled ( $ cacheEnabled );
@@ -171,7 +171,7 @@ public function setRouter( Router $router ): Base
171171 * Get the controller name for cache key generation.
172172 * Returns the short class name (without namespace).
173173 * This matches how the framework's render methods set the controller name.
174- *
174+ *
175175 * @return string The controller class name without namespace
176176 */
177177 protected function getControllerName (): string
@@ -181,6 +181,51 @@ protected function getControllerName(): string
181181 return new \ReflectionClass ( static ::class )->getShortName ();
182182 }
183183
184+ /**
185+ * Get the controller view path accounting for namespace hierarchy.
186+ * Converts controller namespace and class name to snake_case directory structure.
187+ *
188+ * Examples:
189+ * - Neuron\Cms\Controllers\Admin\Posts -> admin/posts
190+ * - Neuron\Cms\Controllers\PostController -> post (backwards compatible with "Controller" suffix)
191+ * - Neuron\Cms\Controllers\Dashboard -> dashboard
192+ *
193+ * @return string The view path (e.g., "admin/posts", "dashboard")
194+ */
195+ protected function getControllerViewPath (): string
196+ {
197+ $ reflection = new \ReflectionClass ( static ::class );
198+ $ fullClassName = $ reflection ->getName ();
199+
200+ // Find the position of "Controllers" in the namespace
201+ $ controllersPos = strrpos ( $ fullClassName , '\\Controllers \\' );
202+
203+ if ( $ controllersPos === false )
204+ {
205+ // No "Controllers" namespace found, fall back to short name
206+ $ shortName = $ reflection ->getShortName ();
207+ // Strip "Controller" suffix for backwards compatibility
208+ $ shortName = preg_replace ( '/Controller$/ ' , '' , $ shortName );
209+ return ( new \Neuron \Core \NString ( $ shortName ) )->toSnakeCase ();
210+ }
211+
212+ // Extract everything after "Controllers\"
213+ $ afterControllers = substr ( $ fullClassName , $ controllersPos + strlen ( '\\Controllers \\' ) );
214+
215+ // Split by namespace separator
216+ $ parts = explode ( '\\' , $ afterControllers );
217+
218+ // Convert each part to snake_case
219+ $ snakeCaseParts = array_map ( function ( $ part ) {
220+ // Strip "Controller" suffix for backwards compatibility
221+ $ part = preg_replace ( '/Controller$/ ' , '' , $ part );
222+ return ( new \Neuron \Core \NString ( $ part ) )->toSnakeCase ();
223+ }, $ parts );
224+
225+ // Join with forward slashes for directory path
226+ return implode ( '/ ' , $ snakeCaseParts );
227+ }
228+
184229 /**
185230 * Initialize ViewCache if not already present in Registry.
186231 * This allows controllers to check cache before making expensive API calls.
@@ -400,7 +445,7 @@ public function renderHtmlWithCacheKey(
400445
401446 // Create view and set up for rendering
402447 $ view = new Html ()
403- ->setController ( $ this ->getControllerName () )
448+ ->setController ( $ this ->getControllerViewPath () )
404449 ->setLayout ( $ layout )
405450 ->setPage ( $ page )
406451 ->setCacheEnabled ( $ cacheEnabled );
@@ -498,7 +543,7 @@ public function renderMarkdownWithCacheKey(
498543
499544 // Create view and set up for rendering
500545 $ view = new Markdown ()
501- ->setController ( $ this ->getControllerName () )
546+ ->setController ( $ this ->getControllerViewPath () )
502547 ->setLayout ( $ layout )
503548 ->setPage ( $ page )
504549 ->setCacheEnabled ( $ cacheEnabled );
0 commit comments