Style Guide, Procedures and Code Documentation

This style guide provides comprehensive standards for writing clean, maintainable, and consistent MOX code for Moxie.Build. Code examples on this page are for illustrative purposes and are only intended to demonstrate style conventions.

Naming Conventions

Database Table Names

Rule

Database table names must always use CamelCase (first letter capitalized), typically with a prefix indicating the module or category.

MemTab.Person
MemTab.Company
Content.Category
Content.Article
Sales.Order
Sales.Invoice

Database Field Names

Rule

Database table field names must always use CamelCase (first letter capitalized).

Rationale: This allows developers to instantly recognize when a field represents a database field value, regardless of where it appears in the code.
' Database field names in table definitions and references
Person.FirstName
Person.LastName
Person.Email
Order.OrderDate
Order.TotalAmount
Invoice.Status

' Work Query field name strings
KeepFields    "FirstName LastName Email Status"

Top Query Fields (local variables) for Non-DB Fields

Rule

All Top Query that do NOT represent database field values must use camelCase (first letter lowercase).

[New] counter       =    0
[New] totalAmount   =    0
[New] recordCount        [WQRecCount]
[New] htmlOutput    |    [HtmlOutput] "MainBody"
[New] startTime     =    %NowXUnix
[New] errorMsg      =    ""

Top Query Fields Holding DB Field Values

Rule

When a local Top Query field holds a value copied from a database field, keep it in CamelCase to maintain the visual connection to its database origin.

' Correct - Email holds a DB field value
[New] Email         |    "Input" | Person.Email
SendMail                 Email, "Subject", "Body"

' Correct - Status holds a DB field value
[New] Status        [L]  Order|{orderId}|Status
If Status = "Pending"
    Order.process        orderId
End If

Work Query Fields for Non-DB Fields

Rule

Work Query fields that do NOT represent database field values must use camelCase (first letter lowercase).

' Creating non-DB fields in Work Query
NewFields                "counter totalAmount recordCount"
SetFirst                 "counter", 1
WithAll              "", "totalAmount", "Sum", "Amount"
WithAll              "", "recordCount", "Count", "", "orderId"

' Using non-DB Work Query fields
[New] total         |    totalAmount
[New] count         |    recordCount

Work Query Fields Representing DB Fields

Rule

Work Query fields that represent database fields must use CamelCase to maintain visual consistency with database naming.

' DB fields in Work Query commands - stay CamelCase
KeepFields               "FirstName LastName Email Status"
NewFields                "OrderDate TotalAmount"
Sort                     "LastName FirstName"
KeepIf                   "Status", =, "`Active"

' When copying DB field values from Work Query
[New] FirstName     |    FirstName
[New] Status        |    Status

Method and Function Names

Rule

Use camelCase for all method and function names (first letter lowercase after the object/table prefix). Method and function names that are not a reference to a database table should be be capitalized.

' Correct
Method Person.save(pPersonId)
Method Order.calculateTotal(pOrderId)
Method Invoice.send(pInvoiceId)
Method utility.formatCurrency(pAmount)

' Incorrect
Method Person.Save(pPersonId)
Method Order.CalculateTotal(pOrderId)
Method Invoice.Send(pInvoiceId)
Method Utility.formatCurrency(pAmount)

Parameter Names

Rule

All parameters should use camelCase with a lowercase p prefix.

Method Person.create(pFirstName, pLastName, pEmail)
Method Order.calculateTotal(pOrderId, pTaxRate)
Method Invoice.send(pInvoiceId, pEmailAddress)

Constant Names

Rule

Constants should use camelCase with a lowercase c prefix.

Const    cMaxRecords         =    "1000"
Const    cDefaultTimeout     =    "30"
Const    cTaxRate            =    "0.0825"
Const    cPageSize           =    "50"

Code Structure and Formatting

Indentation

Rule

Use tabs for indentation, with tabs set to four spaces. All nested code blocks must be indented one level.

Method Order.calculateTotal(pOrderId)
    Rem 'Load order items
        [New] subtotal     =   0
        LoadItems              pOrderId
        [New] itemCount        [WQRecCount]
    EndRem

    Rem 'Calculate totals
        WithAll                "subtotal", "Sum", "Amount"
        [New] tax          =   subtotal * cTaxRate
        [New] total        =   subtotal + tax
    EndRem
End Method

Spacing Between Elements

Two blank lines between Methods, Functions, and Macros

End Method


Method Person.create(pFirstName, pLastName)
    ' Method code here
End Method


Method Person.update(pPersonId, pEmail)
    ' Method code here
End Method

One blank line between Rem/EndRem blocks

Rem 'Validate input
    Rem 'Check required fields
        If Not pFirstName
            'error handling...
            Exit
        End If
    EndRem

    Rem 'Check email format
        If Not (ValidEmail$ pEmail)
            'error handling...
            Exit
        End If
    EndRem
EndRem

Statement Alignment

Rule

Tab-align first parameters of statements within a block as much as practical.

' Good alignment
LoadRecord                "Person", personId
CopyQuery                 "Input", "Output"
Reset                     "Output"

' Parameters aligned at appropriate tab stops
WorkWith                  "Person"
    KeepFields            "FirstName LastName Email"
    Set                   "FirstName", `pFirstName
    Set                   "LastName", `pLastName
    Set                   "Email", `pEmail
End WorkWith

Query Naming

Built-in Query Suffixes

Rule

Query names ending in .Output and .Input should have the suffix in Capitalized while the prefix matches the method/function name.

' Correct - method name is camelCase, .Output suffix is Capitalized
Method Person.getActive(pDepartment)
    ' Query results go to Person.getActive.Output
    AppendQuery          "Person.getActive.Output", "Me.Output"
End Method

Method Order.getRecent(pDays)
    ' Query results go to Order.getRecent.Output
End Method

Main Procedure Queries

Rule

The main procedure's default queries are reserved names and must be capitalized: Input, Output, and Request.

CopyQuery                "Output", "Request"
Reset                    "Output"
WorkQuery                "Order.getRecent.Output"
AppendQuery              "Output", "Me.Output"

Custom Query Names

Rule

Custom query names should follow camelCase conventions.

NewQuery                 "tempResults"
MoveQuery                "tempResults", "Person.search.Output"
WorkQuery                "filteredData"

Comments and Documentation

Rem Block Comments

Rule

Use Rem / EndRem blocks to organize and document major sections of code. Include a descriptive comment after the opening Rem.

Rem 'Validate input parameters
    ' Code here
EndRem

Rem 'Calculate order totals
    ' Code here
EndRem

Rem 'Send confirmation email
    ' Code here
EndRem

Inline Comments

Rule

Use single-line comments (') for inline explanations. Place them on the same line when brief, or on a separate line when more detail is needed.

[New] maxRetries = 3    'Allow up to 3 connection attempts

' Check if order was placed within the last 24 hours
If orderDate >= ($Date - 1)
    ProcessOrder    orderId
End If

Method Documentation

Rule

Document method purpose and parameters at the method definition if the purpose is not immediately clear from the name.

' Calculates the total amount for an order including tax and shipping
' Returns the formatted total in the totalAmount field
Method Order.calculateTotal(pOrderId, pTaxRate)
    ' Method implementation
End Method

Best Practices

Field Declaration

Rule

Always use [New] when declaring new fields in the Top Query.

[New] counter recordCount
counter       =    0
recordCount        [WQRecCount]

[New] message =    "Hello, world!"
[New] Email   |    "Input" | Person.Email

Consistent Naming Patterns

Rule

Use consistent prefixes for related fields to improve code readability.

' Email-related fields
[New] emailTo       =    Person.Email
[New] emailSubject  =    "Welcome"
[New] emailBody     =    "Thank you for registering"

' Date-related fields
[New] startDate     =    $Today
[New] endDate       =    Greg$ (%Greg + 30)
[New] dueDate       =    Greg$ (%Greg + 7)

Error Handling and Logging

Rule

Use descriptive error messages that include context about what failed.

' Good - includes context
If Not pEmail
    api.end.err         ("Error: Email address is required for person: " & pPersonId)
    Exit
End If

' Good - includes relevant details
If responseCode <<>> 200
    api.end.err         ("Error: API returned status " & responseCode & ": " & responseMsg)
    Exit
End If

Quick Reference

Element Convention Example
DB Table Names CamelCase MemTab.Person, Sale.Order
DB Field Names CamelCase FirstName, OrderDate, TotalAmount
Top Query Fields (Non-DB) camelCase counter, recordCount, htmlOutput
Top Query Fields (DB Values) CamelCase Email, Status (when holding DB values)
Work Query Fields (Non-DB) camelCase counter, totalAmount, recordCount
Work Query Fields (DB Values) CamelCase FirstName, Status, OrderDate
Methods/Functions camelCase Person.create(), Order.calculateTotal()
Parameters camelCase with p prefix pPersonId, pEmail, pAmount
Constants camelCase with c prefix cMaxRecords, cTaxRate
Macros camelCase with m prefix Person.mValidate(pAlias)
Query Suffixes CamelCase .Output, .Input
Main Queries Capitalized Input, Output, Request
Indentation Tabs (4 spaces) One tab per nesting level
Method Spacing 2 blank lines Between method definitions
Block Spacing 1 blank line Between Rem blocks

Examples

Complete Method Examples

Method Person.create(pFirstName, pLastName, pEmail)
    Rem 'Validate input
        If Not pEmail
            Exit
        End If
    EndRem

    Rem 'Create new person record
        NewRecord               "Person"
        Set                     "FirstName", `pFirstName
        Set                     "LastName", `pLastName
        Set                     "Email", `pEmail
        Set                     "Created", $Now
        Save
    EndRem
End Method


Method Order.calculateTotal(pOrderId)
    Rem 'Load order items
        LoadRecord              "Finance.Order", pOrderId
        Children                "Finance.LineItem"
        [New] recordCount        [CountIf] Finance.LineItem.Alias
        If Not recordCount
            'error handling...
            Exit
        End If
    EndRem

    Rem 'Calculate totals
        WithAll              "", "Finance.Order.Subtotal", "Sum", "Finance.LineItem.Amount"
        [New] Subtotal       |   Finance.Order.Subtotal
        [New] tax            =   Subtotal * cTaxRate
        [New] Total          =   Subtotal + tax
    EndRem

    Rem 'Update order
        WorkWith                 "Finance.Order"
            SetNew               "Alias", `pOrderId
            SetNew               "Total", `Total
            Backfill
                Update
            End Backfill
            FailIfRecError
        End WorkWith
    EndRem
End Method

Naming Convention Examples

' Database table and field references
MemTab.Person
MemTab.Person.FirstName
Content.Post
Content.Post.Title

' Top Query fields (local variables)
[New] counter       =   0
[New] htmlOutput    =   ""
[New] recordCount       [WQRecCount]

' Top Query Fields holding DB field values
[New] Email         |   MemTab.Person.Email
[New] Status        |   Finance.Order.Status

' Method calls
Person.create           pFirstName, pLastName, pEmail
Order.calculateTotal    orderId
Invoice.send            invoiceId
util.validName          "Me.Output", "FirstName", "LastName"

' Query references
WorkQuery               "Person.getActive.Output"
AppendQuery             "Output", "Order.getRecent.Output"

' Constants
Const    cMaxRetries    = 3
Const    cPageSize      = 50