tangled
alpha
login
or
join now
kokirigla.de
/
nara
0
fork
atom
online Minecraft written book viewer
0
fork
atom
overview
issues
pulls
pipelines
refactor(ui): make footer reused
kokirigla.de
3 weeks ago
93e40f05
f2e89532
verified
This commit was signed with the committer's
known signature
.
kokirigla.de
SSH Key Fingerprint:
SHA256:BlSEtD3ZoKT3iKveofI8gba+lZ9CEolKRM1Pzy3pAwg=
+173
-177
3 changed files
expand all
collapse all
unified
split
templates
base.html
book.html
index.html
+8
-1
templates/base.html
···
11
11
</head>
12
12
13
13
<body class="font-minecraft">
14
14
-
{% block body %}{% endblock %}
14
14
+
<main class="{% block page_class %}page{% endblock %}" {% block page_attrs %}{% endblock %}>
15
15
+
{% block body %}{% endblock %}
16
16
+
<footer class="footer">
17
17
+
<p class="subtle">build <a
18
18
+
href="https://tangled.org/did:plc:uthy5qqccx3hdwxo7sriplmh/nara/commit/{{ git_hash }}">{{ &git_hash[0..6]
19
19
+
}}</a></p>
20
20
+
</footer>
21
21
+
</main>
15
22
</body>
16
23
17
24
</html>
+37
-40
templates/book.html
···
12
12
<meta name="twitter:description" content="By {{ book.author }}. {{ book.page_count }} pages." />
13
13
{% endblock %}
14
14
15
15
+
{% block page_class %}page detail{% endblock %}
16
16
+
{% block page_attrs %} style="--book-mask: url('/assets/image/{{ texture_kind }}/written_book.webp')"{% endblock %}
17
17
+
15
18
{% block body %}
16
16
-
<main class="page detail" style="--book-mask: url('/assets/image/{{ texture_kind }}/written_book.webp')">
17
17
-
<header class="hero detail-hero">
18
18
-
<div class="brand">
19
19
-
<span class="enchanted book-badge">
20
20
-
<img class="item" src="/assets/image/{{ texture_kind }}/written_book.webp" alt="">
21
21
-
</span>
22
22
-
<div>
23
23
-
<p class="eyebrow">Book Detail</p>
24
24
-
<h1 class="font-minecraft">{{ book.title }}</h1>
25
25
-
<p class="meta">by <a href="{{ book.author_href }}">{{ book.author }}</a></p>
26
26
-
<div class="meta-row">
27
27
-
{% if book.has_category %}
28
28
-
<a class="tag-link" href="{{ book.category_href }}"><span class="tag">{{ book.category }}</span></a>
29
29
-
{% endif %}
30
30
-
{% if book.has_location %}
31
31
-
<span class="tag subtle">{{ book.location }}</span>
32
32
-
{% endif %}
33
33
-
<span class="tag subtle">{{ book.page_count }} pages</span>
34
34
-
</div>
19
19
+
<header class="hero detail-hero">
20
20
+
<div class="brand">
21
21
+
<span class="enchanted book-badge">
22
22
+
<img class="item" src="/assets/image/{{ texture_kind }}/written_book.webp" alt="">
23
23
+
</span>
24
24
+
<div>
25
25
+
<p class="eyebrow">Book Detail</p>
26
26
+
<h1 class="font-minecraft">{{ book.title }}</h1>
27
27
+
<p class="meta">by <a href="{{ book.author_href }}">{{ book.author }}</a></p>
28
28
+
<div class="meta-row">
29
29
+
{% if book.has_category %}
30
30
+
<a class="tag-link" href="{{ book.category_href }}"><span class="tag">{{ book.category }}</span></a>
31
31
+
{% endif %}
32
32
+
{% if book.has_location %}
33
33
+
<span class="tag subtle">{{ book.location }}</span>
34
34
+
{% endif %}
35
35
+
<span class="tag subtle">{{ book.page_count }} pages</span>
35
36
</div>
36
37
</div>
37
37
-
<div class="detail-actions">
38
38
-
<a class="button ghost" href="{{ back_href }}">Back to list</a>
39
39
-
</div>
40
40
-
</header>
41
41
-
42
42
-
<section class="detail-body">
43
43
-
<div class="pages">
44
44
-
{% for page in book.pages %}
45
45
-
<article class="book-page">
46
46
-
<div class="book-page-sprite">
47
47
-
<p class="book-page-header font-minecraft">Page {{ page.index }} of {{ book.page_count }}</p>
48
48
-
<div class="book-page-text font-minecraft">{{ page.html }}</div>
49
49
-
</div>
50
50
-
</article>
51
51
-
{% endfor %}
52
52
-
</div>
53
53
-
</section>
38
38
+
</div>
39
39
+
<div class="detail-actions">
40
40
+
<a class="button ghost" href="{{ back_href }}">Back to list</a>
41
41
+
</div>
42
42
+
</header>
54
43
55
55
-
<footer class="footer">
56
56
-
<p class="subtle">build {{ git_hash }}</p>
57
57
-
</footer>
58
58
-
</main>
44
44
+
<section class="detail-body">
45
45
+
<div class="pages">
46
46
+
{% for page in book.pages %}
47
47
+
<article class="book-page">
48
48
+
<div class="book-page-sprite">
49
49
+
<p class="book-page-header font-minecraft">Page {{ page.index }} of {{ book.page_count }}</p>
50
50
+
<div class="book-page-text font-minecraft">{{ page.html }}</div>
51
51
+
</div>
52
52
+
</article>
53
53
+
{% endfor %}
54
54
+
</div>
55
55
+
</section>
59
56
{% endblock %}
+128
-136
templates/index.html
···
15
15
<meta name="twitter:image" content="/assets/image/{{ texture_kind }}/written_book.webp" />
16
16
{% endblock %}
17
17
18
18
+
{% block page_attrs %} style="--book-mask: url('/assets/image/{{ texture_kind }}/written_book.webp')"{% endblock %}
19
19
+
18
20
{% block body %}
19
19
-
<main class="page" style="--book-mask: url('/assets/image/{{ texture_kind }}/written_book.webp')">
20
20
-
<header class="hero">
21
21
-
<div class="brand">
22
22
-
<span class="enchanted book-badge">
23
23
-
<img class="item" src="/assets/image/{{ texture_kind }}/written_book.webp" alt="">
24
24
-
</span>
25
25
-
<div>
26
26
-
<p class="eyebrow">nara</p>
27
27
-
<h1 class="font-minecraft">Book Archive</h1>
28
28
-
<p class="subtle">{{ book_count }} books indexed</p>
29
29
-
</div>
21
21
+
<header class="hero">
22
22
+
<div class="brand">
23
23
+
<span class="enchanted book-badge">
24
24
+
<img class="item" src="/assets/image/{{ texture_kind }}/written_book.webp" alt="">
25
25
+
</span>
26
26
+
<div>
27
27
+
<p class="eyebrow">nara</p>
28
28
+
<h1 class="font-minecraft">Book Archive</h1>
29
29
+
<p class="subtle">{{ book_count }} books indexed</p>
30
30
</div>
31
31
-
32
32
-
<form class="search" method="get" action="/">
33
33
-
<label class="field">
34
34
-
<span>Search</span>
35
35
-
<input type="search" name="q" value="{{ query.q }}" placeholder="Title, author, or text" />
36
36
-
</label>
37
37
-
<label class="field">
38
38
-
<span>Scope</span>
39
39
-
<select name="scope">
40
40
-
<option value="all" {% if query.scope=="all" %}selected{% endif %}>All fields</option>
41
41
-
<option value="title" {% if query.scope=="title" %}selected{% endif %}>Title</option>
42
42
-
<option value="author" {% if query.scope=="author" %}selected{% endif %}>Author</option>
43
43
-
<option value="contents" {% if query.scope=="contents" %}selected{% endif %}>Contents</option>
44
44
-
</select>
45
45
-
</label>
46
46
-
<label class="field">
47
47
-
<span>Author filter</span>
48
48
-
<select name="author">
49
49
-
<option value="" {% if !query.has_author %}selected{% endif %}>All authors</option>
50
50
-
{% for a in authors %}
51
51
-
<option value="{{ a.name }}" {% if query.author==a.name %}selected{% endif %}>{{ a.name }}</option>
52
52
-
{% endfor %}
53
53
-
</select>
54
54
-
</label>
55
55
-
<label class="field">
56
56
-
<span>Category filter</span>
57
57
-
<select name="category">
58
58
-
<option value="" {% if !query.has_category %}selected{% endif %}>All categories</option>
59
59
-
{% for c in categories %}
60
60
-
<option value="{{ c.name }}" {% if query.category==c.name %}selected{% endif %}>{{ c.name }}
61
61
-
</option>
62
62
-
{% endfor %}
63
63
-
</select>
64
64
-
</label>
65
65
-
<div class="actions">
66
66
-
<button type="submit">Search</button>
67
67
-
{% if query.active %}
68
68
-
<a class="link-reset" href="/">Clear</a>
69
69
-
{% endif %}
70
70
-
<button class="surprise-button" type="submit" formaction="/random">Surprise me</button>
71
71
-
</div>
72
72
-
</form>
31
31
+
</div>
73
32
74
74
-
{% if query.has_category || query.has_author %}
75
75
-
<div class="active-filters">
76
76
-
{% if query.has_category %}
77
77
-
<span class="chip">Category: {{ query.category }}</span>
78
78
-
{% endif %}
79
79
-
{% if query.has_author %}
80
80
-
<span class="chip">Author: {{ query.author }}</span>
33
33
+
<form class="search" method="get" action="/">
34
34
+
<label class="field">
35
35
+
<span>Search</span>
36
36
+
<input type="search" name="q" value="{{ query.q }}" placeholder="Title, author, or text" />
37
37
+
</label>
38
38
+
<label class="field">
39
39
+
<span>Scope</span>
40
40
+
<select name="scope">
41
41
+
<option value="all" {% if query.scope=="all" %}selected{% endif %}>All fields</option>
42
42
+
<option value="title" {% if query.scope=="title" %}selected{% endif %}>Title</option>
43
43
+
<option value="author" {% if query.scope=="author" %}selected{% endif %}>Author</option>
44
44
+
<option value="contents" {% if query.scope=="contents" %}selected{% endif %}>Contents</option>
45
45
+
</select>
46
46
+
</label>
47
47
+
<label class="field">
48
48
+
<span>Author filter</span>
49
49
+
<select name="author">
50
50
+
<option value="" {% if !query.has_author %}selected{% endif %}>All authors</option>
51
51
+
{% for a in authors %}
52
52
+
<option value="{{ a.name }}" {% if query.author==a.name %}selected{% endif %}>{{ a.name }}</option>
53
53
+
{% endfor %}
54
54
+
</select>
55
55
+
</label>
56
56
+
<label class="field">
57
57
+
<span>Category filter</span>
58
58
+
<select name="category">
59
59
+
<option value="" {% if !query.has_category %}selected{% endif %}>All categories</option>
60
60
+
{% for c in categories %}
61
61
+
<option value="{{ c.name }}" {% if query.category==c.name %}selected{% endif %}>{{ c.name }}
62
62
+
</option>
63
63
+
{% endfor %}
64
64
+
</select>
65
65
+
</label>
66
66
+
<div class="actions">
67
67
+
<button type="submit">Search</button>
68
68
+
{% if query.active %}
69
69
+
<a class="link-reset" href="/">Clear</a>
81
70
{% endif %}
71
71
+
<button class="surprise-button" type="submit" formaction="/random">Surprise me</button>
82
72
</div>
73
73
+
</form>
74
74
+
75
75
+
{% if query.has_category || query.has_author %}
76
76
+
<div class="active-filters">
77
77
+
{% if query.has_category %}
78
78
+
<span class="chip">Category: {{ query.category }}</span>
83
79
{% endif %}
84
84
-
</header>
80
80
+
{% if query.has_author %}
81
81
+
<span class="chip">Author: {{ query.author }}</span>
82
82
+
{% endif %}
83
83
+
</div>
84
84
+
{% endif %}
85
85
+
</header>
85
86
86
86
-
<section class="layout">
87
87
-
<aside class="sidebar">
88
88
-
<div class="panel">
89
89
-
<h2>Browse Categories</h2>
90
90
-
<a class="all-link" href="/">All books</a>
91
91
-
<ul class="category-list">
92
92
-
{% for c in categories %}
93
93
-
<li>
94
94
-
<a class="category-link {% if c.active %}active{% endif %}" href="{{ c.href }}">
95
95
-
<span>{{ c.name }}</span>
96
96
-
<span class="count">{{ c.count }}</span>
97
97
-
</a>
98
98
-
</li>
99
99
-
{% endfor %}
100
100
-
</ul>
101
101
-
</div>
102
102
-
</aside>
87
87
+
<section class="layout">
88
88
+
<aside class="sidebar">
89
89
+
<div class="panel">
90
90
+
<h2>Browse Categories</h2>
91
91
+
<a class="all-link" href="/">All books</a>
92
92
+
<ul class="category-list">
93
93
+
{% for c in categories %}
94
94
+
<li>
95
95
+
<a class="category-link {% if c.active %}active{% endif %}" href="{{ c.href }}">
96
96
+
<span>{{ c.name }}</span>
97
97
+
<span class="count">{{ c.count }}</span>
98
98
+
</a>
99
99
+
</li>
100
100
+
{% endfor %}
101
101
+
</ul>
102
102
+
</div>
103
103
+
</aside>
103
104
104
104
-
<section class="results">
105
105
-
<div class="results-header">
106
106
-
<div>
107
107
-
<h2>{{ view_label }}</h2>
108
108
-
<p class="subtle">{{ results_label }}</p>
109
109
-
</div>
110
110
-
{% if total > 0 %}
111
111
-
<p class="subtle">Showing {{ page_start }}-{{ page_end }} of {{ total }}</p>
112
112
-
{% endif %}
105
105
+
<section class="results">
106
106
+
<div class="results-header">
107
107
+
<div>
108
108
+
<h2>{{ view_label }}</h2>
109
109
+
<p class="subtle">{{ results_label }}</p>
113
110
</div>
114
114
-
115
115
-
{% if has_prev || has_next %}
116
116
-
<nav class="pager pager-top">
117
117
-
{% if has_prev %}
118
118
-
<a class="button ghost"
119
119
-
href="/?{{ pager_query }}offset={{ prev_offset }}&limit={{ limit }}">Previous</a>
120
120
-
{% endif %}
121
121
-
<span class="pager-spacer"></span>
122
122
-
{% if has_next %}
123
123
-
<a class="button ghost" href="/?{{ pager_query }}offset={{ next_offset }}&limit={{ limit }}">Next</a>
124
124
-
{% endif %}
125
125
-
</nav>
111
111
+
{% if total > 0 %}
112
112
+
<p class="subtle">Showing {{ page_start }}-{{ page_end }} of {{ total }}</p>
126
113
{% endif %}
114
114
+
</div>
127
115
128
128
-
{% if books.len() == 0 %}
129
129
-
<div class="empty-state">
130
130
-
<p>No books found.</p>
131
131
-
<p class="subtle">Try a different search term or browse a category.</p>
132
132
-
</div>
116
116
+
{% if has_prev || has_next %}
117
117
+
<nav class="pager pager-top">
118
118
+
{% if has_prev %}
119
119
+
<a class="button ghost" href="/?{{ pager_query }}offset={{ prev_offset }}&limit={{ limit }}">Previous</a>
133
120
{% endif %}
121
121
+
<span class="pager-spacer"></span>
122
122
+
{% if has_next %}
123
123
+
<a class="button ghost" href="/?{{ pager_query }}offset={{ next_offset }}&limit={{ limit }}">Next</a>
124
124
+
{% endif %}
125
125
+
</nav>
126
126
+
{% endif %}
134
127
135
135
-
<div class="card-grid icon-grid">
136
136
-
{% for book in books %}
137
137
-
<article class="book-tile">
138
138
-
<a class="book-icon" href="{{ book.detail_href }}" aria-label="Open {{ book.title }}">
139
139
-
<span class="enchanted">
140
140
-
<img class="item" src="/assets/image/{{ texture_kind }}/written_book.webp" alt="">
141
141
-
</span>
142
142
-
</a>
143
143
-
<h3 class="font-minecraft">{{ book.title }}</h3>
144
144
-
<p class="meta">by <a href="{{ book.author_href }}">{{ book.author }}</a></p>
145
145
-
</article>
146
146
-
{% endfor %}
147
147
-
</div>
128
128
+
{% if books.len() == 0 %}
129
129
+
<div class="empty-state">
130
130
+
<p>No books found.</p>
131
131
+
<p class="subtle">Try a different search term or browse a category.</p>
132
132
+
</div>
133
133
+
{% endif %}
148
134
149
149
-
{% if has_prev || has_next %}
150
150
-
<nav class="pager">
151
151
-
{% if has_prev %}
152
152
-
<a class="button ghost"
153
153
-
href="/?{{ pager_query }}offset={{ prev_offset }}&limit={{ limit }}">Previous</a>
154
154
-
{% endif %}
155
155
-
<span class="pager-spacer"></span>
156
156
-
{% if has_next %}
157
157
-
<a class="button ghost" href="/?{{ pager_query }}offset={{ next_offset }}&limit={{ limit }}">Next</a>
158
158
-
{% endif %}
159
159
-
</nav>
135
135
+
<div class="card-grid icon-grid">
136
136
+
{% for book in books %}
137
137
+
<article class="book-tile">
138
138
+
<a class="book-icon" href="{{ book.detail_href }}" aria-label="Open {{ book.title }}">
139
139
+
<span class="enchanted">
140
140
+
<img class="item" src="/assets/image/{{ texture_kind }}/written_book.webp" alt="">
141
141
+
</span>
142
142
+
</a>
143
143
+
<h3 class="font-minecraft">{{ book.title }}</h3>
144
144
+
<p class="meta">by <a href="{{ book.author_href }}">{{ book.author }}</a></p>
145
145
+
</article>
146
146
+
{% endfor %}
147
147
+
</div>
148
148
+
149
149
+
{% if has_prev || has_next %}
150
150
+
<nav class="pager">
151
151
+
{% if has_prev %}
152
152
+
<a class="button ghost" href="/?{{ pager_query }}offset={{ prev_offset }}&limit={{ limit }}">Previous</a>
160
153
{% endif %}
161
161
-
</section>
154
154
+
<span class="pager-spacer"></span>
155
155
+
{% if has_next %}
156
156
+
<a class="button ghost" href="/?{{ pager_query }}offset={{ next_offset }}&limit={{ limit }}">Next</a>
157
157
+
{% endif %}
158
158
+
</nav>
159
159
+
{% endif %}
162
160
</section>
163
163
-
164
164
-
<footer class="footer">
165
165
-
<p class="subtle">build <a
166
166
-
href="https://tangled.org/did:plc:uthy5qqccx3hdwxo7sriplmh/nara/commit/{{ git_hash }}">{{
167
167
-
&git_hash[0..6] }}</a></p>
168
168
-
</footer>
169
169
-
</main>
161
161
+
</section>
170
162
{% endblock %}