Plume/templates/posts/new.rs.html
Baptiste Gelez 9076dbaadc
New editor (#458)
With this PR, when JS is activated and WASM supported, the article editor will be dynamically replaced with `contenteditable`s elements. This makes the editing interface simpler and less like a regular form. It will also allow us to easily add visual formatting with native browser APIs (and to insert images or videos directly). Here is a little demo:

![peek 05-03-2019 16-12](https://user-images.githubusercontent.com/16254623/53815536-1dc05680-3f62-11e9-94d3-b363ed84eb97.gif)

There is still a lot to do, but it is a good first step.

Fixes #255
2019-03-15 16:06:10 +01:00

78 lines
3.5 KiB
HTML

@use templates::base;
@use template_utils::*;
@use validator::{ValidationErrors, ValidationErrorsKind};
@use std::borrow::Cow;
@use plume_models::medias::*;
@use plume_models::blogs::Blog;
@use plume_models::posts::Post;
@use routes::posts::NewPostForm;
@use routes::*;
@(ctx: BaseContext, title: String, blog: Blog, editing: bool, form: &NewPostForm, is_draft: bool, article: Option<Post>, errors: ValidationErrors, medias: Vec<Media>, content_len: u64)
@:base(ctx, title.clone(), {}, {}, {
<h1 id="plume-editor-title">@title</h1>
<div id="plume-editor" style="display: none;">
<header>
<button id="publish" class="button">@i18n!(ctx.1, "Publish")</button>
<p id="char-count">@content_len</p>
</header>
</div>
@if let Some(article) = article {
<form id="plume-fallback-editor" class="new-post" method="post" action="@uri!(posts::update: blog = blog.actor_id, slug = &article.slug)" content-size="@content_len">
} else {
<form id="plume-fallback-editor" class="new-post" method="post" action="@uri!(posts::new: blog = blog.actor_id)" content-size="@content_len">
}
@input!(ctx.1, title (text), "Title", form, errors.clone(), "required")
@input!(ctx.1, subtitle (optional text), "Subtitle", form, errors.clone(), "")
@if let Some(ValidationErrorsKind::Field(errs)) = errors.clone().errors().get("content") {
@format!(r#"<p class="error">{}</p>"#, errs[0].message.clone().unwrap_or(Cow::from("Unknown error")))
}
<label for="editor-content">@i18n!(ctx.1, "Content")<small>@i18n!(ctx.1, "Markdown syntax is supported")</small></label>
<textarea id="editor-content" name="content" rows="20">@Html(&form.content)</textarea>
<small id="editor-left">@content_len</small>
<p>
@i18n!(ctx.1, "You can upload medias to your gallery, and copy their Markdown code in your articles to insert them.")
<a href="@uri!(medias::new)">@i18n!(ctx.1, "Upload media")</a>
</p>
@input!(ctx.1, tags (optional text), "Tags, separated by commas", form, errors.clone(), "")
@input!(ctx.1, license (optional text), "License", "Leave it empty to reserve all rights", form, errors, "")
<label for="cover">@i18n!(ctx.1, "Illustration")<small>@i18n!(ctx.1, "Optional")</small></label>
<select id="cover" name="cover">
<option value="none" @if form.cover.is_none() { selected }>@i18n!(ctx.1, "None")</option>
@for media in medias {
@if media.category() == MediaCategory::Image {
<option value="@media.id" @if form.cover.map(|c| c == media.id).unwrap_or(false) { selected }>
@if !media.alt_text.is_empty() {
@media.alt_text
} else {
@media.content_warning.unwrap_or_default()
}
</option>
}
}
</select>
@if is_draft {
<label for="draft">
<input type="checkbox" name="draft" id="draft" checked>
@i18n!(ctx.1, "This is a draft, don't publish it yet.")
</label>
}
@if editing {
<input type="submit" value="@i18n!(ctx.1, "Update")" />
} else {
@if is_draft {
<input type="submit" value="@i18n!(ctx.1, "Update, or publish")" />
} else {
<input type="submit" value="@i18n!(ctx.1, "Publish your post")" />
}
}
</form>
})