Browse Source

render markdown serverside and put it in the noscript tag for people

with no JS
pull/1/head
wes 7 years ago
parent
commit
72df80489e
  1. 2
      blog.ini
  2. 2
      blog.service
  3. 2
      requirements.txt
  4. 41
      src/posts.py
  5. 6
      src/scripts/app.tag
  6. 2
      src/scripts/editor.js
  7. 2
      src/scripts/post.tag
  8. 2
      src/scripts/riotblog.js
  9. 6
      src/templates/index.html
  10. 13
      src/website.py

2
blog.ini

@ -8,7 +8,7 @@ uid = http
gid = http
master = true
processes = 5
processes = 7
socket = /tmp/blog.sock
chown-socket = http:http

2
blog.service

@ -6,7 +6,7 @@ After=network.target
User=http
Group=http
WorkingDirectory=/srv/http/riotblog
ExecStart=/usr/bin/uwsgi --ini /srv/http/riotblog/blog.ini
ExecStart=/usr/bin/uwsgi --single-interpreter --ini /srv/http/riotblog/blog.ini
Environment="RIOTBLOG_SETTINGS=/srv/http/riotblog/riotblog_prod.cfg"
[Install]

2
requirements.txt

@ -23,6 +23,7 @@ Jinja2==2.9.4
lxml==3.7.2
MarkupSafe==0.23
marshmallow==2.13.5
mistune==0.7.4
packaging==16.8
paramiko==2.1.1
pbr==1.10.0
@ -34,6 +35,7 @@ python-dateutil==2.6.0
python-memcached==1.58
pyxdg==0.25
requests==2.18.3
simplejson==3.11.1
six==1.10.0
stevedore==1.20.0
urllib3==1.22

41
src/posts.py

@ -1,11 +1,21 @@
#! /usr/bin/python
import couchdb
import mistune
from werkzeug.local import Local, LocalProxy, LocalManager
from couchdb.http import ResourceConflict, ResourceNotFound
from flask import jsonify
from flask import jsonify, g
from flask_marshmallow import Marshmallow
def get_mistune():
markdown = getattr(g, "markdown", None)
if markdown is None:
markdown = g._markdown = mistune.Markdown()
return markdown
markdown = LocalProxy(get_mistune)
class Posts:
def __init__(self, user, password, host=None, port=None):
if host is None:
@ -41,11 +51,19 @@ class Posts:
results = self.db.iterview("blogPosts/blog-posts", 1, include_docs=True, startkey=_id)
post = [result.doc for result in results][0]
post["content"] = markdown(post["content"])
return jsonify(post) if json else post
def getinitial(self):
results = list(self.db.iterview("blogPosts/blog-posts", 2, include_docs=True))
return [result.doc for result in results][0]
post = [result.doc for result in results][0]
post["content"] = markdown(post["content"])
return post
def iterpost(self, endkey=False, startkey=False, category="programming"):
if startkey and not endkey:
@ -55,22 +73,25 @@ class Posts:
else:
results = self.db.iterview("blogPosts/blog-posts", 2, include_docs=True)
doc_ids = [result.doc for result in results]
docs = [result.doc for result in results]
for doc in docs:
doc["content"] = markdown(doc["content"])
if not doc_ids:
if not docs:
return jsonify("end")
if endkey and not startkey:
if len(doc_ids) < 2 or doc_ids[0] == endkey:
if len(docs) < 2 or docs[0] == endkey:
return jsonify("start")
return jsonify(doc_ids[-2])
return jsonify(docs[-2])
if len(doc_ids) == 1:
return jsonify(doc_ids[0])
if len(docs) == 1:
return jsonify(docs[0])
if doc_ids:
if docs:
# if no startkey or endkey were specified, return the 0th post
return jsonify(doc_ids[1 if startkey else 0])
return jsonify(docs[1 if startkey else 0])
return jsonify("end")

6
src/scripts/app.tag

@ -27,7 +27,7 @@
class="mobile-menu tab tab-block menu">
<li
each="{page in ['posts', 'projects', 'links', 'about']}"
class={"navigate-tab tab-item animated fadeIn " + (parent.active.get(page) ? "active" : "")}
class={"navigate-tab tab-item " + (parent.active.get(page) ? "active" : "")}
data-is="navtab"
active={parent.active.get(page)}
to={parent.to(page)}
@ -41,7 +41,7 @@
<ul class="hide-md hide-sm hide-xs navigate tab tab-block">
<li
each="{page in ['posts', 'projects', 'links', 'about']}"
class={"navigate-tab tab-item animated fadeIn " + (parent.active.get(page) ? "active" : "")}
class={"navigate-tab tab-item " + (parent.active.get(page) ? "active" : "")}
data-is="navtab"
active={parent.active.get(page)}
to={parent.to(page)}
@ -129,7 +129,7 @@ self.state = {
"author" : self.opts.author,
"title" : self.opts.title,
"loaded" : false,
"initial" : decodeURIComponent(self.opts.initial_post),
"initial" : document.getElementsByTagName("noscript")[0].textContent,
"links" : JSON.parse(decodeURIComponent(self.opts.links))
};

2
src/scripts/editor.js

@ -2,11 +2,13 @@ import riot from 'riot';
import { default as RiotControl } from 'riotcontrol';
import { default as promise } from 'es6-promise';
import { default as smooth } from 'smoothscroll-polyfill';
import { default as showdown } from 'showdown';
import 'element-closest';
promise.Promise.polyfill();
smooth.polyfill();
window.showdown = showdown;
window.RiotControl = RiotControl;
RiotControl.addStore(new riot.observable());

2
src/scripts/post.tag

@ -23,7 +23,7 @@
</social>
<p class="post-content centered text-break">
<raw
content="{ window.converter.makeHtml(content) }"
content="{ content }"
>
</raw>
</p>

2
src/scripts/riotblog.js

@ -6,13 +6,11 @@ import './projects.tag';
import './app.tag';
import './grid.js';
import { default as promise } from 'es6-promise';
import { default as showdown } from 'showdown';
import { default as smooth } from 'smoothscroll-polyfill';
import 'element-closest';
import fetchCached from 'fetch-cached';
import 'whatwg-fetch';
window.converter = new showdown.Converter();
window.cache = {};
window.riot = riot;
window.RiotControl = RiotControl;

6
src/templates/index.html

@ -5,6 +5,7 @@
<title>{{ postcontent["title"] }}</title>
</head>
<body>
<noscript>{{ postcontent['content']|safe }}</noscript>
<div data-is="app"></div>
<footer>
<script async type="text/javascript" src="/scripts/riotblog.min.js"></script>
@ -16,7 +17,7 @@
}
</script>
<div id="fb-root"></div>
<script>window.twttr=function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.async=true;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);t._e=[];t.ready=function(f){t._e.push(f)};return t}(document,"script","twitter-wjs");(function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(d.getElementById(id))return;js=d.createElement(s);js.id=id;js.async=true;js.src="//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.8";fjs.parentNode.insertBefore(js,fjs)})(document,"script","facebook-jssdk");</script>
<script>window.twttr=function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.async=true;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);t._e=[];t.ready=function(f){t._e.push(f)};return t}(document,"script","twitter-wjs");(function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(d.getElementById(id))return;js=d.createElement(s);js.id=id;js.async=true;js.src="//connect.facebook.net/en_US/all.js#xfbml=1&version=v2.8";fjs.parentNode.insertBefore(js,fjs)})(document,"script","facebook-jssdk");</script>
<script>
window.addEventListener("load", function() {
window.riot.mount("app",
@ -26,8 +27,7 @@
author : "{{ postcontent['author'] }}",
postid : "{{ postid }}",
title : "{{ postcontent['title'] }}",
csrf_token : "{{ csrf_token() }}",
initial_post: "{{ quote(postcontent['content']) }}"
csrf_token : "{{ csrf_token() }}"
});
});
</script>

13
src/website.py

@ -95,10 +95,11 @@ def NeverWhere(configfile=None):
@cache.cached(timeout=50)
@app.route("/blog/posts/", methods=("GET",))
def renderInitial():
post = dict(initial_post)
return render_template("index.html",
postid=initial_post["_id"],
page="posts",
postcontent=dict(initial_post))
postcontent=post)
@cache.cached(timeout=50)
@app.route("/blog/projects", methods=("GET",))
@ -126,16 +127,18 @@ def NeverWhere(configfile=None):
return renderInitial()
# get the next post
@cache.cached(timeout=50)
@app.route("/blog/posts/<_id>", methods=("GET",))
def renderPost(_id):
post_content = loads(
post_content = dict(loads(
cacheit(_id,
lambda: dumps(posts.getpost(_id, json=False)))
)
))
return render_template("index.html",
page="posts",
postcontent=dict(post_content))
postcontent=post_content)
@cache.cached(timeout=50)
@ -160,7 +163,7 @@ def NeverWhere(configfile=None):
def allposts():
return posts.allposts()
@cache.cached(timeout=50)
@cache.cached(timeout=10000)
@app.route("/blog/categories")
def categories():
return posts.categories()

Loading…
Cancel
Save