| 
									
										
										
										
											2017-10-30 15:47:59 +00:00
										 |  |  | package staticgen | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"io/ioutil" | 
					
						
							|  |  |  | 	"log" | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							|  |  |  | 	"os" | 
					
						
							|  |  |  | 	"os/exec" | 
					
						
							|  |  |  | 	"path/filepath" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fm "github.com/hacdias/filemanager" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Jekyll is the Jekyll static website generator.
 | 
					
						
							|  |  |  | type Jekyll struct { | 
					
						
							|  |  |  | 	// Website root
 | 
					
						
							|  |  |  | 	Root string `name:"Website Root"` | 
					
						
							|  |  |  | 	// Public folder
 | 
					
						
							|  |  |  | 	Public string `name:"Public Directory"` | 
					
						
							|  |  |  | 	// Jekyll executable path
 | 
					
						
							|  |  |  | 	Exe string `name:"Executable"` | 
					
						
							|  |  |  | 	// Jekyll arguments
 | 
					
						
							|  |  |  | 	Args []string `name:"Arguments"` | 
					
						
							|  |  |  | 	// Indicates if we should clean public before a new publish.
 | 
					
						
							|  |  |  | 	CleanPublic bool `name:"Clean Public"` | 
					
						
							|  |  |  | 	// previewPath is the temporary path for a preview
 | 
					
						
							|  |  |  | 	previewPath string | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Name is the plugin's name.
 | 
					
						
							|  |  |  | func (j Jekyll) Name() string { | 
					
						
							|  |  |  | 	return "jekyll" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // SettingsPath retrieves the correct settings path.
 | 
					
						
							|  |  |  | func (j Jekyll) SettingsPath() string { | 
					
						
							|  |  |  | 	return "/_config.yml" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Hook is the pre-api handler.
 | 
					
						
							|  |  |  | func (j Jekyll) Hook(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) { | 
					
						
							|  |  |  | 	return 0, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Publish publishes a post.
 | 
					
						
							|  |  |  | func (j Jekyll) Publish(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) { | 
					
						
							|  |  |  | 	filename := filepath.Join(c.User.Scope, r.URL.Path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// We only run undraft command if it is a file.
 | 
					
						
							|  |  |  | 	if err := j.undraft(filename); err != nil { | 
					
						
							|  |  |  | 		return http.StatusInternalServerError, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Regenerates the file
 | 
					
						
							|  |  |  | 	j.run() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Preview handles the preview path.
 | 
					
						
							|  |  |  | func (j *Jekyll) Preview(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) { | 
					
						
							|  |  |  | 	// Get a new temporary path if there is none.
 | 
					
						
							|  |  |  | 	if j.previewPath == "" { | 
					
						
							|  |  |  | 		path, err := ioutil.TempDir("", "") | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return http.StatusInternalServerError, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		j.previewPath = path | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Build the arguments to execute Hugo: change the base URL,
 | 
					
						
							|  |  |  | 	// build the drafts and update the destination.
 | 
					
						
							|  |  |  | 	args := j.Args | 
					
						
							|  |  |  | 	args = append(args, "--baseurl", c.RootURL()+"/preview/") | 
					
						
							|  |  |  | 	args = append(args, "--drafts") | 
					
						
							|  |  |  | 	args = append(args, "--destination", j.previewPath) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Builds the preview.
 | 
					
						
							|  |  |  | 	if err := runCommand(j.Exe, args, j.Root); err != nil { | 
					
						
							|  |  |  | 		return http.StatusInternalServerError, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Serves the temporary path with the preview.
 | 
					
						
							|  |  |  | 	http.FileServer(http.Dir(j.previewPath)).ServeHTTP(w, r) | 
					
						
							|  |  |  | 	return 0, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (j Jekyll) run() { | 
					
						
							|  |  |  | 	// If the CleanPublic option is enabled, clean it.
 | 
					
						
							|  |  |  | 	if j.CleanPublic { | 
					
						
							|  |  |  | 		os.RemoveAll(j.Public) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := runCommand(j.Exe, j.Args, j.Root); err != nil { | 
					
						
							|  |  |  | 		log.Println(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (j Jekyll) undraft(file string) error { | 
					
						
							|  |  |  | 	if !strings.Contains(file, "_drafts") { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return os.Rename(file, strings.Replace(file, "_drafts", "_posts", 1)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Setup sets up the plugin.
 | 
					
						
							|  |  |  | func (j *Jekyll) Setup() error { | 
					
						
							|  |  |  | 	var err error | 
					
						
							|  |  |  | 	if j.Exe, err = exec.LookPath("jekyll"); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if len(j.Args) == 0 { | 
					
						
							|  |  |  | 		j.Args = []string{"build"} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if j.Args[0] != "build" { | 
					
						
							|  |  |  | 		j.Args = append([]string{"build"}, j.Args...) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } |