config: simplification of some options, moved into html template
This commit is contained in:
parent
3f46b7669d
commit
c70c4449fc
6 changed files with 74 additions and 52 deletions
20
.env.example
20
.env.example
|
|
@ -69,20 +69,26 @@
|
||||||
# .entry-name, .entry-website, .entry-body
|
# .entry-name, .entry-website, .entry-body
|
||||||
# BOOK_STYLE=
|
# BOOK_STYLE=
|
||||||
|
|
||||||
# Text shown above the form. Empty by default.
|
|
||||||
# BOOK_FORM_PROMPT=Thanks for visiting. Sign the guestbook!
|
|
||||||
|
|
||||||
# Submit button text.
|
# Submit button text.
|
||||||
# BOOK_BUTTON_TEXT=sign
|
# BOOK_BUTTON_TEXT=Submit Entry
|
||||||
|
|
||||||
# Label for the name field.
|
# Label for the name field.
|
||||||
# BOOK_LABEL_NAME=name
|
# BOOK_LABEL_NAME=Your name
|
||||||
|
|
||||||
# Label for the website field.
|
# Label for the website field.
|
||||||
# BOOK_LABEL_WEBSITE=website (optional)
|
# BOOK_LABEL_WEBSITE=Link a website (optional)
|
||||||
|
|
||||||
# Label for the message field.
|
# Label for the message field.
|
||||||
# BOOK_LABEL_MESSAGE=message
|
# BOOK_LABEL_MESSAGE=Leave a message (optional)
|
||||||
|
|
||||||
|
# Label for the drawing field (when BOOK_ENABLE_DRAWINGS=true).
|
||||||
|
# BOOK_LABEL_DRAWING=Leave a drawing (optional)
|
||||||
|
|
||||||
|
# Label for the voice note field (when BOOK_ENABLE_VOICE_NOTES=true).
|
||||||
|
# BOOK_LABEL_VOICE_NOTE=Leave a voice note (optional)
|
||||||
|
|
||||||
|
# Initial text on the voice note record button.
|
||||||
|
# BOOK_VOICE_NOTE_RECORD_TEXT=Start recording
|
||||||
|
|
||||||
# Message textarea width in pixels.
|
# Message textarea width in pixels.
|
||||||
# BOOK_TEXTAREA_WIDTH=320
|
# BOOK_TEXTAREA_WIDTH=320
|
||||||
|
|
|
||||||
42
module.nix
42
module.nix
|
|
@ -249,35 +249,47 @@ in
|
||||||
description = "Custom success page template with {{title}} and {{style}} placeholders. Uses built-in default if null.";
|
description = "Custom success page template with {{title}} and {{style}} placeholders. Uses built-in default if null.";
|
||||||
};
|
};
|
||||||
|
|
||||||
greeting = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "";
|
|
||||||
description = "Text shown above the form.";
|
|
||||||
};
|
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
submit = mkOption {
|
submit = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "sign";
|
default = "Submit Entry";
|
||||||
description = "Submit button text.";
|
description = "Submit button text.";
|
||||||
};
|
};
|
||||||
|
|
||||||
name = mkOption {
|
name = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "name";
|
default = "Your name";
|
||||||
description = "Label for the name field (used as both screen-reader label and placeholder).";
|
description = "Label for the name field.";
|
||||||
};
|
};
|
||||||
|
|
||||||
website = mkOption {
|
website = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "website (optional)";
|
default = "Link a website (optional)";
|
||||||
description = "Label for the website field (used as both screen-reader label and placeholder).";
|
description = "Label for the website field.";
|
||||||
};
|
};
|
||||||
|
|
||||||
message = mkOption {
|
message = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "message";
|
default = "Leave a message (optional)";
|
||||||
description = "Label for the message field (used as both screen-reader label and placeholder).";
|
description = "Label for the message field.";
|
||||||
|
};
|
||||||
|
|
||||||
|
drawing = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "Leave a drawing (optional)";
|
||||||
|
description = "Label for the drawing field (when drawing.enable=true).";
|
||||||
|
};
|
||||||
|
|
||||||
|
voiceNote = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "Leave a voice note (optional)";
|
||||||
|
description = "Label for the voice note field (when voiceNote.enable=true).";
|
||||||
|
};
|
||||||
|
|
||||||
|
voiceNoteRecord = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "Start recording";
|
||||||
|
description = "Initial text on the voice note record button.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -323,11 +335,13 @@ in
|
||||||
BOOK_MAX_MESSAGE_LENGTH = toString cfg.limits.message;
|
BOOK_MAX_MESSAGE_LENGTH = toString cfg.limits.message;
|
||||||
BOOK_MAX_WEBSITE_LENGTH = toString cfg.limits.website;
|
BOOK_MAX_WEBSITE_LENGTH = toString cfg.limits.website;
|
||||||
BOOK_STYLE = cfg.styles.css;
|
BOOK_STYLE = cfg.styles.css;
|
||||||
BOOK_FORM_PROMPT = cfg.styles.greeting;
|
|
||||||
BOOK_BUTTON_TEXT = cfg.styles.labels.submit;
|
BOOK_BUTTON_TEXT = cfg.styles.labels.submit;
|
||||||
BOOK_LABEL_NAME = cfg.styles.labels.name;
|
BOOK_LABEL_NAME = cfg.styles.labels.name;
|
||||||
BOOK_LABEL_WEBSITE = cfg.styles.labels.website;
|
BOOK_LABEL_WEBSITE = cfg.styles.labels.website;
|
||||||
BOOK_LABEL_MESSAGE = cfg.styles.labels.message;
|
BOOK_LABEL_MESSAGE = cfg.styles.labels.message;
|
||||||
|
BOOK_LABEL_DRAWING = cfg.styles.labels.drawing;
|
||||||
|
BOOK_LABEL_VOICE_NOTE = cfg.styles.labels.voiceNote;
|
||||||
|
BOOK_VOICE_NOTE_RECORD_TEXT = cfg.styles.labels.voiceNoteRecord;
|
||||||
BOOK_CANVAS_WIDTH = toString cfg.features.drawing.canvasWidth;
|
BOOK_CANVAS_WIDTH = toString cfg.features.drawing.canvasWidth;
|
||||||
BOOK_CANVAS_HEIGHT = toString cfg.features.drawing.canvasHeight;
|
BOOK_CANVAS_HEIGHT = toString cfg.features.drawing.canvasHeight;
|
||||||
BOOK_ENABLE_VOICE_NOTES = if cfg.features.voiceNote.enable then "true" else "false";
|
BOOK_ENABLE_VOICE_NOTES = if cfg.features.voiceNote.enable then "true" else "false";
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,13 @@ pub struct Config {
|
||||||
pub template: Option<String>,
|
pub template: Option<String>,
|
||||||
pub success_template: Option<String>,
|
pub success_template: Option<String>,
|
||||||
pub style: String,
|
pub style: String,
|
||||||
pub form_prompt: String,
|
|
||||||
pub button_text: String,
|
pub button_text: String,
|
||||||
pub label_name: String,
|
pub label_name: String,
|
||||||
pub label_website: String,
|
pub label_website: String,
|
||||||
pub label_message: String,
|
pub label_message: String,
|
||||||
|
pub label_drawing: String,
|
||||||
|
pub label_voice_note: String,
|
||||||
|
pub voice_note_record_text: String,
|
||||||
pub textarea_width: u32,
|
pub textarea_width: u32,
|
||||||
pub textarea_height: u32,
|
pub textarea_height: u32,
|
||||||
}
|
}
|
||||||
|
|
@ -167,14 +169,19 @@ impl Config {
|
||||||
})
|
})
|
||||||
.or_else(|| env::var("BOOK_STYLE").ok())
|
.or_else(|| env::var("BOOK_STYLE").ok())
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
form_prompt: env::var("BOOK_FORM_PROMPT").unwrap_or_default(),
|
|
||||||
button_text: env::var("BOOK_BUTTON_TEXT")
|
button_text: env::var("BOOK_BUTTON_TEXT")
|
||||||
.unwrap_or_else(|_| "Submit".into()),
|
.unwrap_or_else(|_| "Submit Entry".into()),
|
||||||
label_name: env::var("BOOK_LABEL_NAME").unwrap_or_else(|_| "name".into()),
|
label_name: env::var("BOOK_LABEL_NAME").unwrap_or_else(|_| "Your name".into()),
|
||||||
label_website: env::var("BOOK_LABEL_WEBSITE")
|
label_website: env::var("BOOK_LABEL_WEBSITE")
|
||||||
.unwrap_or_else(|_| "website (optional)".into()),
|
.unwrap_or_else(|_| "Link a website (optional)".into()),
|
||||||
label_message: env::var("BOOK_LABEL_MESSAGE")
|
label_message: env::var("BOOK_LABEL_MESSAGE")
|
||||||
.unwrap_or_else(|_| "message (optional)".into()),
|
.unwrap_or_else(|_| "Leave a message (optional)".into()),
|
||||||
|
label_drawing: env::var("BOOK_LABEL_DRAWING")
|
||||||
|
.unwrap_or_else(|_| "Leave a drawing (optional)".into()),
|
||||||
|
label_voice_note: env::var("BOOK_LABEL_VOICE_NOTE")
|
||||||
|
.unwrap_or_else(|_| "Leave a voice note (optional)".into()),
|
||||||
|
voice_note_record_text: env::var("BOOK_VOICE_NOTE_RECORD_TEXT")
|
||||||
|
.unwrap_or_else(|_| "Start recording".into()),
|
||||||
textarea_width: env::var("BOOK_TEXTAREA_WIDTH")
|
textarea_width: env::var("BOOK_TEXTAREA_WIDTH")
|
||||||
.unwrap_or_else(|_| "320".into())
|
.unwrap_or_else(|_| "320".into())
|
||||||
.parse()
|
.parse()
|
||||||
|
|
|
||||||
|
|
@ -13,17 +13,8 @@ pub fn render_page(template: &str, config: &Config, entries: &[Entry], form_html
|
||||||
&config.style
|
&config.style
|
||||||
};
|
};
|
||||||
let style = format!("<style>\n{css}\n </style>");
|
let style = format!("<style>\n{css}\n </style>");
|
||||||
let prompt = if config.enable_submissions {
|
|
||||||
format!(
|
|
||||||
"<span class=\"guestbook-prompt\">{}</span>",
|
|
||||||
config.form_prompt
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
String::new()
|
|
||||||
};
|
|
||||||
template
|
template
|
||||||
.replace("{{title}}", &config.site_title)
|
.replace("{{title}}", &config.site_title)
|
||||||
.replace("{{prompt}}", &prompt)
|
|
||||||
.replace("{{form}}", form_html)
|
.replace("{{form}}", form_html)
|
||||||
.replace("{{entries}}", &entries_html)
|
.replace("{{entries}}", &entries_html)
|
||||||
.replace("{{style}}", &style)
|
.replace("{{style}}", &style)
|
||||||
|
|
@ -50,7 +41,7 @@ pub fn render_form(config: &Config) -> String {
|
||||||
|
|
||||||
let drawing_section = if config.enable_drawings {
|
let drawing_section = if config.enable_drawings {
|
||||||
format!(
|
format!(
|
||||||
r##"<span class="guestbook-label">drawing (optional)</span>
|
r##"<span class="guestbook-label">{label}</span>
|
||||||
<span class="guestbook-drawing-wrap"><span class="guestbook-drawing-tools"></span><span class="guestbook-drawing-content"></span></span><input type="hidden" name="drawing"><script>(function(){{
|
<span class="guestbook-drawing-wrap"><span class="guestbook-drawing-tools"></span><span class="guestbook-drawing-content"></span></span><input type="hidden" name="drawing"><script>(function(){{
|
||||||
var inl=document.querySelector('.guestbook-drawing-tools'),
|
var inl=document.querySelector('.guestbook-drawing-tools'),
|
||||||
cnt=document.querySelector('.guestbook-drawing-content'),
|
cnt=document.querySelector('.guestbook-drawing-content'),
|
||||||
|
|
@ -102,6 +93,7 @@ pub fn render_form(config: &Config) -> String {
|
||||||
if(px.some(function(v){{return v!==0}})){{hid.value=c.toDataURL('image/png')}}
|
if(px.some(function(v){{return v!==0}})){{hid.value=c.toDataURL('image/png')}}
|
||||||
}});
|
}});
|
||||||
}})();</script>"##,
|
}})();</script>"##,
|
||||||
|
label = config.label_drawing,
|
||||||
w = config.canvas_width,
|
w = config.canvas_width,
|
||||||
h = config.canvas_height,
|
h = config.canvas_height,
|
||||||
)
|
)
|
||||||
|
|
@ -111,7 +103,7 @@ pub fn render_form(config: &Config) -> String {
|
||||||
|
|
||||||
let voice_note_section = if config.enable_voice_notes {
|
let voice_note_section = if config.enable_voice_notes {
|
||||||
format!(
|
format!(
|
||||||
r##"<span class="guestbook-label">voice note (optional)</span>
|
r##"<span class="guestbook-label">{label}</span>
|
||||||
<span class="guestbook-voice-wrap"><span class="guestbook-voice-controls"></span><span class="guestbook-voice-playback"></span></span><input type="hidden" name="voice_note"><script>(function(){{
|
<span class="guestbook-voice-wrap"><span class="guestbook-voice-controls"></span><span class="guestbook-voice-playback"></span></span><input type="hidden" name="voice_note"><script>(function(){{
|
||||||
var maxDur={max_dur};
|
var maxDur={max_dur};
|
||||||
var inl=document.querySelector('.guestbook-voice-controls'),
|
var inl=document.querySelector('.guestbook-voice-controls'),
|
||||||
|
|
@ -124,7 +116,7 @@ pub fn render_form(config: &Config) -> String {
|
||||||
rec=null;chunks=[];clearInterval(iv);iv=null;pb.innerHTML='';hid.value='';
|
rec=null;chunks=[];clearInterval(iv);iv=null;pb.innerHTML='';hid.value='';
|
||||||
inl.innerHTML='';
|
inl.innerHTML='';
|
||||||
var a=document.createElement('a');a.href='#';a.className='guestbook-voice-record';
|
var a=document.createElement('a');a.href='#';a.className='guestbook-voice-record';
|
||||||
a.textContent='record';
|
a.textContent='{record}';
|
||||||
a.addEventListener('click',function(e){{e.preventDefault();startRec()}});
|
a.addEventListener('click',function(e){{e.preventDefault();startRec()}});
|
||||||
inl.appendChild(a);
|
inl.appendChild(a);
|
||||||
}}
|
}}
|
||||||
|
|
@ -169,6 +161,8 @@ pub fn render_form(config: &Config) -> String {
|
||||||
}}
|
}}
|
||||||
setInit();
|
setInit();
|
||||||
}})();</script>"##,
|
}})();</script>"##,
|
||||||
|
label = config.label_voice_note,
|
||||||
|
record = config.voice_note_record_text,
|
||||||
max_dur = config.voice_note_max_duration,
|
max_dur = config.voice_note_max_duration,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -176,16 +170,13 @@ pub fn render_form(config: &Config) -> String {
|
||||||
};
|
};
|
||||||
|
|
||||||
format!(
|
format!(
|
||||||
r#"<details class="guestbook-details">
|
r#"<form class="guestbook-form" method="post" action="/submit" accept-charset="UTF-8">
|
||||||
<summary class="guestbook-summary">Leave your own message.</summary>
|
|
||||||
<form class="guestbook-form" method="post" action="/submit" accept-charset="UTF-8">
|
|
||||||
<label class="guestbook-label" for="name">{label_name}</label>
|
<label class="guestbook-label" for="name">{label_name}</label>
|
||||||
<input class="guestbook-input" id="name" name="name" required>
|
<input class="guestbook-input" id="name" name="name" required>
|
||||||
{website_section}<label class="guestbook-label" for="message">{label_message}</label>
|
{website_section}<label class="guestbook-label" for="message">{label_message}</label>
|
||||||
<textarea class="guestbook-textarea" id="message" name="message" style="width:{tw}px;height:{th}px"></textarea>
|
<textarea class="guestbook-textarea" id="message" name="message" style="width:{tw}px;height:{th}px"></textarea>
|
||||||
{drawing_section}{voice_note_section}{captcha_section}<input name="url" aria-hidden="true" style="position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)" tabindex="-1" autocomplete="off"><button class="guestbook-button" type="submit">{button}</button>
|
{drawing_section}{voice_note_section}{captcha_section}<input name="url" aria-hidden="true" style="position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)" tabindex="-1" autocomplete="off"><button class="guestbook-button" type="submit">{button}</button>
|
||||||
</form>
|
</form>"#,
|
||||||
</details>"#,
|
|
||||||
label_name = config.label_name,
|
label_name = config.label_name,
|
||||||
website_section = website_section,
|
website_section = website_section,
|
||||||
label_message = config.label_message,
|
label_message = config.label_message,
|
||||||
|
|
@ -348,11 +339,13 @@ mod tests {
|
||||||
template: None,
|
template: None,
|
||||||
success_template: None,
|
success_template: None,
|
||||||
style: String::new(),
|
style: String::new(),
|
||||||
form_prompt: "Thanks for visiting. Sign the guestbook!".into(),
|
|
||||||
button_text: "sign".into(),
|
button_text: "sign".into(),
|
||||||
label_name: "name".into(),
|
label_name: "name".into(),
|
||||||
label_website: "website (optional)".into(),
|
label_website: "website (optional)".into(),
|
||||||
label_message: "message (optional)".into(),
|
label_message: "message (optional)".into(),
|
||||||
|
label_drawing: "drawing (optional)".into(),
|
||||||
|
label_voice_note: "voice note (optional)".into(),
|
||||||
|
voice_note_record_text: "record".into(),
|
||||||
textarea_width: 400,
|
textarea_width: 400,
|
||||||
textarea_height: 150,
|
textarea_height: 150,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -414,11 +414,13 @@ mod tests {
|
||||||
template: None,
|
template: None,
|
||||||
success_template: None,
|
success_template: None,
|
||||||
style: String::new(),
|
style: String::new(),
|
||||||
form_prompt: "Thanks for visiting. Sign the guestbook!".into(),
|
|
||||||
button_text: "sign".into(),
|
button_text: "sign".into(),
|
||||||
label_name: "name".into(),
|
label_name: "name".into(),
|
||||||
label_website: "website (optional)".into(),
|
label_website: "website (optional)".into(),
|
||||||
label_message: "message (optional)".into(),
|
label_message: "message (optional)".into(),
|
||||||
|
label_drawing: "drawing (optional)".into(),
|
||||||
|
label_voice_note: "voice note (optional)".into(),
|
||||||
|
voice_note_record_text: "record".into(),
|
||||||
textarea_width: 400,
|
textarea_width: 400,
|
||||||
textarea_height: 150,
|
textarea_height: 150,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,11 @@
|
||||||
Available placeholders:
|
Available placeholders:
|
||||||
|
|
||||||
title - Site title (BOOK_SITE_TITLE). Useful in <title> and headings.
|
title - Site title (BOOK_SITE_TITLE). Useful in <title> and headings.
|
||||||
prompt - The form prompt text (BOOK_FORM_PROMPT), wrapped in a
|
|
||||||
<span class="guestbook-prompt">. Empty when submissions
|
|
||||||
are disabled. Place anywhere relative to the form.
|
|
||||||
form - The submission form (labels, inputs, button). Controlled by
|
form - The submission form (labels, inputs, button). Controlled by
|
||||||
BOOK_LABEL_NAME, BOOK_LABEL_WEBSITE, BOOK_LABEL_MESSAGE,
|
BOOK_LABEL_NAME, BOOK_LABEL_WEBSITE, BOOK_LABEL_MESSAGE,
|
||||||
BOOK_BUTTON_TEXT, BOOK_TEXTAREA_WIDTH, BOOK_TEXTAREA_HEIGHT.
|
BOOK_LABEL_DRAWING, BOOK_LABEL_VOICE_NOTE, BOOK_BUTTON_TEXT,
|
||||||
Empty when BOOK_ENABLE_SUBMISSIONS=false.
|
BOOK_TEXTAREA_WIDTH, BOOK_TEXTAREA_HEIGHT. Empty when
|
||||||
|
BOOK_ENABLE_SUBMISSIONS=false.
|
||||||
entries - Approved guestbook entries, newest first.
|
entries - Approved guestbook entries, newest first.
|
||||||
style - Custom CSS from BOOK_STYLE or BOOK_STYLE_FILE, wrapped in
|
style - Custom CSS from BOOK_STYLE or BOOK_STYLE_FILE, wrapped in
|
||||||
a <style> tag. Uses built-in default.css when neither is set.
|
a <style> tag. Uses built-in default.css when neither is set.
|
||||||
|
|
@ -32,8 +30,10 @@
|
||||||
<div class="page-container">
|
<div class="page-container">
|
||||||
<h1>{{title}}</h1>
|
<h1>{{title}}</h1>
|
||||||
|
|
||||||
{{prompt}}
|
<details class="guestbook-details">
|
||||||
|
<summary class="guestbook-summary">Click me to leave an entry</summary>
|
||||||
{{form}}
|
{{form}}
|
||||||
|
</details>
|
||||||
|
|
||||||
<h1>entries</h1>
|
<h1>entries</h1>
|
||||||
{{entries}}
|
{{entries}}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue