diff --git a/system/renderer/generic_html.go b/system/renderer/generic_html.go
index 45811a8c4..277e5d14e 100644
--- a/system/renderer/generic_html.go
+++ b/system/renderer/generic_html.go
@@ -9,20 +9,47 @@ import (
)
type (
- genericHTML struct{}
+ genericHTML struct {
+ def DriverDefinition
+ }
genericHTMLDriver struct{}
)
func newGenericHTML() driverFactory {
- return &genericHTML{}
+ return &genericHTML{
+ def: DriverDefinition{
+ Name: "genericHTML",
+ InputTypes: []types.DocumentType{
+ types.DocumentTypePlain,
+ types.DocumentTypeHTML,
+ },
+ OutputTypes: []types.DocumentType{
+ types.DocumentTypeHTML,
+ },
+ },
+ }
+}
+
+func (d *genericHTML) Define() DriverDefinition {
+ return d.def
}
func (d *genericHTML) CanRender(t types.DocumentType) bool {
- return t == types.DocumentTypeHTML || t == types.DocumentTypePlain
+ for _, i := range d.def.InputTypes {
+ if i == t {
+ return true
+ }
+ }
+ return false
}
func (d *genericHTML) CanProduce(t types.DocumentType) bool {
- return t == types.DocumentTypeHTML
+ for _, o := range d.def.OutputTypes {
+ if o == t {
+ return true
+ }
+ }
+ return false
}
func (d *genericHTML) Driver() driver {
diff --git a/system/renderer/generic_text.go b/system/renderer/generic_text.go
index 204d1edfc..ba4b8aa36 100644
--- a/system/renderer/generic_text.go
+++ b/system/renderer/generic_text.go
@@ -10,7 +10,9 @@ import (
)
type (
- genericText struct{}
+ genericText struct {
+ def DriverDefinition
+ }
genericTextDriver struct{}
)
@@ -19,15 +21,40 @@ var (
)
func newGenericText() driverFactory {
- return &genericText{}
+ return &genericText{
+ def: DriverDefinition{
+ Name: "genericText",
+ InputTypes: []types.DocumentType{
+ types.DocumentTypePlain,
+ types.DocumentTypeHTML,
+ },
+ OutputTypes: []types.DocumentType{
+ types.DocumentTypePlain,
+ },
+ },
+ }
+}
+
+func (d *genericText) Define() DriverDefinition {
+ return d.def
}
func (d *genericText) CanRender(t types.DocumentType) bool {
- return t == types.DocumentTypePlain || t == types.DocumentTypeHTML
+ for _, i := range d.def.InputTypes {
+ if i == t {
+ return true
+ }
+ }
+ return false
}
func (d *genericText) CanProduce(t types.DocumentType) bool {
- return t == types.DocumentTypePlain
+ for _, o := range d.def.OutputTypes {
+ if o == t {
+ return true
+ }
+ }
+ return false
}
func (d *genericText) Driver() driver {
diff --git a/system/renderer/gotenbergPDF.go b/system/renderer/gotenbergPDF.go
index 3c86d9d0b..afe21e7ca 100644
--- a/system/renderer/gotenbergPDF.go
+++ b/system/renderer/gotenbergPDF.go
@@ -15,6 +15,7 @@ import (
type (
gotenbergPDF struct {
url string
+ def DriverDefinition
}
gotenbergPDFDriver struct {
url string
@@ -25,15 +26,40 @@ type (
func newGotenbergPDF(url string) driverFactory {
return &gotenbergPDF{
url: url,
+
+ def: DriverDefinition{
+ Name: "gotenbergPDF",
+ InputTypes: []types.DocumentType{
+ types.DocumentTypePlain,
+ types.DocumentTypeHTML,
+ },
+ OutputTypes: []types.DocumentType{
+ types.DocumentTypePDF,
+ },
+ },
}
}
+func (d *gotenbergPDF) Define() DriverDefinition {
+ return d.def
+}
+
func (d *gotenbergPDF) CanRender(t types.DocumentType) bool {
- return t == types.DocumentTypeHTML || t == types.DocumentTypePlain
+ for _, i := range d.def.InputTypes {
+ if i == t {
+ return true
+ }
+ }
+ return false
}
func (d *gotenbergPDF) CanProduce(t types.DocumentType) bool {
- return t == types.DocumentTypePDF
+ for _, o := range d.def.OutputTypes {
+ if o == t {
+ return true
+ }
+ }
+ return false
}
func (d *gotenbergPDF) Driver() driver {
diff --git a/system/renderer/renderer.go b/system/renderer/renderer.go
index abfac3b09..84cf5cddd 100644
--- a/system/renderer/renderer.go
+++ b/system/renderer/renderer.go
@@ -47,3 +47,11 @@ func (r *renderer) Render(ctx context.Context, pl *RendererPayload) (io.ReadSeek
return nil, errors.New("rendering failed: driver not found")
}
+
+func (r *renderer) Drivers() []DriverDefinition {
+ dd := make([]DriverDefinition, len(r.factories))
+ for i, f := range r.factories {
+ dd[i] = f.Define()
+ }
+ return dd
+}
diff --git a/system/renderer/types.go b/system/renderer/types.go
index a97e8f4b7..a669ea168 100644
--- a/system/renderer/types.go
+++ b/system/renderer/types.go
@@ -39,7 +39,15 @@ type (
Name string
}
+ DriverDefinition struct {
+ Name string `json:"name"`
+ InputTypes []types.DocumentType `json:"inputTypes"`
+ OutputTypes []types.DocumentType `json:"outputTypes"`
+ }
+
driverFactory interface {
+ Define() DriverDefinition
+
CanRender(t types.DocumentType) bool
CanProduce(t types.DocumentType) bool
Driver() driver
diff --git a/system/rest.yaml b/system/rest.yaml
index cb39116c9..72f99a7bf 100644
--- a/system/rest.yaml
+++ b/system/rest.yaml
@@ -1343,6 +1343,10 @@ endpoints:
type: uint64
required: true
title: Template ID
+ - name: renderDrivers
+ method: GET
+ title: Render drivers
+ path: "/render/drivers"
- name: render
method: POST
title: Render template
diff --git a/system/rest/handlers/template.go b/system/rest/handlers/template.go
index f69ed934b..4e49f76fb 100644
--- a/system/rest/handlers/template.go
+++ b/system/rest/handlers/template.go
@@ -25,18 +25,20 @@ type (
Update(context.Context, *request.TemplateUpdate) (interface{}, error)
Delete(context.Context, *request.TemplateDelete) (interface{}, error)
Undelete(context.Context, *request.TemplateUndelete) (interface{}, error)
+ RenderDrivers(context.Context, *request.TemplateRenderDrivers) (interface{}, error)
Render(context.Context, *request.TemplateRender) (interface{}, error)
}
// HTTP API interface
Template struct {
- List func(http.ResponseWriter, *http.Request)
- Create func(http.ResponseWriter, *http.Request)
- Read func(http.ResponseWriter, *http.Request)
- Update func(http.ResponseWriter, *http.Request)
- Delete func(http.ResponseWriter, *http.Request)
- Undelete func(http.ResponseWriter, *http.Request)
- Render func(http.ResponseWriter, *http.Request)
+ List func(http.ResponseWriter, *http.Request)
+ Create func(http.ResponseWriter, *http.Request)
+ Read func(http.ResponseWriter, *http.Request)
+ Update func(http.ResponseWriter, *http.Request)
+ Delete func(http.ResponseWriter, *http.Request)
+ Undelete func(http.ResponseWriter, *http.Request)
+ RenderDrivers func(http.ResponseWriter, *http.Request)
+ Render func(http.ResponseWriter, *http.Request)
}
)
@@ -138,6 +140,22 @@ func NewTemplate(h TemplateAPI) *Template {
api.Send(w, r, value)
},
+ RenderDrivers: func(w http.ResponseWriter, r *http.Request) {
+ defer r.Body.Close()
+ params := request.NewTemplateRenderDrivers()
+ if err := params.Fill(r); err != nil {
+ api.Send(w, r, err)
+ return
+ }
+
+ value, err := h.RenderDrivers(r.Context(), params)
+ if err != nil {
+ api.Send(w, r, err)
+ return
+ }
+
+ api.Send(w, r, value)
+ },
Render: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewTemplateRender()
@@ -166,6 +184,7 @@ func (h Template) MountRoutes(r chi.Router, middlewares ...func(http.Handler) ht
r.Put("/template/{templateID}", h.Update)
r.Delete("/template/{templateID}", h.Delete)
r.Post("/template/{templateID}/undelete", h.Undelete)
+ r.Get("/template/render/drivers", h.RenderDrivers)
r.Post("/template/{templateID}/render/{filename}.{ext}", h.Render)
})
}
diff --git a/system/rest/request/template.go b/system/rest/request/template.go
index fb6c644fc..f11792825 100644
--- a/system/rest/request/template.go
+++ b/system/rest/request/template.go
@@ -192,6 +192,9 @@ type (
TemplateID uint64 `json:",string"`
}
+ TemplateRenderDrivers struct {
+ }
+
TemplateRender struct {
// TemplateID PATH parameter
//
@@ -779,6 +782,22 @@ func (r *TemplateUndelete) Fill(req *http.Request) (err error) {
return err
}
+// NewTemplateRenderDrivers request
+func NewTemplateRenderDrivers() *TemplateRenderDrivers {
+ return &TemplateRenderDrivers{}
+}
+
+// Auditable returns all auditable/loggable parameters
+func (r TemplateRenderDrivers) Auditable() map[string]interface{} {
+ return map[string]interface{}{}
+}
+
+// Fill processes request and fills internal variables
+func (r *TemplateRenderDrivers) Fill(req *http.Request) (err error) {
+
+ return err
+}
+
// NewTemplateRender request
func NewTemplateRender() *TemplateRender {
return &TemplateRender{}
diff --git a/system/rest/template.go b/system/rest/template.go
index 492b532be..2dd3b1c96 100644
--- a/system/rest/template.go
+++ b/system/rest/template.go
@@ -11,6 +11,7 @@ import (
"github.com/cortezaproject/corteza-server/pkg/api"
"github.com/cortezaproject/corteza-server/pkg/filter"
+ "github.com/cortezaproject/corteza-server/system/renderer"
"github.com/cortezaproject/corteza-server/system/rest/request"
"github.com/cortezaproject/corteza-server/system/service"
"github.com/cortezaproject/corteza-server/system/types"
@@ -38,6 +39,14 @@ type (
CanDeleteTemplate bool `json:"canDeleteTemplate"`
}
+ driverSetPayload struct {
+ Set []*driverPayload `json:"set"`
+ }
+
+ driverPayload struct {
+ renderer.DriverDefinition
+ }
+
templateAccessController interface {
CanGrant(context.Context) bool
CanCreateTemplate(context.Context) bool
@@ -56,7 +65,7 @@ func (Template) New() *Template {
func (ctrl *Template) Read(ctx context.Context, r *request.TemplateRead) (interface{}, error) {
tpl, err := ctrl.renderer.FindByID(ctx, r.TemplateID)
- return ctrl.makePayload(ctx, tpl, err)
+ return ctrl.makeTemplatePayload(ctx, tpl, err)
}
func (ctrl *Template) List(ctx context.Context, r *request.TemplateList) (interface{}, error) {
@@ -80,7 +89,7 @@ func (ctrl *Template) List(ctx context.Context, r *request.TemplateList) (interf
}
set, filter, err := ctrl.renderer.Search(ctx, f)
- return ctrl.makeFilterPayload(ctx, set, filter, err)
+ return ctrl.makeFilterTemplatePayload(ctx, set, filter, err)
}
func (ctrl *Template) Create(ctx context.Context, r *request.TemplateCreate) (interface{}, error) {
@@ -98,7 +107,7 @@ func (ctrl *Template) Create(ctx context.Context, r *request.TemplateCreate) (in
)
app, err = ctrl.renderer.Create(ctx, app)
- return ctrl.makePayload(ctx, app, err)
+ return ctrl.makeTemplatePayload(ctx, app, err)
}
func (ctrl *Template) Update(ctx context.Context, r *request.TemplateUpdate) (interface{}, error) {
@@ -117,7 +126,7 @@ func (ctrl *Template) Update(ctx context.Context, r *request.TemplateUpdate) (in
)
app, err = ctrl.renderer.Update(ctx, app)
- return ctrl.makePayload(ctx, app, err)
+ return ctrl.makeTemplatePayload(ctx, app, err)
}
func (ctrl *Template) Delete(ctx context.Context, r *request.TemplateDelete) (interface{}, error) {
@@ -128,6 +137,10 @@ func (ctrl *Template) Undelete(ctx context.Context, r *request.TemplateUndelete)
return api.OK(), ctrl.renderer.UndeleteByID(ctx, r.TemplateID)
}
+func (ctrl *Template) RenderDrivers(ctx context.Context, r *request.TemplateRenderDrivers) (interface{}, error) {
+ return ctrl.makeSetRenderDriverPayload(ctx, ctrl.renderer.Drivers()), nil
+}
+
func (ctrl *Template) Render(ctx context.Context, r *request.TemplateRender) (interface{}, error) {
vars := make(map[string]interface{})
err := json.Unmarshal(r.Variables, &vars)
@@ -151,7 +164,7 @@ func (ctrl *Template) Render(ctx context.Context, r *request.TemplateRender) (in
// Utilities
-func (ctrl Template) makeFilterPayload(ctx context.Context, nn types.TemplateSet, f types.TemplateFilter, err error) (*templateSetPayload, error) {
+func (ctrl Template) makeFilterTemplatePayload(ctx context.Context, nn types.TemplateSet, f types.TemplateFilter, err error) (*templateSetPayload, error) {
if err != nil {
return nil, err
}
@@ -159,13 +172,13 @@ func (ctrl Template) makeFilterPayload(ctx context.Context, nn types.TemplateSet
msp := &templateSetPayload{Filter: f, Set: make([]*templatePayload, len(nn))}
for i := range nn {
- msp.Set[i], _ = ctrl.makePayload(ctx, nn[i], nil)
+ msp.Set[i], _ = ctrl.makeTemplatePayload(ctx, nn[i], nil)
}
return msp, nil
}
-func (ctrl Template) makePayload(ctx context.Context, tpl *types.Template, err error) (*templatePayload, error) {
+func (ctrl Template) makeTemplatePayload(ctx context.Context, tpl *types.Template, err error) (*templatePayload, error) {
if err != nil || tpl == nil {
return nil, err
}
@@ -181,6 +194,18 @@ func (ctrl Template) makePayload(ctx context.Context, tpl *types.Template, err e
return pl, nil
}
+func (ctrl Template) makeSetRenderDriverPayload(ctx context.Context, nn []renderer.DriverDefinition) *driverSetPayload {
+ msp := &driverSetPayload{Set: make([]*driverPayload, len(nn))}
+
+ for i := range nn {
+ msp.Set[i] = &driverPayload{
+ DriverDefinition: nn[i],
+ }
+ }
+
+ return msp
+}
+
func (ctrl *Template) serve(doc io.ReadSeeker, ct string, r *request.TemplateRender, err error) (interface{}, error) {
if err != nil {
return nil, err
diff --git a/system/service/template.go b/system/service/template.go
index 1919e3f25..b3e9e40e7 100644
--- a/system/service/template.go
+++ b/system/service/template.go
@@ -36,6 +36,7 @@ type (
rendererService interface {
Render(ctx context.Context, p *renderer.RendererPayload) (io.ReadSeeker, error)
+ Drivers() []renderer.DriverDefinition
}
TemplateService interface {
@@ -50,6 +51,7 @@ type (
DeleteByID(ctx context.Context, ID uint64) error
UndeleteByID(ctx context.Context, ID uint64) error
+ Drivers() []renderer.DriverDefinition
Render(ctx context.Context, templateID uint64, dstType string, variables map[string]interface{}, options map[string]string) (io.ReadSeeker, error)
}
)
@@ -330,6 +332,10 @@ func (svc template) UndeleteByID(ctx context.Context, ID uint64) (err error) {
return svc.recordAction(ctx, tplProps, TemplateActionUndelete, err)
}
+func (svc template) Drivers() []renderer.DriverDefinition {
+ return svc.renderer.Drivers()
+}
+
func (svc template) Render(ctx context.Context, templateID uint64, dstType string, variables map[string]interface{}, options map[string]string) (document io.ReadSeeker, err error) {
var (
tplProps = &templateActionProps{}