Browse Source

supporting video media

Stephen Searles 1 year ago
parent
commit
acbfdbe8eb
8 changed files with 367 additions and 215 deletions
  1. 10
    36
      media.go
  2. 50
    0
      media/image.go
  3. 53
    174
      media/media.go
  4. 88
    0
      media/size.go
  5. 110
    0
      media/thumb.go
  6. 42
    0
      media/video.go
  7. 2
    2
      theme-additions/bindata.go
  8. 12
    3
      theme-additions/layouts/shortcodes/thumb.html

+ 10
- 36
media.go View File

@@ -2,11 +2,8 @@ package caddyhugo
2 2
 
3 3
 import (
4 4
 	"fmt"
5
-	"image"
6 5
 	"io"
7 6
 	"net/http"
8
-	"path"
9
-	"strings"
10 7
 
11 8
 	"git.stephensearles.com/stephen/caddy-hugo2/media"
12 9
 )
@@ -85,12 +82,18 @@ func (ch *CaddyHugo) serveMediaPage(w http.ResponseWriter, r *http.Request) (int
85 82
 
86 83
 		for _, m := range media.Set(mm).ByDate() {
87 84
 
88
-			src, size, err := ch.Media.ThumbMax(*m, 100)
85
+			size, err := ch.Media.ThumbMax(*m, 100)
89 86
 			if err != nil {
90 87
 				fmt.Fprintf(w, `<div class="img">error rendering %q: %v</div>`, m.Name, err)
91 88
 				continue
92 89
 			}
93
-			fmt.Fprintf(w, `<div class="img"><img width=%d height=%d src=%q data-filename=%q /><br /><input type="text" readonly value=%q /><span class="copy">&#x1F4CB;</span></div>`, size.Dx(), size.Dy(), src, m.Name, src)
90
+			switch m.Type {
91
+			case media.TypeImage:
92
+				fmt.Fprintf(w, `<div class="img"><img width=%d height=%d src=%q data-filename=%q /><br /><input type="text" readonly value=%q /><span class="copy">&#x1F4CB;</span></div>`, size.Dx(), size.Dy(), m.ThumbPath(size), m.Name, m.ThumbPath(size))
93
+			case media.TypeVideo:
94
+				// TODO: onmouseover sucks for mobile
95
+				fmt.Fprintf(w, `<div class="img"><video width=%d height=%d src=%q data-filename=%q onmouseover="this.play()" onmouseout="this.pause();this.currentTime=0;"></video><br /><input type="text" readonly value=%q /><span class="copy">&#x1F4CB;</span></div>`, size.Dx(), size.Dy(), m.ThumbPath(size), m.Name, m.ThumbPath(size))
96
+			}
94 97
 		}
95 98
 	}
96 99
 	io.WriteString(w, `<script>
@@ -102,7 +105,7 @@ func (ch *CaddyHugo) serveMediaPage(w http.ResponseWriter, r *http.Request) (int
102 105
 			evt.target.previousSibling.select();
103 106
 			document.execCommand("copy");
104 107
 		}
105
-		if (evt.target.tagName === "IMG") {
108
+		if (evt.target.tagName === "IMG" || evt.target.tagName === "VIDEO") {
106 109
 			var current = document.querySelector(".img.selected");
107 110
 			if (current) {
108 111
 				current.classList = "img";
@@ -128,35 +131,6 @@ func (ch *CaddyHugo) serveMedia(w http.ResponseWriter, r *http.Request) (int, er
128 131
 		return 404, nil
129 132
 	}
130 133
 
131
-	segs := strings.Split(r.URL.Path, "/")
132
-	name := segs[len(segs)-1] // the last segment is the filename
133
-
134
-	size := image.Rectangle{}
135
-
136
-	m := ch.Media.ByName(name)
137
-
138
-	if len(segs) >= 4 && len(segs) > 2 {
139
-		var err error
140
-		size, err = media.ParseSizeString(segs[len(segs)-2], m.Size)
141
-		if err != nil {
142
-			http.Error(w, err.Error(), http.StatusBadRequest)
143
-			return 400, nil
144
-		}
145
-	}
146
-
147
-	file, err := ch.Media.Thumb(*m, size)
148
-	if err != nil {
149
-		http.Error(w, fmt.Sprintf("unable to load thumb"), http.StatusInternalServerError)
150
-		return 500, nil
151
-	}
152
-
153
-	if file[0] == '/' {
154
-		file = file[1:]
155
-	}
156
-
157
-	file = path.Join(ch.Media.ThumbDir, file)
158
-
159
-	http.ServeFile(w, r, file)
160
-
134
+	ch.Media.ServeHTTP(w, r)
161 135
 	return 200, nil
162 136
 }

+ 50
- 0
media/image.go View File

@@ -0,0 +1,50 @@
1
+package media
2
+
3
+import (
4
+	"image"
5
+	"image/jpeg"
6
+	"os"
7
+	"path"
8
+
9
+	"github.com/nfnt/resize"
10
+)
11
+
12
+func imageSize(name string) (image.Rectangle, error) {
13
+	f, err := os.Open(name)
14
+	if err != nil {
15
+		return image.ZR, err
16
+	}
17
+	defer f.Close()
18
+
19
+	cfg, _, err := image.DecodeConfig(f)
20
+	if err != nil {
21
+		return image.ZR, err
22
+	}
23
+
24
+	width := cfg.Width
25
+	height := cfg.Height
26
+
27
+	return image.Rect(0, 0, width, height), nil
28
+}
29
+
30
+func ThumbImage(filename string, img image.Image, size image.Rectangle) error {
31
+	os.MkdirAll(path.Dir(filename), 0755)
32
+	fthumb, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0655)
33
+	if err != nil {
34
+		return err
35
+	}
36
+
37
+	img = resize.Resize(uint(size.Dx()), uint(size.Dy()), img, resize.Bilinear)
38
+
39
+	err = jpeg.Encode(fthumb, img, nil)
40
+	if err != nil {
41
+		return err
42
+	}
43
+
44
+	err = fthumb.Close()
45
+	if err != nil {
46
+		return err
47
+	}
48
+
49
+	return nil
50
+}

+ 53
- 174
media/media.go View File

@@ -1,26 +1,27 @@
1 1
 package media
2 2
 
3 3
 import (
4
-	"fmt"
5 4
 	"image"
6
-	"image/jpeg"
7 5
 	"io"
6
+	"net/http"
8 7
 	"os"
9 8
 	"path"
10 9
 	"path/filepath"
11
-	"regexp"
12 10
 	"sort"
13
-	"strconv"
14 11
 	"time"
15 12
 
16 13
 	// for processing images
17 14
 	_ "image/gif"
18 15
 	_ "image/png"
19 16
 
20
-	"github.com/nfnt/resize"
21 17
 	"github.com/tajtiattila/metadata"
22 18
 )
23 19
 
20
+const (
21
+	TypeImage = "image"
22
+	TypeVideo = "video"
23
+)
24
+
24 25
 type MediaSource struct {
25 26
 	StorageDir string
26 27
 	ThumbDir   string
@@ -34,32 +35,39 @@ type Media struct {
34 35
 	Size     image.Rectangle
35 36
 	FullName string
36 37
 
38
+	ms       *MediaSource
37 39
 	metadata *metadata.Metadata
38 40
 }
39 41
 
40
-func (ms *MediaSource) LocationOrig(m Media) string {
41
-	return path.Join(ms.StorageDir, m.Name)
42
+func (m Media) ThumbPath(size image.Rectangle) string {
43
+	return "/" + thumbPath(size, m.Name)
42 44
 }
43 45
 
44
-func (ms *MediaSource) ThumbPath(m Media, size image.Rectangle) string {
45
-	w := size.Dx()
46
-	h := size.Dy()
47
-
48
-	var ws, hs string
46
+func (m Media) ThumbFilename(size image.Rectangle) string {
47
+	size = m.NormalizeSize(size)
48
+	return thumbFilename(m.ms.ThumbDir, size, m.Name)
49
+}
49 50
 
50
-	if w != 0 {
51
-		ws = fmt.Sprint(w)
51
+func (ms *MediaSource) ServeHTTP(w http.ResponseWriter, r *http.Request) {
52
+	m, err := ms.ByName(path.Base(r.URL.Path))
53
+	if err != nil {
54
+		http.Error(w, err.Error(), http.StatusInternalServerError)
55
+		return
52 56
 	}
53
-	if h != 0 {
54
-		hs = fmt.Sprint(h)
57
+
58
+	sizeRequested, err := SizeRequested(r.URL.Path, m.Size)
59
+	if err != nil {
60
+		http.Error(w, err.Error(), http.StatusBadRequest)
61
+		return
55 62
 	}
56 63
 
57
-	thumbSlug := filepath.Join(fmt.Sprintf("%sx%s", ws, hs), m.Name)
58
-	return path.Join("/media", thumbSlug)
59
-}
64
+	size, err := ms.Thumb(*m, sizeRequested)
65
+	if err != nil {
66
+		http.Error(w, err.Error(), http.StatusBadRequest)
67
+		return
68
+	}
60 69
 
61
-func (ms *MediaSource) ThumbFilename(m Media, size image.Rectangle) string {
62
-	return filepath.Join(ms.ThumbDir, ms.ThumbPath(m, size))
70
+	http.ServeFile(w, r, m.ThumbFilename(size))
63 71
 }
64 72
 
65 73
 func (ms *MediaSource) ReceiveNewMedia(name string, r io.Reader) error {
@@ -118,123 +126,33 @@ func (m *Media) getMetadata() error {
118 126
 }
119 127
 
120 128
 func (ms *MediaSource) Size(name string) (image.Rectangle, error) {
121
-	f, err := os.Open(name)
122
-	if err != nil {
123
-		return image.ZR, err
124
-	}
125
-	defer f.Close()
126
-
127
-	cfg, _, err := image.DecodeConfig(f)
128
-	if err != nil {
129
-		return image.ZR, err
130
-	}
131
-
132
-	width := cfg.Width
133
-	height := cfg.Height
134
-
135
-	return image.Rect(0, 0, width, height), nil
136
-}
137
-
138
-func (ms *MediaSource) ThumbMax(m Media, maxDim int) (string, image.Rectangle, error) {
139
-	f, err := os.Open(ms.LocationOrig(m))
140
-	if err != nil {
141
-		return "", image.ZR, err
142
-	}
143
-	defer f.Close()
144
-
145
-	cfg, _, err := image.DecodeConfig(f)
146
-	if err != nil {
147
-		return "", image.ZR, err
148
-	}
149
-
150
-	width := cfg.Width
151
-	height := cfg.Height
152
-
153
-	if width > height {
154
-		height = height * maxDim / width
155
-		width = maxDim
156
-	} else {
157
-		width = width * maxDim / height
158
-		height = maxDim
159
-	}
160
-
161
-	size := image.Rect(0, 0, width, height)
162
-	if ms.HasThumb(m, size) {
163
-		return ms.ThumbPath(m, size), size, nil
164
-	}
165
-
166
-	_, err = f.Seek(0, io.SeekStart)
167
-	if err != nil {
168
-		return "", image.ZR, err
169
-	}
170
-
171
-	src, err := ms.thumbReader(f, m, size)
172
-	return src, size, err
173
-}
174
-
175
-func (ms *MediaSource) HasThumb(m Media, size image.Rectangle) bool {
176
-	fi, err := os.Stat(ms.ThumbFilename(m, size))
177
-	if err != nil {
178
-		return false
179
-	}
180
-	return m.Date().Before(fi.ModTime())
181
-}
182
-
183
-func (ms *MediaSource) ByName(name string) *Media {
184
-	size, _ := ms.Size(path.Join(ms.StorageDir, name))
185
-	m := Media{
186
-		Type: "image",
187
-		Name: name,
188
-		Size: size,
189
-	}
190
-	m.FullName = ms.LocationOrig(m)
191
-	return &m
192
-}
193
-
194
-func (ms *MediaSource) Thumb(m Media, size image.Rectangle) (string, error) {
195
-	if ms.HasThumb(m, size) {
196
-		return ms.ThumbPath(m, size), nil
197
-	}
198
-
199
-	f, err := os.Open(ms.LocationOrig(m))
200
-	if err != nil {
201
-		return "", err
129
+	switch filepath.Ext(name) {
130
+	case ".mp4":
131
+		return VideoSize(name)
202 132
 	}
203
-	defer f.Close()
204 133
 
205
-	return ms.thumbReader(f, m, size)
134
+	return imageSize(name)
206 135
 }
207 136
 
208
-func (ms *MediaSource) thumbReader(r io.Reader, m Media, size image.Rectangle) (string, error) {
209
-	img, _, err := image.Decode(r)
210
-	if err != nil {
211
-		return "", err
212
-	}
137
+func (ms *MediaSource) ByName(name string) (*Media, error) {
138
+	ext := filepath.Ext(name)
139
+	typ := TypeImage
213 140
 
214
-	return ms.ThumbImage(img, m, size)
215
-}
216
-
217
-func (ms *MediaSource) ThumbImage(img image.Image, m Media, size image.Rectangle) (string, error) {
218
-	thumbLoc := ms.ThumbFilename(m, size)
219
-	os.MkdirAll(path.Dir(thumbLoc), 0755)
220
-	fthumb, err := os.OpenFile(thumbLoc, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0655)
221
-	if err != nil {
222
-		return "", err
141
+	switch ext {
142
+	case ".mp4":
143
+		typ = TypeVideo
223 144
 	}
224 145
 
225
-	img = resize.Resize(uint(size.Dx()), uint(size.Dy()), img, resize.Bilinear)
226
-
227
-	err = jpeg.Encode(fthumb, img, nil)
228
-	if err != nil {
229
-		return "", err
230
-	}
146
+	fullName := path.Join(ms.StorageDir, name)
147
+	size, _ := ms.Size(fullName)
231 148
 
232
-	err = fthumb.Close()
233
-	if err != nil {
234
-		return "", err
235
-	}
236
-
237
-	return ms.ThumbPath(m, size), nil
149
+	return &Media{
150
+		Type:     typ,
151
+		Name:     name,
152
+		Size:     size,
153
+		FullName: fullName,
154
+		ms:       ms,
155
+	}, nil
238 156
 }
239 157
 
240 158
 func (ms *MediaSource) Walk() ([]*Media, error) {
@@ -248,7 +166,11 @@ func (ms *MediaSource) Walk() ([]*Media, error) {
248 166
 			if fi.IsDir() {
249 167
 				return nil
250 168
 			}
251
-			media = append(media, ms.ByName(path.Base(name)))
169
+			m, err := ms.ByName(path.Base(name))
170
+			if err != nil {
171
+				return nil
172
+			}
173
+			media = append(media, m)
252 174
 			return nil
253 175
 		})
254 176
 
@@ -271,49 +193,6 @@ func (s Set) ByDate() Set {
271 193
 	return s
272 194
 }
273 195
 
274
-var (
275
-	sizeString = regexp.MustCompile(`([0-9]*)(x)?([0-9]*)`)
276
-)
277
-
278
-func ParseSizeString(str string, actual image.Rectangle) (image.Rectangle, error) {
279
-	var err = fmt.Errorf("expected a size string {width}x{height}, saw %q", str)
280
-
281
-	strs := sizeString.FindStringSubmatch(str)
282
-	if len(strs) < 4 {
283
-		return image.ZR, err
284
-	}
285
-
286
-	var w, h int
287
-	var strconvErr error
288
-
289
-	if strs[1] != "" {
290
-		w, strconvErr = strconv.Atoi(strs[1])
291
-		if strconvErr != nil {
292
-			return image.ZR, err
293
-		}
294
-	}
295
-
296
-	if strs[3] != "" {
297
-		h, strconvErr = strconv.Atoi(strs[3])
298
-		if strconvErr != nil {
299
-			return image.ZR, err
300
-		}
301
-	}
302
-
303
-	if strs[2] != "x" {
304
-		// w was the only dimension given, so set it to the greater dimension
305
-		// of the actual image size
306
-		if actual.Dx() > actual.Dy() {
307
-			h = 0
308
-		} else {
309
-			h = w
310
-			w = 0
311
-		}
312
-	}
313
-
314
-	return image.Rect(0, 0, w, h), nil
315
-}
316
-
317 196
 func removeExtension(name string) string {
318 197
 	ext := path.Ext(name)
319 198
 	return name[:len(name)-len(ext)]

+ 88
- 0
media/size.go View File

@@ -0,0 +1,88 @@
1
+package media
2
+
3
+import (
4
+	"fmt"
5
+	"image"
6
+	"regexp"
7
+	"strconv"
8
+	"strings"
9
+)
10
+
11
+var (
12
+	sizeString = regexp.MustCompile(`([0-9]*)(x)?([0-9]*)`)
13
+)
14
+
15
+func SizeRequested(urlpath string, actual image.Rectangle) (image.Rectangle, error) {
16
+	segments := strings.Count(urlpath, "/")
17
+	if segments < 3 {
18
+		return actual, nil
19
+	}
20
+	sizeSpec := strings.Split(urlpath, "/")[2]
21
+	return ParseSizeString(sizeSpec, actual)
22
+}
23
+
24
+func ParseSizeString(str string, actual image.Rectangle) (image.Rectangle, error) {
25
+	var err = fmt.Errorf("expected a size string {width}x{height}, saw %q", str)
26
+
27
+	strs := sizeString.FindStringSubmatch(str)
28
+	if len(strs) < 4 {
29
+		return image.ZR, err
30
+	}
31
+
32
+	var w, h int
33
+	var strconvErr error
34
+
35
+	if strs[1] != "" {
36
+		w, strconvErr = strconv.Atoi(strs[1])
37
+		if strconvErr != nil {
38
+			return image.ZR, err
39
+		}
40
+	}
41
+
42
+	if strs[3] != "" {
43
+		h, strconvErr = strconv.Atoi(strs[3])
44
+		if strconvErr != nil {
45
+			return image.ZR, err
46
+		}
47
+	}
48
+
49
+	if strs[2] != "x" {
50
+		// w was the only dimension given, so set it to the greater dimension
51
+		// of the actual image size
52
+		if actual.Dx() > actual.Dy() {
53
+			h = 0
54
+		} else {
55
+			h = w
56
+			w = 0
57
+		}
58
+	}
59
+
60
+	return image.Rect(0, 0, w, h), nil
61
+}
62
+
63
+func NormalizeSize(media, requested image.Rectangle) image.Rectangle {
64
+	if requested.Dx() == 0 && requested.Dy() == 0 {
65
+		return media
66
+	}
67
+	if requested.Dy()%2 == 1 {
68
+		requested.Max.Y--
69
+	}
70
+	if requested.Dx() != 0 && requested.Dy() != 0 {
71
+		return requested
72
+	}
73
+	scaled := image.Rectangle{}
74
+	if requested.Dx() == 0 {
75
+		scaled.Max.Y = requested.Dy()
76
+		scaled.Max.X = requested.Dy() * media.Dx() / media.Dy()
77
+	}
78
+	if requested.Dy() == 0 {
79
+		scaled.Max.X = requested.Dx()
80
+		scaled.Max.Y = requested.Dx() * media.Dy() / media.Dx()
81
+		for scaled.Max.Y%2 == 1 {
82
+			requested.Max.X--
83
+			scaled.Max.X = requested.Dx()
84
+			scaled.Max.Y = requested.Dx() * media.Dy() / media.Dx()
85
+		}
86
+	}
87
+	return scaled
88
+}

+ 110
- 0
media/thumb.go View File

@@ -0,0 +1,110 @@
1
+package media
2
+
3
+import (
4
+	"fmt"
5
+	"image"
6
+	"io"
7
+	"os"
8
+	"path"
9
+	"path/filepath"
10
+)
11
+
12
+func (ms *MediaSource) ThumbPath(m Media, size image.Rectangle) string {
13
+	size = m.NormalizeSize(size)
14
+	return thumbPath(size, m.Name)
15
+}
16
+
17
+func (ms *MediaSource) ThumbFilename(m Media, size image.Rectangle) string {
18
+	size = m.NormalizeSize(size)
19
+	return thumbFilename(ms.ThumbDir, size, m.Name)
20
+}
21
+
22
+func thumbFilename(dir string, size image.Rectangle, name string) string {
23
+	return filepath.Join(dir, thumbPath(size, name))
24
+}
25
+
26
+func thumbPath(size image.Rectangle, name string) string {
27
+	w := size.Dx()
28
+	h := size.Dy()
29
+
30
+	var ws, hs string
31
+
32
+	if w != 0 {
33
+		ws = fmt.Sprint(w)
34
+	}
35
+	if h != 0 {
36
+		hs = fmt.Sprint(h)
37
+	}
38
+
39
+	thumbSlug := filepath.Join(fmt.Sprintf("%sx%s", ws, hs), name)
40
+	return path.Join("", "media", thumbSlug)
41
+}
42
+
43
+func (ms *MediaSource) ThumbMax(m Media, maxDim int) (image.Rectangle, error) {
44
+	width := m.Size.Dx()
45
+	height := m.Size.Dy()
46
+
47
+	if width == 0 && height == 0 {
48
+		return m.Size, fmt.Errorf("invalid media")
49
+	}
50
+
51
+	if width > height {
52
+		height = height * maxDim / width
53
+		width = maxDim
54
+	} else {
55
+		width = width * maxDim / height
56
+		height = maxDim
57
+	}
58
+
59
+	size := image.Rect(0, 0, width, height)
60
+	actual, err := ms.Thumb(m, size)
61
+	return actual, err
62
+}
63
+
64
+func (ms *MediaSource) HasThumb(m Media, size image.Rectangle) bool {
65
+	fi, err := os.Stat(ms.ThumbFilename(m, size))
66
+	if err != nil {
67
+		return false
68
+	}
69
+	return m.Date().Before(fi.ModTime())
70
+}
71
+
72
+func (m Media) NormalizeSize(size image.Rectangle) image.Rectangle {
73
+	return NormalizeSize(m.Size, size)
74
+}
75
+
76
+func (ms *MediaSource) Thumb(m Media, size image.Rectangle) (image.Rectangle, error) {
77
+	size = m.NormalizeSize(size)
78
+
79
+	if ms.HasThumb(m, size) {
80
+		return size, nil
81
+	}
82
+
83
+	f, err := os.Open(m.FullName)
84
+	if err != nil {
85
+		return size, err
86
+	}
87
+	defer f.Close()
88
+
89
+	return size, ms.thumbReader(f, m, size)
90
+}
91
+
92
+func (ms *MediaSource) thumbReader(r io.Reader, m Media, size image.Rectangle) error {
93
+	size = m.NormalizeSize(size)
94
+
95
+	switch m.Type {
96
+	case TypeImage:
97
+		img, _, err := image.Decode(r)
98
+		if err != nil {
99
+			return err
100
+		}
101
+
102
+		filename := ms.ThumbFilename(m, size)
103
+		return ThumbImage(filename, img, size)
104
+	case TypeVideo:
105
+		return VideoEncode(m.FullName, size, ms.ThumbDir)
106
+
107
+	default:
108
+		return fmt.Errorf("cannot thumb media type %q", m.Type)
109
+	}
110
+}

+ 42
- 0
media/video.go View File

@@ -0,0 +1,42 @@
1
+package media
2
+
3
+import (
4
+	"bytes"
5
+	"fmt"
6
+	"image"
7
+	"os"
8
+	"os/exec"
9
+	"path"
10
+	"path/filepath"
11
+)
12
+
13
+func VideoFrame(filename string) (image.Image, error) {
14
+	cmd := exec.Command("ffmpeg", "-i", filename, "-vframes", "1", "-f", "singlejpeg", "-")
15
+	buffer := new(bytes.Buffer)
16
+	cmd.Stdout = buffer
17
+	if cmd.Run() != nil {
18
+		return nil, fmt.Errorf("could not generate frame")
19
+	}
20
+
21
+	img, _, err := image.Decode(buffer)
22
+	return img, err
23
+}
24
+
25
+func VideoSize(filename string) (image.Rectangle, error) {
26
+	img, err := VideoFrame(filename)
27
+	if err != nil {
28
+		return image.Rectangle{}, err
29
+	}
30
+	return img.Bounds(), nil
31
+}
32
+
33
+func VideoEncode(filename string, size image.Rectangle, thumbDir string) error {
34
+	dest := thumbFilename(thumbDir, size, path.Base(filename))
35
+	os.MkdirAll(filepath.Dir(dest), 0755)
36
+	cmd := exec.Command("ffmpeg", "-i", filename, "-vf", fmt.Sprintf("scale=%d:%d", size.Dx(), size.Dy()), dest)
37
+	if out, err := cmd.CombinedOutput(); err != nil {
38
+		os.Remove(dest)
39
+		return fmt.Errorf("could not thumb video: %s", string(out))
40
+	}
41
+	return nil
42
+}

+ 2
- 2
theme-additions/bindata.go View File

@@ -152,7 +152,7 @@ func layoutsShortcodesCommentsHtml() (*asset, error) {
152 152
 	return a, nil
153 153
 }
154 154
 
155
-var _layoutsShortcodesThumbHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\x90\xc1\x6a\xec\x30\x0c\x45\xf7\xf9\x0a\xa1\xd5\x7b\x8b\x99\x4c\xf7\x49\xb6\xfd\x8c\xa2\x26\x8a\x2d\xea\xb8\x69\x22\x98\x82\xd0\xbf\x17\xa7\x66\x98\x0e\xed\xc6\x20\x38\xe7\xfa\x72\xbb\xb5\x31\x03\x99\x81\x3f\xe0\xdf\xf9\x99\x15\x90\x92\x84\x8c\xff\x01\x13\xcf\x8a\xe0\x3e\x26\xda\xf7\xfe\x38\x65\x09\x68\xc6\x69\xe7\xe2\x3c\x0a\x9b\x84\xa8\x78\x13\x8e\xb3\x1a\x79\x82\x93\x7b\x33\x74\x04\x71\xe3\xb9\xc7\x76\xe1\x49\xa8\x35\x83\xef\x90\x59\x12\x67\x5a\x18\xdd\x11\x94\xb6\xc0\xda\xe3\xcb\x6b\xa2\xfc\x86\x43\x27\x4b\x80\x7d\x1b\x6f\x5a\x63\x76\x82\xab\x68\xac\xf6\x55\x26\x8d\xe8\x6e\x76\x2e\x4f\x29\xe8\xfe\x74\xb9\x1c\x3f\xbb\x7f\x9a\xdd\xc1\x91\x6b\xcf\x1f\x74\x45\x7f\x69\x54\x9a\x63\x99\xe9\x2e\x63\xa4\x55\xe5\x3d\x97\x79\x54\x34\x71\x8f\x47\x18\xd6\x94\xbf\x69\x4a\xfa\xc8\xb6\x43\xd7\xd2\xd0\x74\xed\x3a\x34\x5f\x01\x00\x00\xff\xff\x52\x23\x84\xaa\x90\x01\x00\x00")
155
+var _layoutsShortcodesThumbHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x90\xcf\x6e\x83\x30\x0c\xc6\xef\x3c\x85\x65\xed\xd0\x1e\x5a\x3a\xa9\xa7\x09\xb8\xee\x31\xa6\x14\x0c\x44\x33\x81\x11\x77\xad\x14\xf9\xdd\xa7\xa4\xac\xff\xa4\x9d\x77\x89\x64\xe7\xfb\x3e\xff\xec\x10\xe0\xa5\xb5\x4c\xce\x0c\x04\x6f\x25\x6c\xdf\x49\x00\x7f\x3b\x08\x1b\xd5\x2c\x6a\xe8\x2c\xf1\xdb\x1f\x0f\x5e\xe6\x3b\xcb\xca\x1f\x0f\xb0\x62\x72\xb7\xde\x1a\xf6\x6b\x50\xcd\x8a\x29\x3a\x6d\x0b\xf4\x05\xab\x4b\xae\x61\xdb\x39\x5c\x03\x32\xb5\x82\xa0\x5a\xb3\xf1\xbe\x4c\xa5\x1d\x3a\x0c\x81\xd8\x53\xf4\x3c\x1b\x66\xdb\xf5\x82\x57\x43\x2a\x17\x87\x6b\x40\xb5\xba\xcd\x4a\xac\xb8\x1d\xa6\x3d\x26\x8c\x6f\xdb\xd0\x08\x7e\xae\x4b\xcc\x07\x6a\xac\xc9\xb3\x10\x36\x70\xb2\xd2\x2f\xeb\x9e\x6c\x23\x3d\xaa\x86\xb0\x8d\x4f\x64\x50\x7d\xdd\xed\x52\xb8\xea\x39\x84\x3b\x71\x4f\x0b\xca\x83\x7a\x91\xe6\x0f\xf7\xdc\xa8\x62\x56\x8f\x4e\xe6\x91\x3d\x18\xe6\xf1\xd4\x1e\x99\x7d\x3d\x13\xb9\xac\x2a\xf2\x84\x96\xd0\xd3\xde\x91\xd6\x40\x3f\x53\x7b\x45\x7d\xc8\x53\x45\x10\x33\x77\x24\x25\x7e\x1c\xd8\xb8\x4f\xac\x0a\x3b\x74\xff\xb7\x5c\x08\xf7\xa3\x6a\x33\x89\x1d\x5d\x3c\xbb\x58\x61\x2a\x31\xc5\xe0\xe2\xff\x5b\x6d\x58\x9e\xb5\x79\x55\xe4\x26\x9e\xe6\x52\x16\xf9\x54\x65\x3f\x01\x00\x00\xff\xff\xca\x5c\x71\xf7\xad\x02\x00\x00")
156 156
 
157 157
 func layoutsShortcodesThumbHtmlBytes() ([]byte, error) {
158 158
 	return bindataRead(
@@ -167,7 +167,7 @@ func layoutsShortcodesThumbHtml() (*asset, error) {
167 167
 		return nil, err
168 168
 	}
169 169
 
170
-	info := bindataFileInfo{name: "layouts/shortcodes/thumb.html", size: 400, mode: os.FileMode(420), modTime: time.Unix(1504974306, 0)}
170
+	info := bindataFileInfo{name: "layouts/shortcodes/thumb.html", size: 685, mode: os.FileMode(420), modTime: time.Unix(1505244603, 0)}
171 171
 	a := &asset{bytes: bytes, info: info}
172 172
 	return a, nil
173 173
 }

+ 12
- 3
theme-additions/layouts/shortcodes/thumb.html View File

@@ -1,8 +1,17 @@
1
+{{ $filename := .Get "filename" -}}
2
+{{ $ext := substr $filename (sub (len $filename) 4) }}
1 3
 <p
2
-{{ if eq (.Get "align") "left" }}class="leftimg"{{else if (.Get "align") "right"}}class="rightimg"{{end -}}
3
-><a href="/media/{{ .Get "filename"}}" target="_blank"><img src="/media/
4
-{{- with .Get "width"}}{{.}}{{else}}100{{end}}x{{with .Get "height"}}{{.}}{{else}}{{end}}/{{ .Get "filename" -}}"
4
+{{ if eq (.Get "align") "left" }}class="leftimg"{{else if (.Get "align") "right"}}class="rightimg"{{end }}>
5
+{{ if eq $ext ".mp4" }}
6
+<video src="/media/
7
+{{- with .Get "width"}}{{.}}{{else}}100{{end}}x{{with .Get "height"}}{{.}}{{else}}{{end}}/{{ $filename -}}"
8
+controls allowfullscreen
9
+></video>
10
+{{ else }}
11
+<a href="/media/{{ $filename }}" target="_blank"><img src="/media/
12
+{{- with .Get "width"}}{{.}}{{else}}100{{end}}x{{with .Get "height"}}{{.}}{{else}}{{end}}/{{ $filename -}}"
5 13
 {{ with .Get "caption" }}title="{{.}}"{{end}}
6 14
 {{ with .Get "caption" }}alt="{{.}}"{{end}}
7 15
 /></a>
16
+{{end}}
8 17
 </p>

Loading…
Cancel
Save