View helpers¶
View helpers build HTML. They return SafeString values, so their markup is not
re-escaped when emitted with !=. In templates they are called as bare functions
through the view context (link-to, image-tag, and so on), with arguments and
no sigil.
Tag building¶
content-tag builds an element with content; tag builds a self-closing
element. Attribute values are escaped, a True value becomes a bare boolean
attribute, and a False or undefined value is omitted:
1 2 | |
String content is escaped; a SafeString is emitted as-is.
Nested data and aria attributes¶
A data or aria value that is a hash expands to dasherized attributes, and a
structured value is JSON encoded:
1 2 3 4 5 | |
data-attributes builds the same dasherized keys as a hash for merging into
other attributes.
Class helper¶
A class attribute accepts an array of tokens or a hash of conditional tokens,
and class-names builds the same token list on its own:
1 2 3 4 5 | |
Falsy and duplicate tokens are dropped, and an empty class attribute is omitted.
Script, time, and feed tags¶
javascript-tag wraps script content (emitted unescaped) in a <script>
element, time-tag builds a <time> element with a datetime attribute from a
date, and auto-discovery-link-tag builds a feed <link> for atom, rss, or
json:
1 2 3 | |
atom-feed builds an Atom feed document. The feed builder takes title,
updated, and id, and entry yields an entry builder with title,
content, updated, author, and link:
1 2 3 4 5 6 7 | |
URL helpers¶
url-for turns a target into a URL string. It passes a string through and reads
path from a hash. link-to builds an anchor, and button-to builds a small
form that posts to a URL, adding a _method override for other verbs:
1 2 3 | |
Asset helpers¶
asset-path resolves a source to a URL. A bare source is prefixed with
/assets/; an absolute path or external URL is left alone; a :type adds an
extension when the source has none:
1 2 | |
image-tag, stylesheet-link-tag, and javascript-include-tag build the
matching elements, resolving their sources through asset-path. image-tag
derives a default alt from the filename, and the link and script helpers accept
multiple sources:
1 2 3 | |
Pluggable resolver¶
asset-path and the asset tags accept a resolver, a routine of
($source, $type) that returns the final URL. It is the seam for fingerprinting
or a CDN host. A MVC::Keayl::View carries an asset-resolver that its asset
helpers use:
1 2 3 4 | |
Forms¶
form-with builds a form around a FormBuilder. The builder is passed to a
content callback and scopes field names to the model (or an explicit scope),
prefills values, and annotates errors. The form posts by default, adding a
_method override for other verbs and an authenticity_token field when a
csrf-token is given:
1 2 3 4 5 6 7 8 9 | |
Field helpers¶
The builder provides text-field, password-field, hidden-field,
text-area, check-box, radio-button, select, label, submit, and
button. Field names are scoped (post[title]) and ids derived
(post_title). A check-box renders a hidden companion for its unchecked
value, a select marks the option matching the model value, and a
password-field never emits a value. fields-for builds a nested builder whose
names are scoped under the parent:
1 2 3 | |
HTML5 typed inputs¶
The builder also has the HTML5 typed inputs, each setting its type and
prefilling from the model like text-field: email-field, url-field,
telephone-field (type="tel"), number-field, range-field, search-field,
color-field, date-field, time-field, datetime-field
(type="datetime-local"), month-field, and week-field:
1 2 3 | |
file-field builds a file input. A multiple option appends [] to the name
and adds the multiple attribute, and a direct-upload option sets a
data-direct-upload-url:
1 2 3 | |
Outside a builder, button-tag builds a <button type="submit">, and
image-submit-tag builds an image submit input that resolves its source through
asset-path:
1 2 | |
Select and option helpers¶
options-for-select builds <option> tags from a list of strings, label-value
pairs, or [label, value, attrs] triples, marking the selected value.
options-from-collection-for-select reads value and text methods off each
member of a collection, and grouped-options-for-select wraps choices in
<optgroup> elements. select-tag wraps option markup in a <select>, with
multiple, include-blank, and prompt options:
1 2 3 4 | |
time-zone-select builds a select from a built-in zone list. The date-part
helpers select-year, select-month (with month names), select-day,
select-hour, select-minute, and select-second build a single select each,
and select-date and select-time combine them. They name their fields under a
date prefix by default:
1 2 3 | |
On the builder, collection-select, collection-radio-buttons, and
collection-check-boxes build a select, a radio set, or a checkbox set from a
collection, reading value and text methods and marking the model value.
date-select, time-select, and datetime-select build multiparameter selects
(post[born](1i), (2i), (3i)) prefilled from a model date or time:
1 2 3 | |
Model awareness¶
When the builder has a model, fields prefill from it (calling the
attribute-named method), an explicit value overrides the model, and a field
whose attribute reports errors gets a field-with-errors class. The builder
reads errors through the model's errors-on($attribute) method, and
errors-for renders the messages.
simple_form-style inputs¶
SimpleFormBuilder adds an input method that assembles a label, control, hint,
and error into a wrapper, inferring the control type. simple-form-for wraps it
in a form like form-with:
1 2 3 4 5 6 | |
The type is taken from as, then the attribute name (password, email, the
long-text names body/content/description/notes), then a boolean model
value, defaulting to a string input. A required attribute marks the wrapper and
adds a * to the label, and an attribute with errors marks the wrapper and
appends the messages.
Formatting helpers¶
Text¶
truncate cuts a string to a length (counting the omission) and can break at a
separator. pluralize pairs a count with a singular or pluralized word, using a
small inflector with irregulars and an explicit plural override.
simple-format wraps text in paragraphs, turning blank lines into new paragraphs
and single newlines into <br />, escaping the content:
1 2 3 | |
highlight wraps matches of one or more phrases (case-insensitively, keeping the
original text) using a highlighter template where \1 is the match, escaping
the surrounding text. excerpt extracts a window of text around a phrase with
omission markers, and word-wrap breaks lines at a width:
1 2 3 | |
strip-tags removes every tag, strip-links removes anchors but keeps their
text, and sanitize-css drops style declarations whose values contain unsafe
tokens (javascript:, expression, @import, behavior, -moz-binding):
1 2 3 | |
cycle rotates through a set of values across calls (keyed by an optional
name), current-cycle reports the last value, and reset-cycle restarts it.
capture returns a block's output as a safe string, and provide accumulates
content under a name for a layout yield:
1 2 3 4 5 | |
Numbers¶
1 2 3 4 | |
number-to-currency accepts unit, precision, delimiter, separator, and a
format string (%u for the unit, %n for the number).
number-to-phone groups a phone number, with area-code, delimiter,
country-code, and extension options. number-to-human scales a number to a
word (Thousand, Million, Billion, Trillion, Quadrillion) at a significant-digit
precision:
1 2 3 4 | |
Date and time¶
distance-of-time-in-words describes the gap between two times in words, with an
optional include-seconds for finer detail under a minute. time-ago-in-words
is the same measured against the current time (or an explicit reference):
1 2 3 | |
Helper modules¶
Beyond the built-in helpers, an application defines its own helpers as our subs
in modules under app/helpers/. Each sub becomes a bare template call.
ApplicationHelper is global, available in every view:
1 2 3 4 5 6 | |
1 2 | |
A per-controller helper named after the controller (UsersController →
app/helpers/UsersHelper.rakumod) is available only in that controller's views,
and the chain follows controller inheritance: a controller sees its own helper,
its ancestors' helpers, and ApplicationHelper.
A helper is a plain function. For request state, read $*KEAYL-CONTROLLER:
1 2 3 | |
Helper modules reload on change in development (gated by the view's reload
flag), the same as templates. The controller and scaffold generators write a
matching helper module, and keayl new writes ApplicationHelper.