Component template

The component template is the core part of the .gen file, which is used to describe the page structure. It is contained in the <template> tag, and its syntax style is similar to HTML, but it combines the enhanced syntax of the component system.

Basic syntax

There are two ways to declare components: regular tags and self-close tags.

Regular tags

  • Wrapped by a pair of <$component_name></$component_name>
  • Supports setting component properties, binding values, and event callbacks
  • Supports nested subcomponents

Self-close tags

  • The form is <$component_name />
  • Subcomponents are not allowed
  • Also supports setting properties, bindings, and events

Syntax examples

1<template>
2    <$component_name
3        $($($static_prop="$prop_value")*)?
4        $($(:$bind_prop="$bind_ident")*)?
5        $($(@callback="$callback_ident($($arg),*)")*)?
6    >
7        <$component_name
8            $($($static_prop="$prop_value")*)?
9            $($(:$bind_prop="$bind_ident")*)?
10            $($(@callback="$callback_ident($($arg),*)")*)?
11        />
12        // ...
13    </$component_name>
14</template>
  • $component_name: component name
  • $static_prop: static property
  • $prop_value: property value
  • $bind_prop: binding property
  • $bind_ident: binding variable identifier
  • $callback: callback
  • $callback_ident: callback method identifier
  • $arg: parameter
  • $()*: many1, 1 or more
  • $()?: recognize, 0 or 1

Example

root.gen
1<template>
2  <view id="UiRoot">
3    <label text="'Hello GenUI!'"></label>
4    <view height="100.0" width="100.0" theme="Info"></view>
5    <tag text="'hello'" />
6  </view>
7</template>

Syntax rules

In the syntax rules section, we will explain in detail the rules for writing component templates

Root component

The root component refers to the root component of the component template part in each .gen file, that is, the first tag wrapped by the <template> tag

1<template>
2  <view id="UiRoot"></view>
3</template>

In this example, the root component is <view id="UiRoot"></view>

Unique root principle

Any component template has one and only one unique root component, and the root component must have a unique name

Static unique root
Dynamic unique root
1<view id="SpecialName"></view>
TIP

You may have discovered that the unique naming attributes used statically and dynamically are different. Static uses id and dynamic uses name

The difference between them is that you cannot do any script-level code manipulation when using a static unique root, i.e. using <script>

Naming reference principle

  1. This principle is only valid for the root component. For the root component only, the unique name is the component name when it is referenced externally. For example, when the unique name is Hello, use <Hello></Hello> in other components to represent the component

  2. You can also use snake name rule to name the root component, for example: my_view1, but when it is introduced in other components, it will still be converted to camel name rule, that is: <MyView1></MyView1>

  3. The naming reference principle is only valid for external references

Default inheritance principle

For the root component, the view view component is inherited by default and cannot be changed. We hope that each encapsulated component can appear as an independent single view.

Internal and external principles

The above description of the root component id and name is called the internal principle and the external principle. id is internal and name is external, which means:

  • id is only valid for the current encapsulated component. The external cannot obtain the internal component through the internal id

  • name is only valid for the external, and is the way to use the encapsulated component externally. The component cannot be obtained by name internally, and name only exists in <component>

Static properties

The writing method of static properties is: $static_prop="$prop_value", and multiple properties are separated by spaces, for example:

1<view height="100.0" width="200.0"></view>

The property value of the component is typed, wrong type cannot be compiled

TIP

For the type of property value, please refer to: Data Type

id

id is the unique identifier of a component. Each component has this attribute. id can be used to obtain the corresponding component. It is also the attribute identifier of the component

1<label id="my_label"></label>
TIP

If you can't understand, please read [Inside and Outside Principles](#Inside and Outside Principles) first

class

class is the attribute (style) identifier of a component. class can be used to merge the style (<style>) part into the component

  • class is not unique
  • A component can have multiple classs, but cannot declare multiple classs
1<label class="common_label"></label>
2
3<label class="[common_label, bold_label, font_smaller]"></label>

as_prop property component

as_prop property converts a component into a property of its parent component, which comes from a way to build slots in Makepad

Currently involved in button, view, popup components

Binding properties

For properties that need to be bound, use : as the property prefix, and the property value is of Bind::Ident type, as follows:

1<view id="my_view" :height="view_h"></view>

Computed Properties

Computed properties are values ​​dynamically calculated based on existing properties. In GenUI, computed properties do not store state, but are automatically updated based on changes in their dependencies.

FeaturesComputedTwo-way Binding
Store state?❌ No✅ Yes
Mutable?✅ Update when dependencies change✅ Yes
Manually editable?✅ But cannot use set_xxx method✅ Modify via set_xxx
Dependent data✅ Requires dependencies✅ Component state

Computed properties are written by declaring them using methods when binding properties:

1<view id="my_view" :height="view_h()"></view>
TIP

For a detailed description of computed properties, see Api: #[computed]

Callback

Callback means a method called after a component triggers an event, using @ as the callback prefix, as follows:

1<button id="my_btn" @clicked="click_btn()"></button>
TIP

There may not be any parameters in the callback, but you still need to add ()

If the component uses a callback, you must add id as an identifier

Automatic ID strategy

Since v0.1.2, GenUI has introduced the automatic ID allocation strategy. During the component construction process, the system automatically checks whether each component has explicitly specified an id. If not, a random unique ID will be generated for it.

This mechanism is extremely useful in many scenarios, including:

  • Property binding (:prop="...")
  • Event callback (@event="...")
  • Computed property association
  • Various syntax sugar processing

The introduction of automatic ID greatly reduces the tediousness of manual identifier management and improves the simplicity and maintainability of template code.

ID generation rules

Instead of using ulid or other third-party libraries, we generate IDs according to the following custom strategy:

  1. Start with an English letter: Ensure that the variable naming specification is met to avoid potential syntax conflicts.
  2. Length limit: The ID length is controlled between 6 ~ 12 characters to avoid conflicts caused by being too short or redundant due to being too long.
  3. Character composition: only contain English letters and numbers, no special characters, to maintain compatibility and readability.