Class Enhancements
Spaceport enhances standard Groovy classes with many additional methods designed to make common frontend and backend tasks easier. These utilities provide powerful and convenient shortcuts for data manipulation, web content handling, serialization, and formatting, streamlining the development of web applications.
Becoming a Groovy Luminary will teach you how you can make your own class enhancements, providing a powerful way to tailor your application to your specific needs.
# Quick Reference
This section provides a comprehensive overview of all available class enhancements organized by type. For detailed explanations, examples, and usage patterns, see the Enhancement Concerns section below.
## String Methods
| Method | Returns | Description |
|---|---|---|
clean() |
String |
Sanitizes HTML based on cleanType property ('none', 'simpleText', 'simple', 'basic', 'relaxed') |
surroundWith(String prefix, String suffix) |
String |
Wraps string with prefix and suffix |
surroundWith(String fix) |
String |
Wraps string with HTML tag (auto-generates closing tag) |
escape() |
String |
Converts HTML special characters to entities |
unescape() |
String |
Converts HTML entities back to characters |
quote() |
String |
Wraps string in double quotes and escapes internal quotes |
strip(String regex) |
String |
Removes all occurrences of regex pattern |
encode() |
String |
URL-encodes the string (UTF-8) |
decode() |
String |
URL-decodes the string (UTF-8) |
toBase64() |
String |
Encodes string to Base64 |
fromBase64() |
String |
Decodes Base64 string |
kebab() |
String |
Converts to kebab-case (e.g., "myURLAddress" → "my-url-address") |
snake() |
String |
Converts to snake_case (e.g., "HelloWorld" → "hello_world") |
slugify() |
String |
Converts to URL-friendly slug (removes special chars, transliterates) |
phone() |
String |
Formats 10 or 11-digit number as US phone number |
money() |
BigDecimal |
Parses currency string (e.g., "$1,234.56") to BigDecimal |
time() |
Long |
Parses datetime-local form string to epoch milliseconds |
jsonList() |
List |
Parses JSON array string to List |
jsonMap() |
Map |
Parses JSON object string to Map |
js() |
String |
Wraps string in <script type='text/javascript'> tags |
if(Closure c) |
String |
Returns string if closure evaluates true, empty string otherwise |
roll() |
Integer |
Evaluates dice notation (e.g., "2d6+3") and returns roll result |
cdata() |
String |
Wraps string content in CDATA tags for safe embedding |
## Number Methods
| Method | Returns | Description |
|---|---|---|
money() |
String |
Formats number as currency using default Locale (e.g., "$1,299.95") |
ordinal() |
String |
Returns ordinal representation (e.g., 1 → "1st", 22 → "22nd") |
hours() |
Long |
Converts number to milliseconds (hours × 60 × 60 × 1000) |
minutes() |
Long |
Converts number to milliseconds (minutes × 60 × 1000) |
seconds() |
Long |
Converts number to milliseconds (seconds × 1000) |
days() |
Long |
Converts number to milliseconds (days × 24 × 60 × 60 × 1000) |
time() |
String |
Formats epoch milliseconds as "hh:mm:ss a" (12-hour with AM/PM) |
date() |
String |
Formats epoch milliseconds as "MMMM dd, yyyy" |
dateRaw() |
String |
Formats epoch milliseconds as "MM/dd/yyyy" |
dateTime() |
String |
Formats epoch milliseconds as "MMMM dd, yyyy hh:mm a z" |
dateTimeRaw() |
String |
Formats epoch milliseconds as "MM/dd/yyyy hh:mm a z" |
relativeTime() |
String |
Returns human-friendly relative time (e.g., "5 minutes ago", "in 2 hours") |
formTime() |
String |
Formats epoch milliseconds for HTML datetime-local input ("yyyy-MM-dd'T'HH:mm") |
## Integer-Specific Methods
| Method | Returns | Description |
|---|---|---|
random() |
Integer |
Returns random integer between 0 (inclusive) and the number (exclusive) |
randomID() |
String |
Generates random hex ID of specified length (1-32), starting with letter a-f |
## List Methods
| Method | Returns | Description |
|---|---|---|
clean() |
List |
Cleans String items in list based on cleanType property (modifies in place) |
snap(Integer time, Object obj) |
List |
Temporarily adds item(s) for specified milliseconds, then removes |
random() |
Object |
Returns random item from list |
combine(Closure c) |
String |
Collects items using closure and joins into string |
combine(Closure sort, Closure collect) |
String |
Sorts using first closure, collects with second, joins into string |
including(Object obj) |
List |
Adds item or items from another list, returns modified list for chaining |
json() |
String |
Serializes list to JSON string |
if(Closure c) |
Object |
Returns first element if closure evaluates true, second element otherwise |
## Map Methods
| Method | Returns | Description |
|---|---|---|
snap(Integer time, String key, Object obj) |
Map |
Temporarily adds key-value pair(s) for specified milliseconds, then removes |
combine(Closure c) |
String |
Collects entries using closure and joins into string |
combine(Closure sort, Closure collect) |
String |
Sorts using first closure, collects with second, joins into string |
including(Map map) |
Map |
Adds all entries from another map, returns modified map for chaining |
random() |
Map.Entry |
Returns random key-value entry from map |
json() |
String |
Serializes map to JSON string |
## Collection Methods
| Method | Returns | Description |
|---|---|---|
json() |
String |
Serializes any collection to JSON string |
## Object Methods
| Method | Returns | Description |
|---|---|---|
isPresent(Collection c) |
Boolean |
Fluent alternative to collection.contains(object) |
_update() |
void |
Triggers reactive updates for all bound connections |
_forceUpdate() |
void |
Forces reactive update regardless of value changes |
cdata() |
String |
Wraps object (or its JSON representation) in CDATA tags |
# Enhancement Concerns
The enhancements can be grouped into several categories, each addressing specific development needs. While they can be used throughout your codebase, some are particularly useful in specific contexts, such as within Launchpad templates or when processing user input.
## String Manipulation and Formatting
Spaceport provides powerful tools for transforming strings. Case conversions handle a variety of inputs intelligently:
// Case and format conversions
"hello_world".kebab() // Returns "hello-world"
"HelloWorld".kebab() // Returns "hello-world"
"Hello World".snake() // Returns "hello_world"
"Hello World!".slugify() // Returns "hello-world"
The kebab() and snake() methods intelligently handle CamelCase, spaces, hyphens, and underscores while trimming
excess whitespace. The slugify() method goes further by removing or transliterating non-ASCII characters and
stripping most punctuation.
The versatile surroundWith() method wraps strings with prefix and suffix. When given a single argument that looks
like an HTML tag (even with attributes), it intelligently creates the corresponding closing tag:
"test".surroundWith("->", "<-") // Returns "->test<-"
"content".surroundWith("<div class='main'>")
// Returns "<div class='main'>content</div>"
Additional utilities include quote() for wrapping in quotes with internal escaping, strip(regex) for removing
pattern matches, and phone() for formatting 10 or 11-digit numbers into standard US phone format.
## HTML, Web, and Security
The clean() method sanitizes HTML to prevent XSS attacks. Set the cleanType property to control behavior:
'none': Strips all HTML, leaving only text content'simpleText': Allows basic formatting tags like<b>,<i>, and<strong>'simple': AllowssimpleTexttags plus<br>,<s>, and<strike>'basic': Allows basic HTML elements for simple formatting'relaxed': Allows more comprehensive HTML including images
For manual escaping, escape() converts HTML characters to entities, while unescape() reverts them. URL handling
is simplified with encode() and decode() for safe parameter inclusion. The js() method wraps JavaScript in
proper script tags.
The cdata() method wraps content in CDATA tags for safe embedding in XML contexts, automatically converting
non-string objects to JSON:
"<script>alert('test')</script>".cdata()
// Returns <!--<![CDATA[<script>alert('test')</script>]]>--!>
[name: "Test", value: 123].cdata()
// Returns <!--<![CDATA[{"name":"Test","value":123}]]>--!>
## Data Serialization and Conversion
Convert between data formats effortlessly. The universal json() method serializes any Collection or Map:
[name: "Groovy", version: 4].json()
// Returns '{"name":"Groovy","version":4}'
Parse JSON with jsonMap() for objects or jsonList() for arrays:
'{"name":"Groovy"}'.jsonMap() // Returns [name: "Groovy"]
'[1, 2, 3]'.jsonList() // Returns [1, 2, 3]
Base64 encoding is available through toBase64() and fromBase64(). Parse formatted currency strings into
BigDecimal with String.money():
'$1,234.56'.money() // Returns 1234.56 as BigDecimal
The roll() method evaluates tabletop dice notation, perfect for games or simulations:
"2d6+3".roll() // Returns result of rolling 2 six-sided dice plus 3
"d20".roll() // Returns result of rolling 1 twenty-sided die
## Collection Handling
The snap() method temporarily adds items with automatic removal after a specified duration—ideal for flash
messages or temporary flags:
def messages = []
messages.snap(5000, "This message disappears in 5 seconds.")
def userFlags = [:]
userFlags.snap(1.minutes(), 'isNew', true)
The including() method fluently adds items while returning the collection for chaining:
def list = [1, 2, 3].including(4).including([5, 6])
// Returns [1, 2, 3, 4, 5, 6]
Retrieve random items with random(), which returns a random element from a List or a random Map.Entry from
a Map.
The powerful combine() method aggregates collections into strings:
def list = [5, 3, 1, 4, 2]
// Sorts the list, then joins the items into a string
list.combine({ it }, { it }) // Returns "12345"
def map = [c: 3, a: 1]
// Sorts by key, then combines the values
map.combine({ it.key }, { it.value }) // Returns "13"
## Time and Date Operations
Working with dates and times (represented as epoch milliseconds) is dramatically simplified. Convert numbers into durations:
def fiveHoursThirtyMinutes = 5.hours() + 30.minutes()
def deadline = System.currentTimeMillis() + 2.days()
Format epoch milliseconds into human-readable strings:
def timestamp = System.currentTimeMillis()
timestamp.date() // "October 28, 2025"
timestamp.time() // "02:30:45 PM"
timestamp.dateTime() // "October 28, 2025 02:30 PM EDT"
timestamp.dateRaw() // "10/28/2025"
timestamp.dateTimeRaw() // "10/28/2025 02:30 PM EDT"
timestamp.relativeTime() // "just now" or "in 5 minutes"
timestamp.formTime() // "2025-10-28T14:30" (for datetime-local inputs)
The relativeTime() method provides human-friendly descriptions like "just now", "5 minutes ago", "in 2 hours",
"3 days ago", etc., automatically choosing appropriate units.
Parse form datetime strings back to epoch milliseconds:
"2025-10-28T14:30".time() // Returns epoch milliseconds
## Numeric Utilities and Generation
Format numbers as currency using the default JVM Locale:
1299.95.money() // Returns "$1,299.95" (in US Locale)
Get ordinal representations:
1.ordinal() // Returns "1st"
22.ordinal() // Returns "22nd"
103.ordinal() // Returns "103rd"
Generate random integers:
10.random() // Returns random number from 0 to 9
Create random IDs suitable for HTML IDs and CSS class names with randomID(). It generates hexadecimal strings
guaranteed to start with a letter (a-f), with lengths between 1 and 32 characters:
8.randomID() // Returns random 8-character hex like "e4b1a0c9"
16.randomID() // Returns random 16-character hex like "a3f8d9c2b1e4567f"
## General and Conditional Utilities
The if() method provides concise conditional string production:
// Only show the admin link if the user is an admin
def adminLink = "<a href='/admin'>Admin</a>".if { user.isAdmin() }
For lists, if() enables conditional selection between two values:
def message = ["Success!", "Failed"].if { operation.succeeded() }
// Returns "Success!" if true, "Failed!" if false
Check object presence with readable syntax:
5.isPresent([1, 3, 5]) // Returns true
'x'.isPresent(['a', 'b']) // Returns false
## Reactive System Methods
> Note: These methods are primarily for internal use by Spaceport's reactivity system. Understanding them can be > helpful for advanced scenarios, but most applications won't need to call them directly.
The _update() method triggers reactive updates for all connections bound to an object. When you modify a reactive
variable, this method notifies all connected clients:
// Usually called automatically, but can be triggered manually
myReactiveList.add("new item")
myReactiveList._update() // Notify all connected clients
The _forceUpdate() method forces an update regardless of whether values actually changed, useful when you need to
refresh client state:
// Force refresh even if no changes detected
myObject._forceUpdate()
These methods work behind the scenes with Launchpad's reactive features. See Launchpad and Server Elements for more information on building reactive components.
# Next Steps
Explore the various modules of Spaceport to see how these class enhancements can be applied in real-world scenarios:
- Launchpad - Utilize string and collection enhancements in your HTML templates
- Routing - Leverage string manipulation for URL handling
- Documents - Use data serialization methods for database interactions
- Sessions & Client Management - Apply security-related string methods for user authentication
- Server Elements - Create dynamic components using collection and string utilities
- Groovy Luminary - Learn to create your own custom class enhancements
SPACEPORT DOCS