widget

package module
v0.0.0-...-d0e59db Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2019 License: MIT Imports: 18 Imported by: 1

README

Widget

Widget are defined, customizable, shareable HTML widgets that can be used within QOR Admin or your own frontend.

Getting Started

// Initialize widgets container
Widgets := widget.New(&widget.Config{DB: db})

// Define widget's setting struct
type bannerArgument struct {
  Title           string
  Link            string
  BackgroundImage oss.OSS
}

// Register new widget
Widgets.RegisterWidget(&widget.Widget{
  // Widget's Name
  Name:     "Banner",
  // Widget's available templates
  Templates: []string{"banner1", "banner2"},
  // Widget's setting, which is configurable from the place using the widget with inline edit
  Setting:  Admin.NewResource(&bannerArgument{}),
  // InlineEditURL overwrite widget's inline edit's setting URL, usually we don't require do that, Widget will generate setting form based on Widget's setting resource, but in case of you want to fully customize your widget's setting page, you can overwrite it to return setting's URL
  InlineEditURL: func(context *Context) string {
    return "/different-setting-url"
  },
  // Generate a context to render the widget based on the widget's configurations
  Context: func(context *widget.Context, setting interface{}) *widget.Context {
    context.Options["Setting"] = setting
    context.Options["CurrentTime"] = time.Now()
    return context
  },
})


type slideImage struct {
  Title string
  Image oss.OSS
}

type slideShowArgument struct {
  SlideImages []slideImage
}

slideShowResource := Admin.NewResource(&slideShowArgument{})
slideShowResource.AddProcessor(func(value interface{}, metaValues *resource.MetaValues, context *qor.Context) error {
  if slides, ok := value.(*slideShowArgument); ok {
    for _, slide := range slides.SlideImages {
      if slide.Title == "" {
        return errors.New("slide title is blank")
      }
    }
  }
  return nil
})

Widgets.RegisterWidget(&widget.Widget{
  Name:      "SlideShow",
  Templates: []string{"slideshow"},
  Setting:   slideShowResource,
  Context: func(context *widget.Context, setting interface{}) *widget.Context {
    context.Options["Setting"] = setting
    return context
  },
})

// Define Widget Group
Widgets.RegisterWidgetGroup(&widget.WidgetGroup{
  Name: "HomeBanners",
  Widgets: []string{"Banner", "SlideShow"},
})

// Manage widgets from QOR Admin interface
Admin.AddResource(Widgets)
Render Widget From Controller
func Index(request *http.Request, writer http.ResponseWriter) {
  // Generate widget context
  widgetContext := admin.Widgets.NewContext(&widget.Context{
    DB:         DB(request),
    Options:    map[string]interface{}{"Request": request, "CurrentUser": currentUser}, // those options are accessible from widget views
    InlineEdit: true, // enable inline edit mode for widget
  })

  // Render Widget `HomeBanner` based on widget `Banner`'s definition to HTML template
  homeBannerContent := widgetContext.Render("HomeBanner", "Banner")

  // Render Widget `CampaignBanner` based on widget `Banner`'s definition to HTML template
  campaignBannerContent := widgetContext.Render("CampaignBanner", "Banner")

  // Then you could use the banner's HTML content in your templates
}
Templates

Widget's template is Golang HTML template based, and thus quite flexible.

Continuing on the above widget example, we configure it to use templates banner1, banner2. QOR widget will look up templates from path $APP_ROOT/app/views/widgets by default, so you need to put your template in the right folder!

Once the template is found, QOR Widget will use the widget's generated context and use it to render the template like how Golang template works.

// app/views/widgets/banner1.tmpl
<div class="banner" style="background:url('{{.Setting.BackgroundImage}}') no-repeat center center">
  <div class="container">
    <div class="row">
      <div class="column column-12">
        <a href="{{.Setting.Link}}" class="button button__primary">{{.Setting.Title}}</a>
        {{.CurrentTime}}
      </div>
    </div>
  </div>
</div>

// app/views/widgets/banner2.tmpl
<div class="banner">
  <div class="column column-9">
    <img src="{{.Setting.BackgroundImage}}" class="banner__logo" />
  </div>

  <div class="column column-3" style="margin-top: 2em;">
    <div><a href="{{.Setting.Link}}" class="button button__primary">{{.Setting.Title}}</a></div>
  </div>
</div>

You could also register other paths like:

Widgets.RegisterViewPath("app/views/widgets")
Register Scopes

In some cases, you might want to show a different page according to UTM source/medium/campaign or for A/B testing to increase the conversion rate. Using a Widget's Scope you can register some scopes, configure your widget for each of them, and when a scope's Visible condition is matched the widget will use its configuration to render the widget.

Widgets.RegisterScope(&widget.Scope{
  Name: "From Google",
  Visible: func(context *widget.Context) bool {
    if request, ok := context.Get("Request"); ok {
      return strings.Contains(request.(*http.Request).Referer(), "google.com")
    }
    return false
  },
})

Widgets.RegisterScope(&widget.Scope{
  Name: "VIP User",
  Visible: func(context *widget.Context) bool {
    if user, ok := context.Get("CurrentUser"); ok {
      return user.(*User).Role == "vip"
    }
    return false
  },
})

Live Widget Demo

Widget Demo

License

Released under the MIT License.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	DB            *gorm.DB
	Admin         *admin.Admin
	PreviewAssets []string
}

Config widget config

type Context

type Context struct {
	Widgets          *Widgets
	DB               *gorm.DB
	AvailableWidgets []string
	Options          map[string]interface{}
	InlineEdit       bool
	SourceType       string
	SourceID         string
	FuncMaps         template.FuncMap
	WidgetSetting    QorWidgetSettingInterface
}

Context widget context

func (*Context) Clone

func (context *Context) Clone() *Context

Clone clone a context

func (*Context) FuncMap

func (context *Context) FuncMap() template.FuncMap

FuncMap return funcmap

func (*Context) Funcs

func (context *Context) Funcs(funcMaps template.FuncMap) *Context

Funcs return view functions map

func (Context) Get

func (context Context) Get(name string) (interface{}, bool)

Get get option with name

func (*Context) GetDB

func (context *Context) GetDB() *gorm.DB

GetDB set option by name

func (*Context) Render

func (context *Context) Render(widgetName string, widgetGroupName string) template.HTML

Render render widget based on context

func (*Context) Set

func (context *Context) Set(name string, value interface{})

Set set option by name

type GroupedWidgets

type GroupedWidgets struct {
	Group   string
	Widgets []*Widget
}

type QorWidgetSetting

type QorWidgetSetting struct {
	Name        string `gorm:"primary_key;size:100"`
	Scope       string `gorm:"primary_key;size:128;default:'default'"`
	SourceType  string `gorm:"primary_key;default:'';size:100"`
	SourceID    string `gorm:"primary_key;default:'';size:100"`
	Description string
	Shared      bool
	WidgetType  string
	GroupName   string
	Template    string
	serializable_meta.SerializableMeta
	CreatedAt time.Time
	UpdatedAt time.Time
}

QorWidgetSetting default qor widget setting struct

func (*QorWidgetSetting) ConfigureQorResource

func (widgetSetting *QorWidgetSetting) ConfigureQorResource(res resource.Resourcer)

ConfigureQorResource a method used to config Widget for qor admin

func (QorWidgetSetting) GetGroupName

func (widgetSetting QorWidgetSetting) GetGroupName() string

GetGroupName get widget setting's group name

func (QorWidgetSetting) GetScope

func (widgetSetting QorWidgetSetting) GetScope() string

GetScope get widget's scope

func (*QorWidgetSetting) GetSerializableArgumentKind

func (widgetSetting *QorWidgetSetting) GetSerializableArgumentKind() string

GetSerializableArgumentKind get serializable kind

func (*QorWidgetSetting) GetSerializableArgumentResource

func (widgetSetting *QorWidgetSetting) GetSerializableArgumentResource() *admin.Resource

GetSerializableArgumentResource get setting's argument's resource

func (QorWidgetSetting) GetShared

func (widgetSetting QorWidgetSetting) GetShared() bool

GetShared get widget's source ID

func (QorWidgetSetting) GetSourceID

func (widgetSetting QorWidgetSetting) GetSourceID() string

GetSourceID get widget's source ID

func (QorWidgetSetting) GetSourceType

func (widgetSetting QorWidgetSetting) GetSourceType() string

GetSourceType get widget's source type

func (QorWidgetSetting) GetTemplate

func (widgetSetting QorWidgetSetting) GetTemplate() string

GetTemplate get used widget template

func (QorWidgetSetting) GetWidgetName

func (widgetSetting QorWidgetSetting) GetWidgetName() string

GetWidgetName get widget setting's group name

func (*QorWidgetSetting) ResourceName

func (widgetSetting *QorWidgetSetting) ResourceName() string

ResourceName get widget setting's resource name

func (*QorWidgetSetting) SetGroupName

func (widgetSetting *QorWidgetSetting) SetGroupName(groupName string)

SetGroupName set widget setting's group name

func (*QorWidgetSetting) SetScope

func (widgetSetting *QorWidgetSetting) SetScope(scope string)

SetScope set widget setting's scope

func (*QorWidgetSetting) SetSerializableArgumentKind

func (widgetSetting *QorWidgetSetting) SetSerializableArgumentKind(name string)

SetSerializableArgumentKind set serializable kind

func (*QorWidgetSetting) SetShared

func (widgetSetting *QorWidgetSetting) SetShared(shared bool)

SetShared set widget setting's source id

func (*QorWidgetSetting) SetSourceID

func (widgetSetting *QorWidgetSetting) SetSourceID(sourceID string)

SetSourceID set widget setting's source id

func (*QorWidgetSetting) SetSourceType

func (widgetSetting *QorWidgetSetting) SetSourceType(sourceType string)

SetSourceType set widget setting's souce type

func (*QorWidgetSetting) SetTemplate

func (widgetSetting *QorWidgetSetting) SetTemplate(template string)

SetTemplate set used widget's template

func (*QorWidgetSetting) SetWidgetName

func (widgetSetting *QorWidgetSetting) SetWidgetName(name string)

SetWidgetName set widget setting's group name

type QorWidgetSettingInterface

type QorWidgetSettingInterface interface {
	GetWidgetName() string
	SetWidgetName(string)
	GetGroupName() string
	SetGroupName(string)
	GetScope() string
	SetScope(string)
	GetTemplate() string
	SetTemplate(string)
	GetSourceType() string
	SetSourceType(string)
	GetSourceID() string
	SetSourceID(string)
	GetShared() bool
	SetShared(bool)
	serializable_meta.SerializableMetaInterface
}

QorWidgetSettingInterface qor widget setting interface

type Scope

type Scope struct {
	Name    string
	Param   string
	Visible func(*Context) bool
}

Scope widget scope

func (*Scope) ToParam

func (scope *Scope) ToParam() string

ToParam generate param for scope

type Widget

type Widget struct {
	Name          string
	PreviewIcon   string
	Group         string
	Templates     []string
	Setting       *admin.Resource
	Permission    *roles.Permission
	InlineEditURL func(*Context) string
	Context       func(context *Context, setting interface{}) *Context
}

Widget widget struct

func GetWidget

func GetWidget(name string) *Widget

GetWidget get widget by name

func GetWidgets

func GetWidgets() []*Widget

GetWidgets GetWidgets return registered widgets

func (*Widget) Render

func (w *Widget) Render(context *Context, file string) template.HTML

Render register widget itself content

type Widgets

type Widgets struct {
	Config                *Config
	Resource              *admin.Resource
	AssetFS               assetfs.Interface
	WidgetSettingResource *admin.Resource
	// contains filtered or unexported fields
}

Widgets widgets container

func New

func New(config *Config) *Widgets

New new widgets container

func (*Widgets) ConfigureQorResourceBeforeInitialize

func (widgets *Widgets) ConfigureQorResourceBeforeInitialize(res resource.Resourcer)

ConfigureQorResourceBeforeInitialize a method used to config Widget for qor admin

func (*Widgets) LoadPreviewAssets

func (widgets *Widgets) LoadPreviewAssets() template.HTML

LoadPreviewAssets will return assets tag used for Preview

func (*Widgets) NewContext

func (widgets *Widgets) NewContext(context *Context) *Context

NewContext create new context for widgets

func (*Widgets) RegisterFuncMap

func (widgets *Widgets) RegisterFuncMap(name string, fc interface{})

RegisterFuncMap register view funcs, it could be used when render templates

func (*Widgets) RegisterScope

func (widgets *Widgets) RegisterScope(scope *Scope)

RegisterScope register scope for widget

func (*Widgets) RegisterViewPath

func (widgets *Widgets) RegisterViewPath(p string)

RegisterViewPath register views directory

func (*Widgets) RegisterWidget

func (widgets *Widgets) RegisterWidget(w *Widget)

RegisterWidget register a new widget

func (*Widgets) RegisterWidgetsGroup

func (widgets *Widgets) RegisterWidgetsGroup(group *WidgetsGroup)

RegisterWidgetsGroup register widgets group

func (*Widgets) Render

func (widgets *Widgets) Render(widgetName string, widgetGroupName string) template.HTML

Render find widget by name, render it based on current context

func (*Widgets) SetAssetFS

func (widgets *Widgets) SetAssetFS(assetFS assetfs.Interface)

SetAssetFS set asset fs for render

type WidgetsGroup

type WidgetsGroup struct {
	Name    string
	Widgets []string
}

WidgetsGroup widgets Group

Jump to

Keyboard shortcuts

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