wheels generate view
Generate view files for controllers.
Synopsis
wheels generate view [objectName] [name] [template]
wheels g view [objectName] [name] [template]
Description
The wheels generate view
command creates view files for controllers. It can generate individual views using templates or create blank view files.
Arguments
objectName
View path folder (e.g., user)
Required
name
Name of the file to create (e.g., edit)
Required
template
Optional template to use
Template Options
Available templates:
crud/_form
- Form partial for new/edit viewscrud/edit
- Edit form viewcrud/index
- List/index viewcrud/new
- New form viewcrud/show
- Show/detail view
Examples
Basic view (no template)
wheels generate view user show
Creates: /views/users/show.cfm
with empty content
View with CRUD template
wheels generate view user show crud/show
Creates: /views/users/show.cfm
using the show template
Edit form with template
wheels generate view user edit crud/edit
Creates: /views/users/edit.cfm
using the edit template
Form partial
wheels generate view user _form crud/_form
Creates: /views/users/_form.cfm
using the form partial template
Index view
wheels generate view product index crud/index
Creates: /views/products/index.cfm
using the index template
Generated Code Examples
Without Template (blank file)
<!--- View file created by wheels generate view --->
With CRUD Index Template
<h1>Products</h1>
<p>
#linkTo(text="New Product", action="new", class="btn btn-primary")#
</p>
<cfif products.recordCount>
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Created</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<cfoutput query="products">
<tr>
<td>#products.id#</td>
<td>#products.name#</td>
<td>#dateFormat(products.createdAt, "mm/dd/yyyy")#</td>
<td>
#linkTo(text="View", action="show", key=products.id, class="btn btn-sm btn-info")#
#linkTo(text="Edit", action="edit", key=products.id, class="btn btn-sm btn-warning")#
#linkTo(text="Delete", action="delete", key=products.id, method="delete", confirm="Are you sure?", class="btn btn-sm btn-danger")#
</td>
</tr>
</cfoutput>
</tbody>
</table>
<cfelse>
<p class="alert alert-info">No products found.</p>
</cfif>
Form View (new.cfm)
<h1>New Product</h1>
#includePartial("/products/form")#
Form Partial (_form.cfm)
#startFormTag(action=formAction)#
<cfif product.hasErrors()>
<div class="alert alert-danger">
<h4>Please correct the following errors:</h4>
#errorMessagesFor("product")#
</div>
</cfif>
<div class="form-group">
#textFieldTag(name="product[name]", value=product.name, label="Name", class="form-control")#
</div>
<div class="form-group">
#textAreaTag(name="product[description]", value=product.description, label="Description", class="form-control", rows=5)#
</div>
<div class="form-group">
#numberFieldTag(name="product[price]", value=product.price, label="Price", class="form-control", step="0.01")#
</div>
<div class="form-group">
#selectTag(name="product[categoryId]", options=categories, selected=product.categoryId, label="Category", class="form-control", includeBlank="-- Select Category --")#
</div>
<div class="form-group">
#checkBoxTag(name="product[isActive]", checked=product.isActive, label="Active", value=1)#
</div>
<div class="form-actions">
#submitTag(value=submitLabel, class="btn btn-primary")#
#linkTo(text="Cancel", action="index", class="btn btn-secondary")#
</div>
#endFormTag()#
Show View (show.cfm)
<h1>Product Details</h1>
<div class="card">
<div class="card-body">
<h2 class="card-title">#product.name#</h2>
<dl class="row">
<dt class="col-sm-3">Description</dt>
<dd class="col-sm-9">#product.description#</dd>
<dt class="col-sm-3">Price</dt>
<dd class="col-sm-9">#dollarFormat(product.price)#</dd>
<dt class="col-sm-3">Category</dt>
<dd class="col-sm-9">#product.category.name#</dd>
<dt class="col-sm-3">Status</dt>
<dd class="col-sm-9">
<cfif product.isActive>
<span class="badge badge-success">Active</span>
<cfelse>
<span class="badge badge-secondary">Inactive</span>
</cfif>
</dd>
<dt class="col-sm-3">Created</dt>
<dd class="col-sm-9">#dateTimeFormat(product.createdAt, "mmm dd, yyyy h:nn tt")#</dd>
<dt class="col-sm-3">Updated</dt>
<dd class="col-sm-9">#dateTimeFormat(product.updatedAt, "mmm dd, yyyy h:nn tt")#</dd>
</dl>
</div>
<div class="card-footer">
#linkTo(text="Edit", action="edit", key=product.id, class="btn btn-primary")#
#linkTo(text="Delete", action="delete", key=product.id, method="delete", confirm="Are you sure?", class="btn btn-danger")#
#linkTo(text="Back to List", action="index", class="btn btn-secondary")#
</div>
</div>
View Templates
Available Templates
default
Standard HTML structure
General purpose
bootstrap
Bootstrap 5 components
Modern web apps
tailwind
Tailwind CSS classes
Utility-first design
ajax
AJAX-enabled views
Dynamic updates
mobile
Mobile-optimized
Responsive design
print
Print-friendly layout
Reports
email
Email template
Notifications
Template Structure
Templates are located in:
~/.commandbox/cfml/modules/wheels-cli/templates/views/
├── default/
│ ├── index.cfm
│ ├── show.cfm
│ ├── new.cfm
│ ├── edit.cfm
│ └── _form.cfm
├── bootstrap/
└── custom/
Partial Views
Naming Convention
Partials start with underscore:
_form.cfm
- Form partial_item.cfm
- List item partial_sidebar.cfm
- Sidebar partial
Generate Partials
wheels generate view shared header,footer,navigation --partial
Using Partials
<!--- In layout or view --->
#includePartial("/shared/header")#
#includePartial("/products/form", product=product)#
#includePartial(partial="item", query=products)#
Layout Integration
With Layout (default)
<!--- Generated view assumes layout wrapper --->
<h1>Page Title</h1>
<p>Content here</p>
Without Layout
wheels generate view products standalone --layout=false
<!DOCTYPE html>
<html>
<head>
<title>Standalone View</title>
</head>
<body>
<h1>Products</h1>
<!-- Complete HTML structure -->
</body>
</html>
Custom Formats
HTML Format
wheels generate view products index --format=html
Creates: /views/products/index.html
Custom Extensions
wheels generate view emails welcome --format=txt
Creates: /views/emails/welcome.txt
Ajax Views
Generate AJAX View
wheels generate view products search --template=ajax
AJAX Template Example
<cfif isAjax()>
<!--- Return just the content --->
<cfoutput query="products">
<div class="search-result">
<h3>#products.name#</h3>
<p>#products.description#</p>
</div>
</cfoutput>
<cfelse>
<!--- Include full page structure --->
<div id="search-results">
<cfinclude template="_results.cfm">
</div>
</cfif>
Form Helpers
Standard Form
#startFormTag(action="create", method="post", class="needs-validation")#
#textField(objectName="product", property="name", label="Product Name", class="form-control", required=true)#
#textArea(objectName="product", property="description", label="Description", class="form-control", rows=5)#
#select(objectName="product", property="categoryId", options=categories, label="Category", class="form-control")#
#submitTag(value="Save Product", class="btn btn-primary")#
#endFormTag()#
File Upload Form
#startFormTag(action="upload", multipart=true)#
#fileFieldTag(name="productImage", label="Product Image", accept="image/*", class="form-control")#
#submitTag(value="Upload", class="btn btn-primary")#
#endFormTag()#
Responsive Design
Mobile-First Template
wheels generate view products index --template=mobile
<div class="container-fluid">
<div class="row">
<div class="col-12">
<h1 class="h3">Products</h1>
</div>
</div>
<div class="row">
<cfoutput query="products">
<div class="col-12 col-md-6 col-lg-4 mb-3">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title">#products.name#</h5>
<p class="card-text">#products.description#</p>
#linkTo(text="View", action="show", key=products.id, class="btn btn-primary btn-sm")#
</div>
</div>
</div>
</cfoutput>
</div>
</div>
Localization
Generate Localized Views
wheels generate view products index --locale=es
Creates: /views/products/index_es.cfm
Localized Content
<h1>#l("products.title")#</h1>
<p>#l("products.description")#</p>
#linkTo(text=l("buttons.new"), action="new", class="btn btn-primary")#
Testing Views
Generate View Tests
wheels generate view products index
wheels generate test view products/index
View Test Example
component extends="wheels.Test" {
function test_index_displays_products() {
products = model("Product").findAll(maxRows=5);
result = renderView(view="/products/index", products=products, layout=false);
assert(Find("<h1>Products</h1>", result));
assert(Find("New Product", result));
assertEquals(products.recordCount, ListLen(result, "<tr>") - 1);
}
}
Performance Optimization
Caching Views
<cfcache action="cache" timespan="#CreateTimeSpan(0,1,0,0)#">
<!--- Expensive view content --->
#includePartial("products/list", products=products)#
</cfcache>
Lazy Loading
<div class="products-container" data-lazy-load="/products/more">
<!--- Initial content --->
</div>
<script>
// Implement lazy loading
</script>
Best Practices
Keep views simple and focused on presentation
Use partials for reusable components
Move complex logic to helpers or controllers
Follow naming conventions consistently
Use semantic HTML markup
Include accessibility attributes
Optimize for performance with caching
Test views with various data states
Common Patterns
Empty State
<cfif products.recordCount>
<!--- Show products --->
<cfelse>
<div class="empty-state">
<h2>No products found</h2>
<p>Get started by adding your first product.</p>
#linkTo(text="Add Product", action="new", class="btn btn-primary")#
</div>
</cfif>
Loading State
<div class="loading-spinner" style="display: none;">
<i class="fa fa-spinner fa-spin"></i> Loading...
</div>
Error State
<cfif structKeyExists(variables, "error")>
<div class="alert alert-danger">
<strong>Error:</strong> #error.message#
</div>
</cfif>
See Also
wheels generate controller - Generate controllers
wheels scaffold - Generate complete CRUD
wheels generate test - Generate view tests
Last updated
Was this helpful?