Skip to content

Commit 620ad22

Browse files
committed
What is html templating even about bro 💀
1 parent 907c088 commit 620ad22

6 files changed

Lines changed: 262 additions & 92 deletions

File tree

‎crates/wordbase-cli/src/query.rs‎

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,27 @@ pub async fn render(engine: &Engine, profile: &Profile, text: &str) -> Result<()
3030
.render_html_body(
3131
&records,
3232
&RenderConfig {
33-
s_add_note: "Add Card".into(),
34-
fn_add_note: Some("unimplemented({{ js_headword }}, {{ js_reading }})".into()),
33+
s_add_note: "Add Note".into(),
34+
s_view_note: "View note in Anki".into(),
35+
s_add_duplicate_note: "Add duplicate note".into(),
36+
fn_note_exists: "
37+
<js_callback>(window.wordbase.note_exists({
38+
headword: <js_headword>,
39+
reading: <js_reading>,
40+
}))"
41+
.into(),
42+
fn_add_note: "
43+
window.wordbase.add_note({
44+
headword: <js_headword>,
45+
reading: <js_reading>,
46+
})"
47+
.into(),
48+
fn_view_note: "
49+
window.wordbase.view_note({
50+
headword: <js_headword>,
51+
reading: <js_reading>,
52+
})"
53+
.into(),
3554
},
3655
)
3756
.context("failed to render HTML")?;

‎crates/wordbase/src/records.html‎

Lines changed: 93 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,14 @@
254254

255255
{{ self::style() }}
256256

257+
<script>
258+
function show_with_class(script, class_name) {
259+
Array.from(script.parentNode.children)
260+
.filter(el => el.classList && el.classList.contains(class_name))
261+
.forEach(el => el.style.display = "flex");
262+
}
263+
</script>
264+
257265
<div style="display: none">
258266
<svg
259267
id="speakers-symbolic"
@@ -265,6 +273,33 @@
265273
fill="currentColor"
266274
/>
267275
</svg>
276+
277+
<svg
278+
id="bookmark-outline-symbolic"
279+
xmlns="http://www.w3.org/2000/svg"
280+
viewBox="0 0 16 16"
281+
>
282+
<path d="m 5.019531 0 c -1.332031 0 -2.273437 0.816406 -2.644531 1.554688 c -0.371094 0.738281 -0.355469 1.445312 -0.355469 1.445312 l 0.03125 12.472656 l 5.996094 -2.402344 l 6.003906 2.402344 l -0.03125 -12.476562 c 0 -0.003906 0.011719 -0.707032 -0.355469 -1.441406 c -0.371093 -0.738282 -1.3125 -1.554688 -2.644531 -1.554688 z m 0 2 h 6 c 0.695313 0.011719 1.003907 0.367188 1 1 l 0.023438 9.519531 l -3.996094 -1.601562 l -4.003906 1.601562 l -0.023438 -9.523437 c -0.007812 -0.648438 0.398438 -0.996094 1 -0.996094 z m 0 0"
283+
fill="currentColor"/>
284+
</svg>
285+
286+
<svg
287+
id="bookmark-filled-symbolic"
288+
xmlns="http://www.w3.org/2000/svg"
289+
viewBox="0 0 16 16"
290+
>
291+
<path d="m 5.019531 0 c -1.332031 0 -2.273437 0.816406 -2.644531 1.554688 c -0.371094 0.738281 -0.355469 1.445312 -0.355469 1.445312 l 0.03125 12.472656 l 5.996094 -2.402344 l 6.003906 2.402344 l -0.03125 -12.476562 c 0 -0.003906 0.011719 -0.707032 -0.355469 -1.441406 c -0.371093 -0.738282 -1.3125 -1.554688 -2.644531 -1.554688 z m 0 0"
292+
fill="currentColor"/>
293+
</svg>
294+
295+
<svg
296+
id="copy-symbolic"
297+
xmlns="http://www.w3.org/2000/svg"
298+
viewBox="0 0 16 16"
299+
>
300+
<path d="m 0 3 c 0 -1.644531 1.355469 -3 3 -3 h 5 c 1.644531 0 3 1.355469 3 3 c 0 0.550781 -0.449219 1 -1 1 s -1 -0.449219 -1 -1 c 0 -0.570312 -0.429688 -1 -1 -1 h -5 c -0.570312 0 -1 0.429688 -1 1 v 5 c 0 0.570312 0.429688 1 1 1 c 0.550781 0 1 0.449219 1 1 s -0.449219 1 -1 1 c -1.644531 0 -3 -1.355469 -3 -3 z m 5 5 c 0 -1.644531 1.355469 -3 3 -3 h 5 c 1.644531 0 3 1.355469 3 3 v 5 c 0 1.644531 -1.355469 3 -3 3 h -5 c -1.644531 0 -3 -1.355469 -3 -3 z m 2 0 v 5 c 0 0.570312 0.429688 1 1 1 h 5 c 0.570312 0 1 -0.429688 1 -1 v -5 c 0 -0.570312 -0.429688 -1 -1 -1 h -5 c -0.570312 0 -1 0.429688 -1 1 z m 0 0"
301+
fill="currentColor"/>
302+
</svg>
268303
</div>
269304

270305
<div style="display: flex; flex-direction: column; gap: 32px">
@@ -273,7 +308,7 @@
273308
<div class="header">
274309
<div
275310
class="content"
276-
style="width: 100%; display: flex; flex-direction: row; gap: 16px"
311+
style="width: 100%; display: flex; flex-direction: row; gap: 16px; align-items: center"
277312
>
278313
<div style="padding: 16px 0; font-size: 2em; flex: 1">
279314
<ruby>
@@ -283,10 +318,7 @@
283318
</ruby>
284319
</div>
285320

286-
{% if config.fn_add_note %}
287-
<div
288-
style="display: flex; flex-direction: column; justify-content: center"
289-
>
321+
<div style="display: flex; flex-direction: column; gap: 8px">
290322
<!--
291323
{% if group.term.headword %}
292324
{% set js_headword = group.term.headword | addslashes %}
@@ -301,15 +333,64 @@
301333
{% else %}
302334
{% set js_reading = "null" %}
303335
{% endif %}
336+
337+
{% set fn_note_exists = config.fn_note_exists | replace(from="<js_headword>", to=js_headword) | replace(from="<js_reading>", to=js_reading) %}
338+
{% set fn_add_note = config.fn_add_note | replace(from="<js_headword>", to=js_headword) | replace(from="<js_reading>", to=js_reading) %}
339+
{% set fn_view_note = config.fn_view_note | replace(from="<js_headword>", to=js_headword) | replace(from="<js_reading>", to=js_reading) %}
304340
-->
305-
<button
306-
class="suggested-action"
307-
onclick="{{ config.fn_add_note | replace(from="<js_headword>", to=js_headword) | replace(from="<js_reading>", to=js_reading) }}"
308-
>
309-
{{ config.s_add_note }}
310-
</button>
341+
342+
<div hidden class="add-note">
343+
<button
344+
class="suggested-action"
345+
onclick="{{ fn_add_note | safe }}"
346+
>
347+
<svg class="icon">
348+
<use href="#bookmark-outline-symbolic"></use>
349+
</svg>
350+
{{ config.s_add_note }}
351+
</button>
352+
</div>
353+
354+
<div hidden class="note-actions">
355+
<div style="display: flex; flex-direction: row; gap: 8px">
356+
<button
357+
title="{{ config.s_view_note }}"
358+
onclick="{{ fn_view_note | safe }}"
359+
style="flex: 1"
360+
>
361+
<svg class="icon">
362+
<use href="#bookmark-filled-symbolic"></use>
363+
</svg>
364+
</button>
365+
366+
<button
367+
title="{{ config.s_add_duplicate_note }}"
368+
onclick="{{ fn_add_note | safe }}"
369+
style="flex: 1"
370+
>
371+
<svg class="icon">
372+
<use href="#copy-symbolic"></use>
373+
</svg>
374+
</button>
375+
</div>
376+
</div>
377+
378+
<script>
379+
{
380+
const script = document.currentScript;
381+
382+
const note_exists_callback = exists => {
383+
if (exists) {
384+
show_with_class(script, 'note-actions')
385+
} else {
386+
show_with_class(script, 'add-note')
387+
}
388+
};
389+
390+
{{ fn_note_exists | replace(from="<js_callback>", to="note_exists_callback") | safe }};
391+
}
392+
</script>
311393
</div>
312-
{% endif %}
313394
</div>
314395
</div>
315396

‎crates/wordbase/src/render.rs‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,18 @@ impl Engine {
6666
pub struct RenderConfig {
6767
/// Translated text string "Add Note".
6868
pub s_add_note: String,
69-
/// Template for calling a JS function to add a note for a given term.
69+
pub s_view_note: String,
70+
pub s_add_duplicate_note: String,
71+
/// Template for calling a JS function to check if an Anki note exists for a
72+
/// given term.
73+
///
74+
/// # Examples
75+
///
76+
/// ```text
77+
/// Wordbase.note_exists(<js_headword>, <js_reading>)
78+
/// ```
79+
pub fn_note_exists: String,
80+
/// Template for calling a JS function to add an Anki note for a given term.
7081
///
7182
/// # Examples
7283
///
@@ -80,7 +91,8 @@ pub struct RenderConfig {
8091
/// { headword: <js_headword>, reading: <js_reading> },
8192
/// )
8293
/// ```
83-
pub fn_add_note: Option<String>,
94+
pub fn_add_note: String,
95+
pub fn_view_note: String,
8496
}
8597

8698
pub fn group_terms(entries: &[RecordEntry]) -> Vec<RecordTerm> {

0 commit comments

Comments
 (0)