Various lodgeit fixes.

This commit is contained in:
mitsuhiko 2008-09-14 12:44:16 +02:00
parent 17823ac36e
commit 66165aaa7c
41 changed files with 271 additions and 113 deletions

View File

@ -33,9 +33,6 @@ class LodgeIt(object):
metadata.bind = engine
metadata.create_all(engine)
#: 18n setup
self.locale = Locale('en')
#: jinja_environment update
jinja_environment.globals.update(
i18n_languages=i18n.list_languages()
@ -43,6 +40,7 @@ class LodgeIt(object):
jinja_environment.filters.update(
datetimeformat=i18n.format_datetime
)
jinja_environment.install_null_translations()
#: bind the application to the current context local
self.bind_to_context()
@ -50,17 +48,6 @@ class LodgeIt(object):
def bind_to_context(self):
local.application = self
def set_locale(self, locale):
if not isinstance(locale, Locale):
locale = Locale(locale)
self.translations = i18n.load_translations(locale)
if not self.locale or self.locale.language != locale.language:
self.locale = locale
#: update gettext translations
jinja_environment.install_gettext_translations(self.translations)
def __call__(self, environ, start_response):
"""Minimal WSGI application for request dispatching."""
#: bind the application to the new context local
@ -68,12 +55,6 @@ class LodgeIt(object):
request = Request(environ)
request.bind_to_context()
#: try to get the best language solution for the user
#XXX: does a browser always send the language `-` seperated
user_lang = request.user_agent.language
if self.locale.language != user_lang and request.first_visit:
self.set_locale(Locale.parse(user_lang, sep='-'))
urls = urlmap.bind_to_environ(environ)
try:
endpoint, args = urls.match(request.path)

View File

@ -49,7 +49,8 @@ class PasteController(object):
if check_hashed_solution(captcha):
error = None
else:
error += _(' and the CAPTCHA solution was incorrect')
error = _('your paste contains spam and the '
'CAPTCHA solution was incorrect')
show_captcha = True
if code and language and not error:
paste = Paste(code, language, parent, req.user_hash,
@ -116,7 +117,7 @@ class PasteController(object):
return '/all/%d' % page
form_args = local.request.args
if not 'show_private' in form_args:
if 'show_personal' not in form_args:
query = Paste.find_all()
else:
query = Paste.query.filter_by(
@ -130,7 +131,7 @@ class PasteController(object):
}, form_args, True)
all = filterable.get_objects()
pastes = all.limit(10).offset(10 * (page -1)).all()
pastes = all.limit(10).offset(10 * (page - 1)).all()
if not pastes and page != 1:
raise NotFound()
@ -139,7 +140,7 @@ class PasteController(object):
pagination=generate_pagination(page, 10, all.count(), link),
css=get_style(local.request)[1],
filterable=filterable,
show_private='show_private' in form_args
show_personal='show_personal' in form_args
)
def compare_paste(self, new_id=None, old_id=None):
@ -185,10 +186,11 @@ class PasteController(object):
def set_language(self, lang='en'):
"""Minimal view that set's a different language. Redirects
back to the page the user is coming from."""
resp = redirect(local.request.environ.get('HTTP_REFERER') or '/')
if lang in [x[0] for x in list_languages()]:
local.application.set_locale(lang)
return resp
for key, value in list_languages():
if key == lang:
local.request.set_language(lang)
break
return redirect(local.request.headers.get('referer') or '/')
def show_captcha(self):
"""Show a captcha."""

View File

@ -11,31 +11,42 @@
import os
from babel import Locale, dates, UnknownLocaleError
from babel.support import Translations
from lodgeit import local
_translations = {}
def load_translations(locale):
"""Load the translation for a locale."""
return Translations.load(os.path.dirname(__file__), [locale])
def get_translations(locale):
"""Get the translation for a locale."""
locale = Locale.parse(locale)
translations = _translations.get(str(locale))
if translations is not None:
return translations
rv = Translations.load(os.path.dirname(__file__), [locale])
_translations[str(locale)] = rv
return rv
def gettext(string):
"""Translate the given string to the language of the application."""
if not local.application:
request = getattr(local, 'request', None)
if not request:
return string
return local.application.translations.ugettext(string)
return request.translations.ugettext(string)
def ngettext(singular, plural, n):
"""Translate the possible pluralized string to the language of the
application.
"""
if not local.application:
request = getattr(local, 'request', None)
if not request:
if n == 1:
return singular
return plural
return local.application.translations.ungettext(singular, plural, n)
return request.translations.ungettext(singular, plural, n)
def format_datetime(datetime=None, format='medium'):
@ -45,12 +56,7 @@ def format_datetime(datetime=None, format='medium'):
def list_languages():
"""Return a list of all languages."""
if local.application:
locale = local.application.locale
else:
locale = Locale('en')
languages = [('en', Locale('en').get_display_name(locale))]
languages = [('en', Locale('en').display_name)]
folder = os.path.dirname(__file__)
for filename in os.listdir(folder):
@ -61,7 +67,7 @@ def list_languages():
l = Locale.parse(filename)
except UnknownLocaleError:
continue
languages.append((str(l), l.get_display_name(locale)))
languages.append((str(l), l.display_name))
languages.sort(key=lambda x: x[1].lower())
return languages
@ -73,10 +79,11 @@ def has_language(language):
def _date_format(formatter, obj, format):
if not local.application:
locale = Locale('en')
request = getattr(local, 'request', None)
if request:
locale = request.locale
else:
locale = local.application.locale
locale = Locale('en')
return formatter(obj, format, locale=locale)

View File

@ -8,22 +8,34 @@ msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2008-07-08 10:05+0200\n"
"PO-Revision-Date: 2008-07-20 11:20+0200\n"
"PO-Revision-Date: 2008-09-14 12:24+0200\n"
"Last-Translator: Christopher Grebs <cg@webshox.org>\n"
"Language-Team: de <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 0.9.3\n"
"Generated-By: Babel 1.0dev-r444\n"
#: lodgeit/controllers/pastes.py:45
#: lodgeit/controllers/pastes.py:46
msgid "your paste contains spam"
msgstr "Dein Paste beinhaltet Spam"
#: lodgeit/controllers/pastes.py:51
msgid " and the CAPTCHA solution was incorrect"
msgstr " und die CAPTCHA-Eingabe war falsch"
#: lodgeit/controllers/pastes.py:52
msgid "your paste contains spam and the CAPTCHA solution was incorrect"
msgstr "Dein Paste beinhaltet Spam und die CAPTCHA-Eingabe war falsch"
#: lodgeit/controllers/pastes.py:128
msgid "identifier"
msgstr ""
#: lodgeit/controllers/pastes.py:129
msgid "published"
msgstr ""
#: lodgeit/controllers/pastes.py:130
msgid "language"
msgstr ""
#: lodgeit/controllers/static.py:19
msgid "Pasting"
@ -41,6 +53,39 @@ msgstr "Das XMLRPC Interface benutzen"
msgid "Scripts and Editor Integration"
msgstr "Scripte und Editor-Integration"
#: lodgeit/lib/filterable.py:17 lodgeit/lib/filterable.py:22
#: lodgeit/views/utils/macros.html:19
msgid "is"
msgstr ""
#: lodgeit/lib/filterable.py:18
msgid "contains"
msgstr ""
#: lodgeit/lib/filterable.py:19
msgid "startswith"
msgstr ""
#: lodgeit/lib/filterable.py:23
msgid "greater"
msgstr ""
#: lodgeit/lib/filterable.py:24
msgid "lower"
msgstr ""
#: lodgeit/lib/filterable.py:27
msgid "same date"
msgstr ""
#: lodgeit/lib/filterable.py:28
msgid "later"
msgstr ""
#: lodgeit/lib/filterable.py:29
msgid "earlier"
msgstr ""
#: lodgeit/lib/highlighting.py:23
msgid "Text"
msgstr ""
@ -448,11 +493,11 @@ msgstr "Alle"
msgid "About"
msgstr "Über"
#: lodgeit/views/layout.html:40
#: lodgeit/views/layout.html:43
msgid "Someone Replied To Your Paste"
msgstr "Jemand hat auf dein Paste geantwortet"
#: lodgeit/views/layout.html:42
#: lodgeit/views/layout.html:45
#, python-format
msgid ""
"\n"
@ -471,15 +516,15 @@ msgstr ""
" beide Pastes zu <a "
"href=\"/compare/%(paste)s/%(parent)s/\">vergleichen</a>\n"
#: lodgeit/views/layout.html:51 lodgeit/views/layout.html:63
#: lodgeit/views/layout.html:54 lodgeit/views/layout.html:66
msgid "hide this notification"
msgstr "Benachrichtigung verbergen"
#: lodgeit/views/layout.html:55
#: lodgeit/views/layout.html:58
msgid "Welcome On LodgeIt"
msgstr "Willkommen bei LodgeIt"
#: lodgeit/views/layout.html:56
#: lodgeit/views/layout.html:59
msgid ""
"Welcome to the LodgeIt pastebin. In order to use the notification feature"
"\n"
@ -578,14 +623,31 @@ msgid ""
" coming from is highlighted."
msgstr ""
#: lodgeit/views/show_all.html:2
#: lodgeit/views/show_all.html:3
msgid "All Pastes"
msgstr "Alle Pastes"
#: lodgeit/views/show_all.html:9
#: lodgeit/views/show_all.html:7
#, fuzzy
msgid "Filter pastes"
msgstr "Alle Pastes"
#: lodgeit/views/show_all.html:11
msgid "show <em>only</em> private pastes"
msgstr ""
#: lodgeit/views/show_all.html:12 lodgeit/views/utils/macros.html:58
msgid "update"
msgstr ""
#: lodgeit/views/show_all.html:20
msgid "pasted on "
msgstr ""
#: lodgeit/views/show_all.html:25
msgid "No pastes found"
msgstr ""
#: lodgeit/views/show_paste.html:6
msgid "Paste Details"
msgstr "Paste Details"
@ -974,3 +1036,15 @@ msgstr ""
msgid "Methods"
msgstr ""
#: lodgeit/views/utils/macros.html:20
msgid "is not"
msgstr ""
#: lodgeit/views/utils/macros.html:47
msgid "new filter: "
msgstr ""
#: lodgeit/views/utils/macros.html:55
msgid "ok"
msgstr ""

View File

@ -8,21 +8,33 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2008-07-20 11:18+0200\n"
"POT-Creation-Date: 2008-09-14 12:24+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 0.9.3\n"
"Generated-By: Babel 1.0dev-r444\n"
#: lodgeit/controllers/pastes.py:45
#: lodgeit/controllers/pastes.py:46
msgid "your paste contains spam"
msgstr ""
#: lodgeit/controllers/pastes.py:51
msgid " and the CAPTCHA solution was incorrect"
#: lodgeit/controllers/pastes.py:52
msgid "your paste contains spam and the CAPTCHA solution was incorrect"
msgstr ""
#: lodgeit/controllers/pastes.py:128
msgid "identifier"
msgstr ""
#: lodgeit/controllers/pastes.py:129
msgid "published"
msgstr ""
#: lodgeit/controllers/pastes.py:130
msgid "language"
msgstr ""
#: lodgeit/controllers/static.py:19
@ -41,6 +53,39 @@ msgstr ""
msgid "Scripts and Editor Integration"
msgstr ""
#: lodgeit/lib/filterable.py:17 lodgeit/lib/filterable.py:22
#: lodgeit/views/utils/macros.html:19
msgid "is"
msgstr ""
#: lodgeit/lib/filterable.py:18
msgid "contains"
msgstr ""
#: lodgeit/lib/filterable.py:19
msgid "startswith"
msgstr ""
#: lodgeit/lib/filterable.py:23
msgid "greater"
msgstr ""
#: lodgeit/lib/filterable.py:24
msgid "lower"
msgstr ""
#: lodgeit/lib/filterable.py:27
msgid "same date"
msgstr ""
#: lodgeit/lib/filterable.py:28
msgid "later"
msgstr ""
#: lodgeit/lib/filterable.py:29
msgid "earlier"
msgstr ""
#: lodgeit/lib/highlighting.py:23
msgid "Text"
msgstr ""
@ -407,11 +452,11 @@ msgstr ""
msgid "About"
msgstr ""
#: lodgeit/views/layout.html:40
#: lodgeit/views/layout.html:43
msgid "Someone Replied To Your Paste"
msgstr ""
#: lodgeit/views/layout.html:42
#: lodgeit/views/layout.html:45
#, python-format
msgid ""
"\n"
@ -423,15 +468,15 @@ msgid ""
" those two pastes</a>."
msgstr ""
#: lodgeit/views/layout.html:51 lodgeit/views/layout.html:63
#: lodgeit/views/layout.html:54 lodgeit/views/layout.html:66
msgid "hide this notification"
msgstr ""
#: lodgeit/views/layout.html:55
#: lodgeit/views/layout.html:58
msgid "Welcome On LodgeIt"
msgstr ""
#: lodgeit/views/layout.html:56
#: lodgeit/views/layout.html:59
msgid ""
"Welcome to the LodgeIt pastebin. In order to use the notification feature"
"\n"
@ -513,14 +558,30 @@ msgid ""
" coming from is highlighted."
msgstr ""
#: lodgeit/views/show_all.html:2
#: lodgeit/views/show_all.html:3
msgid "All Pastes"
msgstr ""
#: lodgeit/views/show_all.html:9
#: lodgeit/views/show_all.html:7
msgid "Filter pastes"
msgstr ""
#: lodgeit/views/show_all.html:11
msgid "show <em>only</em> private pastes"
msgstr ""
#: lodgeit/views/show_all.html:12 lodgeit/views/utils/macros.html:58
msgid "update"
msgstr ""
#: lodgeit/views/show_all.html:20
msgid "pasted on "
msgstr ""
#: lodgeit/views/show_all.html:25
msgid "No pastes found"
msgstr ""
#: lodgeit/views/show_paste.html:6
msgid "Paste Details"
msgstr ""
@ -905,3 +966,15 @@ msgstr ""
msgid "Methods"
msgstr ""
#: lodgeit/views/utils/macros.html:20
msgid "is not"
msgstr ""
#: lodgeit/views/utils/macros.html:47
msgid "new filter: "
msgstr ""
#: lodgeit/views/utils/macros.html:55
msgid "ok"
msgstr ""

View File

@ -40,6 +40,7 @@ ACTIONS_MAP = {
class Filterable(object):
def __init__(self, model, objects, fields, args, inline=False):
self.model = model
self.fields = fields
@ -59,7 +60,6 @@ class Filterable(object):
self.inline = inline
def get_html(self):
ret = render_template('utils/filterable.html', plain=True, **{
'filters': self.filters,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 201 B

BIN
lodgeit/static/flags/de.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 B

After

Width:  |  Height:  |  Size: 545 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 362 B

After

Width:  |  Height:  |  Size: 599 B

BIN
lodgeit/static/flags/es.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 B

After

Width:  |  Height:  |  Size: 469 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 B

BIN
lodgeit/static/flags/fr.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 B

After

Width:  |  Height:  |  Size: 545 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 362 B

BIN
lodgeit/static/flags/gr.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 393 B

BIN
lodgeit/static/flags/it.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 B

After

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 476 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 B

BIN
lodgeit/static/flags/ro.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 B

After

Width:  |  Height:  |  Size: 495 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 B

View File

@ -29,7 +29,9 @@ var LodgeIt = {
$('div.related div.content').hide();
/* hide all filter related blocks if in js mode */
$('div.paste_filter form').hide();
var paste_filter = $('div.paste_filter form');
if (paste_filter.length && !paste_filter.is('.open'))
paste_filters.hide();
/**
* links marked with "autoclose" inside the related div

View File

@ -94,16 +94,18 @@ div.text {
}
#languages li {
float: left;
margin-right: 5px;
float: left;
margin-right: 5px;
}
#languages li img {
border: 1px solid #000;
border: none;
padding: 2px;
}
#languages li.active img {
border: 2px solid #000;
border: 1px solid #84BCCA;
padding: 1px;
}
#paste {
@ -444,34 +446,29 @@ ul.xmlrpc-method-list li p.docstring {
/* Filterable */
table.filterable {
width: 100%;
margin-bottom: 0.7em;
margin-top: 0.2em;
border-collapse: collapse;
border-spacing: 0px;
border: solid 1px #ccc;
width: 100%;
margin-bottom: 0.7em;
margin-top: 0.2em;
border-collapse: collapse;
}
table.filterable td {
border-color: #ccc;
border-style: solid;
border-width: 1px 0 1px 0;
vertical-align: middle;
vertical-align: middle;
padding: 5px 10px;
}
table.filterable td.value {
width: 100%;
width: 100%;
}
table.filterable div.add {
float: right;
float: right;
}
table.filterable div.add.left {
float: left;
float: left;
}
input.update_filterable {
margin: 5px 10px 5px 5px;
display: block;
div.paste_filter div.actions {
padding: 5px 10px;
}

View File

@ -13,10 +13,16 @@ import time
from os import path
from random import random
from functools import partial
from werkzeug import Request as RequestBase, Response
from werkzeug.contrib.securecookie import SecureCookie
from jinja2 import Environment, FileSystemLoader
from babel import Locale
from lodgeit import local
from lodgeit.i18n import get_translations
try:
from hashlib import sha1
@ -59,7 +65,7 @@ class Request(RequestBase):
super(Request, self).__init__(environ)
self.first_visit = False
session = SecureCookie.load_cookie(self, COOKIE_NAME,
local.application.secret_key)
local.application.secret_key)
user_hash = session.get('user_hash')
if not user_hash:
@ -68,6 +74,18 @@ class Request(RequestBase):
self.user_hash = session['user_hash']
self.session = session
lang = session.get('language')
if lang is None:
lang = (self.accept_languages.best or 'en').split('-')[0]
self.locale = Locale.parse(lang)
def set_language(self, lang):
self.session['language'] = lang
@property
def translations(self):
return get_translations(self.locale)
def bind_to_context(self):
local.request = self
@ -79,12 +97,14 @@ def render_template(template_name, plain=False, **tcontext):
welcome message.
"""
from lodgeit.database import Paste
if local.request.method == 'GET':
request = local.request
if request.method == 'GET':
tcontext['new_replies'] = Paste.fetch_replies()
if local.request:
tcontext['request'] = local.request
if local.application:
tcontext['active_language'] = local.application.locale.language
tcontext.update(
request=request,
gettext=request.translations.ugettext,
ngettext=request.translations.ungettext
)
t = jinja_environment.get_template(template_name)
if not plain:
resp = Response(t.render(tcontext), mimetype='text/html; charset=utf-8')

View File

@ -30,9 +30,9 @@
{%- endfor %}
</ul>
<ul id="languages">
{% for lang in i18n_languages %}
<li{% if active_language == lang[0] %} class="active"{% endif %}>
<a href="{{ '/language/%s'|format(lang[0]) }}"><img src="{{ '/static/flags/%s.png'|format(lang[0]) }}"></a>
{% for lang, name in i18n_languages %}
<li{% if request.locale.language == lang %} class="active"{% endif %}>
<a href="{{ '/language/%s'|format(lang) }}"><img alt="{{ lang }}" src="{{ '/static/flags/%s.png'|format(lang) }}"></a>
</li>
{% endfor %}
</ul>

View File

@ -3,13 +3,15 @@
{% set page_title = _('All Pastes') %}
{% set active_page = 'all' %}
{% block body %}
<div class="paste_filter">
<div class="paste_filter{% if filterable.filters %} open{% endif %}">
<h3><a href="javascript:LodgeIt.toggleFilterBox()">{%- trans -%}Filter pastes{%- endtrans -%}</a></h3>
<form action="" method="get">
{{ filterable.get_html() }}
<input type="checkbox" name="show_private" id="show_private"{% if show_private %} checked="checked"{% endif %} />
<label for="show_private">{% trans %}show <em>only</em> private pastes{% endtrans %}</label>
<input type="submit" value="{% trans %}update{% endtrans %}" class="update_filterable" />
<div class="actions">
<input type="checkbox" name="show_personal" id="show_personal"{% if show_personal %} checked{% endif %}>
<label for="show_personal">{{ _('Search personal pastes') }}</label>
<input type="submit" value="{{ _('Filter') }}">
</div>
</form>
</div>
{% if pastes %}

View File

@ -4,7 +4,7 @@
{% endif %}
{%- for k, v in args.iteritems() %}
{%- if v %}
<input type="hidden" name="{{ k|e }}" value="{{ v|e }}" />
<input type="hidden" name="{{ k|e }}" value="{{ v|e }}">
{%- endif %}
{%- endfor %}
<table class="filterable">
@ -14,18 +14,18 @@
<tr class="filter_value">
{%- if type == 'bool' %}
<td class="field value" colspan="3">
<input type="hidden" name="{{ field }}_action" value="bool" />
<input type="hidden" name="{{ field }}_action" value="bool">
<select name="{{ field }}_value">
<option {% if value == 'true' %}selected="selected" {% endif %}value="true">{% trans %}is{% endtrans %}</option>
<option {% if value == 'false' %}selected="selected" {% endif %}value="false">{% trans %}is not{% endtrans %}</option>
<option {% if value == 'true' %}selected {% endif %}value="true">{% trans %}is{% endtrans %}</option>
<option {% if value == 'false' %}selected {% endif %}value="false">{% trans %}is not{% endtrans %}</option>
</select> {{ label|e }}
</td>
{%- else %}
<td class="field">{{ label|e }}</td>
<td class="filter">
<select name="{{ field }}_action">
{%- for k, v in actions[type].iteritems() %}:
<option value="{{ k }}"{% if k == action %} selected="selected"{% endif %}>
{%- for k, v in actions[type].iteritems() %}
<option value="{{ k }}"{% if k == action %} selected{% endif %}>
{{- v|e -}}
</option>
{%- endfor %}
@ -33,7 +33,7 @@
</td>
<td class="value">
<input type="{{ fields[field][1] == 'date' and 'date' or 'text' }}"
name="{{ field }}_value" value="{{ value|e }}" />
name="{{ field }}_value" value="{{ value|e }}">
</td>
{%- endif %}
<td class="action">
@ -52,7 +52,7 @@
{%- endif %}
{%- endfor %}
</select>
<input type="submit" name="add_filter" value="{% trans %}ok{% endtrans %}" />
<input type="submit" name="add_filter" value="{% trans %}ok{% endtrans %}">
</div>
{%- if filters and not inline %}
<input type="submit" value="{% trans %}update{% endtrans %}">