hypermedia blog

static site generator

hypermedia blog

src/views/admin/post_editor.html


<title>edit post</title>
<article class="admin edit">
	<header>
		<h2>edit post</h2>
		<h3>{{&title}}</h3>
	</header>
	<form id="edit" {{&form}}>
		<input type="hidden" id="post_id" name="post_id" value="{{&post_id}}" />
		<section class="flex-row">
			<label for="date">date</label>
			<input type="date" id="date" name="date" value="{{&date}}" required onkeydown="return event.key != 'Enter';" />
		</section>
		<section class="flex-row">
			<label for="url">url</label>
			<input type="text" name="url" id="url" value="{{&url}}" maxlength="50" required pattern="[0-9a-z_]+"
				onkeydown="return event.key != 'Enter';" readonly />
			<fieldset hx-on:click="customize()">
				<input type="checkbox" id="custom" />
				<legend>custom?</legend>
				<callout id="url_warn"><i class="nf nf-fa-warning"></i> urls must be alphanumeric, lowercase, and underscored only
				</callout>
			</fieldset>
		</section>
		<section class="flex-row">
			<label for="title">title</label>
			<input type="text" name="title" id="title" value="{{&title}}" maxlength="300" hx-on:keyup="sanitize()" required
				onkeydown="return event.key != 'Enter';" hx-target="#url_warn" />
		</section>
		<section class="flex-row">
			<label for="subtitle">subtitle</label>
			<input type="text" name="subtitle" id="subtitle" value="{{&subtitle}}" maxlength="300" required
				onkeydown="return event.key != 'Enter';" />
		</section>
		<section class="flex-row">
			<label for="excerpt">excerpt</label>
			<textarea id="excerpt" name="excerpt" maxlength="1000" required>{{&excerpt}}</textarea>
		</section>
		<section class="flex-row">
			<label for="content">content</label>
			<textarea id="content" name="content" required>{{&content}}</textarea>
		</section>
		<section class="flex-row">
			<label for="postTags">tags</label>
			<section id="tagCloud">
				<input type="hidden" name="tags" value="" />
				{{&tagcloud}}
			</section>
			<input type="text" list="tags" id="postTags" name="postTags" hx-on:change="tagChange()"
				placeholder="add tags..." onkeydown="return event.key != 'Enter';" />
			<datalist id="tags">
				{{&tags}}
			</datalist>
		</section>
		<section class="flex-row">
			<label for="postCats">categories</label>
			<section id="pounce">
				<input type="hidden" name="cats" value="" />
				{{&pounce}}
			</section>
			<input type="text" list="cats" id="postCats" name="postCats" hx-on:change="meow()"
				placeholder="add categories..." onkeydown="return event.key != 'Enter';" />
			<datalist id="cats">
				{{&cats}}
			</datalist>
		</section>
		<section class="flex-row">
			<fieldset>
				<label for="live">published</label><br />
				<input type="checkbox" id="live" name="live" {{&live}} />
				<legend>live?</legend>
			</fieldset>
		</section>
		<header>
				<button type="submit" id="submitCaptain">save</button>
				<button id="preview" onclick="previewPost(event)">preview</button>
		</header>
	</form>
</article>
<article class="post" id="previewDOM"></article>
<script>
	function sanitize() {
		if (!htmx.find("#custom").checked) {
			htmx.find("#url").value = htmx.find("#title").value.toString().trim().toLowerCase().replace(/ /g, "_").replace(/[^0-9a-z_]/g, "");
		}
	}
	function customize() {
		htmx.find("#custom").toggleAttribute("checked");
		htmx.find("#url").toggleAttribute("readonly");
		htmx.toggleClass(htmx.find("#url_warn"), "revealed");
		sanitize();
	}
	function meow() {
		let val = htmx.values(htmx.find("#edit"));
		let cat = val["postCats"].toString();
		if (!Object.values(val["cats"]).includes(cat)) {
			htmx.find("#pounce").innerHTML += `<button onclick="remove(event, 'btn${cat}')" id="btn${cat}" class="cat">${cat}<input type="hidden" name="cats" value="${cat}"/></button>`;
		}
		htmx.find("#postCats").value = "";
	}
	function tagChange() {
		let val = htmx.values(htmx.find("#edit"));
		let tag = val["postTags"].toString();
		if (!Object.values(val["tags"]).includes(tag)) {
			htmx.find("#tagCloud").innerHTML += `<button onclick="remove(event, 'btn${tag}')" id="btn${tag}" class="tag">${tag}<input type="hidden" name="tags" value="${tag}"/></button>`;
		}
		htmx.find("#postTags").value = "";
	}
	function remove(e, id) {
		e.preventDefault();
		htmx.find("#" + id).outerHTML = '';
	}
	function previewPost(e) {
		e.preventDefault();
		let dom = htmx.find('#previewDOM');
		let val = htmx.values(htmx.find("#edit"));
		dom.innerHTML = "<header><h2>" + val.title + "</h2><h3>" + val.subtitle + '</h3></header>' + val.content;
	}
</script>

Download

raw zip tar