-
Notifications
You must be signed in to change notification settings - Fork 11
/
widget.go
150 lines (126 loc) · 4.92 KB
/
widget.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package widget
import (
"fmt"
"html/template"
"log"
"path/filepath"
"github.com/jinzhu/gorm"
"github.com/qor/admin"
"github.com/qor/assetfs"
"github.com/qor/qor/resource"
"github.com/qor/qor/utils"
"github.com/qor/roles"
)
var (
viewPaths []string
registeredWidgets []*Widget
registeredWidgetsGroup []*WidgetsGroup
)
// Config widget config
type Config struct {
DB *gorm.DB
Admin *admin.Admin
PreviewAssets []string
}
// New new widgets container
func New(config *Config) *Widgets {
widgets := &Widgets{Config: config, funcMaps: template.FuncMap{}, AssetFS: assetfs.AssetFS().NameSpace("widgets")}
if utils.AppRoot != "" {
widgets.RegisterViewPath(filepath.Join(utils.AppRoot, "app/views/widgets"))
}
widgets.RegisterViewPath("app/views/widgets")
return widgets
}
// Widgets widgets container
type Widgets struct {
funcMaps template.FuncMap
Config *Config
Resource *admin.Resource
AssetFS assetfs.Interface
WidgetSettingResource *admin.Resource
}
// SetAssetFS set asset fs for render
func (widgets *Widgets) SetAssetFS(assetFS assetfs.Interface) {
for _, viewPath := range viewPaths {
assetFS.RegisterPath(viewPath)
}
widgets.AssetFS = assetFS
}
// RegisterWidget register a new widget
func (widgets *Widgets) RegisterWidget(w *Widget) {
registeredWidgets = append(registeredWidgets, w)
}
// RegisterWidgetsGroup register widgets group
func (widgets *Widgets) RegisterWidgetsGroup(group *WidgetsGroup) {
registeredWidgetsGroup = append(registeredWidgetsGroup, group)
}
// RegisterFuncMap register view funcs, it could be used when render templates
func (widgets *Widgets) RegisterFuncMap(name string, fc interface{}) {
widgets.funcMaps[name] = fc
}
// ConfigureQorResourceBeforeInitialize a method used to config Widget for qor admin
func (widgets *Widgets) ConfigureQorResourceBeforeInitialize(res resource.Resourcer) {
if res, ok := res.(*admin.Resource); ok {
// register view paths
res.GetAdmin().RegisterViewPath("github.com/qor/widget/views")
// set resources
widgets.Resource = res
// set setting resource
if widgets.WidgetSettingResource == nil {
widgets.WidgetSettingResource = res.GetAdmin().NewResource(&QorWidgetSetting{}, &admin.Config{Name: res.Name})
}
res.Name = widgets.WidgetSettingResource.Name
for funcName, fc := range funcMap {
res.GetAdmin().RegisterFuncMap(funcName, fc)
}
// configure routes
controller := widgetController{Widgets: widgets}
router := res.GetAdmin().GetRouter()
router.Get(widgets.WidgetSettingResource.ToParam(), controller.Index, &admin.RouteConfig{Resource: widgets.WidgetSettingResource})
router.Get(fmt.Sprintf("%v/new", widgets.WidgetSettingResource.ToParam()), controller.New, &admin.RouteConfig{Resource: widgets.WidgetSettingResource})
router.Get(fmt.Sprintf("%v/!setting", widgets.WidgetSettingResource.ToParam()), controller.Setting, &admin.RouteConfig{Resource: widgets.WidgetSettingResource})
router.Get(fmt.Sprintf("%v/%v", widgets.WidgetSettingResource.ToParam(), widgets.WidgetSettingResource.ParamIDName()), controller.Edit, &admin.RouteConfig{Resource: widgets.WidgetSettingResource})
router.Get(fmt.Sprintf("%v/%v/!preview", widgets.WidgetSettingResource.ToParam(), widgets.WidgetSettingResource.ParamIDName()), controller.Preview, &admin.RouteConfig{Resource: widgets.WidgetSettingResource})
router.Get(fmt.Sprintf("%v/%v/edit", widgets.WidgetSettingResource.ToParam(), widgets.WidgetSettingResource.ParamIDName()), controller.Edit, &admin.RouteConfig{Resource: widgets.WidgetSettingResource})
router.Put(fmt.Sprintf("%v/%v", widgets.WidgetSettingResource.ToParam(), widgets.WidgetSettingResource.ParamIDName()), controller.Update, &admin.RouteConfig{Resource: widgets.WidgetSettingResource})
router.Post(widgets.WidgetSettingResource.ToParam(), controller.Update, &admin.RouteConfig{Resource: widgets.WidgetSettingResource})
router.Get(fmt.Sprintf("%v/inline-edit", res.ToParam()), controller.InlineEdit, &admin.RouteConfig{Resource: widgets.WidgetSettingResource})
}
}
// Widget widget struct
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
}
// WidgetsGroup widgets Group
type WidgetsGroup struct {
Name string
Widgets []string
}
// GetWidget get widget by name
func GetWidget(name string) *Widget {
for _, w := range registeredWidgets {
if w.Name == name {
return w
}
}
for _, g := range registeredWidgetsGroup {
if g.Name == name {
for _, widgetName := range g.Widgets {
return GetWidget(widgetName)
}
}
}
log.Println("widget " + name + " not exists, make sure to register it")
return nil
}
// GetWidgets GetWidgets return registered widgets
func GetWidgets() []*Widget {
return registeredWidgets
}