Просмотр исходного кода

Add initial support for tags

You can filter by clicking on them, but it's not possible to clear the
filter without going back, and you can't filter by multiple tags.
Lucas Stadler лет назад: 9
Родитель
Сommit
28e7d2ee56
2 измененных файлов с 102 добавлено и 8 удалено
  1. 83 8
      go/blog/blog.go
  2. 19 0
      go/blog/blog.yaml

+ 83 - 8
go/blog/blog.go

4
	"crypto/md5"
4
	"crypto/md5"
5
	"crypto/rand"
5
	"crypto/rand"
6
	"encoding/hex"
6
	"encoding/hex"
7
	"encoding/json"
7
	"flag"
8
	"flag"
8
	"fmt"
9
	"fmt"
9
	"html/template"
10
	"html/template"
19
)
20
)
20
21
21
type Post struct {
22
type Post struct {
22
	Id      string `yaml:"id"`
23
	Title   string `yaml:"title"`
24
	URL     string `yaml:"url"`
25
	Content string `yaml:"content"`
26
	Date    string `yaml:"date"`
27
	Type    string `yaml:"type"`
23
	Id      string   `yaml:"id"`
24
	Title   string   `yaml:"title"`
25
	URL     string   `yaml:"url"`
26
	Content string   `yaml:"content"`
27
	Tags    []string `yaml:"tags"`
28
	Date    string   `yaml:"date"`
29
	Type    string   `yaml:"type"`
28
}
30
}
29
31
30
var flags struct {
32
var flags struct {
38
40
39
var defaultStyle = `
41
var defaultStyle = `
40
article {
42
article {
41
	margin-bottom: 1em;
43
	margin-bottom: 2em;
42
}
44
}
43
45
44
article header {
46
article header {
71
	max-width: 80vw;
73
	max-width: 80vw;
72
	max-height: 50vh;
74
	max-height: 50vh;
73
}
75
}
76
77
article .tags {
78
	list-style-type: none;
79
	padding: 0;
80
}
81
82
article .tags .tag-link {
83
	float: left;
84
	color: black;
85
	margin-right: 0.5em;
86
}
87
88
article .tags .tag-link:visited {
89
	color: #555;
90
}
91
92
article.does-not-match {
93
	display: none;
94
}
74
`
95
`
75
96
76
func init() {
97
func init() {
176
		}
197
		}
177
	}
198
	}
178
199
200
	fmt.Fprintf(out, `
201
202
	<script>
203
	window.addEventListener("click", function(ev) {
204
		if (ev.target.classList.contains("tag-link")) {
205
			if (ev.target.href == "") {
206
				return;
207
			}
208
209
			var u = new URL(ev.target.href);
210
			if (!u.hash.startsWith("#tag:")) {
211
				return;
212
			}
213
			var tag = u.hash.substr(5);
214
			filterTag(tag);
215
		}
216
	})
217
218
	function filterTag(tag) {
219
		var articles = document.querySelectorAll("article");
220
		for (var i = 0; i < articles.length; i++) {
221
			var article = articles[i];
222
			var matches = false;
223
			if (article && 'tags' in article.dataset) {
224
				var tags = JSON.parse(article.dataset.tags);
225
				for (var j = 0; j < tags.length; j++) {
226
					if (tags[j] == tag) {
227
						matches = true;
228
						break;
229
					}
230
				}
231
			}
232
			if (!matches) {
233
				article.classList.add("does-not-match");
234
			}
235
		}
236
	}
237
	</script>`)
179
	fmt.Fprintf(out, "\n</body>\n</html>\n")
238
	fmt.Fprintf(out, "\n</body>\n</html>\n")
180
	out.Close()
239
	out.Close()
181
240
195
	"safe_url": func(s string) template.URL {
254
	"safe_url": func(s string) template.URL {
196
		return template.URL(s)
255
		return template.URL(s)
197
	},
256
	},
257
	"json": func(v interface{}) (string, error) {
258
		buf, err := json.Marshal(v)
259
		return string(buf), err
260
	},
198
}
261
}
199
262
200
var baseTmpl = template.Must(template.New("base").
263
var baseTmpl = template.Must(template.New("base").
208
		<time>{{ .Date }}</time>{{ end }}
271
		<time>{{ .Date }}</time>{{ end }}
209
	</header>
272
	</header>
210
{{ end }}
273
{{ end }}
274
275
{{ define "tags" }}
276
	<ul class="tags">
277
	{{- range . }}
278
		<li><a class="tag-link" href="#tag:{{ safe_url . }}">{{ . }}</a></li>
279
	{{ end -}}
280
	</ul>
281
{{ end }}
211
`))
282
`))
212
283
213
var shellTmpl = template.Must(baseTmpl.New("shell").
284
var shellTmpl = template.Must(baseTmpl.New("shell").
270
341
271
var textTmpl = template.Must(baseTmpl.New("text").
342
var textTmpl = template.Must(baseTmpl.New("text").
272
	Funcs(funcs).Parse(`
343
	Funcs(funcs).Parse(`
273
<article id="{{ .Id }}" class="text">
344
<article id="{{ .Id }}" class="text" {{- if .Tags }} data-tags="{{ json .Tags }}"{{ end }}>
274
	{{- template "title" . }}
345
	{{- template "title" . }}
275
	{{- if .Content }}
346
	{{- if .Content }}
276
347
277
	{{ markdown .Content }}
348
	{{ markdown .Content }}
278
	{{- end -}}
349
	{{- end -}}
350
351
	<footer>
352
		{{ template "tags" .Tags }}
353
	</footer>
279
</article>
354
</article>
280
`))
355
`))
281
356

+ 19 - 0
go/blog/blog.yaml

63
- url: https://www.youtube.com/watch?v=yLuOzNeHw5I
63
- url: https://www.youtube.com/watch?v=yLuOzNeHw5I
64
  content: Lights, by Archive.
64
  content: Lights, by Archive.
65
  type: video
65
  type: video
66
- title: There are tags now!
67
  content: |
68
    You can now tag articles.  Any kind of string is allowed, have
69
    some fun with it...  :)
70
71
    Use them as follows:
72
73
        - # attributes as usual
74
          tags: [fancy, tags, "stuff:with-interesting!-characters"]
75
76
    Or alternatively:
77
78
        - # as usual
79
          tags:
80
            - fancy
81
            - tags
82
            - "stuff:with-interesting!-characters"
83
  tags: [tags, feature, announcement, "author:lu"]
84
  type: text