mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-10-30 18:22:49 -04:00 
			
		
		
		
	Merge branch 'master' into macros
This commit is contained in:
		
						commit
						345b312e00
					
				| @ -68,8 +68,13 @@ type Config struct { | ||||
| 	// Template(s) to render with | ||||
| 	Template *template.Template | ||||
| 
 | ||||
| 	// a pair of template's name and its underlying file path | ||||
| 	TemplateFiles map[string]string | ||||
| 	// a pair of template's name and its underlying file information | ||||
| 	TemplateFiles map[string]*cachedFileInfo | ||||
| } | ||||
| 
 | ||||
| type cachedFileInfo struct { | ||||
| 	path string | ||||
| 	fi   os.FileInfo | ||||
| } | ||||
| 
 | ||||
| // ServeHTTP implements the http.Handler interface. | ||||
|  | ||||
| @ -62,7 +62,7 @@ func markdownParse(c *caddy.Controller) ([]*Config, error) { | ||||
| 			Extensions:    make(map[string]struct{}), | ||||
| 			Template:      GetDefaultTemplate(), | ||||
| 			IndexFiles:    []string{}, | ||||
| 			TemplateFiles: make(map[string]string), | ||||
| 			TemplateFiles: make(map[string]*cachedFileInfo), | ||||
| 		} | ||||
| 
 | ||||
| 		// Get the path scope | ||||
| @ -133,7 +133,9 @@ func loadParams(c *caddy.Controller, mdc *Config) error { | ||||
| 				return c.Errf("default template parse error: %v", err) | ||||
| 			} | ||||
| 
 | ||||
| 			mdc.TemplateFiles[""] = fpath | ||||
| 			mdc.TemplateFiles[""] = &cachedFileInfo{ | ||||
| 				path: fpath, | ||||
| 			} | ||||
| 			return nil | ||||
| 		case 2: | ||||
| 			fpath := filepath.ToSlash(filepath.Clean(cfg.Root + string(filepath.Separator) + tArgs[1])) | ||||
| @ -142,7 +144,9 @@ func loadParams(c *caddy.Controller, mdc *Config) error { | ||||
| 				return c.Errf("template parse error: %v", err) | ||||
| 			} | ||||
| 
 | ||||
| 			mdc.TemplateFiles[tArgs[0]] = fpath | ||||
| 			mdc.TemplateFiles[tArgs[0]] = &cachedFileInfo{ | ||||
| 				path: fpath, | ||||
| 			} | ||||
| 			return nil | ||||
| 		} | ||||
| 	case "templatedir": | ||||
| @ -164,7 +168,9 @@ func loadParams(c *caddy.Controller, mdc *Config) error { | ||||
| 			return c.Errf("glob %q failed: %v", pattern, err) | ||||
| 		} | ||||
| 		for _, path := range paths { | ||||
| 			mdc.TemplateFiles[filepath.Base(path)] = path | ||||
| 			mdc.TemplateFiles[filepath.Base(path)] = &cachedFileInfo{ | ||||
| 				path: path, | ||||
| 			} | ||||
| 		} | ||||
| 		return nil | ||||
| 	default: | ||||
|  | ||||
| @ -77,7 +77,7 @@ func TestMarkdownParse(t *testing.T) { | ||||
| 			Styles:        []string{"/resources/css/blog.css"}, | ||||
| 			Scripts:       []string{"/resources/js/blog.js"}, | ||||
| 			Template:      GetDefaultTemplate(), | ||||
| 			TemplateFiles: make(map[string]string), | ||||
| 			TemplateFiles: make(map[string]*cachedFileInfo), | ||||
| 		}}}, | ||||
| 		{`markdown /blog { | ||||
| 	ext .md | ||||
| @ -88,8 +88,8 @@ func TestMarkdownParse(t *testing.T) { | ||||
| 				".md": {}, | ||||
| 			}, | ||||
| 			Template: setDefaultTemplate("./testdata/tpl_with_include.html"), | ||||
| 			TemplateFiles: map[string]string{ | ||||
| 				"": "testdata/tpl_with_include.html", | ||||
| 			TemplateFiles: map[string]*cachedFileInfo{ | ||||
| 				"": {path: "testdata/tpl_with_include.html"}, | ||||
| 			}, | ||||
| 		}}}, | ||||
| 	} | ||||
|  | ||||
| @ -17,6 +17,8 @@ package markdown | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"sync" | ||||
| 	"text/template" | ||||
| 
 | ||||
| 	"github.com/mholt/caddy/caddyhttp/httpserver" | ||||
| @ -41,6 +43,8 @@ func (d Data) Include(filename string, args ...interface{}) (string, error) { | ||||
| 	return httpserver.ContextInclude(filename, d, d.Root) | ||||
| } | ||||
| 
 | ||||
| var templateUpdateMu sync.RWMutex | ||||
| 
 | ||||
| // execTemplate executes a template given a requestPath, template, and metadata | ||||
| func execTemplate(c *Config, mdata metadata.Metadata, meta map[string]string, files []FileInfo, ctx httpserver.Context) ([]byte, error) { | ||||
| 	mdData := Data{ | ||||
| @ -51,18 +55,43 @@ func execTemplate(c *Config, mdata metadata.Metadata, meta map[string]string, fi | ||||
| 		Meta:    meta, | ||||
| 		Files:   files, | ||||
| 	} | ||||
| 
 | ||||
| 	templateName := mdata.Template | ||||
| 	// reload template on every request for now | ||||
| 	// TODO: cache templates by a general plugin | ||||
| 	if templateFile, ok := c.TemplateFiles[templateName]; ok { | ||||
| 		err := SetTemplate(c.Template, templateName, templateFile) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 
 | ||||
| 	updateTemplate := func() error { | ||||
| 		templateUpdateMu.Lock() | ||||
| 		defer templateUpdateMu.Unlock() | ||||
| 
 | ||||
| 		templateFile, ok := c.TemplateFiles[templateName] | ||||
| 		if !ok { | ||||
| 			return nil | ||||
| 		} | ||||
| 
 | ||||
| 		currentFileInfo, err := os.Lstat(templateFile.path) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		if !fileChanged(currentFileInfo, templateFile.fi) { | ||||
| 			return nil | ||||
| 		} | ||||
| 
 | ||||
| 		// update template due to file changes | ||||
| 		err = SetTemplate(c.Template, templateName, templateFile.path) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		templateFile.fi = currentFileInfo | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	if err := updateTemplate(); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	b := new(bytes.Buffer) | ||||
| 	templateUpdateMu.RLock() | ||||
| 	defer templateUpdateMu.RUnlock() | ||||
| 	if err := c.Template.ExecuteTemplate(b, templateName, mdData); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| @ -70,6 +99,21 @@ func execTemplate(c *Config, mdata metadata.Metadata, meta map[string]string, fi | ||||
| 	return b.Bytes(), nil | ||||
| } | ||||
| 
 | ||||
| func fileChanged(new, old os.FileInfo) bool { | ||||
| 	// never checked before | ||||
| 	if old == nil { | ||||
| 		return true | ||||
| 	} | ||||
| 
 | ||||
| 	if new.Size() != old.Size() || | ||||
| 		new.Mode() != old.Mode() || | ||||
| 		new.ModTime() != old.ModTime() { | ||||
| 		return true | ||||
| 	} | ||||
| 
 | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // SetTemplate reads in the template with the filename provided. If the file does not exist or is not parsable, it will return an error. | ||||
| func SetTemplate(t *template.Template, name, filename string) error { | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user