make updates
							parent
							
								
									f7227520ea
								
							
						
					
					
						commit
						0549bd73eb
					
				|  | @ -75,6 +75,7 @@ module.exports = function(grunt) { | |||
|             'node_modules/jquery-pjax/jquery.pjax.js', | ||||
|             'node_modules/jquery-serializejson/jquery.serializejson.min.js', | ||||
|             'node_modules/codemirror/lib/codemirror.js', | ||||
|             'node_modules/textarea-autosize/dist/jquery.textarea_autosize.js', | ||||
|             'assets/js/src/**/*.js' | ||||
|           ] | ||||
|         } | ||||
|  |  | |||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							|  | @ -2856,7 +2856,7 @@ nav ul li a:hover { | |||
|   background-color: rgba(255, 255, 255, 0.57); | ||||
| } | ||||
| 
 | ||||
| #main { | ||||
| .box { | ||||
|   position: fixed; | ||||
|   top: 3em; | ||||
|   left: 0; | ||||
|  | @ -2901,29 +2901,27 @@ footer p { | |||
|   display: none; | ||||
| } | ||||
| 
 | ||||
| /* EDITOR STYLE */ | ||||
| /* EDITOR GENERAL STYLES */ | ||||
| .editor .sidebar { | ||||
|   position: fixed; | ||||
|   left: 0; | ||||
|   top: 3em; | ||||
|   overflow-y: auto; | ||||
|   overflow-x: hidden; | ||||
|   height: calc(100% - 3em); | ||||
|   width: 25%; | ||||
|   background-color: #37474f; | ||||
|   color: #ddd; | ||||
|   color: #37474f; | ||||
|   box-sizing: border-box; | ||||
|   padding: 1.5em 1em; | ||||
|   background-color: #ddd; | ||||
| } | ||||
| 
 | ||||
| .editor .container { | ||||
|   overflow: hidden; | ||||
|   width: 100%; | ||||
|   box-sizing: border-box; | ||||
| } | ||||
| 
 | ||||
| .editor.full .container { | ||||
|   position: fixed; | ||||
|   top: 3em; | ||||
|   right: 0; | ||||
|   overflow: hidden; | ||||
|   height: calc(100% - 6em); | ||||
|   width: 75%; | ||||
|   box-sizing: border-box; | ||||
|   height: calc(100% - 6em); | ||||
| } | ||||
| 
 | ||||
| .editor .sidebar h2 { | ||||
|  | @ -2971,20 +2969,21 @@ footer p { | |||
| 
 | ||||
| .editor h3 { | ||||
|   font-size: 1em; | ||||
|   margin: 0 0 .25em; | ||||
|   font-weight: bold; | ||||
|   margin: 0; | ||||
| } | ||||
| 
 | ||||
| .action-bar { | ||||
|   position: fixed; | ||||
|   bottom: 0; | ||||
|   right: 0; | ||||
|   width: 75%; | ||||
|   width: 100%; | ||||
|   background-color: #455a64; | ||||
|   height: 3em; | ||||
|   display: flex; | ||||
|   padding: .5em 1em; | ||||
|   box-sizing: border-box; | ||||
|   z-index: 999; | ||||
| } | ||||
| 
 | ||||
| .action-bar .left { | ||||
|  | @ -2995,6 +2994,59 @@ footer p { | |||
|   margin-left: 1em; | ||||
| } | ||||
| 
 | ||||
| /* EDITOR FRONTMATTER ONLY STYLES */ | ||||
| .frontmatter-only .box, | ||||
| .content-only .box { | ||||
|   height: calc(100% - 6em); | ||||
| } | ||||
| 
 | ||||
| .frontmatter-only .sidebar { | ||||
|   width: 100%; | ||||
| } | ||||
| 
 | ||||
| .frontmatter-only input { | ||||
|   color: rgba(0, 0, 0, 0.2); | ||||
| } | ||||
| 
 | ||||
| .frontmatter-only input:focus { | ||||
|   color: rgba(0, 0, 0, 0.5); | ||||
| } | ||||
| 
 | ||||
| .frontmatter-only .action-bar input, | ||||
| .frontmatter-only .action-bar input:focus { | ||||
|   color: #fff; | ||||
| } | ||||
| 
 | ||||
| .frontmatter-only fieldset { | ||||
|   border-top: 1px solid rgba(0, 0, 0, 0.1); | ||||
| } | ||||
| 
 | ||||
| .frontmatter-only h3 { | ||||
|   font-size: 1.5em; | ||||
| } | ||||
| 
 | ||||
| /* EDITOR CONTENT ONLY STYLES */ | ||||
| .content-only #content-area, | ||||
| .content-only #preview-area { | ||||
|   padding: 0; | ||||
| } | ||||
| 
 | ||||
| /* EDITOR FULL STYLES */ | ||||
| .full .sidebar { | ||||
|   position: fixed; | ||||
|   left: 0; | ||||
|   top: 3em; | ||||
|   width: 25%; | ||||
|   padding: 1.5em 1em; | ||||
|   background-color: #37474f; | ||||
|   color: #ddd; | ||||
|   height: calc(100% - 3em); | ||||
| } | ||||
| 
 | ||||
| .full .action-bar { | ||||
|   width: 75%; | ||||
| } | ||||
| 
 | ||||
| /* FORMS ELEMENTS */ | ||||
| form input { | ||||
|   color: rgba(0, 0, 0, 0.41); | ||||
|  |  | |||
|  | @ -63,7 +63,7 @@ nav ul li a:hover { | |||
|   background-color: rgba(255, 255, 255, 0.57); | ||||
| } | ||||
| 
 | ||||
| #main { | ||||
| .box { | ||||
|   position: fixed; | ||||
|   top     : 3em; | ||||
|   left    : 0; | ||||
|  | @ -108,31 +108,29 @@ footer p { | |||
|   display: none; | ||||
| } | ||||
| 
 | ||||
| /* EDITOR STYLE */ | ||||
| /* EDITOR GENERAL STYLES */ | ||||
| .editor .sidebar { | ||||
|   position        : fixed; | ||||
|   left            : 0; | ||||
|   top             : 3em; | ||||
|   overflow-y      : auto; | ||||
|   overflow-x      : hidden; | ||||
|   height          : calc(100% - 3em); | ||||
|   width           : 25%; | ||||
|   background-color: #37474f; | ||||
|   color           : #ddd; | ||||
|   color           : #37474f; | ||||
|   box-sizing      : border-box; | ||||
|   padding         : 1.5em 1em; | ||||
|   background-color: #ddd; | ||||
| } | ||||
| 
 | ||||
| .editor .container { | ||||
|   position  : fixed; | ||||
|   top       : 3em; | ||||
|   right     : 0; | ||||
|   overflow  : hidden; | ||||
|   height    : calc(100% - 6em); | ||||
|   width     : 75%; | ||||
|   width     : 100%; | ||||
|   box-sizing: border-box; | ||||
| } | ||||
| 
 | ||||
| .editor.full .container { | ||||
|   position: fixed; | ||||
|   top     : 3em; | ||||
|   right   : 0; | ||||
|   width   : 75%; | ||||
|   height  : calc(100% - 6em); | ||||
| } | ||||
| 
 | ||||
| .editor .sidebar h2 { | ||||
|   margin-top: 0; | ||||
| } | ||||
|  | @ -178,20 +176,21 @@ footer p { | |||
| 
 | ||||
| .editor h3 { | ||||
|   font-size  : 1em; | ||||
|   margin     : 0 0 .25em; | ||||
|   font-weight: bold; | ||||
|   margin     : 0; | ||||
| } | ||||
| 
 | ||||
| .action-bar { | ||||
|   position        : fixed; | ||||
|   bottom          : 0; | ||||
|   right           : 0; | ||||
|   width           : 75%; | ||||
|   width           : 100%; | ||||
|   background-color: #455a64; | ||||
|   height          : 3em; | ||||
|   display         : flex; | ||||
|   padding         : .5em 1em; | ||||
|   box-sizing      : border-box; | ||||
|   z-index         : 999; | ||||
| } | ||||
| 
 | ||||
| .action-bar .left { | ||||
|  | @ -202,6 +201,59 @@ footer p { | |||
|   margin-left: 1em; | ||||
| } | ||||
| 
 | ||||
| /* EDITOR FRONTMATTER ONLY STYLES */ | ||||
| .frontmatter-only .box, | ||||
| .content-only .box { | ||||
|   height: calc(100% - 6em); | ||||
| } | ||||
| 
 | ||||
| .frontmatter-only .sidebar { | ||||
|   width: 100%; | ||||
| } | ||||
| 
 | ||||
| .frontmatter-only input { | ||||
|   color: rgba(0, 0, 0, 0.2); | ||||
| } | ||||
| 
 | ||||
| .frontmatter-only input:focus { | ||||
|   color: rgba(0, 0, 0, 0.5); | ||||
| } | ||||
| 
 | ||||
| .frontmatter-only .action-bar input, | ||||
| .frontmatter-only .action-bar input:focus { | ||||
|   color: #fff; | ||||
| } | ||||
| 
 | ||||
| .frontmatter-only fieldset { | ||||
|   border-top: 1px solid rgba(0,0,0,.1); | ||||
| } | ||||
| 
 | ||||
| .frontmatter-only h3 { | ||||
|   font-size: 1.5em; | ||||
| } | ||||
| 
 | ||||
| /* EDITOR CONTENT ONLY STYLES */ | ||||
| .content-only #content-area, | ||||
| .content-only #preview-area { | ||||
|   padding: 0; | ||||
| } | ||||
| 
 | ||||
| /* EDITOR FULL STYLES */ | ||||
| .full .sidebar { | ||||
|   position        : fixed; | ||||
|   left            : 0; | ||||
|   top             : 3em; | ||||
|   width           : 25%; | ||||
|   padding         : 1.5em 1em; | ||||
|   background-color: #37474f; | ||||
|   color           : #ddd; | ||||
|   height          : calc(100% - 3em); | ||||
| } | ||||
| 
 | ||||
| .full .action-bar { | ||||
|   width: 75%; | ||||
| } | ||||
| 
 | ||||
| /* FORMS ELEMENTS */ | ||||
| form input { | ||||
|   color           : rgba(0, 0, 0, 0.41); | ||||
|  |  | |||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							|  | @ -5,6 +5,7 @@ $(document).ready(function() { | |||
| $(document).on('ready pjax:success', function() { | ||||
|   // Starts the perfect scroolbar plugin
 | ||||
|   $('.scroll').perfectScrollbar(); | ||||
|   $('textarea.auto-size').textareaAutoSize(); | ||||
| 
 | ||||
|   // Toggles between preview and editing mode
 | ||||
|   $("#preview").click(function(event) { | ||||
|  | @ -50,6 +51,8 @@ $(document).on('ready pjax:success', function() { | |||
|       url = $(this).attr('action'), | ||||
|       button = $(this).find("input[type=submit]:focus"); | ||||
| 
 | ||||
|     console.log(data) | ||||
| 
 | ||||
|     $.ajax({ | ||||
|       type: 'POST', | ||||
|       url: url, | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ import ( | |||
| 	"strings" | ||||
| 	"text/template" | ||||
| 
 | ||||
| 	"github.com/hacdias/caddy-hugo/edit" | ||||
| 	"github.com/hacdias/caddy-hugo/editor" | ||||
| 	"github.com/hacdias/caddy-hugo/utils" | ||||
| 	"github.com/mholt/caddy/middleware" | ||||
| 	"github.com/mholt/caddy/middleware/browse" | ||||
|  | @ -26,7 +26,7 @@ func Execute(w http.ResponseWriter, r *http.Request) (int, error) { | |||
| 	} | ||||
| 
 | ||||
| 	functions := template.FuncMap{ | ||||
| 		"canBeEdited": edit.CanBeEdited, | ||||
| 		"canBeEdited": editor.CanBeEdited, | ||||
| 	} | ||||
| 
 | ||||
| 	tpl, err := utils.GetTemplate(r, functions, "browse") | ||||
|  |  | |||
							
								
								
									
										127
									
								
								edit/edit.go
								
								
								
								
							
							
						
						
									
										127
									
								
								edit/edit.go
								
								
								
								
							|  | @ -1,127 +0,0 @@ | |||
| package edit | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"io/ioutil" | ||||
| 	"log" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"strings" | ||||
| 	"text/template" | ||||
| 
 | ||||
| 	"github.com/hacdias/caddy-hugo/frontmatter" | ||||
| 	"github.com/hacdias/caddy-hugo/utils" | ||||
| 	"github.com/spf13/hugo/parser" | ||||
| ) | ||||
| 
 | ||||
| type editor struct { | ||||
| 	Name        string | ||||
| 	Content     string | ||||
| 	FrontMatter interface{} | ||||
| } | ||||
| 
 | ||||
| // Execute sth
 | ||||
| func Execute(w http.ResponseWriter, r *http.Request) (int, error) { | ||||
| 	filename := strings.Replace(r.URL.Path, "/admin/edit/", "", 1) | ||||
| 
 | ||||
| 	if r.Method == "POST" { | ||||
| 		// Get the JSON information sent using a buffer
 | ||||
| 		rawBuffer := new(bytes.Buffer) | ||||
| 		rawBuffer.ReadFrom(r.Body) | ||||
| 
 | ||||
| 		// Creates the raw file "map" using the JSON
 | ||||
| 		var rawFile map[string]interface{} | ||||
| 		json.Unmarshal(rawBuffer.Bytes(), &rawFile) | ||||
| 
 | ||||
| 		// The main content of the file
 | ||||
| 		mainContent := rawFile["content"].(string) | ||||
| 		mainContent = "\n\n" + strings.TrimSpace(mainContent) | ||||
| 
 | ||||
| 		// Removes the main content from the rest of the frontmatter
 | ||||
| 		delete(rawFile, "content") | ||||
| 
 | ||||
| 		// Converts the frontmatter in JSON
 | ||||
| 		jsonFrontmatter, err := json.Marshal(rawFile) | ||||
| 
 | ||||
| 		if err != nil { | ||||
| 			log.Print(err) | ||||
| 			return 500, err | ||||
| 		} | ||||
| 
 | ||||
| 		// Indents the json
 | ||||
| 		frontMatterBuffer := new(bytes.Buffer) | ||||
| 		json.Indent(frontMatterBuffer, jsonFrontmatter, "", "  ") | ||||
| 
 | ||||
| 		// Generates the final file
 | ||||
| 		file := new(bytes.Buffer) | ||||
| 		file.Write(frontMatterBuffer.Bytes()) | ||||
| 		file.Write([]byte(mainContent)) | ||||
| 
 | ||||
| 		err = ioutil.WriteFile(filename, file.Bytes(), 0666) | ||||
| 
 | ||||
| 		if err != nil { | ||||
| 			log.Print(err) | ||||
| 			return 500, err | ||||
| 		} | ||||
| 
 | ||||
| 		w.Header().Set("Content-Type", "application/json") | ||||
| 		w.Write([]byte("{}")) | ||||
| 	} else { | ||||
| 		if _, err := os.Stat(filename); os.IsNotExist(err) { | ||||
| 			log.Print(err) | ||||
| 			return 404, nil | ||||
| 		} | ||||
| 
 | ||||
| 		reader, err := os.Open(filename) | ||||
| 
 | ||||
| 		if err != nil { | ||||
| 			log.Print(err) | ||||
| 			return 500, err | ||||
| 		} | ||||
| 
 | ||||
| 		file, err := parser.ReadFrom(reader) | ||||
| 
 | ||||
| 		inf := new(editor) | ||||
| 		inf.Content = strings.TrimSpace(string(file.Content())) | ||||
| 		inf.FrontMatter, err = frontmatter.Pretty(file.FrontMatter()) | ||||
| 
 | ||||
| 		if err != nil { | ||||
| 			log.Print(err) | ||||
| 			return 500, err | ||||
| 		} | ||||
| 
 | ||||
| 		functions := template.FuncMap{ | ||||
| 			"splitCapitalize": utils.SplitCapitalize, | ||||
| 		} | ||||
| 
 | ||||
| 		tpl, err := utils.GetTemplate(r, functions, "edit", "frontmatter") | ||||
| 
 | ||||
| 		if err != nil { | ||||
| 			log.Print(err) | ||||
| 			return 500, err | ||||
| 		} | ||||
| 
 | ||||
| 		tpl.Execute(w, inf) | ||||
| 	} | ||||
| 
 | ||||
| 	return 200, nil | ||||
| } | ||||
| 
 | ||||
| // CanBeEdited checks if a file has a supported extension
 | ||||
| func CanBeEdited(filename string) bool { | ||||
| 	extensions := [...]string{".markdown", ".md", | ||||
| 		".json", ".toml", ".yaml", | ||||
| 		".css", ".sass", ".scss", | ||||
| 		".js", | ||||
| 		".html", | ||||
| 	} | ||||
| 
 | ||||
| 	for _, extension := range extensions { | ||||
| 		if strings.HasSuffix(filename, extension) { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return false | ||||
| } | ||||
|  | @ -0,0 +1,193 @@ | |||
| package editor | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"errors" | ||||
| 	"io/ioutil" | ||||
| 	"log" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| 	"text/template" | ||||
| 
 | ||||
| 	"github.com/hacdias/caddy-hugo/frontmatter" | ||||
| 	"github.com/hacdias/caddy-hugo/utils" | ||||
| 	"github.com/spf13/hugo/parser" | ||||
| ) | ||||
| 
 | ||||
| type editor struct { | ||||
| 	Name        string | ||||
| 	Class       string | ||||
| 	Extension   string | ||||
| 	Content     string | ||||
| 	FrontMatter interface{} | ||||
| } | ||||
| 
 | ||||
| // Execute sth
 | ||||
| func Execute(w http.ResponseWriter, r *http.Request) (int, error) { | ||||
| 	filename := strings.Replace(r.URL.Path, "/admin/edit/", "", 1) | ||||
| 
 | ||||
| 	if r.Method == "POST" { | ||||
| 		// TODO: review post saving
 | ||||
| 		/* | ||||
| 			// Get the JSON information sent using a buffer
 | ||||
| 			rawBuffer := new(bytes.Buffer) | ||||
| 			rawBuffer.ReadFrom(r.Body) | ||||
| 
 | ||||
| 			// Creates the raw file "map" using the JSON
 | ||||
| 			var rawFile map[string]interface{} | ||||
| 			json.Unmarshal(rawBuffer.Bytes(), &rawFile) | ||||
| 
 | ||||
| 			// The main content of the file
 | ||||
| 			mainContent := rawFile["content"].(string) | ||||
| 			mainContent = "\n\n" + strings.TrimSpace(mainContent) | ||||
| 
 | ||||
| 			// Removes the main content from the rest of the frontmatter
 | ||||
| 			delete(rawFile, "content") | ||||
| 
 | ||||
| 			// Converts the frontmatter in JSON
 | ||||
| 			jsonFrontmatter, err := json.Marshal(rawFile) | ||||
| 
 | ||||
| 			if err != nil { | ||||
| 				log.Print(err) | ||||
| 				return 500, err | ||||
| 			} | ||||
| 
 | ||||
| 			// Indents the json
 | ||||
| 			frontMatterBuffer := new(bytes.Buffer) | ||||
| 			json.Indent(frontMatterBuffer, jsonFrontmatter, "", "  ") | ||||
| 
 | ||||
| 			// Generates the final file
 | ||||
| 			file := new(bytes.Buffer) | ||||
| 			file.Write(frontMatterBuffer.Bytes()) | ||||
| 			file.Write([]byte(mainContent)) | ||||
| 
 | ||||
| 			err = ioutil.WriteFile(filename, file.Bytes(), 0666) | ||||
| 
 | ||||
| 			if err != nil { | ||||
| 				log.Print(err) | ||||
| 				return 500, err | ||||
| 			} | ||||
| 
 | ||||
| 			w.Header().Set("Content-Type", "application/json") | ||||
| 			w.Write([]byte("{}")) */ | ||||
| 	} else { | ||||
| 		// Check if the file format is supported. If not, send a "Not Acceptable"
 | ||||
| 		// header and an error
 | ||||
| 		if !CanBeEdited(filename) { | ||||
| 			return 406, errors.New("File format not supported.") | ||||
| 		} | ||||
| 
 | ||||
| 		// Check if the file exists. If it doesn't, send a "Not Found" message
 | ||||
| 		if _, err := os.Stat(filename); os.IsNotExist(err) { | ||||
| 			log.Print(err) | ||||
| 			return 404, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Open the file and check if there was some error while opening
 | ||||
| 		file, err := ioutil.ReadFile(filename) | ||||
| 		if err != nil { | ||||
| 			log.Print(err) | ||||
| 			return 500, err | ||||
| 		} | ||||
| 
 | ||||
| 		// Create a new editor variable and set the extension
 | ||||
| 		page := new(editor) | ||||
| 		page.Extension = strings.TrimPrefix(filepath.Ext(filename), ".") | ||||
| 		page.Name = filename | ||||
| 
 | ||||
| 		// Handle the content depending on the file extension
 | ||||
| 		switch page.Extension { | ||||
| 		case "markdown", "md": | ||||
| 			if hasFrontMatterRune(file) { | ||||
| 				// Starts a new buffer and parses the file using Hugo's functions
 | ||||
| 				buffer := bytes.NewBuffer(file) | ||||
| 				file, err := parser.ReadFrom(buffer) | ||||
| 				if err != nil { | ||||
| 					log.Print(err) | ||||
| 					return 500, err | ||||
| 				} | ||||
| 
 | ||||
| 				// Parses the page content and the frontmatter
 | ||||
| 				page.Content = strings.TrimSpace(string(file.Content())) | ||||
| 				page.FrontMatter, err = frontmatter.Pretty(file.FrontMatter()) | ||||
| 				page.Class = "full" | ||||
| 			} else { | ||||
| 				// The editor will handle only content
 | ||||
| 				page.Class = "content-only" | ||||
| 				page.Content = string(file) | ||||
| 			} | ||||
| 		case "json", "toml", "yaml": | ||||
| 			// Defines the class and declares an error
 | ||||
| 			page.Class = "frontmatter-only" | ||||
| 			var err error | ||||
| 
 | ||||
| 			// Checks if the file already has the frontmatter rune and parses it
 | ||||
| 			if hasFrontMatterRune(file) { | ||||
| 				page.FrontMatter, err = frontmatter.Pretty(file) | ||||
| 			} else { | ||||
| 				page.FrontMatter, err = frontmatter.Pretty(appendFrontMatterRune(file, page.Extension)) | ||||
| 			} | ||||
| 
 | ||||
| 			// Check if there were any errors
 | ||||
| 			if err != nil { | ||||
| 				log.Print(err) | ||||
| 				return 500, err | ||||
| 			} | ||||
| 		default: | ||||
| 			// The editor will handle only content
 | ||||
| 			page.Class = "content-only" | ||||
| 			page.Content = string(file) | ||||
| 		} | ||||
| 
 | ||||
| 		// Create the functions map, then the template, check for erros and
 | ||||
| 		// execute the template if there aren't errors
 | ||||
| 		functions := template.FuncMap{"splitCapitalize": utils.SplitCapitalize} | ||||
| 		tpl, err := utils.GetTemplate(r, functions, "editor", "frontmatter") | ||||
| 		if err != nil { | ||||
| 			log.Print(err) | ||||
| 			return 500, err | ||||
| 		} | ||||
| 		tpl.Execute(w, page) | ||||
| 	} | ||||
| 
 | ||||
| 	return 200, nil | ||||
| } | ||||
| 
 | ||||
| // CanBeEdited checks if a file has a supported extension
 | ||||
| func CanBeEdited(filename string) bool { | ||||
| 	extensions := [...]string{".markdown", ".md", | ||||
| 		".json", ".toml", ".yaml", | ||||
| 		".css", ".sass", ".scss", | ||||
| 		".js", | ||||
| 		".html", | ||||
| 	} | ||||
| 
 | ||||
| 	for _, extension := range extensions { | ||||
| 		if strings.HasSuffix(filename, extension) { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func hasFrontMatterRune(file []byte) bool { | ||||
| 	return strings.HasPrefix(string(file), "---") || | ||||
| 		strings.HasPrefix(string(file), "+++") || | ||||
| 		strings.HasPrefix(string(file), "{") | ||||
| } | ||||
| 
 | ||||
| func appendFrontMatterRune(frontmatter []byte, language string) []byte { | ||||
| 	switch language { | ||||
| 	case "yaml": | ||||
| 		return []byte("---\n" + string(frontmatter) + "\n---") | ||||
| 	case "toml": | ||||
| 		return []byte("+++\n" + string(frontmatter) + "\n+++") | ||||
| 	case "json": | ||||
| 		return frontmatter | ||||
| 	} | ||||
| 
 | ||||
| 	return frontmatter | ||||
| } | ||||
|  | @ -120,15 +120,11 @@ func handleFlatValues(content interface{}, parent *frontmatter, name string) *fr | |||
| 	c := new(frontmatter) | ||||
| 	c.Parent = parent | ||||
| 
 | ||||
| 	// TODO: see why isn't this working
 | ||||
| 	switch reflect.ValueOf(content).Kind() { | ||||
| 	case reflect.Bool: | ||||
| 		c.Type = "boolean" | ||||
| 	case reflect.Int: | ||||
| 	case reflect.Float32: | ||||
| 	case reflect.Float64: | ||||
| 	case reflect.Int, reflect.Float32, reflect.Float64: | ||||
| 		c.Type = "number" | ||||
| 	case reflect.String: | ||||
| 	default: | ||||
| 		c.Type = "string" | ||||
| 	} | ||||
|  |  | |||
							
								
								
									
										23
									
								
								hugo.go
								
								
								
								
							
							
						
						
									
										23
									
								
								hugo.go
								
								
								
								
							|  | @ -5,13 +5,13 @@ package hugo | |||
| import ( | ||||
| 	"mime" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/hacdias/caddy-hugo/assets" | ||||
| 	"github.com/hacdias/caddy-hugo/browse" | ||||
| 	"github.com/hacdias/caddy-hugo/edit" | ||||
| 	"github.com/hacdias/caddy-hugo/settings" | ||||
| 	"github.com/hacdias/caddy-hugo/editor" | ||||
| 	"github.com/hacdias/caddy-hugo/utils" | ||||
| 	"github.com/mholt/caddy/config/setup" | ||||
| 	"github.com/mholt/caddy/middleware" | ||||
|  | @ -82,7 +82,22 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) | |||
| 		// page variable isn't used here to avoid people using URLs like
 | ||||
| 		// "/admin/settings/something".
 | ||||
| 		if r.URL.Path == "/admin/settings/" { | ||||
| 			code, err = settings.Execute(w, r) | ||||
| 			var frontmatter string | ||||
| 
 | ||||
| 			if _, err := os.Stat("config.yaml"); err == nil { | ||||
| 				frontmatter = "yaml" | ||||
| 			} | ||||
| 
 | ||||
| 			if _, err := os.Stat("config.json"); err == nil { | ||||
| 				frontmatter = "json" | ||||
| 			} | ||||
| 
 | ||||
| 			if _, err := os.Stat("config.toml"); err == nil { | ||||
| 				frontmatter = "toml" | ||||
| 			} | ||||
| 
 | ||||
| 			http.Redirect(w, r, "/admin/edit/config."+frontmatter, http.StatusTemporaryRedirect) | ||||
| 			return 0, nil | ||||
| 		} | ||||
| 
 | ||||
| 		// Browse page
 | ||||
|  | @ -92,7 +107,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) | |||
| 
 | ||||
| 		// Edit page
 | ||||
| 		if page == "edit" { | ||||
| 			code, err = edit.Execute(w, r) | ||||
| 			code, err = editor.Execute(w, r) | ||||
| 		} | ||||
| 
 | ||||
| 		// Whenever the header "X-Refenerate" is true, the website should be
 | ||||
|  |  | |||
|  | @ -25,7 +25,8 @@ | |||
|     "normalize.css": "^3.0.3", | ||||
|     "noty": "^2.3.6", | ||||
|     "perfect-scrollbar": "^0.6.4", | ||||
|     "showdown": "^1.2.3" | ||||
|     "showdown": "^1.2.3", | ||||
|     "textarea-autosize": "^0.4.1" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "grunt": "^0.4.5", | ||||
|  |  | |||
|  | @ -1,118 +0,0 @@ | |||
| package settings | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"io/ioutil" | ||||
| 	"log" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"text/template" | ||||
| 
 | ||||
| 	"github.com/hacdias/caddy-hugo/frontmatter" | ||||
| 	"github.com/hacdias/caddy-hugo/utils" | ||||
| ) | ||||
| 
 | ||||
| type page struct { | ||||
| 	Name     string | ||||
| 	Settings interface{} | ||||
| } | ||||
| 
 | ||||
| // Execute the page
 | ||||
| func Execute(w http.ResponseWriter, r *http.Request) (int, error) { | ||||
| 	language := getConfigFrontMatter() | ||||
| 
 | ||||
| 	if language == "" { | ||||
| 		log.Print("Configuration frontmatter can't be defined") | ||||
| 		return 500, nil | ||||
| 	} | ||||
| 
 | ||||
| 	if r.Method == "POST" { | ||||
| 		err := os.Remove("config." + language) | ||||
| 
 | ||||
| 		if err != nil { | ||||
| 			log.Print(err) | ||||
| 			return 500, nil | ||||
| 		} | ||||
| 
 | ||||
| 		buf := new(bytes.Buffer) | ||||
| 		buf.ReadFrom(r.Body) | ||||
| 		raw := buf.Bytes() | ||||
| 
 | ||||
| 		content := new(bytes.Buffer) | ||||
| 		json.Indent(content, raw, "", "  ") | ||||
| 
 | ||||
| 		err = ioutil.WriteFile("config.json", content.Bytes(), 0666) | ||||
| 
 | ||||
| 		if err != nil { | ||||
| 			log.Print(err) | ||||
| 			return 500, err | ||||
| 		} | ||||
| 
 | ||||
| 		w.Header().Set("Content-Type", "application/json") | ||||
| 		w.Write([]byte("{}")) | ||||
| 	} else { | ||||
| 		content, err := ioutil.ReadFile("config." + language) | ||||
| 
 | ||||
| 		if err != nil { | ||||
| 			log.Print(err) | ||||
| 			return 500, err | ||||
| 		} | ||||
| 
 | ||||
| 		f, err := frontmatter.Pretty(appendFrontMatterRune(content, language)) | ||||
| 
 | ||||
| 		if err != nil { | ||||
| 			log.Print(err) | ||||
| 			return 500, err | ||||
| 		} | ||||
| 
 | ||||
| 		functions := template.FuncMap{ | ||||
| 			"splitCapitalize": utils.SplitCapitalize, | ||||
| 		} | ||||
| 
 | ||||
| 		tpl, err := utils.GetTemplate(r, functions, "settings", "frontmatter") | ||||
| 
 | ||||
| 		if err != nil { | ||||
| 			log.Print(err) | ||||
| 			return 500, err | ||||
| 		} | ||||
| 
 | ||||
| 		p := new(page) | ||||
| 		p.Name = "settings" | ||||
| 		p.Settings = f | ||||
| 
 | ||||
| 		tpl.Execute(w, p) | ||||
| 	} | ||||
| 	return 200, nil | ||||
| } | ||||
| 
 | ||||
| func getConfigFrontMatter() string { | ||||
| 	var frontmatter string | ||||
| 
 | ||||
| 	if _, err := os.Stat("config.yaml"); err == nil { | ||||
| 		frontmatter = "yaml" | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err := os.Stat("config.json"); err == nil { | ||||
| 		frontmatter = "json" | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err := os.Stat("config.toml"); err == nil { | ||||
| 		frontmatter = "toml" | ||||
| 	} | ||||
| 
 | ||||
| 	return frontmatter | ||||
| } | ||||
| 
 | ||||
| func appendFrontMatterRune(frontmatter []byte, language string) []byte { | ||||
| 	switch language { | ||||
| 	case "yaml": | ||||
| 		return []byte("---\n" + string(frontmatter) + "\n---") | ||||
| 	case "toml": | ||||
| 		return []byte("+++\n" + string(frontmatter) + "\n+++") | ||||
| 	case "json": | ||||
| 		return frontmatter | ||||
| 	} | ||||
| 
 | ||||
| 	return frontmatter | ||||
| } | ||||
|  | @ -1,24 +0,0 @@ | |||
| {{ define "content" }} | ||||
| 
 | ||||
| <main class="editor"> | ||||
|   <form method="POST" action=""> | ||||
| 
 | ||||
|     <div class="container data"> | ||||
|       <textarea id="content-area" name="content" class="scroll">{{ .Content }}</textarea> | ||||
|       <div id="preview-area" class="scroll hidden"></div> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="sidebar scroll data"> | ||||
|       <h2>Metadata</h2> | ||||
|       {{ template "frontmatter" .FrontMatter }} | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="action-bar"> | ||||
|       <button id="preview" class="left">Preview</button> | ||||
|       <input type="submit" data-message="Post saved." data-regenerate="false"  value="Save"> | ||||
|       <input type="submit" data-message="Post published successfully." data-regenerate="true" class="default" value="Publish"> | ||||
|     </div> | ||||
|   </form> | ||||
| </main> | ||||
| 
 | ||||
| {{ end }} | ||||
|  | @ -0,0 +1,51 @@ | |||
| {{ define "content" }} | ||||
| <div class="editor {{ .Class }}"> | ||||
|   <form method="POST" action=""> | ||||
|     <div class="box scroll"> | ||||
|       <main> | ||||
|         {{ if not (eq .Class "full") }} | ||||
|         <header> | ||||
|           <div class="content"> | ||||
|             <h1>{{ .Name }}</h1> | ||||
|           </div> | ||||
|         </header> | ||||
|         {{ end }} | ||||
| 
 | ||||
|         {{ if eq .Class "frontmatter-only" }} | ||||
|         <div class="sidebar"> | ||||
|           <div class="content"> | ||||
|           {{ template "frontmatter" .FrontMatter }} | ||||
|           </div> | ||||
|         </div> | ||||
|         {{ else if eq .Class "content-only" }} | ||||
|         <div class="container"> | ||||
|           <div class="content"> | ||||
|             <textarea id="content-area" name="content" class="scroll auto-size">{{ .Content }}</textarea> | ||||
|             <div id="preview-area" class="scroll hidden"></div> | ||||
|           </div> | ||||
|         </div> | ||||
|         {{ else }} | ||||
|         <div class="container"> | ||||
|           <textarea id="content-area" name="content" class="scroll">{{ .Content }}</textarea> | ||||
|           <div id="preview-area" class="scroll hidden"></div> | ||||
|         </div> | ||||
|         <div class="sidebar scroll"> | ||||
|           <h2>Metadata</h2> | ||||
|           {{ template "frontmatter" .FrontMatter }} | ||||
|         </div> | ||||
|         {{ end }} | ||||
|       </main> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="action-bar"> | ||||
|       {{ if or (eq .Extension "markdown") (eq .Extension "md") (eq .Class "full") }} | ||||
|       <button id="preview" class="left">Preview</button> | ||||
|       {{ else }} | ||||
|       <span class="left"></span> | ||||
|       {{ end }} | ||||
|       <input type="submit" data-message="Post saved." data-regenerate="false"  value="Save"> | ||||
|       <input type="submit" data-message="Post published successfully." data-regenerate="true" class="default" value="Publish"> | ||||
|     </div> | ||||
|   </form> | ||||
| </div> | ||||
| {{ end }} | ||||
|  | @ -1,17 +0,0 @@ | |||
| {{ define "content" }} | ||||
| <header> | ||||
|   <div class="content"> | ||||
|     <h1>Settings</h1> | ||||
|   </div> | ||||
| </header> | ||||
| 
 | ||||
| <main> | ||||
| <div class="content"> | ||||
|   <form method="POST" action="/admin/settings"> | ||||
|   {{ template "frontmatter" .Settings }} | ||||
|   <input type="submit" data-message="Settings updated." data-regenerate="true" value="Save"> | ||||
|   </form> | ||||
| </div> | ||||
| </main> | ||||
| 
 | ||||
| {{ end }} | ||||
		Loading…
	
		Reference in New Issue
	
	 Henrique Dias
						Henrique Dias