70 lines
3.4 KiB
Plaintext
70 lines
3.4 KiB
Plaintext
:title
|
|
Coming from React, Next, or Remix
|
|
|
|
:sig
|
|
UCE orientation for React-framework developers
|
|
|
|
:see
|
|
1_RENDER
|
|
1_COMPONENT
|
|
component
|
|
unit_render
|
|
3_C++ Preprocessor
|
|
map
|
|
filter
|
|
dv_filter
|
|
|
|
:content
|
|
UCE is server-first C++ with a small template preprocessor. It does not try to be React, but several concepts map cleanly.
|
|
|
|
## Concept Map
|
|
|
|
- `RENDER(Request& context)` is the page/server-render entrypoint.
|
|
- `COMPONENT(Request& context)` and `COMPONENT:NAME(Request& context)` are server-rendered components.
|
|
- `context.props` is the component invocation payload, similar to props.
|
|
- `context.call` is request-local scratch state shared across units during one request.
|
|
- `context.cfg` is structured app/config data.
|
|
- `ONCE(Request& context)` is per-request setup for a unit before its first render/component entry.
|
|
- `INIT(Request& context)` is worker-local setup when a unit is loaded.
|
|
- `<?= expression ?>` is escaped interpolation; prefer it for user-visible text.
|
|
- `<?: expression ?>` is trusted raw markup output, closer to a deliberate `dangerouslySetInnerHTML` decision.
|
|
- `unit_render()` renders another page unit; `component()` returns component HTML as a string.
|
|
|
|
## Routes and Layouts
|
|
|
|
UCE does not require a framework-level router. A front controller can keep routing explicit and app-local. The starter example demonstrates this in `site/examples/uce-starter/index.uce`: it resolves a request path by checking:
|
|
|
|
1. `views/<path>.uce`
|
|
2. `views/<path>/index.uce`
|
|
3. parent index handlers such as `views/workspace/index.uce` with the last segment as a route parameter
|
|
|
|
That keeps file-based and hierarchical routing in normal UCE code instead of hiding it in the runtime.
|
|
|
|
## Data Shaping Near Render Code
|
|
|
|
The function library includes small collection helpers for common route/menu/card transformations:
|
|
|
|
```cpp
|
|
auto visible = filter(routes, [](String route) { return(route != "admin"); });
|
|
auto labels = map(visible, [](String route) { return(to_upper(route)); });
|
|
DValue app_items = dv_filter(menu, [](DValue item, String key) { return(item["section"].to_string() == "app"); });
|
|
DValue by_section = dv_group_by(menu, [](DValue item, String key) { return(item["section"].to_string()); });
|
|
```
|
|
|
|
Use these when the transformation communicates intent. Prefer explicit loops when side effects or multi-step validation are the main concern.
|
|
|
|
## Assets and Islands
|
|
|
|
Global runtime APIs for assets and islands are intentionally not part of UCE core. The starter emits CSS and JavaScript from the owning unit's `ONCE(Request& context)` hook, with a few shared sibling asset components when multiple components need the same files. The only starter web-affordance helper left is `COMPONENT:island` in `components/theme/web_affordances.uce` for small progressive-enhancement modules. This keeps app policy in the app without an asset registry layer.
|
|
|
|
## Debugging
|
|
|
|
When a unit fails to compile, UCE reports the source path, generated C++ path, compile-output artifact, a source/generated excerpt when it can identify a line, and the raw compiler output. The generated C++ under `BIN_DIRECTORY` is the source of truth for what the configured compiler actually saw.
|
|
|
|
## What Not To Expect
|
|
|
|
- No client-side virtual DOM is built into UCE.
|
|
- No global file-router is imposed by the runtime.
|
|
- No JSX-like component tags are required for this workflow.
|
|
- Component children/slot syntax is intentionally deferred; use explicit props and component calls for now.
|