component
lib callCapy
function component(name : string, props : as any = {}, request : capture any) stringDescription
component() renders a component and returns everything it printed as a string.
It collects the output into a buffer, which costs something. Reach for component_render() instead when you are writing the fragment straight into the current response and never look at the string — it skips the buffer entirely, so component_render("card") does less work than print(component("card")).
Capture the string when the string is the goal: wrapping the fragment in surrounding markup, checking whether it produced anything before emitting a container, storing it in an any beside other values, or emitting the same fragment more than once from one call.
How a name resolves
A name is a path with an optional :HANDLER suffix. Bearer appends .capy when the path has no suffix, so "card" and "card.capy" mean the same file.
A path that starts with / is tried first as a real filesystem path and then as a site-root path, so "/tests/capy-request-context.capy" means that file under the site root.
A relative path is tried against three directories, in order:
the directory of the entry unit that is handling the request
the directory of the unit calling
component(), when that differsthe site root
The first match wins. A resolved path that escapes the site root is rejected. Use component_resolve() to see which file a name reached. Test an optional name with length(component_resolve(name)) > 0 before you render it.
Named handlers
"lib/widgets.capy:CARD" calls the COMPONENT:CARD handler in that file. A name that is only ":CARD" calls COMPONENT:CARD in the file that is currently rendering, which lets one file hold several related fragments.
A file with no named handler must define a plain COMPONENT handler.
What the component sees
Declare function COMPONENT(props : any) or function COMPONENT:NAME(props : any) to receive the input.
Props are shared objects. Changes to their contents remain visible to the caller. Each nested component receives its own props argument.
The component binds request implicitly. Both props and request declarations are optional. You can declare function COMPONENT(props : any, request : any) to make both explicit. Bearer does not refresh request keys between handlers. request.unit continues to identify the entry unit.
Relative component paths use the entry unit's directory first, then the current component's directory, then the site root. An entry-directory file can therefore hide a sibling of a nested component. Use a site-root path when the target must be unambiguous.
The target unit's ONCE handler runs before its first render or component invocation in the request. All named components in that unit share the hook. Its output is part of the first captured string. If you discard that string, later component calls do not emit those assets again. ONCE does not place assets in the document head.
Parameters
name : a component path, optionally followed by :HANDLER
props : optional input, received through the component's props parameter
request : the caller's request, captured when omitted
Return Values
The component output as a string.
Errors
An unresolvable component does not raise an error. Bearer sets the response status to 500, returns an empty string, and continues to render the page. Guard optional components with length(component_resolve(name)) > 0 when a missing file should not be an error.
Example
Capy
print(component("/doc/examples/card.capy:CARD", title: "Release notes"), "\n")
Output
<article>Release notes</article>
Example
Capy
var body := component("/doc/examples/card.capy:CARD", title: "Ada")
print("<section>", body, "</section>", "\n")
Output
<section><article>Ada</article></section>
Example
Capy
var titles := ["Ada", "Grace"]
for title := titles
{
print(component("/doc/examples/card.capy:CARD", title: title))
}
print("\n")
Output
<article>Ada</article><article>Grace</article>
Example
Capy
if length(component_resolve("/doc/examples/card.capy")) > 0
{
print(component("/doc/examples/card.capy:CARD", title: "Optional"), "\n")
}
else
{
print("no card component\n")
}
Output
<article>Optional</article>