Skip to content
/ live Public

Ponzu CMS package to add support for live queries. Subscribe to / emit from various hooks, i.e. AfterAPICreate, BeforeAdminDelete, etc.

License

Notifications You must be signed in to change notification settings

ponzu-cms/live

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Live Queries

This package attempts to add a basic version of live queries to Ponzu. By interacting with the database hooks provided with the item.Hookable interface, the live package (import "github.com/ponzu-cms/live") enables users to publish and subscribe to the hookable events throughout the content package.

Usage:

package content

import (
	"fmt"
	"log"
	"net/http"

	"github.com/ponzu-cms/live"
	"github.com/ponzu-cms/ponzu/management/editor"
	"github.com/ponzu-cms/ponzu/system/item"
)

// typical generated ponzu content type
type Customer struct {
	item.Item

	Name  string `json:"name"`
	Email string `json:"email"`
}

// declare a package-level subscriptions container (could be in it's own file 
// within the content package)
var subs live.Subscriptions

func init() {
    item.Types["Customer"] = func() interface{} { return new(Customer) }

    // create the new subscriptions container to Subscribe / Emit
    subs = live.New()

    // create a subscriber to handle AdminUpdate events on a Customer
    go func() {
        adminUpdates := subs.Subscribe("Customer", live.AdminUpdate)
        for event := range adminUpdates {
            log.Println("<g1> UPDATE:", event.Content().(*Customer))
        }
    }()

    // NOTE: any number of subscriptions can be made to the same content type for
    // any event type.

    // create another subscriber for AdminDelete events on a Customer
    go func() {
        adminDeletes := subs.Subscribe("Customer", live.AdminDelete)
        for event := range adminDeletes {
            log.Println("<g2> DELETE:", event.Content().(*Customer))
        }
    }()
}

// emit content events from within the item.Hookable methods provided by Ponzu 
// to broadcast a change (hookable constants are defined in `live` for event types)
func (c *Customer) AfterAdminUpdate(res http.ResponseWriter, req *http.Request) error {
	err := subs.Emit(req.Context(), "Customer", c, live.AdminUpdate)
	if err != nil {
		if liveErr, ok := err.(live.QueryError); ok {
			// handle live error in specific manner
			fmt.Println(liveErr)
			return nil
		}

		return err
	}

	return nil
}

func (c *Customer) BeforeAdminDelete(res http.ResponseWriter, req *http.Request) error {
	err := subs.Emit(req.Context(), "Customer", c, live.AdminDelete)
	if err != nil {
		return err
	}

	return nil
}

// MarshalEditor writes a buffer of html to edit a Customer within the CMS
// and implements editor.Editable
func (c *Customer) MarshalEditor() ([]byte, error) {
	view, err := editor.Form(c,
		// Take note that the first argument to these Input-like functions
		// is the string version of each Customer field, and must follow
		// this pattern for auto-decoding and auto-encoding reasons:
		editor.Field{
			View: editor.Input("Name", c, map[string]string{
				"label":       "Name",
				"type":        "text",
				"placeholder": "Enter the Name here",
			}),
		},
		editor.Field{
			View: editor.Input("Email", c, map[string]string{
				"label":       "Email",
				"type":        "text",
				"placeholder": "Enter the Email here",
			}),
		},
	)

	if err != nil {
		return nil, fmt.Errorf("Failed to render Customer editor view: %s", err.Error())
	}

	return view, nil
}

// String defines how a Customer is printed. Update it using more descriptive
// fields from the Customer struct type
func (c *Customer) String() string {
	return fmt.Sprintf("Customer: %s", c.UUID)
}

About

Ponzu CMS package to add support for live queries. Subscribe to / emit from various hooks, i.e. AfterAPICreate, BeforeAdminDelete, etc.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages