Skip to content
On this page

Pages and components

Kyoto provides a way to define components. It's a very common approach for modern libraries to manage frontend parts. In kyoto each component is a context receiver, which returns it's state. Each component becomes a part of the page or top-level component, which executes component asynchronously and gets a state future object. In that way your components are executing in a non-blocking way.

Pages are just top-level components, where you can configure rendering and page related stuff.

Example:

go
// Component is a context receiver, that returns it's state.
// State can be whatever you want (simple type, struct, slice, map, etc).
func CUUID(ctx *kyoto.Context) (state CUUIDState) {
	// Fetch uuid data
	resp, _ := http.Get("http://httpbin.org/uuid")
	data := map[string]string{}
	json.NewDecoder(resp.Body).Decode(&data)
	// Set state
	state.UUID = data["uuid"]
}

// Page is just a top-level component, which attaches components and defines rendering
func PExample(ctx *kyoto.Context) (state PExampleState) {
	// Define rendering
	kyoto.Template(ctx, "page.example.html")
	// Attach components
	state.UUID1 = kyoto.Use(ctx, CUUID)
	state.UUID2 = kyoto.Use(ctx, CUUID)
}

As an option, you can wrap component with another function to accept additional paramenters from top-level page/component.

Example:

go
func CUUID(hburl string) kyoto.Component[CUUIDState] {
	return func(ctx *kyoto.Context) (state CUUIDState) {
		// Fetch uuid data
		resp, _ := http.Get(hburl)
		data := map[string]string{}
		json.NewDecoder(resp.Body).Decode(&data)
		// Set state
		state.UUID = data["uuid"]
	}
}