decided in favor of dedicated COMPONENT() macro, updates to documentation
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
String Functions
|
||||
|
||||
ascii_safe_name
|
||||
concat
|
||||
filter
|
||||
first
|
||||
join
|
||||
json_encode
|
||||
nibble
|
||||
print
|
||||
split
|
||||
|
||||
@@ -11,6 +11,7 @@ file_put_contents
|
||||
get_cwd
|
||||
ls
|
||||
mkdir
|
||||
path_join
|
||||
set_cwd
|
||||
shell_escape
|
||||
shell_exec
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
Types
|
||||
|
||||
DTree
|
||||
get_by_path
|
||||
set_status
|
||||
String
|
||||
StringMap
|
||||
|
||||
@@ -28,6 +28,9 @@ Name of the session cookie
|
||||
:DTree var
|
||||
Variable user-defined data
|
||||
|
||||
:DTree cfg
|
||||
Request-local configuration tree. Apps can keep structured configuration here and traverse it with `context.cfg.get_by_path("path/to/value")`.
|
||||
|
||||
:DTree call
|
||||
Invocation or message-local structured data
|
||||
|
||||
@@ -43,6 +46,9 @@ Headers to be sent back to the browser
|
||||
:StringList set_cookies;
|
||||
Cookies that should be sent back to the browser
|
||||
|
||||
:context.set_status(s32 code[, String reason])
|
||||
Sets the HTTP status line and updates `context.flags.status`. When `reason` is omitted, UCE uses a built-in standard reason phrase for common status codes.
|
||||
|
||||
:u64 random_seed
|
||||
The current request's "random" noise generator seed
|
||||
|
||||
@@ -64,4 +70,3 @@ Invokes another UCE file using the current or supplied request context
|
||||
:see
|
||||
>types
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
:sig
|
||||
COMPONENT(Request& context)
|
||||
|
||||
:desc
|
||||
Defines the default component entrypoint for the current `.uce` file.
|
||||
|
||||
`component()` and `render_component()` invoke `COMPONENT(Request& context)` by default. Named component entrypoints use `COMPONENT:NAME(Request& context)`.
|
||||
|
||||
This keeps page rendering and component rendering separate:
|
||||
|
||||
- direct HTTP requests call `RENDER(Request& context)`
|
||||
- WebSocket messages call `WS(Request& context)`
|
||||
- component helpers call `COMPONENT(Request& context)` or `COMPONENT:NAME(Request& context)`
|
||||
|
||||
A file intended only for component reuse can define `COMPONENT()` without defining `RENDER()`.
|
||||
|
||||
Inside component handlers, props arrive through `context.call`.
|
||||
|
||||
When you call `component(":NAME", props, context)` or `render_component(":NAME", props, context)`, the runtime resolves `:NAME` against the current `.uce` file instead of requiring the file name again.
|
||||
|
||||
Examples:
|
||||
`COMPONENT(Request& context)`
|
||||
`{`
|
||||
` <><section><?: component(":BODY", context.call, context) ?></section></>`
|
||||
`}`
|
||||
|
||||
`COMPONENT:BODY(Request& context)`
|
||||
`{`
|
||||
` <><p><?= context.call["body"] ?></p></>`
|
||||
`}`
|
||||
|
||||
:see
|
||||
>component
|
||||
>render_component
|
||||
>1_RENDER
|
||||
>1_WS
|
||||
@@ -6,19 +6,17 @@ Defines the main HTTP render handler for the current `.uce` page.
|
||||
|
||||
When a page is requested over HTTP, the runtime loads the target file and calls its `RENDER(Request& context)` function.
|
||||
|
||||
Pages may also export additional named render handlers with `RENDER:NAME(Request& context)`.
|
||||
|
||||
Named render handlers are not used for the page's direct HTTP entrypoint. They are intended for component-style sub-rendering through helpers such as `component("components/card:BODY", props, context)` or `render_component("components/card:BODY", props, context)`.
|
||||
|
||||
The default page entrypoint is always the plain `RENDER(Request& context)` handler.
|
||||
|
||||
Reusable component handlers now live on `COMPONENT(Request& context)` and `COMPONENT:NAME(Request& context)`. The component helpers call those handlers, not `RENDER()`.
|
||||
|
||||
The request environment is passed explicitly through `context`, including params, cookies, post data, session state, headers, uploaded files, and the current `context.call` tree.
|
||||
|
||||
For a normal direct page request, `context.call` starts empty.
|
||||
|
||||
If the page is invoked from another UCE file via `render_file(file_name, context)`, the callee receives that same `context`.
|
||||
|
||||
Pages intended to serve WebSocket traffic may expose both `RENDER(Request& context)` and `WS(Request& context)`. In that case `RENDER(Request& context)` serves the initial HTTP response and `WS(Request& context)` handles subsequent WebSocket messages.
|
||||
Pages intended to serve WebSocket traffic may expose both `RENDER(Request& context)` and `WS(Request& context)`. Files may also define `COMPONENT()` handlers when they intentionally need both page and component behavior in one unit. In that case `RENDER(Request& context)` serves the direct HTTP response, `WS(Request& context)` handles subsequent WebSocket messages, and `COMPONENT()` remains available only through the component helpers.
|
||||
|
||||
:see
|
||||
>ob
|
||||
|
||||
@@ -12,7 +12,8 @@ The implementation lives in `src/lib/compiler.cpp`. It does not try to parse all
|
||||
- Inside a literal block, `<?= expression ?>` emits `print(html_escape(expression));`.
|
||||
- Inside a literal block, `<?: expression ?>` emits `print(expression);` without HTML escaping.
|
||||
- `#load "other.uce"` injects another UCE unit at compile time.
|
||||
- `RENDER(Request& context)` and `WS(Request& context)` are normal C++ macros from `src/lib/compiler.h`.
|
||||
- `RENDER(Request& context)`, `COMPONENT(Request& context)`, and `WS(Request& context)` are normal C++ macros from `src/lib/compiler.h`.
|
||||
- `COMPONENT:NAME(Request& context)` is rewritten by the custom pass into an exported named component handler.
|
||||
- `EXPORT` is also a normal C++ macro, but the custom pass additionally records exported declarations for metadata.
|
||||
|
||||
:Pipeline
|
||||
@@ -25,6 +26,7 @@ The implementation lives in `src/lib/compiler.cpp`. It does not try to parse all
|
||||
- `<?: ... ?>` becomes `print(...);` and is intended for trusted markup or already-escaped content.
|
||||
- `#load "file.uce"` is replaced with a generated C++ `#include` that points at the loaded unit's preprocessed `.cpp` file under `BIN_DIRECTORY`.
|
||||
- Lines beginning with `EXPORT` are scanned so their declarations can be written to a sibling `.exports.txt` file.
|
||||
- Lines beginning with `COMPONENT:NAME(...)` are rewritten into exported `component_render_NAME(...)` functions for the component helpers.
|
||||
- The final generated source is written to `BIN_DIRECTORY + src_path + "/" + source_file + ".cpp"`.
|
||||
- `scripts/compile` then compiles that generated `.cpp` into `source_file + ".so"` with `clang++ -shared -std=c++20 ...`.
|
||||
|
||||
@@ -93,3 +95,4 @@ load
|
||||
render_file
|
||||
call_file
|
||||
0_context
|
||||
1_COMPONENT
|
||||
|
||||
@@ -18,6 +18,7 @@ Useful methods include:
|
||||
`to_string()`
|
||||
`to_json()`
|
||||
`get_type_name()`
|
||||
`get_by_path()`
|
||||
`set_bool()`
|
||||
`remove()`
|
||||
`clear()`
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
:sig
|
||||
String ascii_safe_name(String raw)
|
||||
|
||||
:params
|
||||
raw : input string to normalize
|
||||
return value : ASCII-safe identifier made from letters, digits, and underscores
|
||||
|
||||
:desc
|
||||
Builds a conservative identifier by keeping ASCII letters, digits, and underscores and dropping other characters.
|
||||
|
||||
This is useful when turning user- or config-provided names into handler suffixes, DOM-safe variable stems, or CSS/JS hook names.
|
||||
|
||||
:see
|
||||
>string
|
||||
@@ -10,9 +10,11 @@ Component props are passed in `context.call`.
|
||||
|
||||
Because `<?= ... ?>` HTML-escapes its value, embed component markup with `<?: component(...) ?>`, `print(component(...))`, or use `render_component(...)` for direct output.
|
||||
|
||||
When `name` contains a colon, such as `components/card:BODY`, the part after the colon selects a named render handler exported from the component file through `RENDER:BODY(Request& context)`.
|
||||
When `name` contains a colon, such as `components/card:BODY`, the part after the colon selects a named component handler exported from the component file through `COMPONENT:BODY(Request& context)`.
|
||||
|
||||
The default handler is `RENDER(Request& context)`.
|
||||
The default handler is `COMPONENT(Request& context)`.
|
||||
|
||||
When `name` starts with a colon, such as `:BODY`, the target resolves against the current `.uce` file so component files can call their own named handlers without repeating the file name.
|
||||
|
||||
Resolution order is:
|
||||
exact file name
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
:sig
|
||||
DTree DTree::get_by_path(String path, String delim = "/")
|
||||
|
||||
:params
|
||||
path : slash-delimited path to traverse
|
||||
delim : optional path separator
|
||||
return value : the resolved child node, or an empty `DTree` when the path cannot be followed
|
||||
|
||||
:desc
|
||||
Traverses a nested `DTree` without creating missing keys.
|
||||
|
||||
Empty path segments are ignored, so leading and trailing `/` characters are harmless. If any intermediate node is not a map or a segment is missing, `get_by_path()` returns an empty `DTree`.
|
||||
|
||||
Typical usage:
|
||||
`context.cfg.get_by_path("theme/options/portal-dark/label").to_string()`
|
||||
|
||||
:see
|
||||
DTree
|
||||
0_context
|
||||
>types
|
||||
@@ -1,10 +1,15 @@
|
||||
:sig
|
||||
String json_encode(String s)
|
||||
String json_encode(DTree t)
|
||||
|
||||
:params
|
||||
s : string to encode as a JSON string literal
|
||||
t : DTree object to be serialized
|
||||
return value : string containing the JSON result
|
||||
|
||||
:desc
|
||||
Serializes a DTree structure 't' into a String in JSON notation.
|
||||
Serializes either a `String` or a `DTree` into JSON notation.
|
||||
|
||||
When passed a `String`, `json_encode()` returns a quoted and escaped JSON string literal.
|
||||
|
||||
When passed a `DTree`, scalar values are serialized directly and nested map values are emitted as JSON objects.
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
:sig
|
||||
String path_join(String base, String child)
|
||||
|
||||
:params
|
||||
base : parent path
|
||||
child : child path or absolute override
|
||||
return value : combined path
|
||||
|
||||
:desc
|
||||
Joins two filesystem-style path fragments with a single `/` when needed.
|
||||
|
||||
If `child` is empty, `base` is returned. If `child` already starts with `/`, it is returned unchanged. This makes `path_join()` a better fit for app-level path assembly than open-coded string concatenation.
|
||||
|
||||
:see
|
||||
>sys
|
||||
@@ -6,7 +6,9 @@ Renders another `.uce` file as a component and writes the result directly to the
|
||||
|
||||
This is the direct-output counterpart to `component()`.
|
||||
|
||||
Component props are passed through `context.call`, and `name:RENDERFUNC` may be used to select a named handler exported by `RENDER:RENDERFUNC(Request& context)`.
|
||||
Component props are passed through `context.call`, and `name:COMPONENTFUNC` may be used to select a named handler exported by `COMPONENT:COMPONENTFUNC(Request& context)`.
|
||||
|
||||
When `name` starts with `:`, the runtime resolves that named handler against the current `.uce` file.
|
||||
|
||||
Use `render_component()` when you want to write component output directly from C++ code instead of capturing it as a `String`.
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
:sig
|
||||
void context.set_status(s32 code, String reason = "")
|
||||
|
||||
:params
|
||||
code : HTTP status code
|
||||
reason : optional reason phrase override
|
||||
|
||||
:desc
|
||||
Sets the current request status line and mirrors the numeric status into `context.flags.status`.
|
||||
|
||||
When `reason` is omitted, UCE fills in a standard reason phrase for common HTTP status codes such as `200`, `302`, `400`, `404`, and `500`.
|
||||
|
||||
:see
|
||||
0_context
|
||||
>types
|
||||
Reference in New Issue
Block a user