Skip to content

Conversation

@devDespii
Copy link

🎯 Feature: Subdirectory Support for Domain-Driven Organization

This PR adds support for organizing views, services, dialogs, and bottom sheets in subdirectories using a simple slash notation.

✨ What's New

Create commands now support subdirectories:

stacked create view sales/dashboard
stacked create service auth/login
stacked create dialog admin/confirm
stacked create bottom_sheet user/profile

Delete commands also support subdirectories:

stacked delete view sales/dashboard
stacked delete service auth/login

πŸ“ Generated Structure

lib/ui/views/
β”œβ”€β”€ sales/
β”‚   └── dashboard/
β”‚       β”œβ”€β”€ dashboard_view.dart
β”‚       β”œβ”€β”€ dashboard_viewmodel.dart
β”‚       β”œβ”€β”€ dashboard_view.mobile.dart
β”‚       β”œβ”€β”€ dashboard_view.tablet.dart
β”‚       └── dashboard_view.desktop.dart

πŸ”§ Technical Implementation

  1. Path Parsing: Commands parse input like sales/dashboard into name="dashboard" and subfolder="sales"
  2. Template Updates: Mustache templates use {{{...}}} (triple braces) to prevent HTML encoding of slashes
  3. Import Generation: Correctly generates imports like package:app/ui/views/sales/dashboard/dashboard_view.dart
  4. Backward Compatible: Single-level views (e.g., home) still work exactly as before

πŸ“ Changes

Modified Commands (7 files):

  • βœ… create_view_command.dart
  • βœ… create_service_command.dart
  • βœ… create_dialog_command.dart
  • βœ… create_bottom_sheet_command.dart
  • βœ… delete_view_command.dart
  • βœ… delete_service_command.dart
  • βœ… delete_dialog_command.dart
  • βœ… delete_bottomsheet_command.dart

Modified Templates (4 files):

  • βœ… view/empty/modifications/add_route_import.json
  • βœ… view/web/modifications/add_route_import.json
  • βœ… dialog/empty/modifications/add_dialog_import.json
  • βœ… bottom_sheet/empty/modifications/add_bottom_sheet_import.json

βœ… Testing

Tested end-to-end in production apps:

  • βœ… Create view with subfolder: test/dashboard
  • βœ… Delete view with subfolder: test/dashboard
  • βœ… Import paths generated correctly (no HTML encoding)
  • βœ… Build runner succeeds
  • βœ… App runs without errors
  • βœ… Backward compatibility verified

πŸŽ‰ Benefits

  1. Domain-Driven Organization: Group related features together
  2. Better Scalability: Large projects stay organized
  3. Team Collaboration: Clear feature boundaries
  4. Zero Breaking Changes: Existing code continues to work

πŸ“š Related Commits

  • b0de9cf - feat: add subfolder support to delete commands
  • 1917a42 - fix: prevent HTML encoding of slashes in subfolder imports
  • 09c6464 - fix: generate correct import path for views with subfolders
  • e9e93ff - feat: add subdirectory support for domain-driven organization

Allows creating components in subdirectories for better organization:

Examples:
- stacked create view sales/dashboard
- stacked create service api/auth
- stacked create dialog alerts/error
- stacked create bottom_sheet forms/client_info
- stacked create widget charts/sales_graph

This enhancement maintains full backward compatibility while enabling
domain-driven directory structures.

Implementation:
- Parse path syntax (domain/component) in all create commands
- Extract subfolder from input (e.g., 'sales/dashboard' -> subfolder: 'sales', name: 'dashboard')
- Updated template_service to inject subfolders into output paths
- Support for views, services, dialogs, bottom_sheets, and widgets

Benefits:
- Better code organization by domain/feature
- Maintains Stacked framework compatibility
- No breaking changes - backward compatible
- Comprehensive README documentation with examples
When creating a view with a subfolder (e.g., 'test/dashboard'), the CLI was creating files in the correct location (lib/ui/views/test/dashboard/) but generating incorrect import paths in app.dart (pointing to lib/ui/views/dashboard/ without the subfolder).

Changes:
- Modified RenderFunction typedef to accept optional subfolder parameter
- Updated kTemplateNameView render function to generate viewFolderName with subfolder path
- Modified getTemplateRenderData() to pass subfolder to render functions
- Updated all render function signatures for consistency

This ensures that the generated import statement includes the full subfolder path:
- Before: import 'package:app/ui/views/dashboard/dashboard_view.dart';
- After: import 'package:app/ui/views/test/dashboard/dashboard_view.dart';

Fixes build_runner error: "Route must have either a page or a redirect destination"
When using Mustache templates, the {{variable}} syntax (2 braces) automatically escapes HTML entities, converting forward slashes (/) to /. This caused invalid import statements for views, dialogs, and bottom sheets created with subfolders.

Changes:
- Modified 4 template JSON files to use {{{variable}}} (3 braces) instead of {{variable}} for folder names
- Files updated:
  * view/empty/modifications/add_route_import.json
  * view/web/modifications/add_route_import.json
  * dialog/empty/modifications/add_dialog_import.json
  * bottom_sheet/empty/modifications/add_bottom_sheet_import.json
- Recompiled templates to regenerate compiled_template_map.dart

Before:
import 'package:app/ui/views/test/dashboard/dashboard_view.dart'; ❌

After:
import 'package:app/ui/views/test/dashboard/dashboard_view.dart'; βœ…

This fix ensures that imports with subfolders are valid Dart code and can be resolved by build_runner.
Applied the same subdirectory parsing logic from create commands to all delete commands, ensuring consistent handling of subfolder paths.

Changes:
- Modified 4 delete command files to parse and handle subfolder paths
- Files updated:
  * delete_view_command.dart
  * delete_service_command.dart
  * delete_dialog_command.dart
  * delete_bottomsheet_command.dart

Implementation:
- Parse input path (e.g., 'test/dashboard') to extract subfolder and name
- Pass subfolder parameter to getTemplateOutputPath() calls
- Updated method signatures to accept optional subfolder parameter
- Added documentation for subfolder parameters

Before:
stacked delete view test/dashboard
β†’ Error: PathNotFoundException: 'lib/ui/views/test_dashboard/' ❌

After:
stacked delete view test/dashboard
β†’ Deletes 'lib/ui/views/test/dashboard/' βœ…

This completes the subdirectory support feature, making create and delete commands symmetric.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants