Files
rspade_system/app/RSpade/man/jqhtmldoc.txt
2025-11-24 03:43:45 +00:00

470 lines
16 KiB
Plaintext
Executable File

JQHTMLDOC(3) RSX Framework Manual JQHTMLDOC(3)
NAME
JQHTMLDOC - Component documentation standard for .jqhtml files
SYNOPSIS
<!--
Component_Name
$required_arg - Description of required argument
$optional_arg="default" - Optional argument with default value
this.data.field - Data structure after on_load()
this.args.param - Input parameters from component attributes
method_name() - Public methods for external interaction
CONTENT BLOCKS:
<Block:Custom_Block>
Extension point for customization
Variables: Custom_Block.variable_name
-->
DESCRIPTION
JQHTML component documentation uses HTML comments at the top of
.jqhtml template files. The documentation serves as a contract:
defining inputs (arguments), outputs (data/methods), and extension
points (content blocks).
Philosophy: Treat <Define> like a class definition. Document what
goes in, what comes out, and how it can be extended. Scale the
documentation to component complexity - simple components need
minimal docs, complex ones need comprehensive coverage.
This is code documentation, not user documentation. Write for
developers who need to understand how to use the component in their
code, not for end users who click buttons.
DOCUMENTATION STRUCTURE
The documentation comment appears immediately before the <Define> tag
and follows this structure:
1. Component Name
First line: PascalCase component name matching <Define> tag
2. Arguments Section (if component accepts parameters)
List all $ attributes the component expects
Show default values where applicable
Mark required vs optional
3. Data Section (if component has on_load() or uses this.data)
Document this.data structure after on_load() completes
Document this.args for reference to component parameters
Show data shape and expected types
4. Methods Section (if component has public methods)
List methods that external code should call
Brief description of what each method does
5. Content Blocks Section (if component uses slots)
Document each <Block:Name> the component accepts
List variables available in each block's scope
AVAILABLE SECTIONS
Only include sections relevant to your component. Most components
use 2-3 sections maximum.
Component Name (Required)
First line of comment, PascalCase matching <Define> tag.
Arguments (Use when component accepts $parameters)
Format: $arg_name="default" - Description
Omit ="default" for required arguments
Show actual default values from template
Data (Use when component loads or manipulates data)
this.data.field - What's available after on_load()
this.args.field - Reference to input parameters
Document structure, not implementation
Methods (Use when component has callable public methods)
method_name() - What it does
Include parameters if method signature is important
Only document methods external code should call
Content Blocks (Use when component accepts slots)
<Block:Block_Name>
What goes here
Variables: Block_Name.var1, Block_Name.var2
Notes (Optional, use sparingly)
Implementation notes
Gotchas or non-obvious behavior
Performance considerations
SCALING TO COMPLEXITY
The documentation standard scales to match component complexity.
Simple components need minimal documentation. Complex components
with many parameters, data dependencies, and extension points need
comprehensive documentation.
Simple Component (1-2 sections):
<!--
Text_Input
$name="field_name" - Form field name
$value="" - Initial value (optional)
-->
Medium Component (3-4 sections):
<!--
User_Card
$user_id - User ID to load
$theme="light" - Card theme (light/dark)
this.data.user - User object from API
this.data.user.name - User's display name
this.data.user.email - User's email address
refresh() - Reload user data from server
-->
Complex Component (5+ sections):
<!--
DataGrid
$api="Controller" - Controller with datagrid_fetch() endpoint
$columns=[] - Column definitions (optional, auto-detected)
$per_page="25" - Rows per page (default: 25)
$sortable="true" - Enable column sorting
this.data.records - Array of records from API
this.data.total - Total record count
this.data.page - Current page number
this.data.columns - Resolved column definitions
reload() - Re-fetch data and re-render grid
goto_page(n) - Navigate to page
sort_by(column) - Sort by column
CONTENT BLOCKS:
<Block:Datagrid_Row_Block>
Custom row rendering
Variables: Datagrid_Row_Block.record, Datagrid_Row_Block.index
<Block:Datagrid_Empty_Block>
Shown when no records found
-->
DECISION GUIDE
Should I document this component?
YES - if it accepts arguments or loads data
YES - if other developers will use it
YES - if it has public methods or content blocks
MAYBE - if it's very simple (single argument, no data)
NO - if it's a throwaway test component
What should I document?
Arguments - ALWAYS document if component accepts any
Data - Document if on_load() exists or this.data is used
Methods - Document public methods only (not internals)
Content Blocks - Document all slots
Notes - Only when behavior is non-obvious
How much detail?
Arguments - Show name, default, one-line description
Data - Show structure, not implementation details
Methods - Show signature, one-line description
Content Blocks - List available variables
Notes - Keep brief, focus on gotchas
EXAMPLES
Simple Input Component:
<!--
Text_Input
$name="field_name" - Form field name
$value="initial" - Initial value
$placeholder="" - Input placeholder (optional)
-->
<Define:Text_Input tag="input" type="text" class="form-control"
name="<%= this.args.name %>"
value="<%= this.args.value %>"
placeholder="<%= this.args.placeholder || '' %>"
/>
Card with Data Loading:
<!--
Product_Card
$product_id - Product ID to load
$show_price="true" - Display price (optional)
this.data.product - Product object from API
this.data.product.name - Product name
this.data.product.price - Product price
add_to_cart() - Add product to shopping cart
toggle_favorite() - Toggle favorite status
-->
<Define:Product_Card class="card">
<% if (Object.keys(this.data).length === 0) { %>
<div class="spinner">Loading...</div>
<% } else { %>
<h3><%= this.data.product.name %></h3>
<% if (this.args.show_price === "true") { %>
<p class="price">$<%= this.data.product.price %></p>
<% } %>
<button $sid="cart_btn">Add to Cart</button>
<% } %>
</Define:Product_Card>
Complex Grid with Slots:
<!--
DataGrid
$api="Controller" - Controller with datagrid_fetch() endpoint
$per_page="25" - Rows per page (default: 25)
$sortable="true" - Enable column sorting
$columns=[] - Column definitions (optional)
this.data.records - Array of records from API
this.data.total - Total record count
this.data.page - Current page number
this.data.per_page - Records per page
this.data.sort_column - Current sort column
this.data.sort_direction - 'asc' or 'desc'
reload() - Re-fetch data and re-render grid
goto_page(n) - Navigate to page
sort_by(column) - Sort by column
set_per_page(n) - Change page size
CONTENT BLOCKS:
<Block:Datagrid_Row_Block>
Custom row rendering for each record
Variables: Datagrid_Row_Block.record, Datagrid_Row_Block.index
<Block:Datagrid_Empty_Block>
Shown when no records found
Variables: (none)
<Block:Datagrid_Header_Block>
Custom header row (optional)
Variables: Datagrid_Header_Block.columns
-->
<Define:DataGrid class="datagrid">
<table>
<thead>
<Slot:header>
<% for (let col of this.data.columns) { %>
<th><%= col.title %></th>
<% } %>
</Slot:header>
</thead>
<tbody>
<% if (this.data.records.length === 0) { %>
<tr><td colspan="100"><Slot:empty>No records</Slot:empty></td></tr>
<% } else { %>
<% for (let [idx, record] of this.data.records.entries()) { %>
<tr><Slot:row /></tr>
<% } %>
<% } %>
</tbody>
</table>
</Define:DataGrid>
ARGUMENT DOCUMENTATION PATTERNS
Required Arguments (no default):
$user_id - User ID to load
$api_endpoint - API endpoint for data
Optional Arguments (with default):
$theme="light" - UI theme (light/dark/auto)
$per_page="25" - Records per page
$enabled="true" - Enable/disable feature
Boolean Arguments:
$sortable="true" - Enable column sorting
$show_header="false" - Display table header
Array/Object Arguments:
$columns=[] - Column definitions (optional)
$filters={} - Filter criteria (optional)
Complex Arguments:
$on_select=this.handle_select - Callback when row selected
$custom_renderer=this.render_custom - Custom cell renderer
DATA DOCUMENTATION PATTERNS
Simple Data Structure:
this.data.user - User object from API
this.data.user.name - User's display name
this.data.user.email - User's email address
Array Data:
this.data.items - Array of item objects
this.data.items[].id - Item ID
this.data.items[].name - Item name
Computed Data:
this.data.total_price - Sum of all item prices
this.data.is_valid - True if form passes validation
Referencing Arguments:
this.args.user_id - User ID from $user_id parameter
this.args.theme - Theme from $theme parameter
METHOD DOCUMENTATION PATTERNS
Simple Methods:
reload() - Re-fetch data and re-render component
render() - Re-render component with full lifecycle
stop() - Remove component from DOM
Methods with Parameters:
goto_page(page_number) - Navigate to specific page
sort_by(column_name, direction) - Sort by column
Async Methods:
async save_changes() - Save data to server
async load_user(user_id) - Load specific user
CONTENT BLOCK DOCUMENTATION PATTERNS
Simple Blocks (no variables):
<Block:Header_Block>
Custom header content
Blocks with Variables:
<Block:Row_Block>
Custom row rendering
Variables: Row_Block.record, Row_Block.index
Multiple Variables:
<Block:Cell_Block>
Custom cell content
Variables: Cell_Block.value, Cell_Block.column, Cell_Block.record
Optional Blocks:
<Block:Empty_Block>
Shown when no data (optional, has default)
WRITING STYLE
Write in imperative voice:
✓ "User ID to load"
✗ "This is the user ID that will be loaded"
Be concise:
✓ "Enable column sorting"
✗ "When set to true, enables the ability to sort columns"
Document contract, not implementation:
✓ "this.data.user - User object from API"
✗ "this.data.user - Populated by on_load() which calls fetch()"
Use consistent terminology:
✓ "Records per page" (consistent with this.data.per_page)
✗ "Number of rows to show" (inconsistent)
WHEN TO UPDATE DOCUMENTATION
Update documentation when:
- Adding new arguments
- Changing argument defaults
- Adding/removing data fields
- Adding public methods
- Adding/removing content blocks
- Changing block variable names
Treat documentation as code:
- Update in same commit as implementation changes
- Keep in sync with actual behavior
- Remove documentation for removed features
RELATIONSHIP TO JAVASCRIPT CLASS
The .jqhtml documentation covers the template contract. The
JavaScript class file may have additional JSDoc comments for
implementation details, but the HTML comment is the primary
documentation for component consumers.
.jqhtml comment documents:
- What arguments component accepts
- What data structure on_load() produces
- What public methods are callable
- What content blocks are available
.js JSDoc comments document:
- Implementation details
- Private methods
- Algorithm notes
- Performance considerations
VALIDATION AND ENFORCEMENT
The framework does not currently validate component documentation.
Documentation is enforced through code review and developer
discipline.
Future versions may add:
- Linting rules to require documentation
- Validation that documented arguments match template usage
- IDE integration for autocomplete from documentation
COMMON MISTAKES
Don't document internal implementation:
✗ "Calls fetch() to load data from /api/users endpoint"
✓ "this.data.user - User object from API"
Don't duplicate template code:
✗ Listing every single line of template
✓ High-level contract only
Don't over-document simple components:
✗ Verbose multi-paragraph description for a text input
✓ Brief one-line descriptions
Don't leave outdated documentation:
✗ Documenting removed arguments or data fields
✓ Keep docs in sync with implementation
Don't document private methods:
✗ "internal_helper() - Internal use only"
✓ Only document public API
INTEGRATION WITH DEVELOPMENT WORKFLOW
1. Create component with rsx:app:component:create
Generated stub includes basic documentation template
2. Implement component functionality
Add arguments, data loading, methods as needed
3. Update documentation comment
Document all public contract elements
4. Code review
Reviewer verifies documentation matches implementation
5. Maintenance
Update documentation when changing component behavior
RELATIONSHIP TO MAN PAGES
Component documentation (this standard) differs from man pages:
Component docs (.jqhtml comments):
- Document specific component contract
- Live with the component code
- Brief, focused on usage
- Written for developers using the component
Man pages (rsx:man topic):
- Document framework subsystems
- Comprehensive reference documentation
- Include examples, philosophy, troubleshooting
- Written for framework developers
SEE ALSO
jqhtml(3) - JQHTML component system overview
coding_standards(3) - RSX coding conventions
rsx_architecture(3) - RSX application structure
NOTES
This documentation standard was established 2025-10-10 to provide
consistent component documentation across RSX applications. The
standard emphasizes scaling documentation to component complexity
and treating documentation as code that must stay in sync with
implementation.
RSX Framework 2025-10-10 JQHTMLDOC(3)