Half-Life 2 is older now than Half-Life was when Half-Life 2 was released. (The same is true for HL2 Episode 2 and HL2).
commit #190
to
johnny-cache
Added a get_generation utility function.
| johnny/cache.py |
commit 7ca03c45
to
humanize
100% test coverage, fix a few bugs with humanize.time.naturaltime, added a humanize.time.naturaldelta which returns strings like "a day" or "1 year, 3 months" without any tense (ago/from now), version bump
-
@@ -6,16 +6,15 @@ humanize ----------- .. automodule:: humanize - .. highlight:: sh You can install humanize with pip:: pip install humanize -You can fork humanize `from its hg repository -<http://bitbucket.org/jmoiron/humanize/>`_:: +You can fork humanize `from its git repository +<http://github.com/jmoiron/humanize/>`_:: - hg clone http://bitbucket.org/jmoiron/humanize/ + git clone https://github.com/jmoiron/humanize.git .. highlight:: python
-
@@ -1,9 +1,9 @@ -VERSION = (0,1) +VERSION = (0,2) from humanize.time import * from humanize.number import * from humanize.filesize import * __all__ = ['VERSION', 'naturalday', 'naturaltime', 'ordinal', 'intword', - 'intcomma', 'apnumber', 'naturalsize'] + 'naturaldelta', 'intcomma', 'apnumber', 'naturalsize']
-
@@ -39,58 +39,90 @@ def date_and_delta(value): return (None, value) return date, abs_timedelta(delta) -def naturaltime(value, date_fallback=30, format='%b %d'): +def naturaldelta(value, months=True): + """Given a timedelta or a number of seconds, return a natural + representation of the amount of time elapsed. This is similar to + ``naturaltime``, but does not add tense to the result. If ``months`` + is True, then a number of months (based on 30.5 days) will be used + for fuzziness between years.""" + now = _now() + date, delta = date_and_delta(value) + if date is None: + return value + + use_months = months + + seconds = abs(delta.seconds) + days = abs(delta.days) + years = days // 365 + days = days % 365 + months = int(days // 30.5) + + if not years and days < 1: + if seconds == 0: + return "a moment" + elif seconds == 1: + return "a second" + elif seconds < 60: + return "%d seconds" % (seconds) + elif 60 <= seconds < 120: + return "a minute" + elif 120 <= seconds < 3600: + return "%d minutes" % (seconds // 60) + elif 3600 <= seconds < 3600*2: + return "an hour" + elif 3600 < seconds: + return "%d hours" % (seconds // 3600) + elif years == 0: + if days == 1: + return "a day" + if not use_months: + return "%d days" % days + else: + if not months: + return "%d days" % days + elif months == 1: + return "a month" + else: + return "%d months" % months + elif years == 1: + if not months and not days: + return "a year" + elif not months: + return "1 year, %d days" % days + elif use_months: + if months == 1: + return "1 year, 1 month" + else: + return "1 year, %d months" % months + else: + return "1 year, %d days" % days + else: + return "%d years" % years + + +def naturaltime(value, future=False, months=True): """Given a datetime or a number of seconds, return a natural representation of that time in a resolution that makes sense. This is more or less - compatible with Django's ``naturaltime`` filter.""" + compatible with Django's ``naturaltime`` filter. ``future`` is ignored for + datetimes, where the tense is always figured out based on the current time. + If an integer is passed, the return value will be past tense by default, + unless ``future`` is set to True.""" now = _now() date, delta = date_and_delta(value) if date is None: return value - - future = date > now + # determine tense by value only if datetime/timedelta were passed + if isinstance(value, (datetime, timedelta)): + future = date > now ago = 'from now' if future else 'ago' - if delta.days == 0 and delta.seconds == 0: + delta = naturaldelta(delta) + + if delta == "a moment": return "now" - elif abs(delta.days) == 1: - return 'a day %s' % ago - elif abs(delta.days) == 365: - return 'a year %s' % ago - elif abs(delta.days) > 365: - years = abs(delta.days) // 365 - days = abs(delta.days) % 365 - months = days // 31 - if months == 1 and years == 1: - return '1 year, 1 month %s' % (month, ago) - elif months > 1 and years == 1: - return '1 year, %d months %s' % (months, ago) - elif years == 1: - return 'a year %s' % ago - elif years > 1 and months == 1: - return '%d years, 1 month %s' % (years, ago) - elif years > 1 and months > 1: - return '%d years, %d months %d' % (years, months, ago) - else: - return '%d years %d' % (ago) - elif 365 < abs(delta.days) < 365*2: - return '1 year, %d days %s' % (abs(delta.days) % 365, ago) - elif abs(delta.days) > 365*2: - return '%d years %s' % (abs(delta.days) // 365, ago) - elif 1 < abs(delta.days) < 365: - return '%d days %s' % ago - elif abs(delta.seconds) == 1: - return 'a second %s' % ago - elif abs(delta.seconds) < 60: - return '%d seconds %s' % (delta.seconds, ago) - elif 60 <= abs(delta.seconds) < 120: - return 'a minute %s' % ago - elif 120 <= abs(delta.seconds) < 3600: - return '%d minutes %s' % (delta.seconds // 60, ago) - elif 3600 <= abs(delta.seconds) < 3600*2: - return 'an hour %s' % ago - elif 3600 < abs(delta.seconds): - return '%d hours %s' % (delta.seconds // 3600, ago) + + return "%s %s" % (delta, ago) def naturalday(value, format='%b %d'): """For date values that are tomorrow, today or yesterday compared to @@ -101,11 +133,9 @@ def naturalday(value, format='%b %d'): except AttributeError: # Passed value wasn't date-ish return value - except ValueError: + except (OverflowError, ValueError): # Date arguments out of range return value - if not isinstance(value, (date, datetime)): - return value delta = value - date.today() if delta.days == 0: return 'today'
-
@@ -1,2 +1,3 @@ [upload_docs] +upload-dir = docs/_build/html
-
@@ -6,7 +6,7 @@ from setuptools import setup, find_packages import sys, os -version = '0.1' +version = '0.2' # some trove classifiers:
-
@@ -13,8 +13,10 @@ class FilesizeTestCase(HumanizeTestCase): def test_naturalsize(self): tests = (300, 3000, 3000000, 3000000000, 3000000000000, (300, True), (3000, True), (3000000, True), (300, False, True), (3000, False, True), - (3000000, False, True)) + (3000000, False, True), (1024, False, True), (10**26 * 30, False, True), + (10**26 * 30, True), 10**26 * 30) results = ('300 Bytes', '3.0 kB', '3.0 MB', '3.0 GB', '3.0 TB', - '300 Bytes', '2.9 KiB', '2.9 MiB', '300B', '2.9K', '2.9M') + '300 Bytes', '2.9 KiB', '2.9 MiB', '300B', '2.9K', '2.9M', '1.0K', '2481.5Y', + '2481.5 YiB', '3000.0 YB') self.assertManyResults(filesize.naturalsize, tests, results)
-
@@ -30,10 +30,11 @@ def test_intword(self): test_list = ('100', '1000000', '1200000', '1290000', '1000000000', '2000000000', '6000000000000', '1300000000000000', '3500000000000000000000', '8100000000000000000000000000000000', - None, ('1230000', '%0.2f')) + None, ('1230000', '%0.2f'), 10**101) result_list = ('100', '1.0 million', '1.2 million', '1.3 million', '1.0 billion', '2.0 billion', '6.0 trillion', '1.3 quadrillion', - '3.5 sextillion', '8.1 decillion', None, '1.23 million') + '3.5 sextillion', '8.1 decillion', None, '1.23 million', + '1'+'0'*101) self.assertManyResults(number.intword, test_list, result_list) def test_apnumber(self):
-
@@ -27,10 +27,99 @@ def test_date_and_delta(self): dt, d = time.date_and_delta(arg) self.assertEqualDatetime(dt, result[0]) self.assertEqualTimedelta(d, result[1]) + self.assertEqual(time.date_and_delta("NaN"), (None, "NaN")) class TimeTestCase(HumanizeTestCase): """Tests for the public interface of humanize.time""" + def test_naturaldelta_nomonths(self): + now = datetime.now() + test_list = [ + timedelta(days=7), + timedelta(days=31), + timedelta(days=230), + timedelta(days=400), + ] + result_list = [ + '7 days', + '31 days', + '230 days', + '1 year, 35 days', + ] + with patch('humanize.time._now') as mocked: + mocked.return_value = now + nd_nomonths = lambda d: time.naturaldelta(d, months=False) + self.assertManyResults(nd_nomonths, test_list, result_list) + + def test_naturaldelta(self): + now = datetime.now() + test_list = [ + 0, + 1, + 30, + timedelta(minutes=1, seconds=30), + timedelta(minutes=2), + timedelta(hours=1, minutes=30, seconds=30), + timedelta(hours=23, minutes=50, seconds=50), + timedelta(days=1), + timedelta(days=500), + timedelta(days=365*2 + 35), + timedelta(seconds=1), + timedelta(seconds=30), + timedelta(minutes=1, seconds=30), + timedelta(minutes=2), + timedelta(hours=1, minutes=30, seconds=30), + timedelta(hours=23, minutes=50, seconds=50), + timedelta(days=1), + timedelta(days=500), + timedelta(days=365*2 + 35), + # regression tests for bugs in post-release humanize + timedelta(days=10000), + timedelta(days=365+35), + 30, + timedelta(days=365*2 + 65), + timedelta(days=365 + 4), + timedelta(days=35), + timedelta(days=65), + timedelta(days=9), + timedelta(days=365), + "NaN", + ] + result_list = [ + 'a moment', + 'a second', + '30 seconds', + 'a minute', + '2 minutes', + 'an hour', + '23 hours', + 'a day', + '1 year, 4 months', + '2 years', + 'a second', + '30 seconds', + 'a minute', + '2 minutes', + 'an hour', + '23 hours', + 'a day', + '1 year, 4 months', + '2 years', + '27 years', + '1 year, 1 month', + '30 seconds', + '2 years', + '1 year, 4 days', + 'a month', + '2 months', + '9 days', + 'a year', + "NaN", + ] + with patch('humanize.time._now') as mocked: + mocked.return_value = now + self.assertManyResults(time.naturaldelta, test_list, result_list) + def test_naturaltime(self): now = datetime.now() test_list = [ @@ -53,6 +142,13 @@ def test_naturaltime(self): now + timedelta(days=1), now + timedelta(days=500), now + timedelta(days=365*2 + 35), + # regression tests for bugs in post-release humanize + now + timedelta(days=10000), + now - timedelta(days=365+35), + 30, + now - timedelta(days=365*2 + 65), + now - timedelta(days=365 + 4), + "NaN", ] result_list = [ 'now', @@ -64,7 +160,7 @@ def test_naturaltime(self): '23 hours ago', 'a day ago', '1 year, 4 months ago', - '2 years, 1 month ago', + '2 years ago', 'a second from now', '30 seconds from now', 'a minute from now', @@ -73,19 +169,39 @@ def test_naturaltime(self): '23 hours from now', 'a day from now', '1 year, 4 months from now', - '2 years, 1 month from now', + '2 years from now', + '27 years from now', + '1 year, 1 month ago', + '30 seconds ago', + '2 years ago', + '1 year, 4 days ago', + "NaN", ] with patch('humanize.time._now') as mocked: mocked.return_value = now self.assertManyResults(time.naturaltime, test_list, result_list) def test_naturalday(self): + class fakedate(object): + def __init__(self, year, month, day): + self.year, self.month, self.day = year, month, day tomorrow = today + one_day yesterday = today - one_day - someday = today - timedelta(10) + if today.month != 3: + someday = date(today.year, 3, 5) + someday_result = 'Mar 05' + else: + someday = date(today.year, 9, 5) + someday_result = 'Sep 09' + valerrtest = fakedate(290149024, 2, 2) + overflowtest = fakedate(120390192341, 2, 2) test_list = (today, tomorrow, yesterday, someday, '02/26/1984', - (date(1982, 6, 27), '%Y.%M.%D'), None, "Not a date at all.") - result_list = ('today', 'tomorrow', 'yesterday', 'Sep 29', '02/26/1984', - date(1982, 6, 27).strftime('%Y.%M.%D'), None, "Not a date at all.") + (date(1982, 6, 27), '%Y.%M.%D'), None, "Not a date at all.", + valerrtest, overflowtest + ) + result_list = ('today', 'tomorrow', 'yesterday', someday_result, '02/26/1984', + date(1982, 6, 27).strftime('%Y.%M.%D'), None, "Not a date at all.", + valerrtest, overflowtest + ) self.assertManyResults(time.naturalday, test_list, result_list)
commit 0d7dd139
to
micromongo
fix the setup.py file so it'l work when pymongo is not installed, version bump
-
@@ -6,7 +6,7 @@ from models import * from spec import Field -VERSION = (0, 1, 3) +VERSION = (0, 1, 4) __all__ = ['connect', 'clean_connection', 'Model', 'Field', 'VERSION']
-
@@ -5,8 +5,11 @@ from setuptools import setup, find_packages -from micromongo import VERSION -version = '.'.join(map(str, VERSION)) +try: + from micromongo import VERSION + version = '.'.join(map(str, VERSION)) +except ImportError: + version = '0.1.4' # some trove classifiers:
@simonw in linux, you do it with #python! https://t.co/yUZr3A0T
commit #189
to
johnny-cache
fix tests for Django 1.4a where settings will no longer report a DATABASE_ENGINE setting; if it's there, still check against it to prevent invalid test errors, but otherwise check all databases and fail if any don't support multithreading
| johnny/tests/cache.py |
commit #188
to
johnny-cache
Merged in tobias.mcnulty/johnny-cache (pull request #7)
| docs/queryset_cache.rst |
| johnny/cache.py |
| johnny/settings.py |
| johnny/tests/cache.py |
commit #187
to
johnny-cache
add more docs on multi-db setup
| docs/queryset_cache.rst |
commit #186
to
johnny-cache
use "default" as default cache key rather than "ALL"
| docs/queryset_cache.rst |
| johnny/tests/cache.py |
commit #181
to
johnny-cache
disable multi-db savepoint tests for 1.1.3 (which does not have multi-db support) instead of confusingly failing
| johnny/tests/cache.py |
commit #180
to
johnny-cache
alter pull req #8 a bit to fit in with the enable/disable convenience functions
| docs/index.rst |
| docs/queryset_cache.rst |
commit #179
to
johnny-cache
Merged in akaihola/johnny-cache (pull request #8)
| docs/index.rst |
| docs/queryset_cache.rst |
commit #177
to
johnny-cache
add an `enable` and `disable` function to make doing this from scripts, et al easier; related to pull req #8
| johnny/cache.py |
commit #178
to
johnny-cache
Documentation: Added a warning and instructions about Johnny outside Django's request-response loop A common gotcha only mentioned in some closed Bitbucket issues is that Johnny is not enabled in e.g. scripts, management commands, asynchronous workers and the shell. I gathered and added to the documentation some information about this from the following issues in Bitbucket: https://bitbucket.org/jmoiron/johnny-cache/issue/39 https://bitbucket.org/jmoiron/johnny-cache/issue/49 https://bitbucket.org/jmoiron/johnny-cache/issue/50
| docs/index.rst |
| docs/queryset_cache.rst |
commit #185
to
johnny-cache
clean up diff
| docs/queryset_cache.rst |
| johnny/cache.py |
| johnny/settings.py |
commit #183
to
johnny-cache
use the right db cache key for query keys
| johnny/cache.py |
commit #182
to
johnny-cache
add ability to override cache keys used for databases
| docs/queryset_cache.rst |
| johnny/cache.py |
| johnny/settings.py |
@jorgebastida nice project, wrote one similar a while back, maybe you can get some ideas from it: https://t.co/YeGZwt02
commit 38c8f2ee
to
jmoiron.net
blog-edit form sorta working though integration of comment summary is copy pasta and shitty (i'll have to rethink how I build these things as the actions do involve some admin scaffold junk)
-
@@ -5,6 +5,12 @@ body { padding-bottom: 1em; } +.input-boolean { + .input-append; + .add-on { .border-radius(3px); } + .active { background: lighten(@green, 30); border-color: @green; } +} + .container-fluid { min-width: @siteWidth; } @@ -21,6 +27,11 @@ input, textarea, select { h2 { margin-bottom: 0.25em; } } +label.required { + color: #222; + font-weight: bold; +} + #body { margin-top: 50px; } #header { } #sidebar { border-right: 1px solid #eee; } @@ -33,3 +44,24 @@ input, textarea, select { .content .pagination { margin-top: 0; } + +textarea { + &.maximum { + width: 100%; + height: 300px; + } + &.medium { + width: 70%; + height: 100px; + } +} + +.label { + &.notice { text-shadow: @blue 1px 1px 1px; } + &.important { text-shadow: @red 1px 1px 1px; } + &.new { text-shadow: @green 1px 1px 1px; } + &.big { + font-size: 12px; + padding: 3px 5px; + } +}
-
@@ -7,10 +7,7 @@ #} {%- macro label(field) -%} - <label for="{{field.id}}">{{ field.label.text }} - {% if field.flags.required %} - <abbr title="This field is required">*</abbr> - {% endif %}</label> + <label for="{{field.id}}" {% if field.flags.required %}class="required"{% endif %}>{{ field.label.text }}</label> {%- endmacro -%} {%- macro description(field) -%} @@ -29,7 +26,7 @@ {% endif %} {%- endmacro -%} -{%- macro boolean_field(field) -%} +{%- macro inline_boolean_field(field) -%} <div class="input"> <label>{{ field() }} <span>{{ field.label.text }}</span> @@ -39,12 +36,21 @@ </div> {%- endmacro -%} -{%- macro form_field(field) -%} +{%- macro boolean_field(field) -%} + {{ label(field) }} + <div class="input input-boolean" id="{{ field.id }}-div"> + <label class="add-on active">{{ field() }}</label> + </div> +{%- endmacro -%} + +{%- macro form_field(field, class=none, inline_booleans=false) -%} <div class="clearfix"> {% if field.type == "HiddenField" %} {{ field() }} {% else %} - {% if field.type == "BooleanField" %} + {% if field.type == "BooleanField" and inline_booleans %} + {{ inline_boolean_field(field) }} + {% elif field.type == "BooleanField" %} {{ boolean_field(field) }} {% else %} {{ label(field) }} @@ -52,7 +58,7 @@ {% if field.type == "RadioField" %} {{ field(class="radio-group") }} {% else %} - {{ field() }} + {{ field(class=class) }} {% endif %} {{ description(field) }} {{ errors(field) }}
-
@@ -42,12 +42,15 @@ def post_list(count=20): @post.register("edit") def post_edit(id): - post = Post.find_one({"id": int(id)}) + module = post + post_obj = Post.find_one({"id": int(id)}) + post_obj.load_comments() if not post: abort(404) - import ipdb; ipdb.set_trace(); - form = PostForm(MultiDict(post.items())) - return render_template("blog/admin/post_edit.html", **locals()) + form = PostForm(MultiDict(post_obj.items())) + ctx = locals() + ctx['post'] = post_obj + return render_template("blog/admin/post_edit.html", **ctx) admin.add_module(post)
-
@@ -7,10 +7,13 @@ class PostForm(Form): title = TextField('Title', [validators.required]) + slug = TextField('Slug', [validators.required]) is_published = BooleanField('Publish?') + enable_comments = BooleanField('Enable Comments?') timestamp = TextField('Timestamp') - body = TextAreaField('Body', [validators.required]) + body = TextAreaField('Body', [validators.required], id="body-field") #tags = SelectMultipleField('Tags') summary = TextAreaField('Summary') + # TODO: date, tags, comments
-
@@ -27,6 +27,7 @@ class Post(Model): "body": Field(required=True, default=""), "tags": Field(required=True, default=[]), "comments": Field(required=True, default=[]), + "enable_comments": Field(default=True, type=bool), "is_published": Field(required=True, default=False, type=bool), "summary": Field(), "id": Field(required=True, type=int),
-
@@ -1,7 +1,71 @@ +{% import "admin/forms.html" as forms without context %} +{% set manager = module.manager %} +{% macro post_link(post) -%} + <a href="{{ url_for("blog.detail", slug=post.slug) }}">{{ post.title }}</a> +{%- endmacro %} -{% import "admin/forms.html" as forms without context %} +<div class="page-header"> + <h2>Editing {{ post_link(post) }} <small>id {{ post.id }}</small></h2> +</div> +<form id="post-add" method="POST" action="{{ url_for("admin.add", manager=manager.name, module=module.name) }}"> + <fieldset> + <legend>Title</legend> + {{ forms.form_field(form.title, class="xlarge") }} + {{ forms.form_field(form.slug, class="xlarge") }} + <fieldset> + <legend>Content</legend> + {{ forms.form_field(form.body, class="maximum") }} + {{ forms.form_field(form.summary, class="medium") }} + </fieldset> + <fieldset> + <legend>Tags</legend> + <div class="input"> + {% for tag in post.tags %} + <span class="label notice big">{{ tag }}</span> + {% endfor %} + </div> + </fieldset> + </fieldset> + <fieldset> + <legend>Options</legend> + {{ forms.form_field(form.is_published) }} + {{ forms.form_field(form.enable_comments) }} + <fieldset> +</form> -<form> -{{ forms.form_fields(form._fields.values()) }} +<div class="page-header"> + <h3>{{ post.comments|length }} Comments on {{ post_link(post) }}</h3> +</div> +<form method="POST" action="{{ url_for("admin.delete", manager="comments", module="comment") }}"> +<fieldset> +<table class="zebra-striped bordered-table condensed-table"> + <thead> + <th><span class="label important">x</span></th> + <th>name</th> + <th>url</th> + <th>ip</th> + <th>date</th> + <th>spam</th> + </thead> + <tbody> + {% for comment in post.comments %} + <tr> + <td><input type="checkbox" name="{{ comment.id }}"></td> + <td><a href="mailto:{{comment.email}}">{{ comment.name }}</a></td> + <td><a href="{{ comment.url }}">{{ comment.url|truncate(25) }}</a></td> + <td>{{ comment.ip_address }}</td> + <td>{{ comment.timestamp|pdt }}</td> + <td> + {% if comment.needs_moderation %}<span class="label important">x</span> + {% else %}<span class="label success">✓</span>{% endif %} + </td> + </tr> + {% endfor %} + </tbody> +</table> +<div class="pull-right"> + <button type="submit" class="btn danger">- Delete</button> +</div> +</fieldset> </form>
-
@@ -4,16 +4,16 @@ <h2>Latest comments <small>most recent first</small></h2> {% endblock %} -{% block table_header %} +{%- macro table_header() -%} <th><span class="label important">x</span></th> <th>name</th> <th>url</th> <th>ip</th> <th>date</th> <th>spam</th> -{% endblock %} +{%- endmacro -%} -{% block table_body %} +{%- macro table_body(comments) -%} {% for comment in comments %} <tr> <td><input type="checkbox" name="{{ comment.id }}"></td> @@ -27,5 +27,13 @@ </td> </tr> {% endfor %} +{%- endmacro -%} + +{% block table_header %} + {{ table_header() }} +{% endblock %} + +{% block table_body %} + {{ table_body(comments) }} {% endblock %}
Linux Mint 12: Oneiric Revisited
After my disastrous experience with Oneiric left me with an ugly and half-working xfce/compiz amalgam, I promised myself that when the next version of Linux Mint shipped with the erstwhile Gnome2 fork "Mate", I'd give it a go.
commit e9c98c6d
to
jmoiron.net
start edit/add forms, fleshing out more forms library in the admin, automatically redirect the manager index to the module index (list) if the manager has only one module
-
@@ -12,6 +12,10 @@ body { clear: both; } +input, textarea, select { + color: #404040; +} + .admin-list, .admin-summary { margin-top: 1em; h2 { margin-bottom: 0.25em; }
-
@@ -0,0 +1 @@ +
-
@@ -75,3 +75,9 @@ </fieldset> {%- endmacro -%} +{# delete | save #} +{%- macro edit_action_buttons() -%} + +{%- endmacro -%} + +{# save and add another, save and edit, save #}
-
@@ -1,6 +1,6 @@ {% extends "admin/base.html" %} {% block content %} - {{ module.list()|safe }} + {{ content|safe }} <div class="clearfix"></div> {% endblock %}
-
@@ -26,7 +26,13 @@ def manager(manager): manager_obj = admin_manager.blueprint_map[manager].admin_manager except (KeyError, AttributeError): abort(404) - return render_template("admin/manager_index.html", + + if not len(manager_obj.modules): + abort(404) + if len(manager_obj.modules) == 1: + return redirect(url_for("admin.list", manager=manager, module=manager_obj.modules[0].name)) + + return render_template("admin/manager/index.html", admin_manager=admin_manager, manager=manager_obj) @@ -38,9 +44,13 @@ def list(manager, module): module_obj = manager_obj.modmap[module] except (KeyError, AttributeError): abort(404) - return render_template("admin/module_index.html", + + content = module_obj.list() + return render_template("admin/module/index.html", admin_manager=admin_manager, - manager=manager_obj, module=module_obj) + manager=manager_obj, + module=module_obj, + content=content) @admin.route("/<manager>/<module>/add/", methods=("GET", "POST")) @login_required @@ -57,7 +67,7 @@ def edit(manager, module, id): abort(404) content = module_obj.edit(id) - return render_template("admin/module_edit.html", + return render_template("admin/module/edit.html", admin_manager=admin_manager, manager=manager_obj, module=module_obj,
-
@@ -5,10 +5,13 @@ from flask import * from flaskext.wtf import * +from werkzeug import MultiDict + from jmoiron.utils import Page from jmoiron.admin.models import Manager, Module from models import * +from forms import * admin = Manager(blueprint) @@ -42,6 +45,8 @@ def post_edit(id): post = Post.find_one({"id": int(id)}) if not post: abort(404) + import ipdb; ipdb.set_trace(); + form = PostForm(MultiDict(post.items())) return render_template("blog/admin/post_edit.html", **locals()) admin.add_module(post)
-
@@ -10,7 +10,7 @@ class PostForm(Form): is_published = BooleanField('Publish?') timestamp = TextField('Timestamp') body = TextAreaField('Body', [validators.required]) - tags = SelectMultipleField('Tags') + #tags = SelectMultipleField('Tags') summary = TextAreaField('Summary')
-
@@ -1,7 +1,7 @@ -{% extends "admin/module_edit.html" %} -{% block content %} - {{ content|safe }} -{% endblock %} +{% import "admin/forms.html" as forms without context %} +<form> +{{ forms.form_fields(form._fields.values()) }} +</form>
public domain