Files: 30c0128a864b5c20c2b5f87e29a40f0c8e230a06 / generator / templates / entry.py
9622 bytesRaw
1 | import marko |
2 | |
3 | import common |
4 | |
5 | |
6 | def links_to_nearby_entries(id): |
7 | earlier_entries = [ |
8 | e for e in reversed(list(common.entries)[: list(common.entries).index(id)]) |
9 | ] |
10 | later_entries = [ |
11 | e for e in list(common.entries)[1 + list(common.entries).index(id) :] |
12 | ] |
13 | relevant_earlier_entries = {} |
14 | relevant_later_entries = {} |
15 | for other_entry in earlier_entries: |
16 | if earlier_entries.index(other_entry) == 0: |
17 | relevant_earlier_entries[other_entry] = relevant_earlier_entries.get( |
18 | other_entry, {} |
19 | ) |
20 | relevant_earlier_entries[other_entry].update({"rel": "prev"}) |
21 | if "series" in common.entries[id] and "series" in common.entries[other_entry]: |
22 | if common.slugify(common.entries[id]["series"]) == common.slugify( |
23 | common.entries[other_entry]["series"] |
24 | ): |
25 | if other_entry == common.offset_id( |
26 | common.entries_in_series(common.entries[id]["series"]), id, -1 |
27 | ): |
28 | relevant_earlier_entries[ |
29 | other_entry |
30 | ] = relevant_earlier_entries.get(other_entry, {}) |
31 | relevant_earlier_entries[other_entry].update({"rel": "prev"}) |
32 | if "tags" in common.entries[id] and "tags" in common.entries[other_entry]: |
33 | for tag_string in [ |
34 | tag_string |
35 | for tag_string in common.entries[id]["tags"] |
36 | if common.slugify(tag_string) |
37 | in map(common.slugify, common.entries[other_entry]["tags"]) |
38 | ]: |
39 | entries_with_this_tag = common.entries_with_tag(tag_string) |
40 | if other_entry == common.offset_id(entries_with_this_tag, id, -1): |
41 | relevant_earlier_entries[ |
42 | other_entry |
43 | ] = relevant_earlier_entries.get(other_entry, {}) |
44 | relevant_earlier_entries[other_entry][ |
45 | "labels" |
46 | ] = relevant_earlier_entries[other_entry].get("labels", []) |
47 | relevant_earlier_entries[other_entry]["labels"] += [tag_string] |
48 | relevant_earlier_entries[other_entry].update({"rel": "prev"}) |
49 | for other_entry in later_entries: |
50 | if later_entries.index(other_entry) == 0: |
51 | relevant_later_entries[other_entry] = relevant_later_entries.get( |
52 | other_entry, {} |
53 | ) |
54 | relevant_later_entries[other_entry].update({"rel": "next"}) |
55 | if "series" in common.entries[id] and "series" in common.entries[other_entry]: |
56 | if common.slugify(common.entries[id]["series"]) == common.slugify( |
57 | common.entries[other_entry]["series"] |
58 | ): |
59 | if other_entry == common.offset_id( |
60 | common.entries_in_series(common.entries[id]["series"]), id, +1 |
61 | ): |
62 | relevant_later_entries[other_entry] = relevant_later_entries.get( |
63 | other_entry, {} |
64 | ) |
65 | relevant_later_entries[other_entry].update({"rel": "next"}) |
66 | if "tags" in common.entries[id] and "tags" in common.entries[other_entry]: |
67 | for tag_string in [ |
68 | tag_string |
69 | for tag_string in common.entries[id]["tags"] |
70 | if common.slugify(tag_string) |
71 | in map(common.slugify, common.entries[other_entry]["tags"]) |
72 | ]: |
73 | entries_with_this_tag = common.entries_with_tag(tag_string) |
74 | if other_entry == common.offset_id(entries_with_this_tag, id, +1): |
75 | relevant_later_entries[other_entry] = relevant_later_entries.get( |
76 | other_entry, {} |
77 | ) |
78 | relevant_later_entries[other_entry][ |
79 | "labels" |
80 | ] = relevant_later_entries[other_entry].get("labels", []) |
81 | relevant_later_entries[other_entry]["labels"] += [tag_string] |
82 | relevant_later_entries[other_entry].update({"rel": "next"}) |
83 | links = "" |
84 | if len(relevant_earlier_entries) > 0: |
85 | links += ( |
86 | "<h2>Earlier:</h2>" |
87 | + "<ul>" |
88 | + "".join( |
89 | "<li>" |
90 | + common.link_to_entry(other_id, **relevant_earlier_entries[other_id]) |
91 | + "</li>" |
92 | for other_id in relevant_earlier_entries |
93 | ) |
94 | + "</ul>" |
95 | ) |
96 | if len(relevant_later_entries) > 0: |
97 | links += ( |
98 | "<h2>Later:</h2>" |
99 | + "<ul>" |
100 | + "".join( |
101 | "<li>" |
102 | + common.link_to_entry(other_id, **relevant_later_entries[other_id]) |
103 | + "</li>" |
104 | for other_id in relevant_later_entries |
105 | ) |
106 | + "</ul>" |
107 | ) |
108 | return links |
109 | |
110 | |
111 | def html(entries, id): |
112 | entry = entries[id] |
113 | byline = ( |
114 | ( |
115 | '<div class="series">' |
116 | + "from " |
117 | + f'<a href="{common.url_of_series(entry["series"])}">' |
118 | + entry["series"] |
119 | + "</a>" |
120 | + "</div>" |
121 | if "series" in entry |
122 | else "" |
123 | ) |
124 | + '<div class="byline">' |
125 | + 'by <a href="/">Grey Nicholson</a>' |
126 | + "</div>" |
127 | + '<div class="datestamp">' |
128 | + ("published " if "modified" in entry else "") |
129 | + f'<time datetime="{entry["date"]:%Y-%m-%dT%H:%MZ}">' |
130 | f'{entry["date"]:%Y-%m-%d}' |
131 | " · " |
132 | f'stardate {common.stardate(entry["date"])}' |
133 | "</time>" |
134 | + ( |
135 | "<div>" |
136 | + "edited " |
137 | + f'<time datetime="{entry["modified"]:%Y-%m-%dT%H:%MZ}">' |
138 | + f'{entry["modified"]:%Y-%m-%d}' |
139 | + " · " |
140 | + f'stardate {common.stardate(entry["modified"])}' |
141 | + "</time>" |
142 | + "</div>" |
143 | if "modified" in entry |
144 | else "" |
145 | ) |
146 | + "</div>" |
147 | ) |
148 | colour_class = ( |
149 | common.slugify(entry["series"]) |
150 | if "series" in entry |
151 | else f'month-{entry["date"].month:02d}' |
152 | ) |
153 | decoration = ( |
154 | f"""<div class="decoration" style="background-image: url('{entry["image"]["filename"]}');""" |
155 | + ( |
156 | f""" background-position: {entry["image"]["position"]};""" |
157 | if "position" in entry["image"] |
158 | else "" |
159 | ) |
160 | + ( |
161 | f""" height: {entry["image"]["height"]};""" |
162 | if "height" in entry["image"] |
163 | else "" |
164 | ) |
165 | + '"></div>' |
166 | if "image" in entry |
167 | else '<div class="decoration"></div>' |
168 | if "series" in entry |
169 | else "" |
170 | ) |
171 | description = ( |
172 | ('<div class="description">' + marko.convert(entry["description"]) + "</div>") |
173 | if "description" in entry |
174 | else "" |
175 | ) |
176 | entry_links = ( |
177 | ( |
178 | "<hr/>" |
179 | + "<nav>" |
180 | + "<h2>See also:</h2>" |
181 | + "<ul>" |
182 | + "".join( |
183 | ("<li>" + common.link_with_details(**link) + "</li>") |
184 | for link in entry["links"] |
185 | ) |
186 | + "</ul>" |
187 | + "</nav>" |
188 | ) |
189 | if "links" in entry |
190 | else "" |
191 | ) |
192 | |
193 | repeated_tags = ( |
194 | list( |
195 | common.slugify(tag) |
196 | for tag in entry["tags"] |
197 | if common.slugify(tag) in common.repeated_tags |
198 | ) |
199 | if "tags" in entry |
200 | else [] |
201 | ) |
202 | head = "".join( |
203 | f"""<link href="{common.url_of_tag_feed(tag)}" rel="alternate" type="application/atom+xml" title="{common.title(tag)}">""" |
204 | + "\n" |
205 | for tag in repeated_tags |
206 | ) |
207 | small = "<p><small>" + entry["small"] + "</small></p>" if "small" in entry else "" |
208 | tags = ( |
209 | ( |
210 | '<div class="tags">tags: ' |
211 | + ", ".join( |
212 | f'<a href="{common.url_of_tag(tag)}" rel="tag">' + tag + "</a>" |
213 | for tag in repeated_tags |
214 | ) |
215 | + "</ul>" |
216 | + "</div>" |
217 | ) |
218 | if repeated_tags |
219 | else "" |
220 | ) |
221 | tags = "" # No tags for now |
222 | |
223 | return common.print_html( |
224 | f"""<!doctype html> |
225 | <html> |
226 | <head> |
227 | {common.head} |
228 | {head} |
229 | <title>{entry['title']}</title> |
230 | </head> |
231 | <body class="entry {colour_class}"> |
232 | <article> |
233 | <header> |
234 | {decoration} |
235 | <h1>{entry['title']}</h1> |
236 | </header> |
237 | <main> |
238 | <hr/> |
239 | <section> |
240 | {marko.convert(entry.content)} |
241 | </section> |
242 | <footer> |
243 | <hr/> |
244 | <section> |
245 | {byline} |
246 | {description} |
247 | {tags} |
248 | {small} |
249 | </section> |
250 | {entry_links} |
251 | </footer> |
252 | </main> |
253 | </article> |
254 | <footer> |
255 | <hr/> |
256 | <nav> |
257 | {links_to_nearby_entries(id)} |
258 | </nav> |
259 | </footer> |
260 | {common.footer} |
261 | </body> |
262 | </html> |
263 | """ |
264 | ) |
265 |
Built with git-ssb-web