package module
Version: v0.2.0 Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Dec 22, 2021 License: MIT Imports: 12 Imported by: 1



Library that brings frontend-like components experience to the server side with native html/template on steroids. Supports any serving basis (net/http/gin/etc), that provides io.Writer in response.

License Go Report Card Go Reference

This project in early development, don't use in production! In case of any issues/proposals, feel free to open an issue

Why I need this?

  • Get rid of spaghetti inside of handlers
  • Organize code into configurable components structure
  • Simple and straightforward page rendering lifecycle
  • Asynchronous DTO without goroutine mess
  • Built-in dynamics like Hotwire or Laravel Livewire
  • Everyting on top of well-known html/template
  • Get control over project setup: 0 external dependencies, just kyoto itself

Why not?

  • In active development (not production ready)
  • Not situable for pretty dynamic frontends
  • You want to develop SPA/PWA
  • You're just feeling OK with JS frameworks


As simple as go get
Check documentation page for quick start:


Kyoto project setup may seem complicated and unusual at first sight.
It's highly recommended to follow documentation while using library:

This example is not completely independent and just shows what the code looks like when using kyoto:

package main

import (


type PageIndex struct {
	Navbar kyoto.Component

func (p *PageIndex) Template() *template.Template {
	return mktemplate("page.index.html")

func (p *PageIndex) Init() {
	p.Navbar = kyoto.RegC(p, &twui.AppUINavNavbar{
		Logo: `<img src="/static/img/kyoto.svg" class="h-8 w-8 scale-150" />`,
		Links: []twui.AppUINavNavbarLink{
			{Text: "Kyoto", Href: ""},
			{Text: "UIKit", Href: ""},
			{Text: "Charts", Href: ""},
			{Text: "Starter", Href: ""},
		Profile: twui.AppUINavNavbarProfile{
			Enabled: true,
			Avatar: `
					<svg class="w-6 h-6 text-gray-300" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns=""><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path></svg>
			Links: []twui.AppUINavNavbarLink{
				{Text: "GitHub", Href: ""},
				{Text: "Telegram", Href: ""},
				{Text: "Email", Href: ""},


Demo project, Hacker News client made with kyoto:
Demo project, features overview:


Buy me a Coffee

Or directly with Bitcoin: bc1qgxe4u799f8pdyzk65sqpq28xj0yc6g05ckhvkk




This section is empty.


View Source
var (
	// INSIGHTS config boolean
	INSIGHTS = false
	// INSIGHTS_CLI config boolean
	// INSIGHTS_CLI_JSON output insights in json format
	// INSIGHTS_LIMIT limit of insights
View Source
var (

	// OnError is an error processing function.
	// Panic by default
	OnError = func(p Page, err error) {

RegC is an alias for RegisterComponent


func DelContext

func DelContext(p Page, key string)

DelContext delete the page's context data by key

func GetContext

func GetContext(p Page, key string) interface{}

GetContext of the specified page, return data stored by key

func InsightsID

func InsightsID(p interface{}) string

InsightsID is a function to generate ID from pointer

func InsightsName

func InsightsName(p interface{}) string

InsightsName is a function that extracts type name from pointer

func PageHandler

func PageHandler(p Page) http.HandlerFunc

PageHandler is an opinionated page net/http handler. Context: - internal:rw - http.ResponseWriter - internal:r - *http.Request

func Redirect

func Redirect(rp *RedirectParameters)

Redirect is a wrapper around http.Redirect for correct work inside of SSC

func RenderPage

func RenderPage(w io.Writer, p Page)

RenderPage is a main entrypoint of rendering. Responsible for rendering and components lifecycle

func RenderSSA

func RenderSSA(w io.Writer, dp *DummyPage, p SSAParameters)

RenderSSA is a low-level component rendering function for SSA. Responsible for rendering and components SSA lifecycle

func SSAFlush

func SSAFlush(p Page, c Component)

SSAFlush is a low-level function for rendering and flushing component UI to the client

func SSAHandler

func SSAHandler(tb TemplateBuilder) http.HandlerFunc

SSAHandler is an opinionated SSA net/http handler. Context: - internal:rw - http.ResponseWriter - internal:r - *http.Request

func SetContext

func SetContext(p Page, key string, value interface{})

SetContext of a page, page based key value store using a string as a key and an interface to store the data

func TAction

func TAction(action string, args ...interface{}) template.JS

func TBind

func TBind(field string) template.JS

func TComponentAttrs

func TComponentAttrs(c Component) template.HTMLAttr

func TDynamics

func TDynamics(path ...string) template.HTML

func TFormSubmit

func TFormSubmit() template.JS

func TFuncMap

func TFuncMap() template.FuncMap

TFuncMap is responsible for integration of library functionality into template rendering You need to use this function while template building (or mix with your own)

func TJSON

func TJSON(data interface{}) string

func TMeta

func TMeta(p Page) template.HTML

func TRender added in v0.1.3

func TRender(c Component) string


type Action

type Action func(args ...interface{})

Action is used to pass arguments onto a component to be used

type ActionMap

type ActionMap map[string]Action

ActionMap is a map of Actions stored by string

type Component

type Component interface{}

Component contains only must-have methods

func RegisterComponent

func RegisterComponent(p Page, c Component) Component

RegisterComponent is used while defining components in the Init() section

type DummyPage

type DummyPage struct {
	TemplateBuilder TemplateBuilder

DummyPage is an SSA page placeholder

func (*DummyPage) Template

func (p *DummyPage) Template() *template.Template

Template returns a template

type Hreflang

type Hreflang struct {
	Lang string
	Href string

Hreflang stores the lang and href

type ImplementsActions

type ImplementsActions interface {
	Actions(Page) ActionMap

ImplementsActions interface for implementing actions

type ImplementsActionsWithoutPage

type ImplementsActionsWithoutPage interface {
	Actions() ActionMap

ImplementsActionsWithoutPage interface type

type ImplementsAfterAsync

type ImplementsAfterAsync interface {

ImplementsAfterAsync interface for after asynchronous functions

type ImplementsAfterAsyncWithoutPage

type ImplementsAfterAsyncWithoutPage interface {

ImplementsAfterAsyncWithoutPage interface type

type ImplementsAsync

type ImplementsAsync interface {
	Async(Page) error

ImplementsAsync interface for asynchronous functions

type ImplementsAsyncWithoutPage

type ImplementsAsyncWithoutPage interface {
	Async() error

ImplementsAsyncWithoutPage interface for Asynchronous functions without a page

type ImplementsInit

type ImplementsInit interface {

ImplementsInit interface for implementing init

type ImplementsInitWithoutPage

type ImplementsInitWithoutPage interface {

ImplementsInitWithoutPage interface type

type ImplementsMeta

type ImplementsMeta interface {
	Meta() Meta

ImplementsMeta interface type

type ImplementsRender added in v0.1.2

type ImplementsRender interface {
	Render() string

type ImplementsTemplate added in v0.1.2

type ImplementsTemplate interface {
	Template(Page) *template.Template

type ImplementsTemplateWithoutPage added in v0.1.2

type ImplementsTemplateWithoutPage interface {
	Template() *template.Template

type Insights

type Insights struct {

	ID     string      `json:"id"`
	Name   string      `json:"name"`
	Nested []*Insights `json:"nested"`

Insights data type

func GetInsights

func GetInsights(p interface{}) *Insights

GetInsights returns insights pointer by given object pointer

func GetInsightsByID

func GetInsightsByID(id string) *Insights

GetInsightsByID returns insights pointer by insights id

func NewInsights

func NewInsights(p interface{}) *Insights

NewInsights creates new insights instance for provided object pointer, saves insights pointer to local store and returns it The oldest insights are cut in case of store overflow (INSIGHTS_LIMIT config)

func (*Insights) GetOrCreateNested

func (i *Insights) GetOrCreateNested(p interface{}) *Insights

GetOrCreateNested attempts to return existing nested insights, or returns new ones

func (*Insights) Update

func (i *Insights) Update(t InsightsTiming)

Update the Insights value

type InsightsTiming

type InsightsTiming struct {
	Init       time.Duration `json:"i"`
	Async      time.Duration `json:"a"`
	AfterAsync time.Duration `json:"aa"`
	Render     time.Duration `json:"r"`

InsightsTiming data type

type Meta

type Meta struct {
	Title       string
	Description string
	Canonical   string
	Hreflangs   []Hreflang
	Additional  []map[string]string

Meta data

type Page

type Page interface{}

Page contains only must-have methods

type RedirectParameters

type RedirectParameters struct {
	Page              Page
	ResponseWriter    http.ResponseWriter
	Request           *http.Request
	ResponseWriterKey string
	RequestKey        string
	Target            string
	StatusCode        int

RedirectParameters is a helper for the Redirect function

type SSAParameters

type SSAParameters struct {
	Component string
	Action    string
	State     string // JSON string
	Args      string // JSON string

SSAParameters represents parameters, needed for handling SSA request

type TemplateBuilder

type TemplateBuilder func(p Page) *template.Template

TemplateBuilder is used to build templates.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL