aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby <[email protected]>2022-09-20 02:03:36 -0400
committerBobby <[email protected]>2022-09-20 02:03:36 -0400
commitc5254b6f39939bc0bc6719b854b67928af74c9ea (patch)
tree692510e10ba5619f70b1b3df23352721cfac7159
parente29f7902c8d6dc6e6ee02964b56284d2f69f1ac5 (diff)
downloadthatcomputerscientist-c5254b6f39939bc0bc6719b854b67928af74c9ea.tar.xz
thatcomputerscientist-c5254b6f39939bc0bc6719b854b67928af74c9ea.zip
Added Edit post function
-rw-r--r--blog_admin/urls.py1
-rw-r--r--blog_admin/views.py37
-rw-r--r--static/css/main.css7
-rw-r--r--templates/blog/post.html7
-rw-r--r--templates/blog_admin/edit_post.html253
-rw-r--r--templates/blog_admin/posts.html2
6 files changed, 302 insertions, 5 deletions
diff --git a/blog_admin/urls.py b/blog_admin/urls.py
index b0710851..a8f6bc49 100644
--- a/blog_admin/urls.py
+++ b/blog_admin/urls.py
@@ -10,6 +10,7 @@ urlpatterns = [
path('posts', views.posts, name='posts'),
path('posts/new', views.new_post, name='new-post'),
path('posts/search', views.posts_search, name='posts-search'),
+ path('posts/<str:slug>/edit', views.edit_post, name='edit-post'),
path('comments', views.comments, name='comments'),
path('categories', views.categories, name='categories'),
path('categories/new', views.new_category, name='new-category'),
diff --git a/blog_admin/views.py b/blog_admin/views.py
index 7732866a..ca107390 100644
--- a/blog_admin/views.py
+++ b/blog_admin/views.py
@@ -43,7 +43,6 @@ def new_post(request):
if request.method == 'POST':
title = request.POST.get('title')
body = request.POST.get('body')
- print(body)
category = request.POST.get('category')
tags = request.POST.get('tags')
slug = request.POST.get('slug')
@@ -69,6 +68,42 @@ def new_post(request):
else:
return redirect('blog:home')
+def edit_post(request, slug):
+ if request.user.is_authenticated and (request.user.is_superuser or request.user.is_staff):
+ categories = Category.objects.all()
+ post = Post.objects.get(slug = slug)
+ if request.method == 'POST':
+ title = request.POST.get('title')
+ body = request.POST.get('body')
+ category = request.POST.get('category')
+ tags = request.POST.get('tags')
+ slug = request.POST.get('slug')
+ if title and body and category and tags and slug:
+ try:
+ category = Category.objects.get(slug = category)
+ tags = tags.split(',')
+ tags = [tag.strip() for tag in tags]
+ tags = [Tag.objects.get_or_create(slug = tag, name = tag)[0] for tag in tags]
+ post.title = title
+ post.body = body
+ post.category = category
+ post.slug = slug
+ post.author = request.user
+ post.tags.set(tags)
+ post.save()
+ messages.success(request, 'Post edited successfully!')
+ return redirect('blog-admin:posts')
+ except Exception as e:
+ messages.error(request, 'Error: {}'.format(e), extra_tags='edit_post_create_error')
+ return render(request, 'blog_admin/edit_post.html', { 'title': 'Edit Post', 'categories': categories, 'blog_title': title, 'blog_body': body, 'blog_category': category, 'blog_tags': tags, 'blog_slug': slug, 'post': post })
+ else:
+ messages.error(request, 'Error: All fields are required!', extra_tags='edit_post_create_error')
+ return render(request, 'blog_admin/edit_post.html', { 'title': 'Edit Post', 'categories': categories, 'blog_title': title, 'blog_body': body, 'blog_category': category, 'blog_tags': tags, 'blog_slug': slug, 'post': post })
+ else:
+ return render(request, 'blog_admin/edit_post.html', { 'title': 'Edit Post', 'categories': categories, 'blog_title': post.title, 'blog_body': post.body, 'blog_category': post.category.slug, 'blog_tags': ','.join([tag.slug for tag in post.tags.all()]), 'blog_slug': post.slug, 'post': post })
+ else:
+ return redirect('blog:home')
+
def comments(request):
pass
diff --git a/static/css/main.css b/static/css/main.css
index 494f3197..9210d2ad 100644
--- a/static/css/main.css
+++ b/static/css/main.css
@@ -253,6 +253,13 @@ summary {
margin-top: 0px;
}
+.article-body > p > img {
+ display: block;
+ margin: 0px auto 10px auto;
+ max-height: 50vh;
+ max-width: 100%;
+}
+
/* Optimize for phones */
@media only screen and (max-width: 480px) {
body {
diff --git a/templates/blog/post.html b/templates/blog/post.html
index 0fe9ee07..948ebb95 100644
--- a/templates/blog/post.html
+++ b/templates/blog/post.html
@@ -1,6 +1,6 @@
{% extends 'blog/partials/base.html' %} {% block content %}
<div class="main">
- <section>
+ <article>
<h1 style="margin-bottom: 12px">{{ post.title }}</h1>
<p style="line-height: 1.6em;">
Posted on <em><u>{{ post.date | date:"M d, Y" }}</u></em> by <em><a href="#">{{ post.author }}</a> in <a href="#">{{ post.category }}</a></em>
@@ -12,7 +12,7 @@
</p>
<hr>
- <div>{{ post.body | safe }}</div>
+ <div class="article-body">{{ post.body | safe }}</div>
<div id="comments" style="margin-top: 3rem;">
<h3>Comments</h3>
{% for comment in comments %}
@@ -48,6 +48,7 @@
<p><em>You must be logged in to comment.</em></p>
{% endif %}
</div>
- </section>
+</article>
+ <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
</div>
{% endblock %}
diff --git a/templates/blog_admin/edit_post.html b/templates/blog_admin/edit_post.html
new file mode 100644
index 00000000..09bba62c
--- /dev/null
+++ b/templates/blog_admin/edit_post.html
@@ -0,0 +1,253 @@
+{% extends 'blog/partials/base.html' %} {% block content %}
+<link
+ rel="stylesheet"
+ href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/monokai-sublime.min.css"
+/>
+<link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet" />
+<style>
+ .ql-editor {
+ font-family: "Times New Roman", Times, serif;
+ }
+</style>
+<div class="main">
+ <section>
+ {% include 'blog_admin/partials/posts_topbar.html' %}
+ <form action="{% url 'blog-admin:edit-post' blog_slug %}" method="post">
+ {% csrf_token %}
+ <div class="form-group">
+ <label for="title">Title</label>
+ <input
+ style="display: inline-block"
+ type="text"
+ class="form-control"
+ id="title"
+ name="title"
+ placeholder="Enter an Amazing Title"
+ value="{{ blog_title }}"
+ />
+ </div>
+ <div class="form-group">
+ <label for="slug">Slug</label>
+ <input
+ style="display: inline-block"
+ type="text"
+ class="form-control"
+ id="slug"
+ name="slug"
+ placeholder="Enter an Amazing Slug"
+ value="{{ blog_slug }}"
+ />
+ </div>
+ <div class="form-group">
+ <div id="toolbar-container">
+ <span class="ql-formats">
+ <button class="ql-header" value="1"></button>
+ <button class="ql-header" value="2"></button>
+ </span>
+ <span class="ql-formats">
+ <button class="ql-bold"></button>
+ <button class="ql-italic"></button>
+ <button class="ql-underline"></button>
+ <button class="ql-strike"></button>
+ </span>
+ <span class="ql-formats">
+ <button class="ql-blockquote"></button>
+ <button class="ql-code-block"></button>
+ </span>
+ <span class="ql-formats">
+ <button class="ql-script" value="sub"></button>
+ <button class="ql-script" value="super"></button>
+ </span>
+
+ <span class="ql-formats">
+ <button class="ql-list" value="ordered"></button>
+ <button class="ql-list" value="bullet"></button>
+ </span>
+ <span class="ql-formats">
+ <select class="ql-align"></select>
+ </span>
+ <span class="ql-formats">
+ <button class="ql-link"></button>
+ <button class="ql-image"></button>
+ <button class="ql-formula"></button>
+ {% load static %}
+ <button class="ql-formula-block">
+ <img
+ style="height: 32px; position: relative; top: -6px; left: 4px"
+ src="{% static 'images/icons/formula.png' %}"
+ alt="Block Formula"
+ />
+ </button>
+ </span>
+ <span class="ql-formats">
+ <button class="ql-clean"></button>
+ </span>
+ </div>
+ <div id="editor-container" style="height: 60vh"></div>
+ </div>
+ <div class="form-group">
+ <label for="tags">Tags</label>
+ <input
+ style="display: inline-block"
+ type="text"
+ class="form-control"
+ id="tags"
+ name="tags"
+ placeholder="Enter Tags"
+ value="{{ blog_tags }}"
+ />
+ </div>
+ <div class="form-group">
+ <label for="category">Category</label>
+ <select class="form-control" id="category" name="category" style = "display: inline-block">
+ {% for category in categories %}
+ <option value="{{ category.slug }}" {% if category.slug == blog_category %} selected {% endif %}>{{ category.name }}</option>
+ {% endfor %}
+ </select>
+ </div>
+ <div class="form-group" style="display: none;">
+ <textarea name="body" id="body">{{ blog_body }}</textarea>
+ </div>
+ <div class="form-group">
+ <button type="submit" class="btn btn-primary">Submit</button>
+ </div>
+ </form>
+ </section>
+</div>
+<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
+<script src="https://cdn.quilljs.com/1.3.6/quill.min.js"></script>
+<script src="https://cdn.jsdelivr.net/gh/T-vK/DynamicQuillTools@master/DynamicQuillTools.js"></script>
+<script>
+ const Parchment = Quill.import("parchment");
+ const Delta = Quill.import("delta");
+ class MathjaxInline extends Parchment.Embed {
+ static create(value) {
+ const node = super.create(value);
+ if (typeof value === "string") {
+ node.innerHTML = "&#65279;" + this.tex2svg(value) + "&#65279;";
+ node.contentEditable = "false";
+ node.setAttribute("data-value", value);
+ }
+ return node;
+ }
+
+ static value(domNode) {
+ return domNode.getAttribute("data-value");
+ }
+
+ static tex2svg(latex) {
+ let MathJaxNode = document.createElement("DIV");
+ MathJaxNode.style.visibility = "hidden";
+ MathJaxNode.innerHTML = "\\(" + latex + "\\)";
+ document.body.appendChild(MathJaxNode);
+ MathJax.typeset();
+ let svg = MathJaxNode.innerHTML;
+ document.body.removeChild(MathJaxNode);
+ return svg;
+ }
+ }
+
+ class MathjaxBlock extends Parchment.Embed {
+ static create(value) {
+ const node = super.create(value);
+ if (typeof value === "string") {
+ node.innerHTML = "&#65279;" + this.tex2svg(value) + "&#65279;";
+ node.contentEditable = "false";
+ node.setAttribute("data-value", value);
+ }
+ return node;
+ }
+
+ static value(domNode) {
+ return domNode.getAttribute("data-value");
+ }
+
+ static tex2svg(latex) {
+ let MathJaxNode = document.createElement("DIV");
+ MathJaxNode.style.visibility = "hidden";
+ MathJaxNode.innerHTML = "\\[" + latex + "\\]";
+ document.body.appendChild(MathJaxNode);
+ MathJax.typeset();
+ let svg = MathJaxNode.innerHTML;
+ document.body.removeChild(MathJaxNode);
+ return svg;
+ }
+ }
+
+ // Set module properties
+ MathjaxInline.blotName = "mathjax-inline";
+ MathjaxInline.className = "ql-mathjax-inline";
+ MathjaxInline.tagName = "SPAN";
+ MathjaxBlock.blotName = "mathjax-block";
+ MathjaxBlock.className = "ql-mathjax-block";
+ MathjaxBlock.tagName = "DIV";
+
+ // Register the module
+ Quill.register(MathjaxInline);
+ Quill.register(MathjaxBlock);
+
+ function insertFormula(quill, block) {
+ var range = quill.getSelection();
+ var latex = prompt(
+ "Enter a LaTeX formula",
+ quill.getText(range) == "" ? "e=mc^2" : quill.getText(range)
+ );
+ quill.deleteText(range.index, range.length);
+ if (block) {
+ quill.insertEmbed(range.index, "mathjax-block", latex);
+ } else {
+ quill.insertEmbed(range.index, "mathjax-inline", latex);
+ }
+ quill.insertText(range.index + range.length + 1, " ");
+ quill.setSelection(range.index + range.length + 1);
+ }
+
+ var quill = new Quill("#editor-container", {
+ modules: {
+ syntax: true,
+ toolbar: {
+ container: "#toolbar-container",
+ handlers: {
+ formula: function () {
+ insertFormula(quill, false);
+ },
+ "formula-block": function () {
+ insertFormula(quill, true);
+ },
+ },
+ },
+ },
+ placeholder: "Compose an epic...",
+ theme: "snow",
+ });
+
+ // update body on text change
+ quill.on("text-change", function (delta, oldDelta, source) {
+ document.getElementById("body").value = quill.root.innerHTML;
+ });
+
+ function slugify(text) {
+ return text
+ .toString()
+ .toLowerCase()
+ .replace(/\s+/g, "-") // Replace spaces with -
+ .replace(/[^\w\-]+/g, "") // Remove all non-word chars
+ .replace(/\-\-+/g, "-") // Replace multiple - with single -
+ .replace(/^-+/, "") // Trim - from start of text
+ .replace(/-+$/, ""); // Trim - from end of text
+ }
+
+ // slugify title
+ document.getElementById("title").addEventListener("input", function () {
+ document.getElementById("slug").value = slugify(this.value);
+ });
+
+ try {
+ const delta = quill.clipboard.convert(document.getElementById("body").value);
+ quill.setContents(delta, "silent");
+ } catch (e) {
+ console.log(e);
+ }
+</script>
+{% endblock %}
diff --git a/templates/blog_admin/posts.html b/templates/blog_admin/posts.html
index 8c1e14aa..5d56f0c5 100644
--- a/templates/blog_admin/posts.html
+++ b/templates/blog_admin/posts.html
@@ -25,7 +25,7 @@
<td><a href="#">{{ post.category }}</a></td>
<td style="position: relative;"> {% if post.is_public %} <span class="label label-success">Published</span> {% else %} <span class="label label-warning">Draft</span> {% endif %} </td>
<td>
- <a href="#">Edit</a>
+ <a href="{% url 'blog-admin:edit-post' post.slug %}">Edit</a>
<a href="#" class="error">Delete</a>
{% if post.is_public %}
<a href="#" class="error">UnPublish</a>