Capy-Bearer Documentation

component

lib call

Capy

function component(name : string, props : as any = {}, request : capture any) string

Description

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:

  1. the directory of the entry unit that is handling the request

  2. the directory of the unit calling component(), when that differs

  3. the 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>