Пример #1
0
// Render updates the given destinationPath according to the given template and options.
// Returns true if the file was created or changed, false if nothing has changed.
func Render(templateName, destinationPath string, options interface{}, destinationFileMode os.FileMode) (bool, error) {
	asset, err := Asset(templateName)
	if err != nil {
		return false, maskAny(err)
	}

	// parse template
	var tmpl *template.Template
	tmpl = template.New(templateName)
	funcMap := template.FuncMap{
		"escape": escape,
		"quote":  strconv.Quote,
	}
	tmpl.Funcs(funcMap)
	_, err = tmpl.Parse(string(asset))
	if err != nil {
		return false, maskAny(err)
	}
	// execute template to buffer
	buf := &bytes.Buffer{}
	tmpl.Funcs(funcMap)
	err = tmpl.Execute(buf, options)
	if err != nil {
		return false, maskAny(err)
	}

	// Update file
	changed, err := util.UpdateFile(destinationPath, buf.Bytes(), destinationFileMode)
	return changed, maskAny(err)
}
Пример #2
0
func Render(templateName string, options interface{}) (string, error) {
	asset, err := Asset(templateName)
	if err != nil {
		return "", maskAny(err)
	}

	// parse template
	var tmpl *template.Template
	tmpl = template.New(templateName)
	funcMap := template.FuncMap{
		"escape":     escape,
		"quote":      strconv.Quote,
		"yamlPrefix": yamlPrefix,
	}
	tmpl.Funcs(funcMap)
	_, err = tmpl.Parse(string(asset))
	if err != nil {
		return "", maskAny(err)
	}
	// write file to buffer
	tmpl.Funcs(funcMap)
	buffer := &bytes.Buffer{}
	err = tmpl.Execute(buffer, options)
	if err != nil {
		return "", maskAny(err)
	}

	return buffer.String(), nil
}
Пример #3
0
// AddRegisterFunc provides an easy to add function for getting a Register to your text/template.Template
func AddRegisterFunc(tmpl *template.Template, name string) *template.Template {
	if name == "" {
		name = "getregister"
	}
	tmpl.Funcs(map[string]interface{}{
		name: func() *Register {
			return NewRegister()
		},
	})
	return tmpl
}
Пример #4
0
func (self *DefaultDocumentedRoute) Render(templ *template.Template) (result string, err error) {
	buf := &bytes.Buffer{}
	r := utils.RandomString(10)
	if err = templ.Funcs(map[string]interface{}{
		"UUID": func() string {
			return r
		},
	}).Execute(buf, self); err != nil {
		return
	}
	result = buf.String()
	return
}
Пример #5
0
// Renders an existing parsed template.Template instance.
func (ts *Templates) RenderTemplate(tmpl *template.Template, data map[string]interface{}) (out string, err error) {
	var (
		clone  *template.Template
		writer *bytes.Buffer
	)
	tmpl.Funcs(*ts.fmap)
	if clone, err = ts.mergeTemplate(tmpl); err != nil {
		return
	}
	writer = bytes.NewBufferString("")
	if err = clone.Execute(writer, data); err == nil {
		out = writer.String()
	}
	return
}
Пример #6
0
func (tabFormPanel tabFormPanel) generate(terminal, packageName string, r *http.Request, employee Employee) []byte {

	var t *template.Template

	var buf bytes.Buffer

	tabFormPanel.Id = packageName + "." + tabFormPanel.Id

	runtimeComponentContain[tabFormPanel.Id] = tabFormPanel

	t = template.New("tabformpanel.html")

	t = t.Funcs(template.FuncMap{
		"getComponentId":  getComponentId,
		"compareInt":      CompareInt,
		"compareString":   CompareString,
		"getPropValue":    GetPropValue,
		"dealHTMLEscaper": DealHTMLEscaper,
	})

	t, err := t.ParseFiles("../lessgo/template/component/" + terminal + "/tabformpanel.html")

	if err != nil {
		Log.Error(err.Error())
		return []byte{}
	}

	if err != nil {
		Log.Error(err.Error())
		return []byte{}
	}

	data := make(map[string]interface{})

	data["TabFormPanel"] = tabFormPanel
	data["Terminal"] = terminal
	data["Employee"] = employee

	err = t.Execute(&buf, data)

	if err != nil {
		Log.Error(err.Error())
		return []byte{}
	}

	return buf.Bytes()
}
Пример #7
0
func (gridpanel gridPanel) generate(entity Entity, terminal, packageName string, employee Employee) []byte {

	var t *template.Template

	var buf bytes.Buffer

	gridpanel.Id = packageName + "." + gridpanel.Id

	runtimeComponentContain[gridpanel.Id] = gridpanel

	t = template.New("gridpanel.html")

	t = t.Funcs(template.FuncMap{
		"getComponentId": getComponentId,
		"compareInt":     CompareInt,
		"compareString":  CompareString,
	})

	t, err := t.ParseFiles("../lessgo/template/component/" + terminal + "/gridpanel.html")

	if err != nil {
		Log.Error(err.Error())
		return []byte{}
	}

	data := make(map[string]interface{})

	data["Gridpanel"] = gridpanel
	data["Entity"] = entity
	data["Terminal"] = terminal
	data["SearchLength"] = len(gridpanel.Searchs)
	data["ActionLength"] = len(gridpanel.Actions)
	data["Employee"] = employee

	err = t.Execute(&buf, data)

	if err != nil {
		Log.Error(err.Error())
		return []byte{}
	}

	return buf.Bytes()

}
Пример #8
0
func (t *TemplateDir) LoadPartial() error {
	partials := []string{}

	directory, err := os.Open(t.src)
	if err != nil {
		return errs.WithEF(err, t.fields, "Failed to open template dir")
	}
	objects, err := directory.Readdir(-1)
	if err != nil {
		return errs.WithEF(err, t.fields, "Failed to read template dir")
	}
	for _, obj := range objects {
		if !obj.IsDir() && strings.HasSuffix(obj.Name(), ".partial") {
			partials = append(partials, t.src+"/"+obj.Name())
		}
	}

	if len(partials) == 0 {
		return nil
	}
	var tmpl *txttmpl.Template
	for _, partial := range partials {
		if tmpl == nil {
			tmpl = txttmpl.New(partial).Funcs(TemplateFunctions).Funcs(map[string]interface{}(gtf.GtfFuncMap))
		} else {
			tmpl = tmpl.New(partial).Funcs(TemplateFunctions).Funcs(map[string]interface{}(gtf.GtfFuncMap))
		}

		content, err := ioutil.ReadFile(partial)
		if err != nil {
			return errs.WithEF(err, t.fields.WithField("partial", partial), "Cannot read partial file")
		}
		tmpl, err = tmpl.Funcs(TemplateFunctions).Parse(CleanupOfTemplate(string(content)))
		if err != nil {
			return errs.WithEF(err, t.fields.WithField("partial", partial), "Failed to parse partial")
		}
	}
	t.Partials = tmpl
	return nil
}
Пример #9
0
//loadTemplate 加载解析模板
func (d *dynamic) loadTemplate(currDir string) (*template.Template, error) {
	if len(d.Template) == 0 {
		return nil, fmt.Errorf(ErrorPageNotTemplate)
	}
	var (
		t                           *template.Template = nil
		filePath, fileName, content string
		b                           []byte
		err                         error
	)

	for _, filename := range d.Template {
		filePath = filepath.Join(currDir, filename)
		fileName = filepath.Base(filename)

		b, err = ioutil.ReadFile(filePath)
		if err != nil {
			return nil, err
		}
		content = d.formatTemplate(string(b))

		var tmpl *template.Template
		if t == nil {
			t = template.New(fileName)
		}
		if fileName == t.Name() {
			tmpl = t
		} else {
			tmpl = t.New(fileName)
		}
		tmpl.Delims(d.Delims.Left, d.Delims.Right)
		tmpl.Funcs(TemplateFuncMap)
		_, err = tmpl.Parse(content)
		if err != nil {
			return nil, err
		}
	}
	return t, nil
}
Пример #10
0
// setFuncs imports certain functions from the Golang API to make them
// available to templates
func setFuncs(t *template.Template) {
	t.Funcs(template.FuncMap{
		"contains":      strings.Contains,
		"containsAny":   strings.ContainsAny,
		"containsRune":  strings.ContainsRune,
		"count":         strings.Count,
		"equalFold":     strings.EqualFold,
		"fields":        strings.Fields,
		"hasPrefix":     strings.HasPrefix,
		"hasSuffix":     strings.HasSuffix,
		"index":         strings.Index,
		"indexAny":      strings.IndexAny,
		"indexByte":     strings.IndexByte,
		"indexRune":     strings.IndexRune,
		"join":          strings.Join,
		"lastIndex":     strings.LastIndex,
		"lastIndexAny":  strings.LastIndexAny,
		"lastIndexByte": strings.LastIndexByte,
		"repeat":        strings.Repeat,
		"replace":       strings.Replace,
		"split":         strings.Split,
		"splitAfter":    strings.SplitAfter,
		"splitAfterN":   strings.SplitAfterN,
		"splitN":        strings.SplitN,
		"title":         strings.Title,
		"toLower":       strings.ToLower,
		"toTitle":       strings.ToTitle,
		"toUpper":       strings.ToUpper,
		"trim":          strings.Trim,
		"trimLeft":      strings.TrimLeft,
		"trimPrefix":    strings.TrimPrefix,
		"trimRight":     strings.TrimRight,
		"trimSpace":     strings.TrimSpace,
		"trimSuffix":    strings.TrimSuffix,
	})
}
Пример #11
0
func (formpanel formPanel) generate(entity Entity, terminal, packageName string, r *http.Request, employee Employee) []byte {

	var t *template.Template

	var buf bytes.Buffer

	formpanel.Id = packageName + "." + formpanel.Id

	runtimeComponentContain[formpanel.Id] = formpanel

	t = template.New("formpanel.html")

	t = t.Funcs(template.FuncMap{
		"getComponentId":  getComponentId,
		"compareInt":      CompareInt,
		"compareString":   CompareString,
		"getPropValue":    GetPropValue,
		"dealHTMLEscaper": DealHTMLEscaper,
	})

	t, err := t.ParseFiles("../lessgo/template/component/" + terminal + "/formpanel.html")

	if err != nil {
		Log.Error(err.Error())
		return []byte{}
	}

	if err != nil {
		Log.Error(err.Error())
		return []byte{}
	}

	data := make(map[string]interface{})

	data["Formpanel"] = formpanel
	data["Entity"] = entity
	data["Terminal"] = terminal
	data["Employee"] = employee

	if formpanel.Load == "true" {
		id := r.FormValue("id")
		model, err := findById(entity, id)

		if err != nil {
			Log.Error(err.Error())
			return []byte{}
		}

		data["Model"] = model
	}

	err = t.Execute(&buf, data)

	if err != nil {
		Log.Error(err.Error())
		return []byte{}
	}

	return buf.Bytes()

}
Пример #12
0
//扩展viewport的同时,记得同时扩展container
func (viewport viewport) generateViewport(terminal, packageName string, r *http.Request, employee Employee) []byte {

	content := ""

	for _, formpanel := range viewport.FormPanels {
		content += string(formpanel.generate(getEntity(formpanel.Entity), terminal, packageName, r, employee))
	}

	for _, tabFormPanel := range viewport.TabFormPanels {
		content += string(tabFormPanel.generate(terminal, packageName, r, employee))
	}

	for _, gridpanel := range viewport.GridPanels {
		content += string(gridpanel.generate(getEntity(gridpanel.Entity), terminal, packageName, employee))
	}

	for _, customgridpanel := range viewport.CustomGridPanels {
		content += string(customgridpanel.generate(terminal, packageName, employee))
	}

	for _, customformpanel := range viewport.CustomFormPanels {
		content += string(customformpanel.generate(terminal, packageName, employee))
	}

	for _, blankpanel := range viewport.BlankPanels {
		content += string(blankpanel.generate(terminal, packageName, employee))
	}

	data := make(map[string]interface{})
	data["Content"] = content
	data["Crumbs"] = viewport.Crumbs
	data["Employee"] = employee
	data["SiteName"] = SiteName
	data["SiteIcon"] = SiteIcon
	data["CustomJs"] = viewport.CustomJs

	var t *template.Template

	var buf bytes.Buffer

	tempName := ""

	if viewport.Window == "true" {
		t = template.New("window.html")
		data["ParentComponentId"] = r.FormValue("parentComponentId")
		data["ParentWindowName"] = r.FormValue("parentWindowName")
		tempName = "../lessgo/template/component/" + terminal + "/window.html"
	} else {
		t = template.New("viewport.html")
		tempName = "../lessgo/template/component/" + terminal + "/viewport.html"
	}

	t = t.Funcs(template.FuncMap{
		"compareString": CompareString,
	})

	t, err := t.ParseFiles(tempName)

	if err != nil {
		Log.Error(err.Error())
		return []byte{}
	}

	err = t.Execute(&buf, data)

	if err != nil {
		Log.Error(err.Error())
		return []byte{}
	}

	return buf.Bytes()
}
Пример #13
0
/*
DocHandler will return a handler that renders the documentation for all routes registerd with DocHandle.

The resulting func will do this by going through each route in DocumentedRoutes and render the endpoint
using the provided template, providing it template functions to render separate endpoints, types, sub types
and examples of types.
*/
func DocHandler(templ *template.Template) http.Handler {
	return httpcontext.HandlerFunc(func(c httpcontext.HTTPContextLogger) (err error) {
		c.Resp().Header().Set("Content-Type", "text/html; charset=UTF-8")
		// we define a func to render a type
		// it basically just executes the "TypeTemplate" with the provided
		// stack to avoid infinite recursion
		renderType := func(t JSONType, stack []string) (result string, err error) {
			// if the type is already mentioned in one of the parents we have already mentioned,
			// bail
			for _, parent := range stack {
				if parent != "" && parent == t.ReflectType.Name() {
					result = fmt.Sprintf("[loop protector enabled, render stack: %v]", stack)
					return
				}
			}
			stack = append(stack, t.ReflectType.Name())
			buf := &bytes.Buffer{}
			// then execute the TypeTemplate with this type and this stack
			if err = templ.ExecuteTemplate(buf, "TypeTemplate", map[string]interface{}{
				"Type":  t,
				"Stack": stack,
			}); err != nil {
				return
			}
			result = buf.String()
			return
		}

		// routes are documented alphabetically
		sort.Sort(routes)
		// define all the functions that we left empty earlier
		err = templ.Funcs(map[string]interface{}{
			"RenderEndpoint": func(r DocumentedRoute) (string, error) {
				return r.Render(templ.Lookup("EndpointTemplate"))
			},
			"RenderSubType": func(t JSONType, stack []string) (result string, err error) {
				return renderType(t, stack)
			},
			"RenderType": func(t JSONType) (result string, err error) {
				return renderType(t, nil)
			},
			"First": first,
			"Example": func(r JSONType) (result string, err error) {
				// this will render an example of the provided JSONType
				defer func() {
					if e := recover(); e != nil {
						result = fmt.Sprintf("%v\n%s", e, utils.Stack())
					}
				}()
				x := utils.Example(r.ReflectType)
				b, err := json.MarshalIndent(x, "", "  ")
				if err != nil {
					return
				}
				if len(r.Fields) > 0 {
					var i interface{}
					if err = json.Unmarshal(b, &i); err != nil {
						return
					}
					if m, ok := i.(map[string]interface{}); ok {
						newMap := map[string]interface{}{}
						for k, v := range m {
							if _, found := r.Fields[k]; found {
								newMap[k] = v
							}
						}
						if b, err = json.MarshalIndent(newMap, "", "  "); err != nil {
							return
						}
					}
				}
				result = string(b)
				return
			},
		}).Execute(c.Resp(), map[string]interface{}{
			"Endpoints": routes,
		})
		return
	})
}