Converted app into a package
This commit is contained in:
parent
ef7818e10e
commit
904fe68d51
22 changed files with 49 additions and 35 deletions
14
flask_website/__init__.py
Normal file
14
flask_website/__init__.py
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
from flask import Flask, render_template
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.errorhandler(404)
|
||||
def not_found(error):
|
||||
return render_template('404.html'), 404
|
||||
|
||||
from flask_website.views.general import general
|
||||
from flask_website.views.mailinglist import mailinglist
|
||||
from flask_website.views.snippets import snippets
|
||||
app.register_module(general)
|
||||
app.register_module(mailinglist)
|
||||
app.register_module(snippets)
|
||||
BIN
flask_website/static/logo.png
Normal file
BIN
flask_website/static/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
34
flask_website/static/mailinglist.js
Normal file
34
flask_website/static/mailinglist.js
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
$(function() {
|
||||
var first_mail = $('div.mail:first')[0].id;
|
||||
|
||||
function display(id) {
|
||||
var pos = {
|
||||
x: window.pageXOffset || document.body.scrollLeft,
|
||||
y: window.pageYOffset || document.body.scrollTop
|
||||
};
|
||||
$('ul.mailtree div.link').removeClass('selected');
|
||||
$('#link-' + id).addClass('selected').focus();
|
||||
$('div.mail').hide();
|
||||
$('h2:first').text($('h3', $('#' + id).show()).text());
|
||||
if (!(document.location.hash == '' && id == first_mail))
|
||||
document.location.href = '#' + id;
|
||||
window.scrollTo(pos.x, pos.y);
|
||||
}
|
||||
|
||||
$('div.mail')
|
||||
.addClass('dynamic-mail')
|
||||
.appendTo($('<div></div>').insertBefore('div.mail:first'))
|
||||
.hide();
|
||||
$('div.mail h3').hide();
|
||||
|
||||
$('div.link').each(function() {
|
||||
var id = $('a', $(this).parent()).attr('href').substr(1);
|
||||
$(this).click(function() {
|
||||
display(id);
|
||||
return false;
|
||||
});
|
||||
}).css({cursor: 'pointer'});
|
||||
|
||||
var href = document.location.href.split(/#/, 2)[1];
|
||||
display(href != null ? href : first_mail);
|
||||
});
|
||||
BIN
flask_website/static/mailinglist.png
Executable file
BIN
flask_website/static/mailinglist.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
BIN
flask_website/static/mask.png
Normal file
BIN
flask_website/static/mask.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
BIN
flask_website/static/ship.png
Normal file
BIN
flask_website/static/ship.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 61 KiB |
BIN
flask_website/static/snippets.png
Normal file
BIN
flask_website/static/snippets.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
47
flask_website/static/style.css
Normal file
47
flask_website/static/style.css
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
body { font-family: 'Georgia', serif; font-size: 17px; color: #000; }
|
||||
a { color: #004B6B; }
|
||||
a:hover { color: #6D4100; }
|
||||
.box { width: 540px; margin: 40px auto; }
|
||||
h1, h2, h3 { font-family: 'Garamond', 'Georgia', serif; font-weight: normal; }
|
||||
h2 { font-size: 28px; margin: 15px 0 5px 0; }
|
||||
h3 { font-size: 22px; margin: 15px 0 5px 0; }
|
||||
code,
|
||||
pre { font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono',
|
||||
monospace; font-size: 15px; background: #eee; }
|
||||
pre { padding: 7px 30px; margin: 15px -30px; line-height: 1.3; }
|
||||
.ig { color: #888; }
|
||||
p { line-height: 1.4; }
|
||||
ul { margin: 15px 0 15px 0; padding: 0; list-style: none; line-height: 1.4; }
|
||||
ul li:before { content: "\00BB \0020"; color: #888; position: absolute; margin-left: -19px; }
|
||||
blockquote { margin: 0; font-style: italic; color: #444; }
|
||||
.footer { font-size: 13px; color: #888; text-align: right; margin-top: 25px; }
|
||||
.nav { text-align: center; }
|
||||
.nav a { font-style: italic; }
|
||||
.backnav { float: right; color: #444; font-style: italic;
|
||||
margin: 5px 0 0 0; font-size: 0.9em; }
|
||||
|
||||
/* mailinglist */
|
||||
.pagination { text-align: center; font-size: 15px; margin: 20px 0 0 0; }
|
||||
.disabled { color: #888; }
|
||||
.archive .meta { font-size: 0.9em; display: block; margin: 0 0 0.5em 1em; }
|
||||
.mailtree { border-top: 1px solid black; padding: 5px 12px 5px 12px;
|
||||
border-bottom: 1px solid black; font-size: 14px;
|
||||
max-height: 100px; overflow: auto; }
|
||||
.mailtree ul { margin: 0 0 0 15px; line-height: 1.5; }
|
||||
.mailtree li:before { display: none; }
|
||||
.mailtree .selected { background: #fafafa; }
|
||||
.mailtree .selected:before { content: "\00BB\0020"; color: #888;
|
||||
position: relative; margin-left: -12px;
|
||||
width: 12px!important; }
|
||||
.mail { margin: 15px 0; }
|
||||
.children .mail { margin: 15px 0 15px 20px; }
|
||||
.dynamic-mail { margin-left: 0!important; }
|
||||
.mail dl { margin: 0; padding-bottom: 15px;
|
||||
border-bottom: 1px solid black; }
|
||||
.mail dl dt { color: #888; width: 70px; float: left; height: 20px; }
|
||||
.mail dl dd { height: 20px; width: 500px; }
|
||||
.mail dl dd.from { text-decoration: underline; }
|
||||
.mail pre { background: transparent; font-size: 13px;
|
||||
line-height: 1.15; }
|
||||
.mail .quote { color: #004B6B; }
|
||||
.mail .sig { color: #888; }
|
||||
47
flask_website/templates/404.html
Normal file
47
flask_website/templates/404.html
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<!doctype html>
|
||||
<title>Chapter 404: The Lost Page</title>
|
||||
<style type=text/css>
|
||||
body, html {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
background: url(/static/ship.png) no-repeat center right;
|
||||
}
|
||||
|
||||
body:after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 30px;
|
||||
background: url(/static/mask.png) repeat-y left;
|
||||
}
|
||||
|
||||
a { color: #004B6B; }
|
||||
a:hover { color: #6D4100; }
|
||||
|
||||
h1 {
|
||||
font-family: 'Garamond', 'Georgia', serif;
|
||||
font-weight: normal;
|
||||
color: #222;
|
||||
font-size: 36px;
|
||||
padding: 50px 0 10px 50px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
font-family: 'Georgia', serif;
|
||||
color: #000;
|
||||
font-size: 17px;
|
||||
padding: 10px 0 0 90px;
|
||||
margin: 0;
|
||||
width: 360px;
|
||||
}
|
||||
</style>
|
||||
<h1>Chapter 404: The Lost Page</h1>
|
||||
<p>A careful and diligent search has been made for the desired page, but it just cannot be found.
|
||||
<p>And so they returned to <a href=/>familiar waters</a>.
|
||||
72
flask_website/templates/general/index.html
Normal file
72
flask_website/templates/general/index.html
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
{% extends "layout.html" %}
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
<style type=text/css>
|
||||
h1 { margin: 0 0 30px 0; background: url(/static/logo.png) no-repeat center; height: 165px; }
|
||||
h1 span, p.tagline { display: none; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% block body_title %}
|
||||
{{ super() }}
|
||||
<p class=tagline>because sometimes a pocket knife is not enough
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<blockquote>
|
||||
Flask is a microframework for Python based on Werkzeug, Jinja 2 and good intentions.
|
||||
And before you ask: It's <a href=docs/license/>BSD licensed</a>!
|
||||
</blockquote>
|
||||
<h2>Flask is Fun</h2>
|
||||
<pre><span class=ig>from flask import Flask
|
||||
app = Flask(__name__)</span>
|
||||
|
||||
@app.route("/")
|
||||
def hello():
|
||||
return "Hello World!"
|
||||
|
||||
<span class=ig>if __name__ == "__main__":
|
||||
app.run()</span></pre>
|
||||
<h2>And Easy to Setup</h2>
|
||||
<pre><span class=ig>$ </span>easy_install Flask
|
||||
<span class=ig>$ </span>python hello.py
|
||||
<span class=ig> * Running on http://localhost:5000/</span></pre>
|
||||
<h2>Interested?</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a href=docs/>Read the documentation</a> or download as
|
||||
<a href=docs/flask-docs.pdf>PDF</a> and
|
||||
<a href=docs/flask-docs.zip>zipped HTML</a>
|
||||
<li><a href=mailinglist/>Join the mailinglist</a>
|
||||
<li><a href=http://github.com/mitsuhiko/flask>Fork it on github</a>
|
||||
<li><a href=http://pypi.python.org/pypi/Flask>Download it from PyPI</a>
|
||||
</ul>
|
||||
<h2>What’s in the Box?</h2>
|
||||
<ul>
|
||||
<li>built in development server and <a href=docs/quickstart/#debug-mode>debugger</a>
|
||||
<li>integrated support for <a href=docs/testing/>unittesting support</a>
|
||||
<li>RESTful <a href=docs/quickstart/#routing>request dispatching</a>
|
||||
<li>uses <a href=http://jinja.pocoo.org/2/documentation/templates>Jinja2 templating</a>
|
||||
<li>support for <a href=docs/quickstart/#sessions>secure cookies</a> (client side sessions)
|
||||
<li>100% <a href=http://www.python.org/dev/peps/pep-0333/>WSGI 1.0</a> compliant
|
||||
<li>Unicode based
|
||||
</ul>
|
||||
<h2>What do Flask Apps look like?</h2>
|
||||
<p>
|
||||
If you are looking for some example code of applications written with Flask,
|
||||
have a look at the sources of the examples on github:
|
||||
<ul>
|
||||
<li><a href=http://github.com/mitsuhiko/flask/tree/master/examples/flaskr/>flaskr</a>
|
||||
— a microblog
|
||||
<li><a href=http://github.com/mitsuhiko/flask/tree/master/examples/minitwit/>minitwit</a>
|
||||
— a twitter clone
|
||||
<li><a href=http://github.com/mitsuhiko/flask/tree/website>this website</a>
|
||||
— static pages + mailinglist archives
|
||||
</ul>
|
||||
<h2>Contribute</h2>
|
||||
<p>Found a bug? Have a good idea for improving Flask? Head over to
|
||||
<a href=http://github.com/mitsuhiko/flask>Flask's github</a> page and
|
||||
create a new ticket or fork. If you just want to chat with fellow
|
||||
developers, go to <code>#pocoo</code> on irc.freenode.net.
|
||||
|
||||
<a href="http://github.com/mitsuhiko/flask"><img style="position: fixed; top: 0; right: 0; border: 0;"
|
||||
src="http://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png" alt="Fork me on GitHub"></a>
|
||||
{% endblock %}
|
||||
20
flask_website/templates/layout.html
Normal file
20
flask_website/templates/layout.html
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<!doctype html>
|
||||
{% block head %}
|
||||
<title>{% block title %}Welcome{% endblock %} | Flask (A Python Microframework)</title>
|
||||
<meta charset=utf-8>
|
||||
<link rel=stylesheet type=text/css href="/static/style.css">
|
||||
<script type=text/javascript
|
||||
src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
|
||||
{% endblock %}
|
||||
<div class=box>
|
||||
{% block body_title %}
|
||||
<h1><span>{{ self.title() }}</span></h1>
|
||||
{% endblock %}
|
||||
<p class=nav>
|
||||
<a href=/>overview</a> //
|
||||
<a href=/docs/>documentation</a> //
|
||||
<a href=/mailinglist/>mailinglist</a> //
|
||||
<a href=/snippets/>snippets</a>
|
||||
{% block body %}{% endblock %}
|
||||
<p class=footer>© Copyright 2010 by <a href=http://lucumr.pocoo.org/>Armin Ronacher</a>
|
||||
</div>
|
||||
27
flask_website/templates/mailinglist/archive.html
Normal file
27
flask_website/templates/mailinglist/archive.html
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{% extends "mailinglist/layout.html" %}
|
||||
{% block title %}Mailinglist Archive{% endblock %}
|
||||
{% block body %}
|
||||
<h2>Mailinglist Archive</h2>
|
||||
<ul class=archive>
|
||||
{% for thread in threads %}
|
||||
<li><a href="{{ thread.url }}">{{ thread.title }}</a>
|
||||
<span class=meta>
|
||||
by {{ thread.author_name or thread.author_email }}
|
||||
on {{ thread.date.strftime('%Y-%m-%d @ %H:%M') }}
|
||||
({{ thread.reply_count }} repl{{ thread.reply_count == 1 and 'y' or 'ies' }})</span>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<div class=pagination>
|
||||
{% if page > 1 %}
|
||||
<a href="{{ url_for('mailinglist.archive', page=page - 1) }}">« Previous</a>
|
||||
{% else %}
|
||||
<span class=disabled>« Previous</span>
|
||||
{% endif %}
|
||||
| <strong>{{ page }}</strong> |
|
||||
{% if page < page_count %}
|
||||
<a href="{{ url_for('mailinglist.archive', page=page + 1) }}">Next »</a>
|
||||
{% else %}
|
||||
<span class=disabled>Next »</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
20
flask_website/templates/mailinglist/index.html
Normal file
20
flask_website/templates/mailinglist/index.html
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{% extends "mailinglist/layout.html" %}
|
||||
{% block title %}Mailinglist{% endblock %}
|
||||
{% block body %}
|
||||
<p>
|
||||
There is a mailinglist for Flask hosted on <a
|
||||
href=http://librelist.com/>librelist</a> you can use for both user requests
|
||||
and development discussions.
|
||||
|
||||
<p>
|
||||
To subscribe, send a mail to <em>flask@librelist.com</em> and reply
|
||||
to the confirmation mail. Make sure to check your Spam folder, just in
|
||||
case. To unsubscribe again, send a mail to
|
||||
<em>flask-unsubscribe@librelist.com</em> and reply to the
|
||||
confirmation mail.
|
||||
|
||||
<p>
|
||||
The <a href="{{ url_for('mailinglist.archive') }}">mailinglist archive</a>
|
||||
is synched every hour. Go there to read up old discussions grouped by
|
||||
thread.
|
||||
{% endblock %}
|
||||
11
flask_website/templates/mailinglist/layout.html
Normal file
11
flask_website/templates/mailinglist/layout.html
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{% extends "layout.html" %}
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
<style type=text/css>
|
||||
h1 { margin: 0 0 30px 0; background: url(/static/mailinglist.png) no-repeat center; height: 165px; }
|
||||
h1 span { display: none; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% block body_title %}
|
||||
<h1><span>Flask Mailinglist</span></h1>
|
||||
{% endblock %}
|
||||
36
flask_website/templates/mailinglist/show_thread.html
Normal file
36
flask_website/templates/mailinglist/show_thread.html
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
{% extends "mailinglist/layout.html" %}
|
||||
{% block title %}{{ thread.title }}{% endblock %}
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
<script type=text/javascript src=/static/mailinglist.js></script>
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<p class=backnav>
|
||||
<a href=/mailinglist/archive/>« back to archive</a>
|
||||
<h2>{{ thread.title }}</h2>
|
||||
|
||||
<ul class=mailtree>
|
||||
{% for mail in [thread.root] recursive %}
|
||||
<li><div class=link id="link-{{ mail.id }}"><a href="#{{
|
||||
mail.id }}">{{ mail.subject }}</a> by {{
|
||||
mail.author_name or mail.author_email }}</div>
|
||||
{% if mail.children %}<ul>{{ loop(mail.children) }}</ul>{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% for mail in [thread.root] recursive %}
|
||||
<div class=mail id="{{ mail.id }}">
|
||||
<h3>{{ mail.subject }}</h3>
|
||||
<dl>
|
||||
<dt>From:
|
||||
<dd class=from>{{ mail.author_name or mail.author_email }}
|
||||
<dt>Date:
|
||||
<dd>{{ mail.date.strftime('%Y-%m-%d @ %H:%M') }}
|
||||
</dl>
|
||||
<pre>{{ mail.rendered_text }}</pre>
|
||||
{% if mail.children %}
|
||||
<div class=children>{{ loop(mail.children) }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
17
flask_website/templates/snippets/index.html
Normal file
17
flask_website/templates/snippets/index.html
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{% extends "snippets/layout.html" %}
|
||||
{% block title %}Snippets Archive{% endblock %}
|
||||
{% block body %}
|
||||
<p>
|
||||
Welcome to the Flask snippet archive. This is the place where anyone
|
||||
can drop helpful pieces of code for others to use.
|
||||
<p>
|
||||
In order to add snippets to this page or to add comments, all you need
|
||||
is an <a href=http://en.wikipedia.org/wiki/OpenID>OpenID</a> account.
|
||||
<form action=/snippets/search/ method=get>
|
||||
<p>
|
||||
Search snippets:
|
||||
<input type=text name=q size=30>
|
||||
<input type=submit value=Search>
|
||||
</form>
|
||||
<h2>Snippets by Category</h2>
|
||||
{% endblock %}
|
||||
11
flask_website/templates/snippets/layout.html
Normal file
11
flask_website/templates/snippets/layout.html
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{% extends "layout.html" %}
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
<style type=text/css>
|
||||
h1 { margin: 0 0 30px 0; background: url(/static/snippets.png) no-repeat center; height: 165px; }
|
||||
h1 span { display: none; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% block body_title %}
|
||||
<h1><span>Flask Snippets</span></h1>
|
||||
{% endblock %}
|
||||
0
flask_website/views/__init__.py
Normal file
0
flask_website/views/__init__.py
Normal file
8
flask_website/views/general.py
Normal file
8
flask_website/views/general.py
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
from flask import Module, render_template
|
||||
|
||||
general = Module(__name__)
|
||||
|
||||
|
||||
@general.route('/')
|
||||
def index():
|
||||
return render_template('general/index.html')
|
||||
97
flask_website/views/mailinglist.py
Normal file
97
flask_website/views/mailinglist.py
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
from __future__ import with_statement
|
||||
import os
|
||||
from hashlib import md5
|
||||
from werkzeug import parse_date
|
||||
from jinja2.utils import urlize
|
||||
from flask import Module, render_template, json, url_for, abort, Markup
|
||||
|
||||
mailinglist = Module(__name__)
|
||||
THREADS_PER_PAGE = 15
|
||||
MAILINGLIST_PATH = os.path.join(os.path.dirname(__file__), '..', '..', '_mailinglist')
|
||||
|
||||
|
||||
class Mail(object):
|
||||
|
||||
def __init__(self, d):
|
||||
self.msgid = d['msgid']
|
||||
self.author_name, self.author_addr = d['author']
|
||||
self.date = parse_date(d['date'])
|
||||
self.subject = d['subject']
|
||||
self.children = [Mail(x) for x in d['children']]
|
||||
self.text = d['text']
|
||||
|
||||
@property
|
||||
def rendered_text(self):
|
||||
result = []
|
||||
in_sig = False
|
||||
for line in self.text.splitlines():
|
||||
if line == u'-- ':
|
||||
in_sig = True
|
||||
if in_sig:
|
||||
line = Markup(u'<span class=sig>%s</span>' % line)
|
||||
elif line.startswith('>'):
|
||||
line = Markup(u'<span class=quote>%s</span>' % line)
|
||||
result.append(urlize(line))
|
||||
return Markup(u'\n'.join(result))
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
return md5(self.msgid.encode('utf-8')).hexdigest()
|
||||
|
||||
|
||||
class Thread(object):
|
||||
|
||||
def __init__(self, d):
|
||||
self.slug = d['slug'].rsplit('/', 1)[-1]
|
||||
self.title = d['title']
|
||||
self.reply_count = d['reply_count']
|
||||
self.author_name, self.author_email = d['author']
|
||||
self.date = parse_date(d['date'])
|
||||
if 'root' in d:
|
||||
self.root = Mail(d['root'])
|
||||
|
||||
@staticmethod
|
||||
def get(year, month, day, slug):
|
||||
try:
|
||||
with open('%s/threads/%s-%02d-%02d/%s' %
|
||||
(MAILINGLIST_PATH, year, month, day, slug)) as f:
|
||||
return Thread(json.load(f))
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def get_list():
|
||||
with open('%s/threads/threadlist' % MAILINGLIST_PATH) as f:
|
||||
return [Thread(x) for x in json.load(f)]
|
||||
|
||||
@property
|
||||
def url(self):
|
||||
return url_for('mailinglist.show_thread', year=self.date.year,
|
||||
month=self.date.month, day=self.date.day,
|
||||
slug=self.slug)
|
||||
|
||||
|
||||
@mailinglist.route('/mailinglist/')
|
||||
def index():
|
||||
return render_template('mailinglist/index.html')
|
||||
|
||||
|
||||
@mailinglist.route('/mailinglist/archive/', defaults={'page': 1})
|
||||
@mailinglist.route('/mailinglist/archive/page/<int:page>/')
|
||||
def archive(page):
|
||||
all_threads = Thread.get_list()
|
||||
offset = (page - 1) * THREADS_PER_PAGE
|
||||
threads = all_threads[offset:offset + THREADS_PER_PAGE]
|
||||
if page != 1 and not threads:
|
||||
abort(404)
|
||||
return render_template('mailinglist/archive.html',
|
||||
page_count=len(threads) // THREADS_PER_PAGE + 1,
|
||||
page=page, threads=threads)
|
||||
|
||||
|
||||
@mailinglist.route('/mailinglist/archive/<int:year>/<int:month>/<int:day>/<slug>/')
|
||||
def show_thread(year, month, day, slug):
|
||||
thread = Thread.get(year, month, day, slug)
|
||||
if thread is None:
|
||||
abort(404)
|
||||
return render_template('mailinglist/show_thread.html', thread=thread)
|
||||
8
flask_website/views/snippets.py
Normal file
8
flask_website/views/snippets.py
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
from flask import Module, render_template
|
||||
|
||||
snippets = Module(__name__, url_prefix='/snippets')
|
||||
|
||||
|
||||
@snippets.route('/')
|
||||
def index():
|
||||
return render_template('snippets/index.html')
|
||||
Loading…
Add table
Add a link
Reference in a new issue