shithub: hugo

Download patch

ref: 2818878994e906c292cbe00cb2a83f1531a21f32
parent: b6a30283f099ce9578d491ba8fbbf45f673dbf3b
author: digitalcraftsman <[email protected]>
date: Thu Sep 28 15:52:34 EDT 2017

tpl: Add os.fileExists template function

Fixes #3839


--- /dev/null
+++ b/docs/content/functions/fileExists.md
@@ -1,0 +1,29 @@
+---
+title: "fileExists"
+linktitle: "fileExists"
+date: 2017-08-31T22:38:22+02:00
+description: Checks whether a file exists under the given path.
+godocref:
+publishdate: 2017-08-31T22:38:22+02:00
+lastmod: 2017-08-31T22:38:22+02:00
+categories: [functions]
+menu:
+  docs:
+    parent: "functions"
+signature: ["fileExists PATH"]
+workson: []
+hugoversion:
+relatedfuncs: []
+deprecated: false
+aliases: []
+---
+
+`fileExists` allows you to check if a file exists under a given path, e.g. before inserting code into a template:
+
+```
+{{ if (fileExists "static/img/banner.jpg") -}}
+<img src="{{ "img/banner.jpg" | absURL }}" />
+{{- end }}
+```
+
+In the example above, a banner from the `static` folder should be shown if the given path points to an existing file.
\ No newline at end of file
--- a/tpl/os/init.go
+++ b/tpl/os/init.go
@@ -48,6 +48,13 @@
 			},
 		)
 
+		ns.AddMethodMapping(ctx.FileExists,
+			[]string{"fileExists"},
+			[][2]string{
+				{`{{ fileExists "foo.txt" }}`, `false`},
+			},
+		)
+
 		return ns
 
 	}
--- a/tpl/os/os.go
+++ b/tpl/os/os.go
@@ -96,3 +96,22 @@
 
 	return list, nil
 }
+
+// FileExists checks whether a file exists under the given path.
+func (ns *Namespace) FileExists(i interface{}) (bool, error) {
+	path, err := cast.ToStringE(i)
+	if err != nil {
+		return false, err
+	}
+
+	if path == "" {
+		return false, errors.New("fileExists needs a path to a file")
+	}
+
+	status, err := afero.Exists(ns.deps.Fs.WorkingDir, path)
+	if err != nil {
+		return false, err
+	}
+
+	return status, nil
+}
--- a/tpl/os/os_test.go
+++ b/tpl/os/os_test.go
@@ -63,3 +63,39 @@
 		assert.Equal(t, test.expect, result, errMsg)
 	}
 }
+
+func TestFileExists(t *testing.T) {
+	t.Parallel()
+
+	workingDir := "/home/hugo"
+
+	v := viper.New()
+	v.Set("workingDir", workingDir)
+
+	ns := New(&deps.Deps{Fs: hugofs.NewMem(v)})
+
+	afero.WriteFile(ns.deps.Fs.Source, filepath.Join(workingDir, "/f/f1.txt"), []byte("f1-content"), 0755)
+	afero.WriteFile(ns.deps.Fs.Source, filepath.Join("/home", "f2.txt"), []byte("f2-content"), 0755)
+
+	for i, test := range []struct {
+		filename string
+		expect   interface{}
+	}{
+		{filepath.FromSlash("/f/f1.txt"), true},
+		{filepath.FromSlash("f/f1.txt"), true},
+		{filepath.FromSlash("../f2.txt"), false},
+		{"b", false},
+		{"", nil},
+	} {
+		errMsg := fmt.Sprintf("[%d] %v", i, test)
+		result, err := ns.FileExists(test.filename)
+
+		if test.expect == nil {
+			require.Error(t, err, errMsg)
+			continue
+		}
+
+		require.NoError(t, err, errMsg)
+		assert.Equal(t, test.expect, result, errMsg)
+	}
+}