# Views — `public/views/` PHP view templates, organized by controller name. ## Directory Structure ``` public/views/ ├── / # snake_case folder per controller │ ├── index.php │ ├── show.php │ └── edit.php ├── modals/ # Modal fragment views (AJAX loaded) │ └── .php ├── partial/ # Reusable partial views │ ├── admin_header.php │ ├── admin_sidebar.php │ ├── admin_toolbar.php │ └── admin_footer.php └── wrapper/ # Layout wrappers ├── admin/ │ ├── header.php │ └── footer.php └── site/ ├── header.php └── footer.php ``` ## File Naming - Folder: `snake_case` matching the controller name (lowercased) - Files: `snake_case.php` matching the method name ## Rendering Called from the controller: ```php // Standard — uses __CLASS__/__FUNCTION__ convention $this->view->render(__CLASS__ . '/' . __FUNCTION__); // With explicit wrapper $this->view->render('clients/index', true, 'site'); $this->view->render('admin/dashboard', true, 'admin'); // Login / minimal wrapper $this->view->render('auth/login', 'login'); // No wrapper $this->view->render('auth/login', false); ``` ## Accessing View Data Variables set on the controller via `$this->view->VarName = $value` are accessed in the view as **`$this->VarName`**. `View::render()` calls `extract((array) $this)` before including the template, so all properties set on the view object are available as bare `$VarName` locals. ```php // Controller $this->view->Users = Db::select("SELECT * FROM sp_users"); $this->view->PageTitle = 'Users'; // View — use bare $VarName

``` ## Wrappers Wrappers live in `public/views/wrapper/`. The wrapper auto-loads: - `public/assets/css/.css` if it exists - `public/assets/js/.js` if it exists ## Partial Views Partials are reusable snippets loaded from the controller constructor: ```php // In controller __construct() $this->view->Header = $this->view->PartialView('admin_header'); $this->view->SideBar = $this->view->PartialView('admin_sidebar'); $this->view->ToolBar = $this->view->PartialView('admin_toolbar'); $this->view->Footer = $this->view->PartialView('admin_footer'); ``` Then echoed in the view: ```php ``` ## Modal System Modals are loaded dynamically via AJAX. Trigger a modal with: ```html ``` `data-size` accepts any Bootstrap modal width class or a custom `mw-*` value: | Value | Width | |-------|-------| | *(omit)* | Default (~500px) | | `mw-500px` | 500px max-width | | `mw-650px` | 650px max-width | | `mw-750px` | 750px max-width | | `modal-lg` | ~800px (Bootstrap) | | `modal-xl` | ~1140px (Bootstrap) — use for wizards / multi-step forms | Modal views live at `public/views/modals/.php` and render **only** the `.modal-content` fragment (no full page wrapper): ```html ``` ## Assets Structure ``` public/assets/ ├── css/ │ ├── custom.css # Global overrides │ └── .css # Page-specific (auto-loaded by wrapper) ├── js/ │ └── .js # Page-specific (auto-loaded by wrapper) ├── plugins/ │ └── datatables/ │ ├── datatables.bundle.css │ └── datatables.bundle.js └── media/ └── svg/ └── brand-logos/ # Integration / vendor logos ``` Inject additional assets from the controller method: ```php $this->Styles[] = '/public/assets/plugins/datatables/datatables.bundle.css'; $this->view->Styles = $this->Styles; $this->JavaScript[] = '/public/assets/plugins/datatables/datatables.bundle.js'; $this->view->JavaScript = $this->JavaScript; ```