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