summaryrefslogtreecommitdiffstats
path: root/resource
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2018-04-15 17:07:49 +0200
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2018-04-15 18:08:06 +0200
commit0e7716a42450401c7998aa81ad2ed98c8ab109e8 (patch)
tree7b00293c175bd100d49138c5d5d3764444c6d1d5 /resource
parent417c5e2b67b97fa80a0b6f77d259966f03b95344 (diff)
resource: Implement Resource.Content
Fixes #4622
Diffstat (limited to 'resource')
-rw-r--r--resource/image.go1
-rw-r--r--resource/image_test.go12
-rw-r--r--resource/resource.go35
3 files changed, 48 insertions, 0 deletions
diff --git a/resource/image.go b/resource/image.go
index 84dc56fa7..19b68a296 100644
--- a/resource/image.go
+++ b/resource/image.go
@@ -568,6 +568,7 @@ func (i *Image) encodeToDestinations(img image.Image, conf imageConfig, resource
func (i *Image) clone() *Image {
g := *i.genericResource
+ g.resourceContent = &resourceContent{}
return &Image{
imaging: i.imaging,
diff --git a/resource/image_test.go b/resource/image_test.go
index 39e538d33..11807d695 100644
--- a/resource/image_test.go
+++ b/resource/image_test.go
@@ -322,6 +322,18 @@ func TestSVGImage(t *testing.T) {
assert.NotNil(svg)
}
+func TestSVGImageContent(t *testing.T) {
+ assert := require.New(t)
+ spec := newTestResourceSpec(assert)
+ svg := fetchResourceForSpec(spec, assert, "circle.svg")
+ assert.NotNil(svg)
+
+ content, err := svg.Content()
+ assert.NoError(err)
+ assert.IsType("", content)
+ assert.Contains(content.(string), `<svg height="100" width="100">`)
+}
+
func BenchmarkResizeParallel(b *testing.B) {
assert := require.New(b)
img := fetchSunset(assert)
diff --git a/resource/resource.go b/resource/resource.go
index 7fe3b4ff9..12e1160cf 100644
--- a/resource/resource.go
+++ b/resource/resource.go
@@ -87,6 +87,14 @@ type Resource interface {
// Params set in front matter for this resource.
Params() map[string]interface{}
+
+ // Content returns this resource's content. It will be equivalent to reading the content
+ // that RelPermalink points to in the published folder.
+ // The return type will be contextual, and should be what you would expect:
+ // * Page: template.HTML
+ // * JSON: String
+ // * Etc.
+ Content() (interface{}, error)
}
// Resources represents a slice of resources, which can be a mix of different types.
@@ -360,6 +368,11 @@ func (d dirFile) path() string {
return path.Join(d.dir, d.file)
}
+type resourceContent struct {
+ content string
+ contentInit sync.Once
+}
+
// genericResource represents a generic linkable resource.
type genericResource struct {
// The relative path to this resource.
@@ -390,6 +403,26 @@ type genericResource struct {
osFileInfo os.FileInfo
targetPathBuilder func(rel string) string
+
+ // We create copies of this struct, so this needs to be a pointer.
+ *resourceContent
+}
+
+func (l *genericResource) Content() (interface{}, error) {
+ var err error
+ l.contentInit.Do(func() {
+ var b []byte
+
+ b, err := afero.ReadFile(l.sourceFs(), l.AbsSourceFilename())
+ if err != nil {
+ return
+ }
+
+ l.content = string(b)
+
+ })
+
+ return l.content, err
}
func (l *genericResource) sourceFs() afero.Fs {
@@ -444,6 +477,7 @@ func (l *genericResource) updateParams(params map[string]interface{}) {
// Implement the Cloner interface.
func (l genericResource) WithNewBase(base string) Resource {
l.base = base
+ l.resourceContent = &resourceContent{}
return &l
}
@@ -611,5 +645,6 @@ func (r *Spec) newGenericResource(
params: make(map[string]interface{}),
name: baseFilename,
title: baseFilename,
+ resourceContent: &resourceContent{},
}
}