Merge pull request #2 from kirsle/feature/blog-drafts-and-privacy
Many blog improvements
This commit is contained in:
commit
646620fa92
|
@ -43,6 +43,9 @@ app.DEBUG = Config.site.debug == "true"
|
||||||
app.secret_key = bytes(Config.security.secret_key.encode("utf-8")) \
|
app.secret_key = bytes(Config.security.secret_key.encode("utf-8")) \
|
||||||
.decode(string_escape)
|
.decode(string_escape)
|
||||||
|
|
||||||
|
# Make templates easier to edit live.
|
||||||
|
app.config["TEMPLATES_AUTO_RELOAD"] = True
|
||||||
|
|
||||||
# Security?
|
# Security?
|
||||||
if Config.security.force_ssl == True:
|
if Config.security.force_ssl == True:
|
||||||
app.config['SESSION_COOKIE_SECURE'] = True
|
app.config['SESSION_COOKIE_SECURE'] = True
|
||||||
|
|
|
@ -18,7 +18,7 @@ from rophako.settings import Config
|
||||||
import rophako.jsondb as JsonDB
|
import rophako.jsondb as JsonDB
|
||||||
from rophako.log import logger
|
from rophako.log import logger
|
||||||
|
|
||||||
def get_index():
|
def get_index(drafts=False):
|
||||||
"""Get the blog index.
|
"""Get the blog index.
|
||||||
|
|
||||||
The index is the cache of available blog posts. It has the format:
|
The index is the cache of available blog posts. It has the format:
|
||||||
|
@ -37,6 +37,10 @@ def get_index():
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Args:
|
||||||
|
drafts (bool): Whether to allow draft posts to be included in the index
|
||||||
|
(for logged-in users only).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Index doesn't exist?
|
# Index doesn't exist?
|
||||||
|
@ -44,16 +48,67 @@ def get_index():
|
||||||
return rebuild_index()
|
return rebuild_index()
|
||||||
db = JsonDB.get("blog/index")
|
db = JsonDB.get("blog/index")
|
||||||
|
|
||||||
# Hide any private posts if we aren't logged in.
|
# Filter out posts that shouldn't be visible (draft/private)
|
||||||
if not g.info["session"]["login"]:
|
|
||||||
posts = list(db.keys())
|
posts = list(db.keys())
|
||||||
for post_id in posts:
|
for post_id in posts:
|
||||||
if db[post_id]["privacy"] == "private":
|
privacy = db[post_id]["privacy"]
|
||||||
|
|
||||||
|
# Drafts are hidden universally so they can't be seen on any of the
|
||||||
|
# normal blog routes.
|
||||||
|
if privacy == "draft":
|
||||||
|
if drafts is False or not g.info["session"]["login"]:
|
||||||
|
del db[post_id]
|
||||||
|
|
||||||
|
# Private posts are only visible to logged in users.
|
||||||
|
elif privacy == "private" and not g.info["session"]["login"]:
|
||||||
del db[post_id]
|
del db[post_id]
|
||||||
|
|
||||||
return db
|
return db
|
||||||
|
|
||||||
|
|
||||||
|
def get_drafts():
|
||||||
|
"""Get the draft blog posts.
|
||||||
|
|
||||||
|
Drafts are hidden from all places of the blog, just like private posts are
|
||||||
|
(for non-logged-in users), so get_index() skips drafts and therefore
|
||||||
|
resolve_id, etc. does too, making them invisible on the normal blog pages.
|
||||||
|
|
||||||
|
This function is like get_index() except it *only* returns the drafts.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Index doesn't exist?
|
||||||
|
if not JsonDB.exists("blog/index"):
|
||||||
|
return rebuild_index()
|
||||||
|
db = JsonDB.get("blog/index")
|
||||||
|
|
||||||
|
# Filter out only the draft posts.
|
||||||
|
return {
|
||||||
|
key: data for key, data in db.items() if data["privacy"] == "draft"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_private():
|
||||||
|
"""Get only the private blog posts.
|
||||||
|
|
||||||
|
Since you can view only drafts, it made sense to have an easy way to view
|
||||||
|
only private posts, too.
|
||||||
|
|
||||||
|
This function is like get_index() except it *only* returns the private
|
||||||
|
posts. It doesn't check for logged-in users, because the routes that view
|
||||||
|
all private posts are login_required anyway.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Index doesn't exist?
|
||||||
|
if not JsonDB.exists("blog/index"):
|
||||||
|
return rebuild_index()
|
||||||
|
db = JsonDB.get("blog/index")
|
||||||
|
|
||||||
|
# Filter out only the draft posts.
|
||||||
|
return {
|
||||||
|
key: data for key, data in db.items() if data["privacy"] == "private"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def rebuild_index():
|
def rebuild_index():
|
||||||
"""Rebuild the index.json if it goes missing."""
|
"""Rebuild the index.json if it goes missing."""
|
||||||
index = {}
|
index = {}
|
||||||
|
@ -76,13 +131,13 @@ def update_index(post_id, post, index=None, commit=True):
|
||||||
* index: If you already have the index open, you can pass it here
|
* index: If you already have the index open, you can pass it here
|
||||||
* commit: Write the DB after updating the index (default True)"""
|
* commit: Write the DB after updating the index (default True)"""
|
||||||
if index is None:
|
if index is None:
|
||||||
index = get_index()
|
index = get_index(drafts=True)
|
||||||
|
|
||||||
index[post_id] = dict(
|
index[post_id] = dict(
|
||||||
fid = post["fid"],
|
fid = post["fid"],
|
||||||
time = post["time"] or int(time.time()),
|
time = post["time"] or int(time.time()),
|
||||||
categories = post["categories"],
|
categories = post["categories"],
|
||||||
sticky = False, # TODO
|
sticky = post["sticky"],
|
||||||
author = post["author"],
|
author = post["author"],
|
||||||
privacy = post["privacy"] or "public",
|
privacy = post["privacy"] or "public",
|
||||||
subject = post["subject"],
|
subject = post["subject"],
|
||||||
|
@ -125,11 +180,11 @@ def get_entry(post_id):
|
||||||
|
|
||||||
|
|
||||||
def post_entry(post_id, fid, epoch, author, subject, avatar, categories,
|
def post_entry(post_id, fid, epoch, author, subject, avatar, categories,
|
||||||
privacy, ip, emoticons, comments, format, body):
|
privacy, ip, emoticons, sticky, comments, format, body):
|
||||||
"""Post (or update) a blog entry."""
|
"""Post (or update) a blog entry."""
|
||||||
|
|
||||||
# Fetch the index.
|
# Fetch the index.
|
||||||
index = get_index()
|
index = get_index(drafts=True)
|
||||||
|
|
||||||
# Editing an existing post?
|
# Editing an existing post?
|
||||||
if not post_id:
|
if not post_id:
|
||||||
|
@ -180,7 +235,7 @@ def post_entry(post_id, fid, epoch, author, subject, avatar, categories,
|
||||||
ip = ip,
|
ip = ip,
|
||||||
time = epoch or int(time.time()),
|
time = epoch or int(time.time()),
|
||||||
categories = categories,
|
categories = categories,
|
||||||
sticky = False, # TODO: implement sticky
|
sticky = sticky,
|
||||||
comments = comments,
|
comments = comments,
|
||||||
emoticons = emoticons,
|
emoticons = emoticons,
|
||||||
avatar = avatar,
|
avatar = avatar,
|
||||||
|
@ -203,7 +258,7 @@ def post_entry(post_id, fid, epoch, author, subject, avatar, categories,
|
||||||
def delete_entry(post_id):
|
def delete_entry(post_id):
|
||||||
"""Remove a blog entry."""
|
"""Remove a blog entry."""
|
||||||
# Fetch the blog information.
|
# Fetch the blog information.
|
||||||
index = get_index()
|
index = get_index(drafts=True)
|
||||||
post = get_entry(post_id)
|
post = get_entry(post_id)
|
||||||
if post is None:
|
if post is None:
|
||||||
logger.warning("Can't delete post {}, it doesn't exist!".format(post_id))
|
logger.warning("Can't delete post {}, it doesn't exist!".format(post_id))
|
||||||
|
@ -216,9 +271,14 @@ def delete_entry(post_id):
|
||||||
JsonDB.commit("blog/index", index)
|
JsonDB.commit("blog/index", index)
|
||||||
|
|
||||||
|
|
||||||
def resolve_id(fid):
|
def resolve_id(fid, drafts=False):
|
||||||
"""Resolve a friendly ID to the blog ID number."""
|
"""Resolve a friendly ID to the blog ID number.
|
||||||
index = get_index()
|
|
||||||
|
Args:
|
||||||
|
drafts (bool): Whether to allow draft IDs to be resolved (for
|
||||||
|
logged-in users only).
|
||||||
|
"""
|
||||||
|
index = get_index(drafts=drafts)
|
||||||
|
|
||||||
# If the ID is all numeric, it's the blog post ID directly.
|
# If the ID is all numeric, it's the blog post ID directly.
|
||||||
if re.match(r'^\d+$', fid):
|
if re.match(r'^\d+$', fid):
|
||||||
|
|
|
@ -5,6 +5,16 @@
|
||||||
|
|
||||||
<h1>Admin Center</h1>
|
<h1>Admin Center</h1>
|
||||||
|
|
||||||
|
<h2>Blog</h2>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><a href="{{ url_for('blog.update') }}">Post a new blog entry</a></li>
|
||||||
|
<li><a href="{{ url_for('blog.drafts') }}">View draft entries</a></li>
|
||||||
|
<li><a href="{{ url_for('blog.private') }}">View private entries</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Users</h2>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="{{ url_for('admin.users') }}">View and Manage Users</a></li>
|
<li><a href="{{ url_for('admin.users') }}">View and Manage Users</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -80,13 +80,24 @@ def category(category):
|
||||||
g.info["url_category"] = category
|
g.info["url_category"] = category
|
||||||
return template("blog/index.html")
|
return template("blog/index.html")
|
||||||
|
|
||||||
|
@mod.route("/drafts")
|
||||||
|
@login_required
|
||||||
|
def drafts():
|
||||||
|
"""View all of the draft blog posts."""
|
||||||
|
return template("blog/drafts.html")
|
||||||
|
|
||||||
|
@mod.route("/private")
|
||||||
|
@login_required
|
||||||
|
def private():
|
||||||
|
"""View all of the blog posts marked as private."""
|
||||||
|
return template("blog/private.html")
|
||||||
|
|
||||||
@mod.route("/entry/<fid>")
|
@mod.route("/entry/<fid>")
|
||||||
def entry(fid):
|
def entry(fid):
|
||||||
"""Endpoint to view a specific blog entry."""
|
"""Endpoint to view a specific blog entry."""
|
||||||
|
|
||||||
# Resolve the friendly ID to a real ID.
|
# Resolve the friendly ID to a real ID.
|
||||||
post_id = Blog.resolve_id(fid)
|
post_id = Blog.resolve_id(fid, drafts=True)
|
||||||
if not post_id:
|
if not post_id:
|
||||||
flash("That blog post wasn't found.")
|
flash("That blog post wasn't found.")
|
||||||
return redirect(url_for(".index"))
|
return redirect(url_for(".index"))
|
||||||
|
@ -165,21 +176,16 @@ def update():
|
||||||
avatar="",
|
avatar="",
|
||||||
categories="",
|
categories="",
|
||||||
privacy=Config.blog.default_privacy,
|
privacy=Config.blog.default_privacy,
|
||||||
|
sticky=False,
|
||||||
emoticons=True,
|
emoticons=True,
|
||||||
comments=Config.blog.allow_comments,
|
comments=Config.blog.allow_comments,
|
||||||
month="",
|
|
||||||
day="",
|
|
||||||
year="",
|
|
||||||
hour="",
|
|
||||||
min="",
|
|
||||||
sec="",
|
|
||||||
preview=False,
|
preview=False,
|
||||||
))
|
))
|
||||||
|
|
||||||
# Editing an existing post?
|
# Editing an existing post?
|
||||||
post_id = request.args.get("id", None)
|
post_id = request.args.get("id", None)
|
||||||
if post_id:
|
if post_id:
|
||||||
post_id = Blog.resolve_id(post_id)
|
post_id = Blog.resolve_id(post_id, drafts=True)
|
||||||
if post_id:
|
if post_id:
|
||||||
logger.info("Editing existing blog post {}".format(post_id))
|
logger.info("Editing existing blog post {}".format(post_id))
|
||||||
post = Blog.get_entry(post_id)
|
post = Blog.get_entry(post_id)
|
||||||
|
@ -187,22 +193,11 @@ def update():
|
||||||
g.info["post"] = post
|
g.info["post"] = post
|
||||||
|
|
||||||
# Copy fields.
|
# Copy fields.
|
||||||
for field in ["author", "fid", "subject", "format", "format",
|
for field in ["author", "fid", "subject", "time", "format",
|
||||||
"body", "avatar", "categories", "privacy",
|
"body", "avatar", "categories", "privacy",
|
||||||
"emoticons", "comments"]:
|
"sticky", "emoticons", "comments"]:
|
||||||
g.info[field] = post[field]
|
g.info[field] = post[field]
|
||||||
|
|
||||||
# Dissect the time.
|
|
||||||
date = datetime.datetime.fromtimestamp(post["time"])
|
|
||||||
g.info.update(dict(
|
|
||||||
month="{:02d}".format(date.month),
|
|
||||||
day="{:02d}".format(date.day),
|
|
||||||
year=date.year,
|
|
||||||
hour="{:02d}".format(date.hour),
|
|
||||||
min="{:02d}".format(date.minute),
|
|
||||||
sec="{:02d}".format(date.second),
|
|
||||||
))
|
|
||||||
|
|
||||||
# Are we SUBMITTING the form?
|
# Are we SUBMITTING the form?
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
action = request.form.get("action")
|
action = request.form.get("action")
|
||||||
|
@ -211,10 +206,9 @@ def update():
|
||||||
g.info["post_id"] = request.form.get("id")
|
g.info["post_id"] = request.form.get("id")
|
||||||
for field in ["fid", "subject", "format", "body", "avatar", "categories", "privacy"]:
|
for field in ["fid", "subject", "format", "body", "avatar", "categories", "privacy"]:
|
||||||
g.info[field] = request.form.get(field)
|
g.info[field] = request.form.get(field)
|
||||||
for boolean in ["emoticons", "comments"]:
|
for boolean in ["sticky", "emoticons", "comments"]:
|
||||||
g.info[boolean] = True if request.form.get(boolean, None) == "true" else False
|
g.info[boolean] = True if request.form.get(boolean, None) == "true" else False
|
||||||
for number in ["author", "month", "day", "year", "hour", "min", "sec"]:
|
g.info["author"] = int(g.info["author"])
|
||||||
g.info[number] = int(request.form.get(number, 0))
|
|
||||||
|
|
||||||
# What action are they doing?
|
# What action are they doing?
|
||||||
if action == "preview":
|
if action == "preview":
|
||||||
|
@ -240,20 +234,11 @@ def update():
|
||||||
invalid = True
|
invalid = True
|
||||||
flash("You must enter a subject for your blog post.")
|
flash("You must enter a subject for your blog post.")
|
||||||
|
|
||||||
# Make sure the times are valid.
|
# Resetting the post's time stamp?
|
||||||
date = None
|
if not request.form.get("id") or request.form.get("reset-time"):
|
||||||
try:
|
g.info["time"] = float(time.time())
|
||||||
date = datetime.datetime(
|
else:
|
||||||
g.info["year"],
|
g.info["time"] = float(request.form.get("time", time.time()))
|
||||||
g.info["month"],
|
|
||||||
g.info["day"],
|
|
||||||
g.info["hour"],
|
|
||||||
g.info["min"],
|
|
||||||
g.info["sec"],
|
|
||||||
)
|
|
||||||
except ValueError as e:
|
|
||||||
invalid = True
|
|
||||||
flash("Invalid date/time: " + str(e))
|
|
||||||
|
|
||||||
# Format the categories.
|
# Format the categories.
|
||||||
tags = []
|
tags = []
|
||||||
|
@ -262,12 +247,9 @@ def update():
|
||||||
|
|
||||||
# Okay to update?
|
# Okay to update?
|
||||||
if invalid is False:
|
if invalid is False:
|
||||||
# Convert the date into a Unix time stamp.
|
|
||||||
epoch = float(date.strftime("%s"))
|
|
||||||
|
|
||||||
new_id, new_fid = Blog.post_entry(
|
new_id, new_fid = Blog.post_entry(
|
||||||
post_id = g.info["post_id"],
|
post_id = g.info["post_id"],
|
||||||
epoch = epoch,
|
epoch = g.info["time"],
|
||||||
author = g.info["author"],
|
author = g.info["author"],
|
||||||
subject = g.info["subject"],
|
subject = g.info["subject"],
|
||||||
fid = g.info["fid"],
|
fid = g.info["fid"],
|
||||||
|
@ -276,6 +258,7 @@ def update():
|
||||||
privacy = g.info["privacy"],
|
privacy = g.info["privacy"],
|
||||||
ip = remote_addr(),
|
ip = remote_addr(),
|
||||||
emoticons = g.info["emoticons"],
|
emoticons = g.info["emoticons"],
|
||||||
|
sticky = g.info["sticky"],
|
||||||
comments = g.info["comments"],
|
comments = g.info["comments"],
|
||||||
format = g.info["format"],
|
format = g.info["format"],
|
||||||
body = g.info["body"],
|
body = g.info["body"],
|
||||||
|
@ -297,7 +280,7 @@ def delete():
|
||||||
post_id = request.args.get("id")
|
post_id = request.args.get("id")
|
||||||
|
|
||||||
# Resolve the post ID.
|
# Resolve the post ID.
|
||||||
post_id = Blog.resolve_id(post_id)
|
post_id = Blog.resolve_id(post_id, drafts=True)
|
||||||
if not post_id:
|
if not post_id:
|
||||||
flash("That blog post wasn't found.")
|
flash("That blog post wasn't found.")
|
||||||
return redirect(url_for(".index"))
|
return redirect(url_for(".index"))
|
||||||
|
@ -408,11 +391,30 @@ def xml_add_text_tags(doc, root_node, tags):
|
||||||
root_node.appendChild(channelTag)
|
root_node.appendChild(channelTag)
|
||||||
|
|
||||||
|
|
||||||
def partial_index(template_name="blog/index.inc.html"):
|
def partial_index(template_name="blog/index.inc.html", mode="normal"):
|
||||||
"""Partial template for including the index view of the blog."""
|
"""Partial template for including the index view of the blog.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
template_name (str): The name of the template to be rendered.
|
||||||
|
mode (str): The view mode of the posts, one of:
|
||||||
|
- normal: Only list public entries, or private posts for users
|
||||||
|
who are logged in.
|
||||||
|
- drafts: Only list draft entries for logged-in users.
|
||||||
|
"""
|
||||||
|
|
||||||
# Get the blog index.
|
# Get the blog index.
|
||||||
|
if mode == "normal":
|
||||||
index = Blog.get_index()
|
index = Blog.get_index()
|
||||||
|
elif mode == "drafts":
|
||||||
|
index = Blog.get_drafts()
|
||||||
|
elif mode == "private":
|
||||||
|
index = Blog.get_private()
|
||||||
|
else:
|
||||||
|
return "Invalid partial_index mode."
|
||||||
|
|
||||||
|
# Let the pages know what mode they're in.
|
||||||
|
g.info["mode"] = mode
|
||||||
|
|
||||||
pool = {} # The set of blog posts to show.
|
pool = {} # The set of blog posts to show.
|
||||||
|
|
||||||
category = g.info.get("url_category", None)
|
category = g.info.get("url_category", None)
|
||||||
|
@ -449,7 +451,7 @@ def partial_index(template_name="blog/index.inc.html"):
|
||||||
g.info["older"] = offset + int(Config.blog.entries_per_page)
|
g.info["older"] = offset + int(Config.blog.entries_per_page)
|
||||||
if g.info["earlier"] < 0:
|
if g.info["earlier"] < 0:
|
||||||
g.info["earlier"] = 0
|
g.info["earlier"] = 0
|
||||||
if g.info["older"] < 0 or g.info["older"] > len(posts):
|
if g.info["older"] < 0 or g.info["older"] > len(posts) - 1:
|
||||||
g.info["older"] = 0
|
g.info["older"] = 0
|
||||||
g.info["count"] = 0
|
g.info["count"] = 0
|
||||||
|
|
||||||
|
@ -530,7 +532,7 @@ def partial_tags():
|
||||||
has_small = False
|
has_small = False
|
||||||
for tag in sort_tags:
|
for tag in sort_tags:
|
||||||
result.append(dict(
|
result.append(dict(
|
||||||
category=tag,
|
category=tag if len(tag) else Config.blog.default_category,
|
||||||
count=tags[tag],
|
count=tags[tag],
|
||||||
small=tags[tag] < 3, # TODO: make this configurable
|
small=tags[tag] < 3, # TODO: make this configurable
|
||||||
))
|
))
|
||||||
|
|
9
rophako/modules/blog/templates/blog/drafts.html
Normal file
9
rophako/modules/blog/templates/blog/drafts.html
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
{% block title %}Draft Entries{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<h1>Draft Entries</h1>
|
||||||
|
|
||||||
|
{{ include_page("blog.partial_index", mode="drafts") | safe }}
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -25,6 +25,15 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="blog-timestamp">
|
<div class="blog-timestamp">
|
||||||
|
{% if post["privacy"] == "private" %}
|
||||||
|
<span class="blog-entry-private">[Private]</span>
|
||||||
|
{% elif post["privacy"] == "draft" %}
|
||||||
|
<span class="blog-entry-draft">[Draft]</span>
|
||||||
|
{% endif %}
|
||||||
|
{% if post["sticky"] %}
|
||||||
|
<span class="blog-entry-sticky">[Sticky]</span>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
Posted by {{ post["profile"]["name"] }}
|
Posted by {{ post["profile"]["name"] }}
|
||||||
on <span title="{{ post['time'] }}">{{ post["pretty_time"] }}</span>
|
on <span title="{{ post['time'] }}">{{ post["pretty_time"] }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -65,6 +74,14 @@
|
||||||
<a href="{{ url_for('blog.index') }}">Blog</a>
|
<a href="{{ url_for('blog.index') }}">Blog</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if post["privacy"] == "private" %}
|
||||||
|
| <a href="{{ url_for('blog.private') }}">Private posts</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if post["privacy"] == "draft" %}
|
||||||
|
| <a href="{{ url_for('blog.drafts') }}">Drafts</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if session["login"] %}
|
{% if session["login"] %}
|
||||||
|
|
|
|
||||||
<a href="{{ url_for('blog.update', id=post['post_id']) }}">Edit</a>
|
<a href="{{ url_for('blog.update', id=post['post_id']) }}">Edit</a>
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
{# Older/Newer links #}
|
{# Older/Newer links #}
|
||||||
|
|
||||||
{% if can_older or can_newer %}
|
{# The relative blog index to link to #}
|
||||||
|
{% if mode == "drafts" %}
|
||||||
|
{% set blog_index = "blog.drafts" %}
|
||||||
|
{% elif mode == "private" %}
|
||||||
|
{% set blog_index = "blog.private" %}
|
||||||
|
{% else %}
|
||||||
|
{% set blog_index = "blog.index" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if can_older or can_earlier %}
|
||||||
<div class="right">
|
<div class="right">
|
||||||
[
|
[
|
||||||
<a href="{{ url_for('blog.rss') }}">RSS Feed</a> |
|
<a href="{{ url_for('blog.rss') }}">RSS Feed</a> |
|
||||||
|
@ -8,7 +17,7 @@
|
||||||
{% if category %}
|
{% if category %}
|
||||||
<a href="{{ url_for('blog.category', category=category) }}?skip={{ earlier }}">< Newer</a>
|
<a href="{{ url_for('blog.category', category=category) }}?skip={{ earlier }}">< Newer</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{{ url_for('blog.index') }}?skip={{ earlier }}">< Newer</a>
|
<a href="{{ url_for(blog_index) }}?skip={{ earlier }}">< Newer</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if can_older %} | {% endif %}
|
{% if can_older %} | {% endif %}
|
||||||
|
@ -18,7 +27,7 @@
|
||||||
{% if category %}
|
{% if category %}
|
||||||
<a href="{{ url_for('blog.category', category=category) }}?skip={{ older }}">Older ></a>
|
<a href="{{ url_for('blog.category', category=category) }}?skip={{ older }}">Older ></a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{{ url_for('blog.index') }}?skip={{ older }}">Older ></a>
|
<a href="{{ url_for(blog_index) }}?skip={{ older }}">Older ></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
9
rophako/modules/blog/templates/blog/private.html
Normal file
9
rophako/modules/blog/templates/blog/private.html
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{% extends "layout.html" %}
|
||||||
|
{% block title %}Draft Entries{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<h1>Private Entries</h1>
|
||||||
|
|
||||||
|
{{ include_page("blog.partial_index", mode="private") | safe }}
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -56,12 +56,19 @@
|
||||||
<option value="public"{% if privacy == "public" %} selected{% endif %}>
|
<option value="public"{% if privacy == "public" %} selected{% endif %}>
|
||||||
Public: everybody can see this blog entry
|
Public: everybody can see this blog entry
|
||||||
</option>
|
</option>
|
||||||
|
<option value="draft"{% if privacy == "draft" %} selected{% endif %}>
|
||||||
|
Draft: don't show this on the blog anywhere
|
||||||
|
</option>
|
||||||
<option value="private"{% if privacy == "private" %} selected{% endif %}>
|
<option value="private"{% if privacy == "private" %} selected{% endif %}>
|
||||||
Private: only site admins can see this blog entry
|
Private: only site admins can see this blog entry
|
||||||
</option>
|
</option>
|
||||||
</select><p>
|
</select><p>
|
||||||
|
|
||||||
<strong>Options:</strong><br>
|
<strong>Options:</strong><br>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="sticky" value="true"{% if sticky %} checked{% endif %}>
|
||||||
|
Make this post sticky (always on top)
|
||||||
|
</label><br>
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" name="emoticons" value="true"{% if emoticons %} checked{% endif %}>
|
<input type="checkbox" name="emoticons" value="true"{% if emoticons %} checked{% endif %}>
|
||||||
Enable graphical emoticons
|
Enable graphical emoticons
|
||||||
|
@ -71,18 +78,14 @@
|
||||||
Enable comments on this entry
|
Enable comments on this entry
|
||||||
</label><p>
|
</label><p>
|
||||||
|
|
||||||
<strong>Time Stamp:</strong><br>
|
<input type="hidden" name="time" value="{{ time }}">
|
||||||
<input type="text" class="form-control input-sm inline" size="2" name="month" id="month" value="{{ month }}"> /
|
{% if post_id != "" %}
|
||||||
<input type="text" class="form-control input-sm inline" size="2" name="day" id="day" value="{{ day }}"> /
|
<strong>Reset Time Stamp:</strong><br>
|
||||||
<input type="text" class="form-control input-sm inline" size="4" name="year" id="year" value="{{ year }}"> @
|
|
||||||
<input type="text" class="form-control input-sm inline" size="2" name="hour" id="hour" value="{{ hour }}"> :
|
|
||||||
<input type="text" class="form-control input-sm inline" size="2" name="min" id="min" value="{{ min }}"> :
|
|
||||||
<input type="text" class="form-control input-sm inline" size="2" name="sec" id="sec" value="{{ sec }}"><br>
|
|
||||||
mm / dd / yyyy @ hh:mm:ss<br>
|
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" id="autoup" value="yes"{% if post_id == "" %} checked{% endif %}>
|
<input type="checkbox" name="reset-time" value="yes"{% if post_id == "" %} checked{% endif %}>
|
||||||
Automatically update
|
Reset the post's time stamp to the current time.
|
||||||
</label><p>
|
</label><p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<button type="submit" class="btn btn-default" name="action" value="preview">Preview</button>
|
<button type="submit" class="btn btn-default" name="action" value="preview">Preview</button>
|
||||||
<button type="submit" class="btn btn-primary" name="action" value="publish">Publish Entry</button>
|
<button type="submit" class="btn btn-primary" name="action" value="publish">Publish Entry</button>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user