Skip to content

Commit

Permalink
Support open "current content page" in browser
Browse files Browse the repository at this point in the history
This commit adds a new `--navigateToChanged` and config setting with the same name, that, when running the Hugo server with live reload enabled, will navigate to the current content file's URL on save. 

This is really useful for site-wide content changes (copyedits etc.).
Fixes #3643
  • Loading branch information
bep committed Jun 26, 2017
1 parent 7198ea8 commit c825a73
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 6 deletions.
34 changes: 32 additions & 2 deletions commands/hugo.go
Expand Up @@ -981,8 +981,28 @@ func (c *commandeer) newWatcher(port int) error {
}

if !buildWatch && !c.Cfg.GetBool("disableLiveReload") {
// Will block forever trying to write to a channel that nobody is reading if livereload isn't initialized
livereload.ForceRefresh()

navigate := c.Cfg.GetBool("navigateToChanged")

var p *hugolib.Page

if navigate {

// It is probably more confusing than useful
// to navigate to a new URL on RENAME etc.
// so for now we use the WRITE event only.
name := pickOneWritePath(dynamicEvents)

if name != "" {
p = Hugo.GetContentPage(name)
}
}

if p != nil {
livereload.NavigateToPath(p.RelPermalink())
} else {
livereload.ForceRefresh()
}
}
}
case err := <-watcher.Errors:
Expand All @@ -1007,6 +1027,16 @@ func (c *commandeer) newWatcher(port int) error {
return nil
}

func pickOneWritePath(events []fsnotify.Event) string {
for _, ev := range events {
if ev.Op&fsnotify.Write == fsnotify.Write {
return ev.Name
}
}

return ""
}

func (c *commandeer) isStatic(path string) bool {
return strings.HasPrefix(path, c.PathSpec().GetStaticDirPath()) || (len(c.PathSpec().GetThemesDirPath()) > 0 && strings.HasPrefix(path, c.PathSpec().GetThemesDirPath()))
}
Expand Down
6 changes: 6 additions & 0 deletions commands/server.go
Expand Up @@ -33,6 +33,7 @@ import (

var (
disableLiveReload bool
navigateToChanged bool
renderToDisk bool
serverAppend bool
serverInterface string
Expand Down Expand Up @@ -87,6 +88,7 @@ func init() {
serverCmd.Flags().BoolVarP(&serverWatch, "watch", "w", true, "watch filesystem for changes and recreate as needed")
serverCmd.Flags().BoolVarP(&serverAppend, "appendPort", "", true, "append port to baseURL")
serverCmd.Flags().BoolVar(&disableLiveReload, "disableLiveReload", false, "watch without enabling live browser reload on rebuild")
serverCmd.Flags().BoolVar(&navigateToChanged, "navigateToChanged", false, "navigate to changed content file on live browser reload")
serverCmd.Flags().BoolVar(&renderToDisk, "renderToDisk", false, "render to Destination path (default is render to memory & serve from there)")
serverCmd.Flags().String("memstats", "", "log memory usage to this file")
serverCmd.Flags().String("meminterval", "100ms", "interval to poll memory usage (requires --memstats), valid time units are \"ns\", \"us\" (or \"µs\"), \"ms\", \"s\", \"m\", \"h\".")
Expand All @@ -110,6 +112,10 @@ func server(cmd *cobra.Command, args []string) error {
c.Set("disableLiveReload", disableLiveReload)
}

if cmd.Flags().Changed("navigateToChanged") {
c.Set("navigateToChanged", navigateToChanged)
}

if serverWatch {
c.Set("watch", true)
}
Expand Down
23 changes: 23 additions & 0 deletions hugolib/hugo_sites.go
Expand Up @@ -19,6 +19,8 @@ import (
"strings"
"sync"

"path/filepath"

"github.com/gohugoio/hugo/deps"
"github.com/gohugoio/hugo/helpers"

Expand All @@ -38,6 +40,27 @@ type HugoSites struct {
*deps.Deps
}

// GetContentPage finds a Page with content given the absolute filename.
// Returns nil if none found.
func (h *HugoSites) GetContentPage(filename string) *Page {
s := h.Sites[0]
contendDir := filepath.Join(s.PathSpec.AbsPathify(s.Cfg.GetString("contentDir")))
if !strings.HasPrefix(filename, contendDir) {
return nil
}

rel := strings.TrimPrefix(filename, contendDir)
rel = strings.TrimPrefix(rel, helpers.FilePathSeparator)

pos := s.rawAllPages.findPagePosByFilePath(rel)

if pos == -1 {
return nil
}
return s.rawAllPages[pos]

}

// NewHugoSites creates a new collection of sites given the input sites, building
// a language configuration based on those.
func newHugoSites(cfg deps.DepsCfg, sites ...*Site) (*HugoSites, error) {
Expand Down
6 changes: 6 additions & 0 deletions hugolib/hugo_sites_build_test.go
Expand Up @@ -223,6 +223,12 @@ func doTestMultiSitesBuild(t *testing.T, configTemplate, configSuffix string) {
require.NotNil(t, s.disabledKinds)
}

gp1 := sites.GetContentPage(filepath.FromSlash("content/sect/doc1.en.md"))
require.NotNil(t, gp1)
require.Equal(t, "doc1", gp1.Title)
gp2 := sites.GetContentPage(filepath.FromSlash("content/sect/notfound.md"))
require.Nil(t, gp2)

enSite := sites.Sites[0]
enSiteHome := enSite.getPage(KindHome)
require.True(t, enSiteHome.IsTranslated())
Expand Down

0 comments on commit c825a73

Please sign in to comment.