github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/service/plugin.go (about) 1 package service 2 3 import ( 4 "bytes" 5 "io" 6 "net/http" 7 "path/filepath" 8 9 "github.com/evergreen-ci/evergreen/model/user" 10 "github.com/evergreen-ci/evergreen/plugin" 11 ) 12 13 // pluginHTML the given set of template files and executes the template named entryPoint against 14 // the context data, writing the result to out. Returns error if the template could not be 15 // loaded or if executing the template failed. 16 func (uis *UIServer) pluginHTML(out io.Writer, data interface{}, entryPoint, pluginName, pluginFile string, files ...string) error { 17 18 // check if the template is cached and execute cached template if so. 19 if uis.Settings.Ui.CacheTemplates { 20 if templ, ok := uis.PluginTemplates[pluginName]; ok { 21 return templ.ExecuteTemplate(out, entryPoint, data) 22 } 23 } 24 25 t, err := uis.GetHTMLTemplate(files...) 26 if err != nil { 27 return err 28 } 29 newTemplate, err := t.Clone() 30 if err != nil { 31 return err 32 } 33 34 newTemplate, err = newTemplate.ParseFiles(pluginFile) 35 if err != nil { 36 return err 37 } 38 39 // cache the template if necessary 40 if uis.Settings.Ui.CacheTemplates { 41 uis.PluginTemplates[pluginName] = newTemplate 42 } 43 err = newTemplate.ExecuteTemplate(out, entryPoint, data) 44 return err 45 } 46 47 // PluginWriteHTML calls HTML() on its args and writes the output to the response with the given status. 48 // If the template can't be loaded or executed, the status is set to 500 and error details 49 // are written to the response body. 50 func (uis *UIServer) PluginWriteHTML(w http.ResponseWriter, status int, data interface{}, entryPoint, pluginName, pluginFile string, files ...string) { 51 out := &bytes.Buffer{} 52 err := uis.pluginHTML(out, data, entryPoint, pluginName, pluginFile, files...) 53 if err != nil { 54 http.Error(w, err.Error(), http.StatusInternalServerError) 55 return 56 } 57 58 w.Header().Set("Content-Type", "text/html; charset=UTF-8") 59 w.WriteHeader(status) 60 _, err = w.Write(out.Bytes()) 61 if err != nil { 62 http.Error(w, err.Error(), http.StatusInternalServerError) 63 } 64 } 65 66 // GetPluginHandler returns a handler function given the template route and data to go to that page. 67 func (uis *UIServer) GetPluginHandler(uiPage *plugin.UIPage, pluginName string) func(http.ResponseWriter, *http.Request) { 68 return func(w http.ResponseWriter, r *http.Request) { 69 projCtx := MustHaveProjectContext(r) 70 u := GetUser(r) 71 pluginCtx := plugin.UIContext{ 72 Settings: uis.Settings, 73 User: u, 74 Task: projCtx.Task, 75 Build: projCtx.Build, 76 Version: projCtx.Version, 77 Patch: projCtx.Patch, 78 Project: projCtx.Project, 79 ProjectRef: projCtx.ProjectRef, 80 Request: r, 81 } 82 pluginData, err := uiPage.DataFunc(pluginCtx) 83 if err != nil { 84 http.Error(w, err.Error(), http.StatusInternalServerError) 85 return 86 } 87 data := struct { 88 Data interface{} 89 User *user.DBUser 90 ProjectData projectContext 91 }{pluginData, u, projCtx} 92 93 pluginTemplatePath := filepath.Join(plugin.TemplateRoot(pluginName), uiPage.TemplatePath) 94 uis.PluginWriteHTML(w, http.StatusOK, data, "base", pluginName, pluginTemplatePath, "base_angular.html", "menu.html") 95 } 96 }