Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
leafstorm
committed
Jul 15, 2010
1 parent
c731151
commit 94f30e1
Showing
10 changed files
with
318 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
# example posts for Theme Sandbox | ||
# part of Flask-Themes | ||
# copyright 2010 Matthew "LeafStorm" Frazier | ||
# licensed under the MIT/X11 license (see LICENSE for details) | ||
|
||
slug: introduction | ||
created: 2010-07-01 16:00:00 | ||
title: Introduction | ||
body: > | ||
Welcome to the Theme Sandbox. This is a simple Web application intended | ||
to emulate a weblog. Of course, to save on time and effort, all the posts | ||
are pregenerated, and the application is just displaying them. But still, | ||
it gives people a chance to see how themes are implemented. | ||
There are some templates by default, but they aren't particularly shiny. | ||
You will want to set a theme if you want the blog to look good. | ||
--- | ||
|
||
slug: creating-themes | ||
created: 2010-07-01 14:00:00 | ||
title: Creating Themes | ||
body: > | ||
With the Theme Sandbox, probably the easiest way to create a theme is just | ||
to drop it in the "themes/" folder. You can set THEME_PATHS in the | ||
configuration, but that is still the easiest. | ||
To actually create a theme, you will need to check the manual for details. | ||
But it essentially boils down to: | ||
An info.json file that contains metadata about the theme, | ||
A templates/ folder that contains the theme's Jinja2 templates. | ||
A static/ folder containing static files to be served. | ||
A license.txt file (optional) containing the theme's complete license. | ||
--- | ||
|
||
slug: inspirations | ||
created: 2010-07-01 13:00:00 | ||
title: Theme System Inspirations | ||
body: > | ||
My primary inspiration for the theme system was the blogging system Zine. | ||
I didn't implement all its features, like options for themes, simply | ||
because those are tied in to Zine's particular mode of configuration, and | ||
applications will probably have their own. | ||
One person asked if it was inspired by Deliverance. I looked it up, and | ||
thought that it looked confusing. But basically, the differences are that | ||
Flask-Themes is for single applications, Deliverance is for multiple | ||
applications. Flask-Themes works at the template level, Deliverance works | ||
at the HTML level. Flask-Themes doesn't deal with HTML/XML, while | ||
Deliverance does. | ||
--- | ||
|
||
slug: templates | ||
created: 2010-07-01 11:00:00 | ||
title: Templates | ||
body: > | ||
The templates used by this site are: | ||
layout.html, which should have a "body" block and a "head" block (where | ||
"head" is in the HTML head element), and should expect an exported | ||
variable named "title" that is the page's title. | ||
index.html, which accepts a "posts" variable that contains three posts. | ||
_helpers.html, which exports a "link_to" macro that takes a caption, an | ||
endpoint, and keyword arguments. | ||
archive.html, which accepts a "posts" variable that contains *all* of the | ||
posts. | ||
post.html, which accepts a single "post". | ||
about.html, which accepts "text", the about text as Markup. | ||
themes.html, which accepts a list of themes and should create links to | ||
"settheme" for each of them. | ||
--- | ||
|
||
slug: adding-posts | ||
created: 2010-07-01 9:00:00 | ||
title: Adding Posts | ||
body: > | ||
The blog probably seems pretty small to you. And that's the idea - have a | ||
dataset just big enough to simulate real-world usage. But if you want, you | ||
can add more posts. | ||
All the posts are stored in the posts.yaml file. You can add them there. | ||
Slugs must be unique, but that's about the only restriction. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{% macro link_to(text, endpoint) -%} | ||
<a href="{{ url_for(endpoint, **kwargs) }}">{{ text }}</a> | ||
{%- endmacro %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{% macro show_post(post) %} | ||
|
||
<h2>{{ post.title }}</h2> | ||
|
||
<p class=meta>Created on {{ post.created.strftime('%x at %X') }}</p> | ||
|
||
{{ post.content }} | ||
|
||
{% endmacro %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{% extends theme('layout.html') %} | ||
|
||
{% set title = 'About' %} | ||
|
||
{% block body %} | ||
|
||
<h2>About</h2> | ||
|
||
{{ text }} | ||
|
||
{% endblock body %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{% extends theme('layout.html') %} | ||
|
||
{% set title = 'Archive' %} | ||
|
||
{% block body %} | ||
<h2>Archive</h2> | ||
|
||
<ul> | ||
{%- for post in posts %} | ||
<li>{{ link_to(post.title, 'post', slug=post.slug) }} | ||
— created on {{ post.created.strftime('%x at %X') }}</li> | ||
{%- endfor %} | ||
</ul> | ||
{% endblock body %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{% extends theme('layout.html') %} | ||
{% from theme('_post.html') import show_post %} | ||
|
||
{% set title = 'Index' %} | ||
|
||
{% block body %} | ||
|
||
{% for post in posts %} | ||
|
||
{{ show_post(post) }} | ||
|
||
<p class=permalink>{{ link_to('Permalink', 'post', slug=post.slug) }}</p> | ||
|
||
{% endfor %} | ||
|
||
{% endblock body %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<!doctype html> | ||
{% from "_helpers.html" import link_to %} | ||
<head> | ||
<title>Theme Sandbox: {{ title }}</title> | ||
{% block head %}{% endblock head %} | ||
</head> | ||
|
||
<body> | ||
<h1>Theme Sandbox</h1> | ||
|
||
<p> | ||
{{ link_to('Index', 'index') }} | | ||
{{ link_to('Archive', 'archive') }} | | ||
{{ link_to('About', 'about') }} | | ||
{{ link_to('Themes', 'themes') }} | ||
</p> | ||
|
||
{% block body %} | ||
{% endblock body %} | ||
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{% extends theme('layout.html') %} | ||
{% from theme('_post.html') import show_post %} | ||
|
||
{% set title = post.title %} | ||
|
||
{% block body %} | ||
|
||
{{ show_post(post) }} | ||
|
||
{% endblock body %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{% extends theme('layout.html') %} | ||
{% from "_helpers.html" import link_to %} | ||
|
||
{% set title = 'Themes' %} | ||
|
||
{% block body %} | ||
|
||
<h2>Theme Selection</h2> | ||
|
||
{% for theme in themes %} | ||
|
||
<h3>{{ theme.title }}</h3> | ||
|
||
<p>{{ theme.description }}</p> | ||
|
||
<p class=select>{{ link_to('Select this theme', 'settheme', ident=theme.identifier) }}</p> | ||
|
||
{% endfor %} | ||
|
||
{% endblock body %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
""" | ||
themesandbox.py | ||
=============== | ||
A sandbox to play around with themes in. | ||
:copyright: 2010 Matthew "LeafStorm" Frazier | ||
:license: MIT/X11, see LICENSE for details | ||
""" | ||
import yaml | ||
from flask import (Flask, url_for, redirect, session, Markup, abort) | ||
from flaskext.themes import (setup_themes, render_theme_template, | ||
get_themes_list) | ||
from operator import attrgetter | ||
|
||
# default settings | ||
|
||
DEFAULT_THEME = 'calmblue' | ||
SECRET_KEY = 'not really secret' | ||
|
||
|
||
# application | ||
|
||
app = Flask(__name__) | ||
app.config.from_object(__name__) | ||
setup_themes(app, app_identifier='themesandbox') | ||
|
||
|
||
# data | ||
|
||
class Post(object): | ||
def __init__(self, data): | ||
self.slug = data['slug'] | ||
self.body = data['body'] | ||
self.title = data['title'] | ||
self.created = data['created'] | ||
|
||
@property | ||
def content(self): | ||
return Markup('\n\n'.join( | ||
'<p>%s</p>' % line for line in self.body.splitlines() | ||
)) | ||
|
||
|
||
class PostStore(object): | ||
def __init__(self): | ||
self.by_date = [] | ||
self.by_slug = {} | ||
|
||
def add_posts(self, post_data): | ||
posts = [Post(post) for post in post_data] | ||
for post in posts: | ||
if post.slug in self.by_slug: | ||
raise RuntimeError("slugs must be unique") | ||
self.by_slug[post.slug] = post | ||
self.by_date.extend(posts) | ||
self.by_date.sort(key=attrgetter('created'), reverse=True) | ||
|
||
|
||
store = PostStore() | ||
|
||
with app.open_resource('posts.yaml') as fd: | ||
post_data = yaml.load_all(fd) | ||
store.add_posts(post_data) | ||
|
||
|
||
ABOUT_TEXT = Markup('<p>This is a demonstration of Flask-Themes.</p>') | ||
|
||
|
||
# themes | ||
|
||
def render(template, **context): | ||
theme = session.get('theme', app.config['DEFAULT_THEME']) | ||
return render_theme_template(theme, template, **context) | ||
|
||
|
||
# views | ||
|
||
@app.route('/') | ||
def index(): | ||
posts = store.by_date[:3] | ||
return render('index.html', posts=posts) | ||
|
||
|
||
@app.route('/archive') | ||
def archive(): | ||
posts = store.by_date[:] | ||
return render('archive.html', posts=posts) | ||
|
||
|
||
@app.route('/post/<slug>') | ||
def post(slug): | ||
post = store.by_slug.get(slug) | ||
if post is None: | ||
abort(404) | ||
return render('post.html', post=post) | ||
|
||
|
||
@app.route('/about') | ||
def about(): | ||
return render('about.html', text=ABOUT_TEXT) | ||
|
||
|
||
@app.route('/themes/') | ||
def themes(): | ||
themes = get_themes_list() | ||
return render('themes.html', themes=themes) | ||
|
||
|
||
@app.route('/themes/<ident>') | ||
def settheme(ident): | ||
if ident not in app.theme_manager.themes: | ||
abort(404) | ||
session['theme'] = ident | ||
return redirect(url_for('themes')) | ||
|
||
|
||
if __name__ == '__main__': | ||
app.run(debug=True) |