component

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Mar 29, 2021 License: MIT Imports: 8 Imported by: 4

Documentation

Overview

Package component provides a Gear, which represents an HTML shadow-dom component. This allows creation of isolated HTML components using the webgear/html package.

Simply attach an *html.Doc element with a .Body and no .Head. This will be automatically isolated from other css styles in the top level document. The component tag name will be the name you pass along in the constructor and you can access this component in your main document via the html.Component{} object.

Prerequisites

To properly understand this package, you will need the following:

  • Understanding of the webgears/html package
  • Understand the idea of the Shadow-DOM in Web Components

If you don't know about web components, a good introduction can be found here: https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM

Example Component

This creates a component that simply prints a name and attaches that to an html.Doc object for rendering.

type dynName struct {
	name string
}

func(d dynName) Name() []html.Element {
	return []html.Element{html.TextElement(d.name)}
}

// New is our custom Gear's constructor that will print out the name we pass in via printName.
// The compName will be used to specify our custom HTML tag that allows exeuction of the component.
// If compName is "my-component", the the <my-component></my-component> tag is used to execute this component.
func New(compName, printName string) (*component.Gear, error) {
	// Create doc that will be used by the Gear.
	var doc := &html.Doc{
		Body: &html.Body{
			Elements: []html.Element{
				&html.Link{Rel: "stylesheet", Href: "/static/main/gear.css"},
				html.Dynamic(dynName{"John Doak"}.Name),
			},
		},
	}

	return component.New(name, doc)
}

Attaching a Component

To use a componenet in a page, it needs to be attached to an html.Doc to be rendered.

gear, err := printname.New("print-name-author", "John Doak")
if err != nil {
	// Do something
}

// Use the Gear in your index page. This is usually not in the same package as the component.
doc := &html.Doc{
	Head: &html.Head{
		&html.Meta{Charset: "UTF-8"},
		&html.Title{TagValue: html.TextElement("My site showing my name")},
		&html.Link{Rel: "stylesheet", Href: html.URLParse("/static/main/index.css")},
		&html.Link{Href: html.URLParse("https://fonts.googleapis.com/css2?family=Share+Tech+Mono&display=swap"), Rel: "stylesheet"},
	},
	Body: &html.Body{
		Elements: []html.Element{
			// This causes the gear's generated code to be written to output.
			gear,
			// This is the gear tag that causes the code to be executed, aka <print-name-author></print-name-author>.
			&html.Component{TagType: template.HTMLAttr(gear.Name())},
		},
	},
},

Serving a page

Now we need to serve the page and any external file required such as images or css files.

// Setup server handlers.
h := handlers.New(handlers.DoNotCache())

// Serve all files from the the binary working directory and below it (recursively) that have
// the file extensions listed.
h.ServeFilesWorkingDir([]string{".css", ".jpg", ".svg", ".png"})

// Attach our page containing the gear to "/".
h.MustHandle("/", doc)

// Serve the content using the http.Server.
server := &http.Server{
	Addr:           fmt.Sprintf(":%d", *port),
	Handler:        h.ServerMux(),
	ReadTimeout:    10 * time.Second,
	WriteTimeout:   10 * time.Second,
	MaxHeaderBytes: 1 << 20,
}

log.Printf("http server serving on :%d", *port)

log.Fatal(server.ListenAndServe())

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type DataFunc

type DataFunc func(r *http.Request) (interface{}, error)

DataFunc represents a function that provides data in the html.Pipeline.GearData. The DataFunc should return data that will be stored in the html.Pipeline.GearData field. The returned object must be thread-safe.

type Gear

type Gear struct {
	// Doc is public to allow its use in internal templating code. It should only be set by the call to New().
	Doc *html.Doc
	// Gears is public to allow external packages to access Gear data. This houls only be set by AddGear().
	Gears []*Gear
	// contains filtered or unexported fields
}

Gear is a shadow-dom component.

func New

func New(name string, doc *html.Doc, options ...Option) (*Gear, error)

New creates a new Gear object called "name" using the HTML provided by the doc passed. Name also is used for the tag's ID when using the html.Component{} type.

func (*Gear) Execute

func (g *Gear) Execute(pipe html.Pipeline) string

Execute executes the internal templates and renders the html for output with the given pipeline.

func (*Gear) GearID

func (g *Gear) GearID() string

GearID outputs the ID of the gear stored in the .Doc. Gear's are special and are never output to HTML with this name (output with TemplateName() and LoaderName()), but we still need a way to reference them in our Doc tree. This is that ID.

func (*Gear) LoaderName

func (g *Gear) LoaderName() template.JS

LoaderName is the name of the JS function that defines the HTML custom element and causes the custom element to render.

func (*Gear) Name

func (g *Gear) Name() string

Name returns the name of the Gear so that it may be referenced.

func (*Gear) TagType

func (g *Gear) TagType() template.HTMLAttr

TagType is the same as Name() except the type works in the templates.

func (*Gear) TemplateContent

func (g *Gear) TemplateContent() string

TemplateContent outputs the content of the HTML template object used for this component, but not the script.

func (*Gear) TemplateName

func (g *Gear) TemplateName() string

TemplateName is the DOM id of the template that is used for this component.

type Option

type Option func(g *Gear)

Option is an optional argument to the New() constructor.

func AddGear

func AddGear(newGear *Gear) Option

AddGear adds another Gear that will be called before this gear is called. This allows a componenet to use other components. You still must use html.Component{} to insert your custom tag where you want the componenet to be displayed.

func ApplyDataFunc

func ApplyDataFunc(f DataFunc) Option

ApplyDataFunc adds a function that populates the html.Pipeline.GearData attribute on Execute() calls.

Directories

Path Synopsis
Package viewer provides a library to make rendering just your component a snap so that it is easy to view visual changes quickly without loading up an entire website.
Package viewer provides a library to make rendering just your component a snap so that it is easy to view visual changes quickly without loading up an entire website.

Jump to

Keyboard shortcuts

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