mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-10-31 10:37:24 -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(s) to render with | ||||||
| 	Template *template.Template | 	Template *template.Template | ||||||
| 
 | 
 | ||||||
| 	// a pair of template's name and its underlying file path | 	// a pair of template's name and its underlying file information | ||||||
| 	TemplateFiles map[string]string | 	TemplateFiles map[string]*cachedFileInfo | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type cachedFileInfo struct { | ||||||
|  | 	path string | ||||||
|  | 	fi   os.FileInfo | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ServeHTTP implements the http.Handler interface. | // ServeHTTP implements the http.Handler interface. | ||||||
|  | |||||||
| @ -62,7 +62,7 @@ func markdownParse(c *caddy.Controller) ([]*Config, error) { | |||||||
| 			Extensions:    make(map[string]struct{}), | 			Extensions:    make(map[string]struct{}), | ||||||
| 			Template:      GetDefaultTemplate(), | 			Template:      GetDefaultTemplate(), | ||||||
| 			IndexFiles:    []string{}, | 			IndexFiles:    []string{}, | ||||||
| 			TemplateFiles: make(map[string]string), | 			TemplateFiles: make(map[string]*cachedFileInfo), | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// Get the path scope | 		// 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) | 				return c.Errf("default template parse error: %v", err) | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			mdc.TemplateFiles[""] = fpath | 			mdc.TemplateFiles[""] = &cachedFileInfo{ | ||||||
|  | 				path: fpath, | ||||||
|  | 			} | ||||||
| 			return nil | 			return nil | ||||||
| 		case 2: | 		case 2: | ||||||
| 			fpath := filepath.ToSlash(filepath.Clean(cfg.Root + string(filepath.Separator) + tArgs[1])) | 			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) | 				return c.Errf("template parse error: %v", err) | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			mdc.TemplateFiles[tArgs[0]] = fpath | 			mdc.TemplateFiles[tArgs[0]] = &cachedFileInfo{ | ||||||
|  | 				path: fpath, | ||||||
|  | 			} | ||||||
| 			return nil | 			return nil | ||||||
| 		} | 		} | ||||||
| 	case "templatedir": | 	case "templatedir": | ||||||
| @ -164,7 +168,9 @@ func loadParams(c *caddy.Controller, mdc *Config) error { | |||||||
| 			return c.Errf("glob %q failed: %v", pattern, err) | 			return c.Errf("glob %q failed: %v", pattern, err) | ||||||
| 		} | 		} | ||||||
| 		for _, path := range paths { | 		for _, path := range paths { | ||||||
| 			mdc.TemplateFiles[filepath.Base(path)] = path | 			mdc.TemplateFiles[filepath.Base(path)] = &cachedFileInfo{ | ||||||
|  | 				path: path, | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 		return nil | 		return nil | ||||||
| 	default: | 	default: | ||||||
|  | |||||||
| @ -77,7 +77,7 @@ func TestMarkdownParse(t *testing.T) { | |||||||
| 			Styles:        []string{"/resources/css/blog.css"}, | 			Styles:        []string{"/resources/css/blog.css"}, | ||||||
| 			Scripts:       []string{"/resources/js/blog.js"}, | 			Scripts:       []string{"/resources/js/blog.js"}, | ||||||
| 			Template:      GetDefaultTemplate(), | 			Template:      GetDefaultTemplate(), | ||||||
| 			TemplateFiles: make(map[string]string), | 			TemplateFiles: make(map[string]*cachedFileInfo), | ||||||
| 		}}}, | 		}}}, | ||||||
| 		{`markdown /blog { | 		{`markdown /blog { | ||||||
| 	ext .md | 	ext .md | ||||||
| @ -88,8 +88,8 @@ func TestMarkdownParse(t *testing.T) { | |||||||
| 				".md": {}, | 				".md": {}, | ||||||
| 			}, | 			}, | ||||||
| 			Template: setDefaultTemplate("./testdata/tpl_with_include.html"), | 			Template: setDefaultTemplate("./testdata/tpl_with_include.html"), | ||||||
| 			TemplateFiles: map[string]string{ | 			TemplateFiles: map[string]*cachedFileInfo{ | ||||||
| 				"": "testdata/tpl_with_include.html", | 				"": {path: "testdata/tpl_with_include.html"}, | ||||||
| 			}, | 			}, | ||||||
| 		}}}, | 		}}}, | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -17,6 +17,8 @@ package markdown | |||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"io/ioutil" | 	"io/ioutil" | ||||||
|  | 	"os" | ||||||
|  | 	"sync" | ||||||
| 	"text/template" | 	"text/template" | ||||||
| 
 | 
 | ||||||
| 	"github.com/mholt/caddy/caddyhttp/httpserver" | 	"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) | 	return httpserver.ContextInclude(filename, d, d.Root) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | var templateUpdateMu sync.RWMutex | ||||||
|  | 
 | ||||||
| // execTemplate executes a template given a requestPath, template, and metadata | // 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) { | func execTemplate(c *Config, mdata metadata.Metadata, meta map[string]string, files []FileInfo, ctx httpserver.Context) ([]byte, error) { | ||||||
| 	mdData := Data{ | 	mdData := Data{ | ||||||
| @ -51,18 +55,43 @@ func execTemplate(c *Config, mdata metadata.Metadata, meta map[string]string, fi | |||||||
| 		Meta:    meta, | 		Meta:    meta, | ||||||
| 		Files:   files, | 		Files:   files, | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	templateName := mdata.Template | 	templateName := mdata.Template | ||||||
| 	// reload template on every request for now | 
 | ||||||
| 	// TODO: cache templates by a general plugin | 	updateTemplate := func() error { | ||||||
| 	if templateFile, ok := c.TemplateFiles[templateName]; ok { | 		templateUpdateMu.Lock() | ||||||
| 		err := SetTemplate(c.Template, templateName, templateFile) | 		defer templateUpdateMu.Unlock() | ||||||
| 		if err != nil { | 
 | ||||||
| 			return nil, err | 		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) | 	b := new(bytes.Buffer) | ||||||
|  | 	templateUpdateMu.RLock() | ||||||
|  | 	defer templateUpdateMu.RUnlock() | ||||||
| 	if err := c.Template.ExecuteTemplate(b, templateName, mdData); err != nil { | 	if err := c.Template.ExecuteTemplate(b, templateName, mdData); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @ -70,6 +99,21 @@ func execTemplate(c *Config, mdata metadata.Metadata, meta map[string]string, fi | |||||||
| 	return b.Bytes(), nil | 	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. | // 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 { | func SetTemplate(t *template.Template, name, filename string) error { | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user