Skip to content

Navigation Menu

Sign in
Appearance settings

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 8e25775

Browse filesBrowse files
authored
Merge pull request revel#1238 from notzippy/pre-release
Added template read and population
2 parents 0928f02 + 183fdec commit 8e25775
Copy full SHA for 8e25775

File tree

7 files changed

+186
-89
lines changed
Filter options

7 files changed

+186
-89
lines changed

‎.codebeatsettings

Copy file name to clipboardExpand all lines: .codebeatsettings
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{
22
"GOLANG": {
3+
"ABC":[15, 25, 50, 70],
4+
"BLOCK_NESTING":[5, 6, 7, 8],
5+
"CYCLO":[20, 30, 45, 60],
36
"TOO_MANY_IVARS": [15, 18, 20, 25],
47
"TOO_MANY_FUNCTIONS": [20, 30, 40, 50],
58
"TOTAL_COMPLEXITY": [150, 250, 400, 500],

‎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
@@ -208,6 +208,11 @@ func (c *Controller) RenderTemplate(templatePath string) Result {
208208
}
209209
}
210210

211+
// TemplateOutput returns the result of the template rendered using the controllers ViewArgs.
212+
func (c *Controller) TemplateOutput(templatePath string) (data []byte,err error) {
213+
return TemplateOutputArgs(templatePath,c.ViewArgs)
214+
}
215+
211216
// RenderJSON uses encoding/json.Marshal to return JSON to the client.
212217
func (c *Controller) RenderJSON(o interface{}) Result {
213218
c.setStatusIfNil(http.StatusOK)

‎logger/handlers.go

Copy file name to clipboardExpand all lines: logger/handlers.go
+16-2Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,18 @@ func NilHandler() LogHandler {
7878
})
7979
}
8080

81-
// Rather then chaining multiple filter handlers, process all here
81+
// Match all values in map to log
8282
func MatchMapHandler(matchMap map[string]interface{}, a LogHandler) LogHandler {
83+
return matchMapHandler(matchMap, false, a)
84+
}
85+
86+
// Match !(Match all values in map to log) The inverse of MatchMapHandler
87+
func NotMatchMapHandler(matchMap map[string]interface{}, a LogHandler) LogHandler {
88+
return matchMapHandler(matchMap, true, a)
89+
}
90+
91+
// Rather then chaining multiple filter handlers, process all here
92+
func matchMapHandler(matchMap map[string]interface{}, inverse bool, a LogHandler) LogHandler {
8393
return log15.FuncHandler(func(r *log15.Record) error {
8494
checkMap := map[string]bool{}
8595
// Copy the map to a bool
@@ -89,6 +99,10 @@ func MatchMapHandler(matchMap map[string]interface{}, a LogHandler) LogHandler {
8999
}
90100
}
91101
if len(checkMap) == len(matchMap) {
102+
if !inverse {
103+
return a.Log(r)
104+
}
105+
} else if inverse {
92106
return a.Log(r)
93107
}
94108
return nil
@@ -232,7 +246,7 @@ func (h *CompositeMultiHandler) SetHandler(handler LogHandler, replace bool, lev
232246
if ll, found := (*source).(*ListLogHandler); found {
233247
ll.Add(handler)
234248
} else {
235-
*source = NewListLogHandler(h.CriticalHandler, handler)
249+
*source = NewListLogHandler(*source, handler)
236250
}
237251
} else {
238252
*source = handler

‎logger/utils.go

Copy file name to clipboardExpand all lines: logger/utils.go
+58-31Lines changed: 58 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,19 @@ func GetLogger(name string, logger MultiLogger) (l *log.Logger) {
4444
func InitializeFromConfig(basePath string, config *config.Context) (c *CompositeMultiHandler) {
4545
// If the configuration has an all option we can skip some
4646
c, _ = NewCompositeMultiHandler()
47+
48+
// Filters are assigned first, non filtered items override filters
4749
initAllLog(c, basePath, config)
4850
initLogLevels(c, basePath, config)
49-
initRequestLog(c, basePath, config)
50-
// Check to see if critical handler needs to be assigned to the error handler
5151
if c.CriticalHandler == nil && c.ErrorHandler != nil {
5252
c.CriticalHandler = c.ErrorHandler
5353
}
54+
initFilterLog(c, basePath, config)
55+
if c.CriticalHandler == nil && c.ErrorHandler != nil {
56+
c.CriticalHandler = c.ErrorHandler
57+
}
58+
initRequestLog(c, basePath, config)
59+
5460
return c
5561
}
5662

@@ -62,19 +68,57 @@ func initAllLog(c *CompositeMultiHandler, basePath string, config *config.Contex
6268
log.Printf("Adding standard handler for levels to >%s< ", output)
6369
initHandlerFor(c, output, basePath, NewLogOptions(config, true, nil, LvlAllList...))
6470
}
65-
optionList := config.Options("log.all.filter")
66-
for _, option := range optionList {
67-
splitOptions := strings.Split(option, ".")
68-
keyMap := map[string]interface{}{}
69-
for x := 3; x < len(splitOptions); x += 2 {
70-
keyMap[splitOptions[x]] = splitOptions[x+1]
71-
}
71+
}
72+
}
7273

73-
log.Printf("Adding key map handler to all %s output %s", option, config.StringDefault(option, ""))
74-
phandler := NewParentLogHandler(func(child LogHandler) LogHandler {
75-
return MatchMapHandler(keyMap, child)
76-
})
77-
initHandlerFor(c, config.StringDefault(option, ""), basePath, NewLogOptions(config, false, phandler))
74+
// Init the filter options
75+
// log.all.filter ....
76+
// log.error.filter ....
77+
func initFilterLog(c *CompositeMultiHandler, basePath string, config *config.Context) {
78+
if config != nil {
79+
// The commands to use
80+
logFilterList := []struct {
81+
LogPrefix, LogSuffix string
82+
parentHandler func(map[string]interface{}) ParentLogHandler
83+
}{{
84+
"log.", ".filter",
85+
func(keyMap map[string]interface{}) ParentLogHandler {
86+
return NewParentLogHandler(func(child LogHandler) LogHandler {
87+
return MatchMapHandler(keyMap, child)
88+
})
89+
90+
},
91+
}, {
92+
"log.", ".nfilter",
93+
func(keyMap map[string]interface{}) ParentLogHandler {
94+
return NewParentLogHandler(func(child LogHandler) LogHandler {
95+
return NotMatchMapHandler(keyMap, child)
96+
})
97+
},
98+
}}
99+
100+
for _, logFilter := range logFilterList {
101+
// Init for all filters
102+
for _, name := range []string{"all", "debug", "info", "warn", "error", "crit",
103+
"trace", // TODO trace is deprecated
104+
} {
105+
optionList := config.Options(logFilter.LogPrefix + name + logFilter.LogSuffix)
106+
for _, option := range optionList {
107+
splitOptions := strings.Split(option, ".")
108+
keyMap := map[string]interface{}{}
109+
for x := 3; x < len(splitOptions); x += 2 {
110+
keyMap[splitOptions[x]] = splitOptions[x+1]
111+
}
112+
phandler := logFilter.parentHandler(keyMap)
113+
log.Printf("Adding key map handler %s %s output %s", option, name, config.StringDefault(option, ""))
114+
115+
if name == "all" {
116+
initHandlerFor(c, config.StringDefault(option, ""), basePath, NewLogOptions(config, false, phandler))
117+
} else {
118+
initHandlerFor(c, config.StringDefault(option, ""), basePath, NewLogOptions(config, false, phandler, toLevel[name]))
119+
}
120+
}
121+
}
78122
}
79123
}
80124
}
@@ -90,23 +134,6 @@ func initLogLevels(c *CompositeMultiHandler, basePath string, config *config.Con
90134
log.Printf("Adding standard handler %s output %s", name, output)
91135
initHandlerFor(c, output, basePath, NewLogOptions(config, true, nil, toLevel[name]))
92136
}
93-
// Now check to see if we have any module specific loggers
94-
// Names should be module.name or module.name.context.name
95-
optionList := config.Options("log." + name + ".filter")
96-
for _, option := range optionList {
97-
splitOptions := strings.Split(option, ".")
98-
keyMap := map[string]interface{}{}
99-
for x := 3; x < len(splitOptions); x += 2 {
100-
keyMap[splitOptions[x]] = splitOptions[x+1]
101-
}
102-
103-
phandler := NewParentLogHandler(func(child LogHandler) LogHandler {
104-
return MatchMapHandler(keyMap, child)
105-
})
106-
log.Printf("Adding key map handler %s %s output %s", option, name, config.StringDefault(option, ""))
107-
initHandlerFor(c, config.StringDefault(option, ""), basePath, NewLogOptions(config, false, phandler, toLevel[name]))
108-
}
109-
110137
// Gets the list of options with said prefix
111138
} else {
112139
initHandlerFor(c, "stderr", basePath, NewLogOptions(config, true, nil, toLevel[name]))

‎panic.go

Copy file name to clipboardExpand all lines: panic.go
+1-2Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
package revel
66

77
import (
8-
"github.com/revel/revel/logger"
98
"net/http"
109
"runtime/debug"
1110
)
@@ -25,7 +24,7 @@ func PanicFilter(c *Controller, fc []Filter) {
2524
// It cleans up the stack trace, logs it, and displays an error page.
2625
func handleInvocationPanic(c *Controller, err interface{}) {
2726
error := NewErrorFromPanic(err)
28-
utilLog.Error("PanicFilter: Caught panic", "error", err, "trace", logger.NewCallStack())
27+
utilLog.Error("PanicFilter: Caught panic", "error", err, "stack", error.Stack)
2928
if error == nil && DevMode {
3029
// Only show the sensitive information in the debug stack trace in development mode, not production
3130
c.Response.SetStatus(http.StatusInternalServerError)

‎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.