Drag this branch up into the current century
This commit is contained in:
parent
50ceeba973
commit
045e452f5b
@ -3,3 +3,6 @@ dist
|
|||||||
*.pyc
|
*.pyc
|
||||||
__pycache__
|
__pycache__
|
||||||
*.egg-info
|
*.egg-info
|
||||||
|
config.ini
|
||||||
|
scribeengine.sqlite
|
||||||
|
.env
|
||||||
|
14
README.rst
14
README.rst
@ -10,19 +10,11 @@ Install ScribeEngine using ``pip``::
|
|||||||
|
|
||||||
pip install ScribeEngine
|
pip install ScribeEngine
|
||||||
|
|
||||||
Create a config file with these options set::
|
Run the setup wizard to create a config file::
|
||||||
|
|
||||||
[mail]
|
$ python -m scribeengine.config
|
||||||
server = mail.example.com
|
|
||||||
port = 25
|
|
||||||
use_tls = false
|
|
||||||
username = me
|
|
||||||
password = secret
|
|
||||||
|
|
||||||
[sqlalchemy]
|
|
||||||
database_uri = sqlite:///scribeengine.sqlite
|
|
||||||
|
|
||||||
Run a local server::
|
Run a local server::
|
||||||
|
|
||||||
$ python -m scribeengine.application.run()
|
$ python -m scribeengine
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
[sqlalchemy]
|
[flask]
|
||||||
|
secret_key = changeme
|
||||||
|
|
||||||
|
[sqlalchemy]
|
||||||
|
database_uri = sqlite:///scribeengine.sqlite
|
||||||
|
track_modifications = false
|
||||||
|
|
||||||
[mail]
|
[mail]
|
||||||
username = email@example.com
|
username = email@example.com
|
||||||
@ -13,3 +17,14 @@ use_tls = false
|
|||||||
[theme]
|
[theme]
|
||||||
paths =
|
paths =
|
||||||
default =
|
default =
|
||||||
|
|
||||||
|
[user]
|
||||||
|
app_name = ScribeEngine
|
||||||
|
enable_email = true
|
||||||
|
enable_username = false
|
||||||
|
email_sender_email = noreply@example.com
|
||||||
|
|
||||||
|
[site]
|
||||||
|
name = Example Blog
|
||||||
|
slogan = An example of a blog
|
||||||
|
about = This is an example of a blog using the ScribeEngine blogging engine
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
from scribeengine import application
|
|
||||||
application.run(host='0.0.0.0', port=8080, debug=True)
|
|
@ -3,10 +3,11 @@ Flask-Admin
|
|||||||
Flask-Login
|
Flask-Login
|
||||||
Flask-Mail
|
Flask-Mail
|
||||||
Flask-SQLAlchemy
|
Flask-SQLAlchemy
|
||||||
Flask-Themes
|
Flask-Themes2
|
||||||
Flask-Uploads
|
Flask-Uploads
|
||||||
Flask-User
|
Flask-User
|
||||||
Flask-WTF
|
Flask-WTF
|
||||||
passlib
|
passlib
|
||||||
py-bcrypt
|
py-bcrypt
|
||||||
pycrypto
|
pycrypto
|
||||||
|
pytz
|
||||||
|
@ -26,12 +26,22 @@ import os
|
|||||||
|
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
from flask_mail import Mail
|
from flask_mail import Mail
|
||||||
from flask_themes import setup_themes
|
from flask_themes2 import Themes, packaged_themes_loader, theme_paths_loader, load_themes_from
|
||||||
from flask_user import SQLAlchemyAdapter, UserManager
|
from flask_user import UserManager
|
||||||
|
|
||||||
from scribeengine.config import read_config_from_file
|
from scribeengine.config import read_config_from_file
|
||||||
from scribeengine.db import db
|
from scribeengine.db import db
|
||||||
from scribeengine.models import User
|
from scribeengine.models import User
|
||||||
|
from scribeengine.views.account import account
|
||||||
|
from scribeengine.views.blog import blog
|
||||||
|
|
||||||
|
|
||||||
|
def _scribeengine_themes_loader(app):
|
||||||
|
"""
|
||||||
|
Loads ScribeEngine's themes
|
||||||
|
"""
|
||||||
|
themes_path = os.path.join(os.path.dirname(__file__), 'themes')
|
||||||
|
return load_themes_from(themes_path)
|
||||||
|
|
||||||
|
|
||||||
def create_app(config_file=None):
|
def create_app(config_file=None):
|
||||||
@ -43,19 +53,23 @@ def create_app(config_file=None):
|
|||||||
if not config_file:
|
if not config_file:
|
||||||
if os.environ.get('SCRIBEENGINE_CONFIG'):
|
if os.environ.get('SCRIBEENGINE_CONFIG'):
|
||||||
config_file = os.environ['SCRIBEENGINE_CONFIG']
|
config_file = os.environ['SCRIBEENGINE_CONFIG']
|
||||||
elif os.path.exists('sundaybuilder.conf'):
|
elif os.path.exists('config.ini'):
|
||||||
config_file = 'sundaybuilder.conf'
|
config_file = 'config.ini'
|
||||||
if config_file:
|
if config_file:
|
||||||
application.config.update(read_config_from_file(config_file))
|
application.config.update(read_config_from_file(config_file))
|
||||||
# Set up mail, themes
|
# Set up mail, themes
|
||||||
Mail(application)
|
Mail(application)
|
||||||
setup_themes(application, app_identifier='ScribeEngine')
|
Themes(application, app_identifier='ScribeEngine', loaders=[
|
||||||
|
_scribeengine_themes_loader, packaged_themes_loader, theme_paths_loader])
|
||||||
|
print(application.root_path)
|
||||||
|
print(application.theme_manager.themes)
|
||||||
# Set up database
|
# Set up database
|
||||||
db.init_app(application)
|
db.init_app(application)
|
||||||
db.create_all()
|
db.create_all(app=application)
|
||||||
# Setup Flask-User
|
# Setup Flask-User
|
||||||
db_adapter = SQLAlchemyAdapter(db, User) # Register the User model
|
UserManager(application, db, User)
|
||||||
user_manager = UserManager(db_adapter, application) # Initialize Flask-User
|
|
||||||
# Register all the blueprints
|
# Register all the blueprints
|
||||||
|
application.register_blueprint(blog)
|
||||||
|
application.register_blueprint(account)
|
||||||
# Return the application object
|
# Return the application object
|
||||||
return application
|
return application
|
||||||
|
3
scribeengine/__main__.py
Normal file
3
scribeengine/__main__.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
from scribeengine import create_app
|
||||||
|
create_app().run(host='0.0.0.0', port=9080, debug=True)
|
@ -20,10 +20,21 @@
|
|||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
"""
|
"""
|
||||||
The :mod:`~scribeengine.themes` module contains some theme helper methods
|
The :mod:`~scribeengine.helpers` module contains some theme helper methods
|
||||||
"""
|
"""
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
from flask_themes import get_theme, render_theme_template
|
from flask_themes2 import get_theme, render_theme_template
|
||||||
|
|
||||||
|
from scribeengine.models import Site
|
||||||
|
|
||||||
|
|
||||||
|
def get_site_details():
|
||||||
|
"""
|
||||||
|
Returns an object with the details of the site
|
||||||
|
"""
|
||||||
|
return Site(current_app.config.get('SITE_NAME', 'Example Blog'),
|
||||||
|
current_app.config.get('SITE_SLOGAN', 'From the Firehose'),
|
||||||
|
current_app.config.get('SITE_ABOUT', ''))
|
||||||
|
|
||||||
|
|
||||||
def get_current_theme():
|
def get_current_theme():
|
||||||
@ -38,4 +49,5 @@ def render(template, **context):
|
|||||||
"""
|
"""
|
||||||
Render a template, after selecting a theme
|
Render a template, after selecting a theme
|
||||||
"""
|
"""
|
||||||
|
context.update({'site': get_site_details(), 'archives': []})
|
||||||
return render_theme_template(get_current_theme(), template, **context)
|
return render_theme_template(get_current_theme(), template, **context)
|
@ -202,9 +202,9 @@ class User(Model, UserMixin):
|
|||||||
confirmed_at = Column(DateTime)
|
confirmed_at = Column(DateTime)
|
||||||
active = Column('is_active', Boolean, nullable=False, server_default='0')
|
active = Column('is_active', Boolean, nullable=False, server_default='0')
|
||||||
|
|
||||||
comments = relationship('Comment', backref='user'),
|
comments = relationship('Comment', backref='user')
|
||||||
files = relationship('File', backref='user'),
|
files = relationship('File', backref='user')
|
||||||
posts = relationship('Post', backref='user'),
|
posts = relationship('Post', backref='user')
|
||||||
roles = relationship('Role', backref='users', secondary=roles_users)
|
roles = relationship('Role', backref='users', secondary=roles_users)
|
||||||
|
|
||||||
def has_permission(self, permission):
|
def has_permission(self, permission):
|
||||||
@ -239,3 +239,17 @@ class Variable(Model):
|
|||||||
key = Column(String(100), primary_key=True, index=True)
|
key = Column(String(100), primary_key=True, index=True)
|
||||||
value = Column(String(100), nullable=False)
|
value = Column(String(100), nullable=False)
|
||||||
type = Column(String(10), default='string')
|
type = Column(String(10), default='string')
|
||||||
|
|
||||||
|
|
||||||
|
class Site(object):
|
||||||
|
"""
|
||||||
|
Generic model to hold the site-specfic data
|
||||||
|
"""
|
||||||
|
name = None
|
||||||
|
slogan = None
|
||||||
|
about = None
|
||||||
|
|
||||||
|
def __init__(self, name, slogan=None, about=None):
|
||||||
|
self.name = name
|
||||||
|
self.slogan = slogan
|
||||||
|
self.about = about
|
||||||
|
12
scribeengine/themes/quill/info.json
Normal file
12
scribeengine/themes/quill/info.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"application": "ScribeEngine",
|
||||||
|
"identifier": "quill",
|
||||||
|
"name": "Quill",
|
||||||
|
"author": "Raoul Snyman",
|
||||||
|
"description": "A basic theme built using Bootstrap 4 and based on Bootstrap 4's blog example",
|
||||||
|
"website": "https://scribeengine.org",
|
||||||
|
"license": "GPL3+",
|
||||||
|
"preview": "screenshot.png",
|
||||||
|
"doctype": "html5",
|
||||||
|
"version": "0.1"
|
||||||
|
}
|
141
scribeengine/themes/quill/static/css/quill.css
Normal file
141
scribeengine/themes/quill/static/css/quill.css
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/* stylelint-disable selector-list-comma-newline-after */
|
||||||
|
|
||||||
|
.blog-header {
|
||||||
|
line-height: 1;
|
||||||
|
border-bottom: 1px solid #e5e5e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blog-header-logo {
|
||||||
|
font-family: "Playfair Display", Georgia, "Times New Roman", serif;
|
||||||
|
font-size: 2.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blog-header-logo:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
font-family: "Playfair Display", Georgia, "Times New Roman", serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.display-4 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.display-4 {
|
||||||
|
font-size: 3rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-scroller {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
height: 2.75rem;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-scroller .nav {
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-ms-flex-wrap: nowrap;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
margin-top: -1px;
|
||||||
|
overflow-x: auto;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-scroller .nav-link {
|
||||||
|
padding-top: .75rem;
|
||||||
|
padding-bottom: .75rem;
|
||||||
|
font-size: .875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-img-right {
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 0 3px 3px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-auto {
|
||||||
|
-ms-flex: 0 0 auto;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-250 { height: 250px; }
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.h-md-250 { height: 250px; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Blog name and description
|
||||||
|
*/
|
||||||
|
.blog-title {
|
||||||
|
margin-bottom: 0;
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
.blog-description {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 40em) {
|
||||||
|
.blog-title {
|
||||||
|
font-size: 3.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pagination */
|
||||||
|
.blog-pagination {
|
||||||
|
margin-bottom: 4rem;
|
||||||
|
}
|
||||||
|
.blog-pagination > .btn {
|
||||||
|
border-radius: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Blog posts
|
||||||
|
*/
|
||||||
|
.blog-post {
|
||||||
|
margin-bottom: 4rem;
|
||||||
|
}
|
||||||
|
.blog-post-title {
|
||||||
|
margin-bottom: .25rem;
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
.blog-post-meta {
|
||||||
|
margin-bottom: 1.25rem;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Footer
|
||||||
|
*/
|
||||||
|
.blog-footer {
|
||||||
|
padding: 2.5rem 0;
|
||||||
|
color: #999;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
border-top: .05rem solid #e5e5e5;
|
||||||
|
}
|
||||||
|
.blog-footer p:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.bd-placeholder-img {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
text-anchor: middle;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.bd-placeholder-img-lg {
|
||||||
|
font-size: 3.5rem;
|
||||||
|
}
|
||||||
|
}
|
4
scribeengine/themes/quill/templates/about.html
Normal file
4
scribeengine/themes/quill/templates/about.html
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<div class="p-4 mb-3 bg-light rounded">
|
||||||
|
<h4 class="font-italic">About</h4>
|
||||||
|
<p class="mb-0">{{site.about}}</p>
|
||||||
|
</div>
|
8
scribeengine/themes/quill/templates/archives.html
Normal file
8
scribeengine/themes/quill/templates/archives.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<div class="p-4">
|
||||||
|
<h4 class="font-italic">Archives</h4>
|
||||||
|
<ol class="list-unstyled mb-0">
|
||||||
|
{% for archive in archives %}
|
||||||
|
<li><a href="/{{archive.year}}/{{archive.month}}">{{archive.month_name}} {{archive.year}}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ol>
|
||||||
|
</div>
|
17
scribeengine/themes/quill/templates/base.html
Normal file
17
scribeengine/themes/quill/templates/base.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<title>{{title}}</title>
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Playfair+Display:700,900">
|
||||||
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||||
|
<link rel="stylesheet" href="{{ theme_static('css/quill.css') }}">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{% include theme("header.html") %}
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
{% include theme("footer.html") %}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
30
scribeengine/themes/quill/templates/blog.html
Normal file
30
scribeengine/themes/quill/templates/blog.html
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{% extends theme("base.html") %}
|
||||||
|
{% block content %}
|
||||||
|
<main role="main" class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8 blog-main">
|
||||||
|
{% if site.slogan %}
|
||||||
|
<h3 class="pb-4 mb-4 font-italic border-bottom">{{site.slogan}}</h3>
|
||||||
|
{% endif %}
|
||||||
|
{% for post in posts %}
|
||||||
|
{% include theme("post-teaser.html") %}
|
||||||
|
{% endfor %}
|
||||||
|
<nav class="blog-pagination">
|
||||||
|
<a class="btn btn-outline-primary" href="{{request.base_url}}?page={{'1'}}">Older</a>
|
||||||
|
<a class="btn btn-outline-secondary disabled" href="{{request.base_url}}?page={{'1'}}" tabindex="-1" aria-disabled="true">Newer</a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<aside class="col-md-4 blog-sidebar">
|
||||||
|
{% if site.about %}
|
||||||
|
{% include theme("about.html") %}
|
||||||
|
{% endif %}
|
||||||
|
{% if archives %}
|
||||||
|
{% include theme("archives.html") %}
|
||||||
|
{% endif %}
|
||||||
|
{% if site.social_links %}
|
||||||
|
{% include theme("social_links.html") %}
|
||||||
|
{% endif %}
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
{% endblock %}
|
6
scribeengine/themes/quill/templates/footer.html
Normal file
6
scribeengine/themes/quill/templates/footer.html
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<footer class="blog-footer">
|
||||||
|
<p>Blog template built for <a href="https://getbootstrap.com/">Bootstrap</a> by <a href="https://twitter.com/mdo">@mdo</a>.</p>
|
||||||
|
<p>
|
||||||
|
<a href="#">Back to top</a>
|
||||||
|
</p>
|
||||||
|
</footer>
|
9
scribeengine/themes/quill/templates/header.html
Normal file
9
scribeengine/themes/quill/templates/header.html
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<div class="container">
|
||||||
|
<header class="blog-header py-3">
|
||||||
|
<div class="row flex-nowrap justify-content-between align-items-center">
|
||||||
|
<div class="col-12 text-center">
|
||||||
|
<a class="blog-header-logo text-dark" href="#">{{ site.name }}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
</div>
|
5
scribeengine/themes/quill/templates/post-teaser.html
Normal file
5
scribeengine/themes/quill/templates/post-teaser.html
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<div class="blog-post">
|
||||||
|
<h2 class="blog-post-title">{{post.title}}</h2>
|
||||||
|
<p class="blog-post-meta">{{post.created.strftime('%A %d, %B %Y')}} by <a href="/authors/{{post.author.id}}">{{post.user.name}}</a></p>
|
||||||
|
{{post.content}}
|
||||||
|
</div>
|
5
scribeengine/themes/quill/templates/post.html
Normal file
5
scribeengine/themes/quill/templates/post.html
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<div class="blog-post">
|
||||||
|
<h2 class="blog-post-title">{{post.title}}</h2>
|
||||||
|
<p class="blog-post-meta">{{post.created.strftime('%A %d, %B %Y')}} by <a href="/authors/{{post.author.id}}">{{post.user.name}}</a></p>
|
||||||
|
{{post.content}}
|
||||||
|
</div>
|
8
scribeengine/themes/quill/templates/social_links.html
Normal file
8
scribeengine/themes/quill/templates/social_links.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<div class="p-4">
|
||||||
|
<h4 class="font-italic">Elsewhere</h4>
|
||||||
|
<ol class="list-unstyled">
|
||||||
|
{% for link in social_links %}
|
||||||
|
<li><a href="{{link.url}}">{{link.name}}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ol>
|
||||||
|
</div>
|
@ -25,11 +25,11 @@ The :mod:`~scribeengine.views.account` module contains the account views
|
|||||||
from flask import Blueprint
|
from flask import Blueprint
|
||||||
from pytz import all_timezones
|
from pytz import all_timezones
|
||||||
|
|
||||||
from scribeengine.themes import render
|
from scribeengine.helpers import render
|
||||||
|
|
||||||
account = Blueprint('account', __file__, prefix='/account')
|
account = Blueprint('account', __name__, url_prefix='/account')
|
||||||
|
|
||||||
|
|
||||||
@account.route('', methods=['GET'])
|
@account.route('', methods=['GET'])
|
||||||
def index(self):
|
def index():
|
||||||
return render('/account/index.html', page_title='My Account', timezones=all_timezones)
|
return render('/account/index.html', page_title='My Account', timezones=all_timezones)
|
||||||
|
42
scribeengine/views/blog.py
Normal file
42
scribeengine/views/blog.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# ScribeEngine - Open Source Blog Software #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2010-2017 Raoul Snyman #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# This program is free software; you can redistribute it and/or modify it #
|
||||||
|
# under the terms of the GNU General Public License as published by the Free #
|
||||||
|
# Software Foundation; version 2 of the License. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||||
|
# more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License along #
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
|
###############################################################################
|
||||||
|
"""
|
||||||
|
The :mod:`~scribeengine.views.blog` module contains the blog post views
|
||||||
|
"""
|
||||||
|
from flask import Blueprint
|
||||||
|
|
||||||
|
from scribeengine.helpers import render
|
||||||
|
from scribeengine.models import Post
|
||||||
|
|
||||||
|
blog = Blueprint('blog', __name__, url_prefix='/')
|
||||||
|
|
||||||
|
|
||||||
|
@blog.route('', methods=['GET'])
|
||||||
|
def index():
|
||||||
|
posts = Post.query.limit(10).all()
|
||||||
|
return render('/blog.html', title='ScribeEngine', posts=posts)
|
||||||
|
|
||||||
|
|
||||||
|
@blog.route('/<int:year>/<int:month>', methods=['GET'])
|
||||||
|
def archive(year, month=None):
|
||||||
|
posts = Post.query.limit(10).all()
|
||||||
|
return render('/blog.html', title='ScribeEngine', posts=posts)
|
Loading…
Reference in New Issue
Block a user