| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -8,15 +8,28 @@ import (
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						"text/template"
 | 
					 | 
					 | 
					 | 
						"text/template"
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					)
 | 
					 | 
					 | 
					 | 
					)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					var template_dir string = GetDefaultEnv("GOWIKI_TEMPLATE_DIR", "./tmpl")
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					var data_dir string = GetDefaultEnv("GOWIKI_DATA_DIR", "./data")
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Template caching
 | 
					 | 
					 | 
					 | 
					// Template caching
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// var templates = template.Must(template.ParseFiles("edit.html", "view.html"))
 | 
					 | 
					 | 
					 | 
					// var templates = template.Must(template.ParseFiles("edit.html", "view.html"))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					var templates = template.Must(template.ParseGlob("./tmpl/*.html"))
 | 
					 | 
					 | 
					 | 
					var templates = template.Must(template.ParseGlob(template_dir + "/*.html"))
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// var templates = template.Must(template.ParseFiles("edit.html", "view.html"))
 | 
					 | 
					 | 
					 | 
					// var templates = template.Must(template.ParseFiles("edit.html", "view.html"))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Validation to prevent abitrary paths
 | 
					 | 
					 | 
					 | 
					// Validation to prevent abitrary paths
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					var validPath = regexp.MustCompile("^/(edit|save|view)/([a-zA-Z0-9]+)$")
 | 
					 | 
					 | 
					 | 
					var validPath = regexp.MustCompile("^/(edit|save|view)/([a-zA-Z0-9]+)$")
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					// // Retreives and environment variable or supplies the specified default
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					// func GetDefaultEnv(key, default_value string) string {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					// 	// TODO figure out how to write unit test for this How would you wring
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					// 	value := os.Getenv(key)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					// 	if value == "" {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					// 		value = default_value
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					// 	}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					// 	return value
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					// }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// A wiki consists of a series of interconnected pages, each of which has a title and a body
 | 
					 | 
					 | 
					 | 
					// A wiki consists of a series of interconnected pages, each of which has a title and a body
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					type Page struct {
 | 
					 | 
					 | 
					 | 
					type Page struct {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Title string
 | 
					 | 
					 | 
					 | 
						Title string
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -26,7 +39,7 @@ type Page struct {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// save Saves a page to disk.
 | 
					 | 
					 | 
					 | 
					// save Saves a page to disk.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func (p *Page) save() error {
 | 
					 | 
					 | 
					 | 
					func (p *Page) save() error {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						filename := p.Title + ".txt"
 | 
					 | 
					 | 
					 | 
						filename := data_dir + "/" + p.Title + ".txt"
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return os.WriteFile(filename, p.Body, 0600)
 | 
					 | 
					 | 
					 | 
						return os.WriteFile(filename, p.Body, 0600)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -46,7 +59,7 @@ func (p *Page) save() error {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// file, and returns a pointer to a Page struct containing the title and body.
 | 
					 | 
					 | 
					 | 
					// file, and returns a pointer to a Page struct containing the title and body.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// If an error occurs during reading, it returns the error.
 | 
					 | 
					 | 
					 | 
					// If an error occurs during reading, it returns the error.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					func loadPage(title string) (*Page, error) {
 | 
					 | 
					 | 
					 | 
					func loadPage(title string) (*Page, error) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						filename := title + ".txt"
 | 
					 | 
					 | 
					 | 
						filename := data_dir + "/" + title + ".txt"
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						body, err := os.ReadFile(filename)
 | 
					 | 
					 | 
					 | 
						body, err := os.ReadFile(filename)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if err != nil {
 | 
					 | 
					 | 
					 | 
						if err != nil {
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
 
 |