Skip to content

Commit 85190a4

Browse files
committed
Added language support to templates
Deprecated TemplateLoader.Template - Replaced with TemplateLoader.TemplateLang (old function still exists for backwards compatibility) Renamed TemplateEngine interface "IsEngineFor" to "Handles"
1 parent 97ebc2b commit 85190a4

File tree

5 files changed

+85
-30
lines changed

5 files changed

+85
-30
lines changed

controller.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ func (c *Controller) RenderTemplate(templatePath string) Result {
124124
c.setStatusIfNil(http.StatusOK)
125125

126126
// Get the Template.
127-
template, err := MainTemplateLoader.Template(templatePath)
127+
lang, _ := c.ViewArgs[CurrentLocaleViewArg].(string)
128+
template, err := MainTemplateLoader.TemplateLang(templatePath, lang)
128129
if err != nil {
129130
return c.RenderError(err)
130131
}

results.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ func (r ErrorResult) Apply(req *Request, resp *Response) {
4444
if contentType == DefaultFileContentType {
4545
contentType = "text/plain"
4646
}
47-
47+
lang, _ := r.ViewArgs[CurrentLocaleViewArg].(string)
4848
// Get the error template.
4949
var err error
5050
templatePath := fmt.Sprintf("errors/%d.%s", status, format)
51-
tmpl, err := MainTemplateLoader.Template(templatePath)
51+
tmpl, err := MainTemplateLoader.TemplateLang(templatePath, lang)
5252

5353
// This func shows a plaintext error message, in case the template rendering
5454
// doesn't work.
@@ -236,7 +236,8 @@ func (r *RenderTemplateResult) render(req *Request, resp *Response, wr io.Writer
236236
templateName = r.Template.Name()
237237
templateContent = r.Template.Content()
238238
} else {
239-
if tmpl, err := MainTemplateLoader.Template(templateName); err == nil {
239+
lang, _ := r.ViewArgs[CurrentLocaleViewArg].(string)
240+
if tmpl, err := MainTemplateLoader.TemplateLang(templateName, lang); err == nil {
240241
templateContent = tmpl.Content()
241242
}
242243
}

template.go

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ func (loader *TemplateLoader) findAndAddTemplate(path, fullSrcDir, basePath stri
210210

211211
// Try to find a default engine for the file
212212
for _, engine := range loader.templatesAndEngineList {
213-
if engine.IsEngineFor(engine, baseTemplate) {
213+
if engine.Handles(baseTemplate) {
214214
_, err = loader.loadIntoEngine(engine, baseTemplate)
215215
return
216216
}
@@ -296,16 +296,36 @@ func ParseTemplateError(err error) (templateName string, line int, description s
296296
return templateName, line, description
297297
}
298298

299+
// DEPRECATED Use TemplateLang, will be removed in future release
300+
func (loader *TemplateLoader) Template(name string) (tmpl Template, err error) {
301+
return loader.TemplateLang(name, "")
302+
}
299303
// Template returns the Template with the given name. The name is the template's path
300304
// relative to a template loader root.
301305
//
302306
// An Error is returned if there was any problem with any of the templates. (In
303307
// this case, if a template is returned, it may still be usable.)
304-
func (loader *TemplateLoader) Template(name string) (tmpl Template, err error) {
308+
func (loader *TemplateLoader) TemplateLang(name, lang string) (tmpl Template, err error) {
305309
if loader.compileError != nil {
306310
return nil, loader.compileError
307311
}
312+
// Attempt to load a localized template first.
313+
if lang != "" {
314+
// Look up and return the template.
315+
tmpl = loader.templateLoad(name + "." + lang)
316+
}
317+
// Return non localized version
318+
if tmpl == nil {
319+
tmpl = loader.templateLoad(name)
320+
}
308321

322+
if tmpl == nil && err == nil {
323+
err = fmt.Errorf("Template %s not found.", name)
324+
}
325+
326+
return
327+
}
328+
func (loader *TemplateLoader) templateLoad(name string) (tmpl Template) {
309329
if t,found := loader.TemplateMap[name];!found && t != nil {
310330
tmpl = t
311331
} else {
@@ -316,12 +336,7 @@ func (loader *TemplateLoader) Template(name string) (tmpl Template, err error) {
316336
break
317337
}
318338
}
319-
}
320-
321-
if tmpl == nil && err == nil {
322-
err = fmt.Errorf("Template %s not found.", name)
323339
}
324-
325340
return
326341
}
327342

template_adapter_go.go

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"reflect"
1010
"strings"
1111
"time"
12+
"bytes"
1213
)
1314

1415
const GO_TEMPLATE = "go"
@@ -147,6 +148,43 @@ var (
147148
},
148149
"slug": Slug,
149150
"even": func(a int) bool { return (a % 2) == 0 },
151+
"i18ntemplate": func(args ...interface{}) (template.HTML, error) {
152+
templateName, lang := "", ""
153+
var viewArgs interface{}
154+
switch len(args) {
155+
case 0:
156+
ERROR.Printf("No arguements passed to template call")
157+
case 1:
158+
// Assume only the template name is passed in
159+
templateName = args[0].(string)
160+
case 2:
161+
// Assume template name and viewArgs is passed in
162+
templateName = args[0].(string)
163+
viewArgs = args[1]
164+
// Try to extract language from the view args
165+
if viewargsmap,ok := viewArgs.(map[string]interface{});ok {
166+
lang,_ = viewargsmap[CurrentLocaleViewArg].(string)
167+
}
168+
default:
169+
// Assume third argument is the region
170+
templateName = args[0].(string)
171+
viewArgs = args[1]
172+
lang, _ = args[2].(string)
173+
if len(args)>3 {
174+
ERROR.Printf("Received more parameters then needed for %s",templateName)
175+
}
176+
}
177+
178+
var buf bytes.Buffer
179+
// Get template
180+
tmpl, err := MainTemplateLoader.TemplateLang(templateName, lang)
181+
if err == nil {
182+
err = tmpl.Render(&buf, viewArgs)
183+
} else {
184+
ERROR.Printf("Failed to render i18ntemplate %s %v",templateName,err)
185+
}
186+
return template.HTML(buf.String()), err
187+
},
150188
}
151189
)
152190

@@ -168,7 +206,18 @@ type GoEngine struct {
168206
// TemplatesBylowerName is a map from lower case template name to the real template.
169207
templatesBylowerName map[string]*GoTemplate
170208
splitDelims []string
171-
TemplateEngineHelper
209+
CaseInsensitiveMode bool
210+
}
211+
212+
func (i *GoEngine) ConvertPath(path string) string {
213+
if i.CaseInsensitiveMode {
214+
return strings.ToLower(path)
215+
}
216+
return path
217+
}
218+
219+
func (i *GoEngine) Handles(templateView *TemplateView) bool{
220+
return EngineHandles(i, templateView)
172221
}
173222

174223
func (engine *GoEngine) ParseAndAdd(baseTemplate *TemplateView) error {

template_engine.go

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ type TemplateEngine interface {
2020
Event(event int, arg interface{})
2121

2222
// returns true if this engine should be used to parse the file specified in baseTemplate
23-
IsEngineFor(engine TemplateEngine, templateView *TemplateView) bool
23+
Handles(templateView *TemplateView) bool
2424

2525
// returns the name of the engine
2626
Name() string
@@ -35,11 +35,6 @@ type TemplateView struct {
3535
EngineType string // The name of the engine used to render the view
3636
}
3737

38-
// Template engine helper
39-
type TemplateEngineHelper struct {
40-
CaseInsensitiveMode bool
41-
}
42-
4338
var templateLoaderMap = map[string]func(loader *TemplateLoader) (TemplateEngine, error){}
4439

4540
// Allow for templates to be registered during init but not initialized until application has been started
@@ -96,33 +91,27 @@ func (loader *TemplateLoader) InitializeEngines(templateEngineNameList string) (
9691
return
9792
}
9893

99-
func (i *TemplateEngineHelper) IsEngineFor(engine TemplateEngine, description *TemplateView) bool {
100-
if line, _, e := bufio.NewReader(bytes.NewBuffer(description.FileBytes)).ReadLine(); e == nil && string(line[:3]) == "#! " {
94+
func EngineHandles(engine TemplateEngine, templateView *TemplateView) bool {
95+
if line, _, e := bufio.NewReader(bytes.NewBuffer(templateView.FileBytes)).ReadLine(); e == nil && string(line[:3]) == "#! " {
10196
// Extract the shebang and look at the rest of the line
10297
// #! pong2
10398
// #! go
10499
templateType := strings.TrimSpace(string(line[2:]))
105100
if engine.Name() == templateType {
106101
// Advance the read file bytes so it does not include the shebang
107-
description.FileBytes = description.FileBytes[len(line)+1:]
108-
description.EngineType = templateType
102+
templateView.FileBytes = templateView.FileBytes[len(line)+1:]
103+
templateView.EngineType = templateType
109104
return true
110105
}
111106
}
112-
filename := filepath.Base(description.FilePath)
107+
filename := filepath.Base(templateView.FilePath)
113108
bits := strings.Split(filename, ".")
114109
if len(bits) > 2 {
115110
templateType := strings.TrimSpace(bits[len(bits)-2])
116111
if engine.Name() == templateType {
117-
description.EngineType = templateType
112+
templateView.EngineType = templateType
118113
return true
119114
}
120115
}
121116
return false
122117
}
123-
func (i *TemplateEngineHelper) ConvertPath(path string) string {
124-
if i.CaseInsensitiveMode {
125-
return strings.ToLower(path)
126-
}
127-
return path
128-
}

0 commit comments

Comments
 (0)