Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a39fdb3

Browse filesBrowse files
committed
Added template read and population
Added controller.TemplateOut, revel.TemplateOutArgs
1 parent b1df5bf commit a39fdb3
Copy full SHA for a39fdb3

File tree

3 files changed

+108
-54
lines changed
Filter options

3 files changed

+108
-54
lines changed

‎controller.go

Copy file name to clipboardExpand all lines: controller.go
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,11 @@ func (c *Controller) RenderTemplate(templatePath string) Result {
198198
}
199199
}
200200

201+
// TemplateOutput returns the result of the template rendered using the controllers ViewArgs.
202+
func (c *Controller) TemplateOutput(templatePath string) (data []byte,err error) {
203+
return TemplateOutputArgs(templatePath,c.ViewArgs)
204+
}
205+
201206
// RenderJSON uses encoding/json.Marshal to return JSON to the client.
202207
func (c *Controller) RenderJSON(o interface{}) Result {
203208
c.setStatusIfNil(http.StatusOK)

‎results.go

Copy file name to clipboardExpand all lines: results.go
+84-54Lines changed: 84 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -156,63 +156,20 @@ func (r *RenderTemplateResult) Apply(req *Request, resp *Response) {
156156
// error pages distorted by HTML already written)
157157
if chunked && !DevMode {
158158
resp.WriteHeader(http.StatusOK, "text/html; charset=utf-8")
159-
r.render(req, resp, out)
159+
if err := r.renderOutput(out); err !=nil {
160+
r.renderError(err,req,resp)
161+
}
160162
return
161163
}
162164

163165
// Render the template into a temporary buffer, to see if there was an error
164166
// rendering the template. If not, then copy it into the response buffer.
165167
// Otherwise, template render errors may result in unpredictable HTML (and
166168
// would carry a 200 status code)
167-
var b bytes.Buffer
168-
r.render(req, resp, &b)
169-
170-
// Trimming the HTML will do the following:
171-
// * Remove all leading & trailing whitespace on every line
172-
// * Remove all empty lines
173-
// * Attempt to keep formatting inside <pre></pre> tags
174-
//
175-
// This is safe unless white-space: pre; is used in css for formatting.
176-
// Since there is no way to detect that, you will have to keep trimming off in these cases.
177-
if Config.BoolDefault("results.trim.html", false) {
178-
var b2 bytes.Buffer
179-
// Allocate length of original buffer, so we can write everything without allocating again
180-
b2.Grow(b.Len())
181-
insidePre := false
182-
for {
183-
text, err := b.ReadString('\n')
184-
// Convert to lower case for finding <pre> tags.
185-
tl := strings.ToLower(text)
186-
if strings.Contains(tl, "<pre>") {
187-
insidePre = true
188-
}
189-
// Trim if not inside a <pre> statement
190-
if !insidePre {
191-
// Cut trailing/leading whitespace
192-
text = strings.Trim(text, " \t\r\n")
193-
if len(text) > 0 {
194-
if _, err = b2.WriteString(text); err != nil {
195-
resultsLog.Error("Apply: ", "error", err)
196-
}
197-
if _, err = b2.WriteString("\n"); err != nil {
198-
resultsLog.Error("Apply: ", "error", err)
199-
}
200-
}
201-
} else {
202-
if _, err = b2.WriteString(text); err != nil {
203-
resultsLog.Error("Apply: ", "error", err)
204-
}
205-
}
206-
if strings.Contains(tl, "</pre>") {
207-
insidePre = false
208-
}
209-
// We are finished
210-
if err != nil {
211-
break
212-
}
213-
}
214-
// Replace the buffer
215-
b = b2
169+
b, err := r.ToBytes()
170+
if err!=nil {
171+
r.renderError(err,req,resp)
172+
return
216173
}
217174

218175
if !chunked {
@@ -224,12 +181,85 @@ func (r *RenderTemplateResult) Apply(req *Request, resp *Response) {
224181
}
225182
}
226183

227-
func (r *RenderTemplateResult) render(req *Request, resp *Response, wr io.Writer) {
228-
err := r.Template.Render(wr, r.ViewArgs)
229-
if err == nil {
230-
return
184+
// Return a byte array and or an error object if the template failed to render
185+
func (r *RenderTemplateResult) ToBytes() (b *bytes.Buffer,err error) {
186+
defer func() {
187+
if rerr := recover(); rerr != nil {
188+
resultsLog.Error("ApplyBytes: panic recovery", "recover-error", rerr)
189+
err = fmt.Errorf("Template Execution Panic in %s:\n%s", r.Template.Name(), rerr)
190+
}
191+
}()
192+
b = &bytes.Buffer{}
193+
if err = r.renderOutput(b); err==nil {
194+
if Config.BoolDefault("results.trim.html", false) {
195+
b = r.compressHtml(b)
196+
}
197+
}
198+
return
199+
}
200+
201+
// Output the template to the writer, catch any panics and return as an error
202+
func (r *RenderTemplateResult) renderOutput(wr io.Writer) (err error) {
203+
defer func() {
204+
if rerr := recover(); rerr != nil {
205+
resultsLog.Error("ApplyBytes: panic recovery", "recover-error", rerr)
206+
err = fmt.Errorf("Template Execution Panic in %s:\n%s", r.Template.Name(), rerr)
207+
}
208+
}()
209+
err = r.Template.Render(wr, r.ViewArgs)
210+
return
211+
}
212+
213+
// Trimming the HTML will do the following:
214+
// * Remove all leading & trailing whitespace on every line
215+
// * Remove all empty lines
216+
// * Attempt to keep formatting inside <pre></pre> tags
217+
//
218+
// This is safe unless white-space: pre; is used in css for formatting.
219+
// Since there is no way to detect that, you will have to keep trimming off in these cases.
220+
func (r *RenderTemplateResult) compressHtml(b *bytes.Buffer) (b2 *bytes.Buffer) {
221+
222+
// Allocate length of original buffer, so we can write everything without allocating again
223+
b2.Grow(b.Len())
224+
insidePre := false
225+
for {
226+
text, err := b.ReadString('\n')
227+
// Convert to lower case for finding <pre> tags.
228+
tl := strings.ToLower(text)
229+
if strings.Contains(tl, "<pre>") {
230+
insidePre = true
231+
}
232+
// Trim if not inside a <pre> statement
233+
if !insidePre {
234+
// Cut trailing/leading whitespace
235+
text = strings.Trim(text, " \t\r\n")
236+
if len(text) > 0 {
237+
if _, err = b2.WriteString(text); err != nil {
238+
resultsLog.Error("Apply: ", "error", err)
239+
}
240+
if _, err = b2.WriteString("\n"); err != nil {
241+
resultsLog.Error("Apply: ", "error", err)
242+
}
243+
}
244+
} else {
245+
if _, err = b2.WriteString(text); err != nil {
246+
resultsLog.Error("Apply: ", "error", err)
247+
}
248+
}
249+
if strings.Contains(tl, "</pre>") {
250+
insidePre = false
251+
}
252+
// We are finished
253+
if err != nil {
254+
break
255+
}
231256
}
232257

258+
return
259+
}
260+
261+
// Render the error in the response
262+
func (r *RenderTemplateResult) renderError(err error,req *Request, resp *Response) {
233263
var templateContent []string
234264
templateName, line, description := ParseTemplateError(err)
235265
if templateName == "" {

‎template.go

Copy file name to clipboardExpand all lines: template.go
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,25 @@ var invalidSlugPattern = regexp.MustCompile(`[^a-z0-9 _-]`)
5050
var whiteSpacePattern = regexp.MustCompile(`\s+`)
5151
var templateLog = RevelLog.New("section", "template")
5252

53+
// TemplateOutputArgs returns the result of the template rendered using the passed in arguments.
54+
func TemplateOutputArgs(templatePath string, args map[string]interface{}) (data []byte,err error) {
55+
// Get the Template.
56+
lang, _ := args[CurrentLocaleViewArg].(string)
57+
template, err := MainTemplateLoader.TemplateLang(templatePath, lang)
58+
if err != nil {
59+
return nil, err
60+
}
61+
tr := &RenderTemplateResult{
62+
Template: template,
63+
ViewArgs: args,
64+
}
65+
b,err := tr.ToBytes()
66+
if err!=nil {
67+
return nil,err
68+
}
69+
return b.Bytes(), nil
70+
}
71+
5372
func NewTemplateLoader(paths []string) *TemplateLoader {
5473
loader := &TemplateLoader{
5574
paths: paths,

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.