Commits

Ronny Pfannschmidt committed 802b119

first version where the new paste view shows

  • Participants
  • Parent commits 4bb4643
  • Branches flask-port

Comments (0)

Files changed (57)

lodgeit/__init__.py

     :copyright: 2007 by Armin Ronacher.
     :license: BSD
 """
+
 from lodgeit.application import make_app

lodgeit/application.py

     :license: BSD
 """
 import os
+import flask
 from datetime import datetime, timedelta
 from werkzeug import SharedDataMiddleware, ClosingIterator
 from werkzeug.exceptions import HTTPException, NotFound
-from sqlalchemy import create_engine
-from lodgeit import i18n
-from lodgeit.local import ctx, _local_manager
-from lodgeit.urls import urlmap
-from lodgeit.utils import COOKIE_NAME, Request, jinja_environment
-from lodgeit.database import db
-from lodgeit.models import Paste
-from lodgeit.controllers import get_controller
+from lodgeit.models import Paste, db
 
 
 class LodgeIt(object):
                                self.cleanup_callbacks)
 
 
-def make_app(dburi, secret_key, debug=False, shell=False):
+def make_app(dburi, secret_key, debug=False):
     """Apply the used middlewares and create the application."""
     static_path = os.path.join(os.path.dirname(__file__), 'static')
-    app = LodgeIt(dburi, secret_key)
-    if debug:
-        app.engine.echo = True
-    app.bind_to_context()
-    if not shell:
-        # we don't need access to the shared data middleware in shell mode
-        app = SharedDataMiddleware(app, {
-            '/static': static_path})
+    app = flask.Flask('lodgeit', static_path=static_path)
+    from flask.ext.babel import Babel
+    app.config['SQLALCHEMY_DATABASE_URI'] = dburi
+    app.babel = Babel(app)
+    app.debug = debug
+    from lodgeit import controllers
+    for blueprint in controllers.all:
+        app.register_blueprint(blueprint)
+    
     return app

lodgeit/controllers/__init__.py

     module = __import__('lodgeit.controllers.' + cname, None, None, [''])
     controller = module.controller()
     return getattr(controller, hname)
+
+from .pastes import pastes
+from .static import static
+
+all = [ pastes, static]

lodgeit/controllers/pastes.py

 """
 from werkzeug import redirect, Response
 from werkzeug.exceptions import NotFound
-from lodgeit import local
+
+from flask import request, session, render_template
 from lodgeit.lib import antispam
-from lodgeit.i18n import list_languages as i18n_list_languages, _
-from lodgeit.utils import render_to_response
-from lodgeit.models import Paste
-from lodgeit.database import db
+#from lodgeit.i18n import list_languages as i18n_list_languages, _
+from lodgeit.models import Paste, db
 from lodgeit.lib.highlighting import list_languages, STYLES
 from lodgeit.lib.pagination import generate_pagination
 from lodgeit.lib.captcha import check_hashed_solution, Captcha
 
 
-class PasteController(object):
-    """Provides all the handler callback for paste related stuff."""
 
-    def new_paste(self, language=None):
-        """The 'create a new paste' view."""
-        language = local.request.args.get('language', language)
-        if language is None:
-            language = local.request.session.get('language', 'text')
+from flask import Blueprint
 
-        code = error = ''
-        show_captcha = private = False
-        parent = None
-        req = local.request
-        getform = req.form.get
 
-        if local.request.method == 'POST':
-            code = getform('code', u'')
-            language = getform('language')
+pastes = Blueprint('pastes', __name__)
 
-            parent_id = getform('parent')
-            if parent_id is not None:
-                parent = Paste.get(parent_id)
+@pastes.route('/')
+@pastes.route('/+<language>')
+def new_paste(language=None):
+    """The 'create a new paste' view."""
+    language = request.args.get('language', language)
+    if language is None:
+        language = session.get('language', 'text')
 
-            spam = getform('webpage') or antispam.is_spam(code)
-            if spam:
-                error = _('your paste contains spam')
-                captcha = getform('captcha')
-                if captcha:
-                    if check_hashed_solution(captcha):
-                        error = None
-                    else:
-                        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,
-                              'private' in req.form)
-                db.session.add(paste)
-                db.session.commit()
-                local.request.session['language'] = language
-                return redirect(local.request.get_url('pastes/show_paste', identifier=paste.identifier))
+    code = error = ''
+    show_captcha = private = False
+    parent = None
+    getform = request.form.get
 
-        else:
-            parent_id = req.values.get('reply_to')
-            if parent_id is not None:
-                parent = Paste.get(parent_id)
-                if parent is not None:
-                    code = parent.code
-                    language = parent.language
-                    private = parent.private
+    if request.method == 'POST':
+        code = getform('code', u'')
+        language = getform('language')
 
-        return render_to_response('new_paste.html',
-            languages=list_languages(),
-            parent=parent,
-            code=code,
-            language=language,
-            error=error,
-            show_captcha=show_captcha,
-            private=private
-        )
+        parent_id = getform('parent')
+        if parent_id is not None:
+            parent = Paste.get(parent_id)
 
-    def show_paste(self, identifier, raw=False):
-        """Show an existing paste."""
-        linenos = local.request.args.get('linenos') != 'no'
-        paste = Paste.get(identifier)
-        if paste is None:
-            raise NotFound()
-        if raw:
-            return Response(paste.code, mimetype='text/plain; charset=utf-8')
+        spam = getform('webpage') or antispam.is_spam(code)
+        if spam:
+            error = _('your paste contains spam')
+            captcha = getform('captcha')
+            if captcha:
+                if check_hashed_solution(captcha):
+                    error = None
+                else:
+                    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,
+                          'private' in req.form)
+            db.session.add(paste)
+            db.session.commit()
+            session['language'] = language
+            return redirect(url_for('show_paste', identifier=paste.identifier))
 
-        return render_to_response('show_paste.html',
-            paste=paste,
-            styles=STYLES,
-            linenos=linenos,
-        )
+    else:
+        parent_id = request.values.get('reply_to')
+        if parent_id is not None:
+            parent = Paste.get(parent_id)
+            if parent is not None:
+                code = parent.code
+                language = parent.language
+                private = parent.private
 
-    def raw_paste(self, identifier):
-        """Show an existing paste in raw mode."""
-        return self.show_paste(identifier, raw=True)
+    return render_template('new_paste.html',
+        languages=list_languages(),
+        parent=parent,
+        code=code,
+        language=language,
+        error=error,
+        show_captcha=show_captcha,
+        private=private
+    )
 
-    def show_tree(self, identifier):
-        """Display the tree of some related pastes."""
-        paste = Paste.resolve_root(identifier)
-        if paste is None:
-            raise NotFound()
-        return render_to_response('paste_tree.html',
-            paste=paste,
-            current=identifier
-        )
 
-    def show_all(self, page=1):
-        """Paginated list of pages."""
-        def link(page):
-            if page == 1:
-                return local.request.get_url('pastes/show_all')
-            return local.request.get_url('pastes/show_all', page=page)
+@pastes.route('/show/<identifier>')
+def show_paste(identifier, raw=False):
+    """Show an existing paste."""
+    linenos = local.request.args.get('linenos') != 'no'
+    paste = Paste.get(identifier)
+    if paste is None:
+        raise NotFound()
+    if raw:
+        return Response(paste.code, mimetype='text/plain; charset=utf-8')
 
-        form_args = local.request.args
-        query = Paste.find_all()
+    return render_to_response('show_paste.html',
+        paste=paste,
+        styles=STYLES,
+        linenos=linenos,
+    )
 
-        pastes = query.limit(10).offset(10 * (page - 1)).all()
-        if not pastes and page != 1:
-            raise NotFound()
+@pastes.route('/raw/<identifier>')
+def raw_paste(identifier):
+    """Show an existing paste in raw mode."""
+    return show_paste(identifier, raw=True)
 
-        return render_to_response('show_all.html',
-            pastes=pastes,
-            pagination=generate_pagination(page, 10, query.count(), link),
-            show_personal='show_personal' in form_args
-        )
 
-    def compare_paste(self, new_id=None, old_id=None):
-        """Render a diff view for two pastes."""
-        getform = local.request.form.get
-        # redirect for the compare form box
-        if old_id is None:
-            old_id = getform('old', '-1').lstrip('#')
-            new_id = getform('new', '-1').lstrip('#')
-            return redirect(local.request.get_url('pastes/compare_paste', new_id=new_id, old_id=old_id))
+@pastes.route('/tree/<identifier>')
+def show_tree(identifier):
+    """Display the tree of some related pastes."""
+    paste = Paste.resolve_root(identifier)
+    if paste is None:
+        raise NotFound()
+    return render_to_response('paste_tree.html',
+        paste=paste,
+        current=identifier
+    )
 
-        old = Paste.get(old_id)
-        new = Paste.get(new_id)
-        if old is None or new is None:
-            raise NotFound()
+@pastes.route('/all/', defaults={'page':1})
+@pastes.route('/all/<int:page>')
+def show_all(page=1):
+    """Paginated list of pages."""
+    def link(page):
+        if page == 1:
+            return local.request.get_url('pastes/show_all')
+        return local.request.get_url('pastes/show_all', page=page)
 
-        return render_to_response('compare_paste.html',
-            old=old,
-            new=new,
-            diff=old.compare_to(new, template=True)
-        )
+    form_args = local.request.args
+    query = Paste.find_all()
 
-    def unidiff_paste(self, new_id=None, old_id=None):
-        """Render an udiff for the two pastes."""
-        old = Paste.get(old_id)
-        new = Paste.get(new_id)
+    pastes = query.limit(10).offset(10 * (page - 1)).all()
+    if not pastes and page != 1:
+        raise NotFound()
 
-        if old is None or new is None:
-            raise NotFound()
+    return render_to_response('show_all.html',
+        pastes=pastes,
+        pagination=generate_pagination(page, 10, query.count(), link),
+        show_personal='show_personal' in form_args
+    )
 
-        return Response(old.compare_to(new), mimetype='text/plain')
+def compare_paste(self, new_id=None, old_id=None):
+    """Render a diff view for two pastes."""
+    getform = local.request.form.get
+    # redirect for the compare form box
+    if old_id is None:
+        old_id = getform('old', '-1').lstrip('#')
+        new_id = getform('new', '-1').lstrip('#')
+        return redirect(local.request.get_url('pastes/compare_paste', new_id=new_id, old_id=old_id))
 
-    def set_colorscheme(self):
-        """Minimal view that updates the style session cookie. Redirects
-        back to the page the user is coming from.
-        """
-        style_name = local.request.form.get('style')
-        resp = redirect(local.request.environ.get('HTTP_REFERER') or local.request.get_url('pastes/new_paste'))
-        if style_name in STYLES:
-            resp.set_cookie('style', style_name)
-        return resp
+    old = Paste.get(old_id)
+    new = Paste.get(new_id)
+    if old is None or new is None:
+        raise NotFound()
 
-    def set_language(self, lang='en'):
-        """Minimal view that sets a different language. Redirects
-        back to the page the user is coming from."""
-        for key, value in i18n_list_languages():
-            if key == lang:
-                local.request.set_language(lang)
-                break
-        return redirect(local.request.headers.get('HTTP_REFERER') or local.request.get_url('pastes/new_paste'))
+    return render_to_response('compare_paste.html',
+        old=old,
+        new=new,
+        diff=old.compare_to(new, template=True)
+    )
 
-    def show_captcha(self):
-        """Show a captcha."""
-        return Captcha().get_response(set_cookie=True)
+def unidiff_paste(self, new_id=None, old_id=None):
+    """Render an udiff for the two pastes."""
+    old = Paste.get(old_id)
+    new = Paste.get(new_id)
 
+    if old is None or new is None:
+        raise NotFound()
 
-controller = PasteController
+    return Response(old.compare_to(new), mimetype='text/plain')
+
+def set_colorscheme(self):
+    """Minimal view that updates the style session cookie. Redirects
+    back to the page the user is coming from.
+    """
+    style_name = local.request.form.get('style')
+    resp = redirect(local.request.environ.get('HTTP_REFERER') or local.request.get_url('pastes/new_paste'))
+    if style_name in STYLES:
+        resp.set_cookie('style', style_name)
+    return resp
+
+def set_language(self, lang='en'):
+    """Minimal view that sets a different language. Redirects
+    back to the page the user is coming from."""
+    for key, value in i18n_list_languages():
+        if key == lang:
+            local.request.set_language(lang)
+            break
+    return redirect(local.request.headers.get('HTTP_REFERER') or local.request.get_url('pastes/new_paste'))
+
+def show_captcha(self):
+    """Show a captcha."""
+    return Captcha().get_response(set_cookie=True)
+
+

lodgeit/controllers/static.py

     :copyright: 2007-2008 by Armin Ronacher, Christopher Grebs.
     :license: BSD
 """
+import flask
 from werkzeug.exceptions import NotFound
-from lodgeit import local
-from lodgeit.i18n import lazy_gettext
-from lodgeit.utils import render_to_response
 from lodgeit.lib.webapi import get_public_methods
 from lodgeit.lib.highlighting import LANGUAGES
 
+#XXX: l
+lazy_gettext = lambda x:x
+
+
+static = flask.Blueprint('static', __name__)
 
 HELP_PAGES = [
     ('pasting',         lazy_gettext('Pasting')),
 known_help_pages = set(x[0] for x in HELP_PAGES)
 
 
-class StaticController(object):
+def not_found(self):
+    return render_to_response('not_found.html')
 
-    def not_found(self):
-        return render_to_response('not_found.html')
+@static.route('/about/')
+def about(self):
+    return render_to_response('about.html')
 
-    def about(self):
-        return render_to_response('about.html')
 
-    def help(self, topic=None):
-        if topic is None:
-            tmpl_name = 'help/index.html'
-        elif topic in known_help_pages:
-            tmpl_name = 'help/%s.html' % topic
-        else:
-            raise NotFound()
-        return render_to_response(
-            tmpl_name,
-            help_topics=HELP_PAGES,
-            current_topic=topic,
-            pastebin_url=local.request.host_url,
-            formatters=LANGUAGES,
-            xmlrpc_methods=get_public_methods()
-        )
+@static.route('/help')
+@static.route('/help/<topic>')
+def help(self, topic=None):
+    if topic is None:
+        tmpl_name = 'help/index.html'
+    elif topic in known_help_pages:
+        tmpl_name = 'help/%s.html' % topic
+    else:
+        raise NotFound()
+    return flask.render_template(
+        tmpl_name,
+        help_topics=HELP_PAGES,
+        current_topic=topic,
+        pastebin_url=flask.request.host_url,
+        formatters=LANGUAGES,
+        xmlrpc_methods=get_public_methods()
+    )
 
-
-controller = StaticController

lodgeit/database.py

-# -*- coding: utf-8 -*-
-"""
-    lodgeit.database
-    ~~~~~~~~~~~~~~~~
-
-    Database fun :)
-
-    :copyright: 2007-2010 by Armin Ronacher, Christopher Grebs.
-    :license: BSD
-"""
-import sys
-from types import ModuleType
-import sqlalchemy
-from sqlalchemy import MetaData
-from sqlalchemy import orm
-from sqlalchemy.ext.declarative import declarative_base
-from lodgeit.local import application, _local_manager
-
-
-metadata = MetaData()
-
-
-def session_factory():
-    options = {'autoflush': True, 'autocommit': False}
-    return orm.create_session(application.engine, **options)
-
-session = orm.scoped_session(session_factory,
-    scopefunc=_local_manager.get_ident)
-
-
-class ModelBase(object):
-    """Internal baseclass for all models.  It provides some syntactic
-    sugar and maps the default query property.
-
-    We use the declarative model api from sqlalchemy.
-    """
-
-
-# configure the declarative base
-Model = declarative_base(name='Model', cls=ModelBase,
-    mapper=orm.mapper, metadata=metadata)
-ModelBase.query = session.query_property()
-
-
-def _make_module():
-    db = ModuleType('db')
-    for mod in sqlalchemy, orm:
-        for key, value in mod.__dict__.iteritems():
-            if key in mod.__all__:
-                setattr(db, key, value)
-
-    db.session = session
-    db.metadata = metadata
-    db.Model = Model
-    db.NoResultFound = orm.exc.NoResultFound
-    return db
-
-sys.modules['lodgeit.database.db'] = db = _make_module()

lodgeit/lib/captcha.py

 except ImportError:
     import ImageFont, ImageDraw, Image, ImageChops, ImageColor
 from werkzeug import Response
-from lodgeit import local
+#from lodgeit import local
 
 try:
     from hashlib import sha1

lodgeit/lib/highlighting.py

 from pygments.styles import get_all_styles
 from pygments.formatters import HtmlFormatter
 
-from lodgeit import local
-from lodgeit.i18n import lazy_gettext as _
 from lodgeit.lib.diff import prepare_udiff
 from lodgeit.lib.compilerparser import parse_gcc_messages, \
      parse_javac_messages
 
 from werkzeug import escape
 
+_ = lambda x:x
 
 #: we use a hardcoded list here because we want to keep the interface
 #: simple

lodgeit/lib/json.py

 """
 from simplejson import dumps, loads
 from werkzeug import Response
-from lodgeit import local
-
+from flask import request
 
 class JSONRequestHandler(object):
 
 
     def handle_request(self):
         try:
-            method_name = local.request.args['method']
-            if not local.request.data:
+            method_name = request.args['method']
+            if not request.data:
                 args = ()
                 kwargs = {}
             else:
-                args = loads(local.request.data)
+                args = loads(request.data)
                 if isinstance(args, dict):
                     kwargs = dict((str(key), value) for
                                   key, value in args.iteritems())
             }
         except Exception, e:
             response = {'data': None, 'error': str(e).decode('utf-8')}
-        body = dumps(response, indent=local.request.is_xhr and 2 or 0)
+        body = dumps(response, indent=request.is_xhr and 2 or 0)
         return Response(body + '\n', mimetype='application/json')

lodgeit/lib/pagination.py

     :license: BSD
 """
 import math
-from lodgeit.i18n import _
-
+#from lodgeit.i18n import _
+_ = lambda x:x
 
 def generate_pagination(page, per_page, total, link_builder=None,
                         normal='<a href="%(url)s">%(page)d</a>',

lodgeit/lib/webapi.py

 """
 import inspect
 from lodgeit.models import Paste
-from lodgeit.database import db
+from lodgeit.models import db
 from lodgeit.lib.xmlrpc import XMLRPCRequestHandler
 from lodgeit.lib.json import JSONRequestHandler
 from lodgeit.lib.highlighting import STYLES, LANGUAGES, get_style, \

lodgeit/lib/xmlrpc.py

 import re
 from SimpleXMLRPCServer import SimpleXMLRPCDispatcher
 from werkzeug import Response
-from lodgeit import local
+from flask import request
 
 
 _strip_re = re.compile(r'[\x00-\x08\x0B-\x1F]')
             if rv is None:
                 rv = False
             return rv
-        response = self._marshaled_dispatch(local.request.data, dispatch)
+        response = self._marshaled_dispatch(request.data, dispatch)
         return Response(_strip_re.sub('', response), mimetype='text/xml')

lodgeit/local.py

-# -*- coding: utf-8 -*-
-"""
-    lodgeit.utils
-    ~~~~~~~~~~~~~
-
-    Serveral utilities used by LodgeIt.
-
-    :copyright: 2008 by Christopher Grebs.
-    :license: BSD
-"""
-from werkzeug import Local, LocalManager, LocalProxy
-
-#: context locals
-ctx = Local()
-_local_manager = LocalManager(ctx)
-
-#: local objects
-request = LocalProxy(ctx, 'request')
-application = LocalProxy(ctx, 'application')

lodgeit/models.py

 from datetime import datetime
 from werkzeug import cached_property
 
-from lodgeit import local
+from flask_sqlalchemy import SQLAlchemy
+
 from lodgeit.utils import generate_paste_hash
 from lodgeit.lib.highlighting import highlight, preview_highlight, LANGUAGES
 from lodgeit.lib.diff import prepare_udiff
-from lodgeit.database import db
 
 
+db = SQLAlchemy()
+
 class Paste(db.Model):
     __tablename__ = 'pastes'
 

lodgeit/templates/about.html

+{% extends "layout.html" %}
+{% set page_title = _('About LodgeIt') %}
+{% set active_page = 'about' %}
+{% block body %}
+  <div class="text">
+    <h3 id="why-the-hell-another-pastebin">{% trans %} Why the hell another pastebin?{% endtrans %}</h3>
+    <p>{% trans %}
+      Good question. Basically the world doesn't need another pastebin.
+      There is <a href="http://pastie.caboo.se/">pastie</a> and
+      <a href="http://dpaste.com/">dpaste.com</a> which
+      both use kick-ass highlighting libraries for highlighting the
+      code and both have an	intuitive user interface. Nevertheless there
+      are some features which are unique to LodgeIt.{% endtrans %}
+    </p>
+    <h3 id="features">{% trans %}Features{% endtrans %}</h3>
+    <ul>
+       <li>{% trans %}clean user interface{% endtrans %}</li>
+       <li>{% trans %}different color schemes for the sourcecode{% endtrans %}</li>
+       <li>{% trans %}reply to pastes{% endtrans %}</li>
+       <li>{% trans %}diffs of two pastes{% endtrans %}</li>
+       <li>{% trans %}support for many python template languages{% endtrans %}</li>
+       <li>{% trans %}support for many scripting languages like Python and Ruby, even with
+           weird syntax (ruby *cough*){% endtrans %}</li>
+       <li><a href="{{ url('static/help', topic='api') }}">{% trans %}XMLRPC support{% endtrans %}</a></li>
+       <li><a href="{{ url('static/help', topic='integration' ) }}">{% trans %}command-line and editor integration{% endtrans %}</a></li>
+       <li>{% trans %}persistent pastes{% endtrans %}</li>
+       <li>{% trans %}reply notification{% endtrans %}</li>
+       <li>{% trans %}valid HTML 4.0{% endtrans %}</li>
+    </ul>
+    <h3 id="request-more-languages">{% trans %}Request More Languages{% endtrans %}</h3>
+    <p>{% trans %}
+      A language is missing in the list? File a ticket in the
+      <a href="http://dev.pocoo.org/projects/pygments">Pygments trac</a> and we add that as soon
+      as possible.{% endtrans %}
+    </p>
+    <h3 id="software-used">{% trans %}Software Used{% endtrans %}</h3>
+    <ul>
+      <li>{% trans %}<a href="http://pygments.pocoo.org/">Pygments</a> for syntax highlighting{% endtrans %}</li>
+      <li>{% trans %}<a href="http://www.python.org/">Python</a> as scripting language{% endtrans %}</li>
+      <li>{% trans %}<a href="http://jinja.pocoo.org/2">Jinja 2</a> for templating{% endtrans %}</li>
+      <li>{% trans %}<a href="http://werkzeug.pocoo.org/">Werkzeug</a> for the WSGI implementation{% endtrans %}</li>
+      <li>{% trans %}<a href="http://www.sqlalchemy.org">SQLAlchemy</a> as database layer{% endtrans %}</li>
+      <li>{% trans %}<a href="http://www.jquery.com/">jQuery</a> for scripting{% endtrans %}</li>
+    </ul>
+    <h3 id="who">{% trans %}Who?{% endtrans %}</h3>
+    <p>{% trans %}
+      This paste was founded by <a href="http://lucumr.pocoo.org/">Armin Ronacher</a>
+      from the Pocoo team and is now maintained by
+      <a href="http://webshox.org">Christopher Grebs</a>.  Pygments is a Pocoo project
+      led by Georg Brandl.{% endtrans %}
+    </p>
+    <h3 id="privacy">{% trans %}Privacy{% endtrans %}</h3>
+    <p>{% trans %}
+      LodgeIt does not use user accounts because it's logging in for using a
+      pastebin is useless. However this pastebin creates unique user ids for you
+      and for 31 days. Whenever you return to the pastebin it will notify you
+      about replies to your pastes.  If you don't want to have that feature you
+      can let Lodgeit forget about you by <a
+      href="javascript:LodgeIt.removeCookie()">removing the cookie</a>.
+      Please note that on the next request you will get a new id.{% endtrans %}
+    </p>
+  </div>
+{% endblock %}

lodgeit/templates/compare_paste.html

+{% extends "layout.html" %}
+{% from 'utils/macros.html' import render_diff_part %}
+{% set page_title = 'Compare Pastes' %}
+{% set active_page = 'all' %}
+{% block body %}
+  <p>
+    Differences between the pastes
+    <a href="{{ url('pastes/show_paste', identifier=new.identifier) }}">#{{ new.identifier }}</a> ({{ new.pub_date|datetimeformat }})
+    and <a href="{{ url('pastes/show_paste', identifier=old.identifier) }}">#{{ old.identifier }}</a> ({{ old.pub_date|datetimeformat }}). Download as <a href="{{ url('pastes/unidiff_paste', new_id=new.identifier, old_id=old.identifier) }}">unified diff</a>.
+  </p>
+  {% if diff.chunks %}
+    {{ render_diff_part(diff) }}
+  {% else %}
+    <p>{% trans %}The two pastes are identical.{% endtrans %}</p>
+  {% endif %}
+{% endblock %}

lodgeit/templates/help/advanced.html

+{% extends "help/layout.html" %}
+{% block help_body %}
+  <h3>{% trans %}Advanced Features{% endtrans %}</h3>
+  <p>{% trans %}
+    If you are looking at a paste you can toggle the paste detail
+    box by clicking on "paste detail". From there you have (depending on
+    the type of paste) a couple of options:{% endtrans %}
+  </p>
+  <img src="{{ url('static', file='help/advanced_features.png') }}" class="standalone" alt="{% trans %}screenshot of the paste detail box{% endtrans %}">
+  <p>{% trans %}
+    In any case you can reply to that paste by clicking on the
+    "reply to this paste" link. Also always possible is downloading the
+    paste, changing the color scheme and toggeling the line numbers.{% endtrans %}
+  </p>
+  <p>{% trans %}
+    If the paste you're looking at is a reply to another paste you can
+    compare it with the parent paste by clicking on the "compare it with
+    parent paste" link. If this paste has pastes that replied to you will
+    see a list of replies in the detail box.{% endtrans %}
+  </p>
+  <p>{% trans %}
+    Even if someone copied over the paste by hand to make changes you can
+    still compare those two pastes if you enter the id of the other paste
+    into the textfield and click compare.{% endtrans %}
+  </p>
+  <p>{% trans %}
+    If you want to see all pastes that are somehow related to the current
+    one, click on the "show paste tree" link:{% endtrans %}
+  </p>
+  <img src="{{ url('static', file='help/paste_tree.png') }}" class="standalone" alt="{% trans %}screenshot of the paste tree{% endtrans %}">
+  <h3>{% trans %}Comparing Pastes{% endtrans %}</h3>
+  <p>{% trans %}
+    In the diff view you can see the differences between two pastes. Deleted
+    lines have a redish background, added lines a bright green one. You can
+    also download the changes as unified diff.{% endtrans %}
+  </p>
+  <img src="{{ url('static', file='help/diff_view.png') }}" class="standalone" alt="{% trans %}screenshot of the diff viewer{% endtrans %}">
+  <h3>{% trans %}Paste Notifications{% endtrans %}</h3>
+  <p>{% trans %}
+    If someone replies to one of your pastes you will get a notification the
+    next time you visit the pastebin. This however doesn't work for pastes
+    older than 31 days because after that time you get a new cookie for
+    privacy reasons.{% endtrans %}
+  </p>
+  <h3>{% trans %}Multi-File Pastes{% endtrans %}</h3>
+  <p>{% trans %}
+    If you select the "Multi-File" formatter from the list you can combine
+    multiple files into one paste.  Each file has to be introduced with a
+    formatter line of the following format:
+  {% endtrans %}</p>
+  <pre class="sample">{{ _('### filename [formatter key]') }}</pre>
+  <p>{% trans %}
+    Both the filename and the formatter key is optional.  If no formatter
+    key is provided the formatter is guessed from the filename.  If the
+    filename is given it will be used as headline for the section.
+  {% endtrans %}</p>
+  <p>{{ _('The list of formatters is on the bottom of this page.') }}</p>
+  <h3>{{ _('Formatter Preselection') }}</h3>
+  <p>{% trans %}
+    If you want to use lodgeit on your project's IRC channel you can add
+    <code>+FORMATTER</code> to the URL where <code>FORMATTER</code> is the
+    name of the formatter to select from the list below:
+  {% endtrans %}</p>
+  <h3>{{ _('Supported Formatters') }}</h3>
+  <table>
+    <tr><th>{{ _('Key') }}</th><th>{{ _('Name') }}</th></tr>
+    {%- for key, name in formatters|dictsort(true, 'value') %}
+      <tr><td><code>{{ key }}</code></td><td>{{ name }}</td></tr>
+    {%- endfor %}
+  </table>
+{% endblock %}

lodgeit/templates/help/api.html

+{% extends "help/layout.html" %}
+{% block help_body %}
+  <h3>{% trans %}Using the LodegeIt API{% endtrans %}</h3>
+  <p>{% trans %}
+    LodgeIt supports currently two APIs: XMLRPC and good old JSON.
+  {% endtrans %}</p>
+  <p>{{ _('API URLs:') }}</p>
+  <ul>
+    <li><strong>XMLRPC:</strong> <tt>{{ pastebin_url }}xmlrpc/</tt></li>
+    <li><strong>JSON:</strong> <tt>{{ pastebin_url }}json/</tt></li>
+  </ul>
+  <p><small>{{ _('Note the trailing slash in both URLs!') }}</small></p>
+  <h3>{% trans %}XMLRPC Quickstart{% endtrans %}</h3>
+  <p>{% trans %}
+    You can connect to the XMLRPC interface with any XMLRPC library. If you're
+    using Python the following piece of code connects you to the XMLRPC service:{% endtrans %}
+  </p>
+  <pre class="sample">{% filter escape %}
+>>> from xmlrpclib import ServerProxy
+>>> s = ServerProxy('{{ pastebin_url|escape }}xmlrpc/')
+{% endfilter %}</pre>  
+  <p>
+    {% trans %}For example if you want to fetch one paste from the server you can do this:{% endtrans %}
+  </p>
+<pre class="sample">{% filter escape %}
+>>> paste = s.pastes.getPaste(23)
+>>> print paste['code']
+'{{ "{% if users %}" }}\n...'
+{% endfilter %}</pre>
+  <h3>{% trans %}JSON Quickstart{% endtrans %}</h3>
+  <p>{% trans %}
+    Alternatively you can use the JSON API.  Basically what you do is sending
+    the function arguments as a serialized JSON object or array to the JSON URL
+    from above with the method name as URL parameter.  You can do this for
+    example by using the curl command line tool:
+  {% endtrans %}</p>
+  <pre class="sample">
+$ curl -d '{"paste_id": 23}' -H 'Content-Type: application/json'
+  '{{ pastebin_url|escape }}json/?method=pastes.getPaste'
+{
+"data": {
+"code": '{{ '{% if users %}' }}\n...',
+"parsed_code": ...,
+"language": 'html+django',
+"url": "/show/23/",
+"parent_id": null,
+"paste_id": 23
+},
+"error": null
+}</pre>
+  <h3>{% trans %}Methods{% endtrans %}</h3>
+  <p>{% trans %}For a list of all supported methods see the list below.{% endtrans %}</p>
+  <ul class="xmlrpc-method-list">
+  {% for method in xmlrpc_methods %}
+    <li class="{{ loop.cycle('even', 'odd') }}"><p class="signature"><strong>{{
+      method.name|escape }}</strong><em>{{ method.signature|escape }}</em></p>
+        <p class="docstring">{{ method.doc|e }}</p></li>
+  {% endfor %}
+  </ul>
+{% endblock %}

lodgeit/templates/help/index.html

+{% extends "help/layout.html" %}
+{% block help_body %}
+  <h3>{% trans %}Welcome in the LodgeIt Help Section{% endtrans %}</h3>
+  <p>{% trans %}
+    Here you can read about the features of LodgeIt and how to use them
+    properly.{% endtrans %}
+  </p>
+  <p>
+    {% trans %}Select the topic you're interested in from the list on the right.{% endtrans %}
+  </p>
+{% endblock %}

lodgeit/templates/help/integration.html

+{% extends "help/layout.html" %}
+{% block help_body %}
+  <h3>{% trans %}Scripts and Editor Integration{% endtrans %}</h3>
+  <p>{% trans %}
+    For some popular editors lodgeit integration scripts/plugins exist.
+    Additionally there is also a small script that allows pasting from the
+    command line.{% endtrans %}
+  </p>
+  <h3>{% trans %}Command Line Script{% endtrans %}</h3>
+  <p>
+    {% trans %}The usage is pretty simple, to paste a file use the following command{% endtrans %}
+  </p>
+  <pre class="sample">{% trans %}lodgeit.py /path/to/file{% endtrans %}</pre>
+  <p>{% trans %}
+    This will use various guessing methods to get the correct language of
+    the file. If all guessing fails it falls back to a normal text paste.
+    You can also provide the language yourself.{% endtrans %}
+  </p>
+  <pre class="sample">{% trans %}lodgeit.py -l LANGUAGE /path/to/file{% endtrans %}</pre>
+  <p>
+    {% trans %}For a list of supported languages use the following command:{% endtrans %}
+  </p>
+  <pre class="sample">{% trans %}lodgeit.py --languages{% endtrans %}</pre>
+  <p>{% trans %}If no file is given it will read from the standard input stream.{% endtrans %}</p>
+  <p>{% trans %}If multiple files are given, they will be put into one paste using the
+    "multi-file" formatter.{% endtrans %}</p>
+  <p>
+    <strong>{% trans %}Download:{% endtrans %}</strong>
+    <a href="http://dev.pocoo.org/hg/lodgeit-main/raw-file/tip/scripts/lodgeit.py">lodgeit.py</a>
+  </p>
+  <h3>{% trans %}Vim Support{% endtrans %}</h3>
+  <p>{% trans %}
+    If Vim is your editor you can paste and download pastes directly from
+    within Vim.{% endtrans %}
+  </p>
+  <p>{% trans %}
+    All you have to do to paste the current range or whole buffer to lodgeit
+    is executing <tt>:Lodgeit</tt>. If you want you can map this command to
+    a mapping like ctrl+p by adding this to your vimrc:{% endtrans %}
+  </p>
+  <pre class="sample">map ^P :Lodgeit&lt;CR&gt;</pre>
+  <p>{% trans %}(^P is entered using ctrl + v, ctrl + in vim){% endtrans %}</p>
+  <p>{% trans %}
+    If you want to reply to a paste from within Vim you can call
+    <tt>:Lodgeit PASTE_URL</tt> or <tt>:Lodgeit #PASTE_ID</tt> and load the
+    paste into a new tab. After modifing it you can push the new version to
+    the server using <tt>:Lodgeit</tt>.{% endtrans %}
+  </p>
+  <p>
+    <strong>{% trans %}Download:{% endtrans %}</strong>
+    <a href="http://www.vim.org/scripts/script.php?script_id=1965">lodgeit.vim</a>
+  </p>
+  <h3>{% trans %}Emacs Support{% endtrans %}</h3>
+  <p>{% trans %}
+    You need a working installation of <a href="http://pymacs.progiciels-bpi.ca/">Pymacs</a>.
+    For Linux users, many distributions already include a package; otherwise, refer to the
+    <a href="http://pymacs.progiciels-bpi.ca/manual/Installation.html#Installation">Pymacs documentation</a>
+    for help. If Pymacs is working, you just need to put <tt>paste.py</tt> into a directory where
+    Pymacs can find it (see the variable <tt>pymacs-load-path</tt>), and add the line
+    <tt>(pymacs-load "paste")</tt> to your <tt>.emacs</tt> file. If you want a Pastebin menu in
+    your menu bar, you also need to add the line <tt>(paste-menu)</tt>.{% endtrans %}
+  </p>
+  <p>
+    {% trans %}Detailed usage instructions are located at <a href="http://lunaryorn.de/projects/paste/">on the project page{% endtrans %}</a>.
+  </p>
+  <p>
+    <strong>{% trans %}Download:{% endtrans %}</strong>
+    <a href="http://lunaryorn.de/projects/paste/">paste.py</a>
+  </p>
+{% endblock %}

lodgeit/templates/help/layout.html

+{% extends "layout.html" %}
+{% set page_title = _('Help') %}
+{% set active_page = 'help' %}
+{% block body %}
+  <ul id="help-navigation">
+  {%- for topic, title in help_topics %}
+    <li{% if current_topic == topic %} class="active"{% endif
+      %}><a href="{{ url('static/help', topic=topic) }}">{{ title|e }}</a></li>
+  {%- endfor %}
+  </ul>
+  <div class="text">
+    {% block help_body %}{% endblock %}
+  </div>
+{% endblock %}

lodgeit/templates/help/pasting.html

+{% extends "help/layout.html" %}
+{% block help_body %}
+  <h3>{% trans %}Creating New Pastes{% endtrans %}</h3>
+  <p>{% trans url=url('pastes/new_paste') %}
+    If you use the web interface to create new pastes the process is
+    straightforward. All you have to do is to click on the <a href="{{ url }}">new</a>
+    tab and fill in the text field. Additionally you should select a proper
+    highlighter from the list below to make it easier to read your paste.{% endtrans %}
+  </p>
+  <img src="{{ url('static', file='help/new_paste.png') }}" class="standalone" alt="{% trans %}screenshot of the form{% endtrans %}">
+  <p>
+    {% trans %}After you have finished just hit "paste" to submit the paste.{% endtrans %}
+  </p>
+  <h3>{% trans %}Replying to Pastes{% endtrans %}</h3>
+  <p>{% trans %}
+    Another way of creating a new paste is to reply to an existing paste.
+    When looking at a paste click on the "Paste Details" link to open the
+    paste menu. From there select the "reply to this paste" link.{% endtrans %}
+  </p>
+  <img src="{{ url('static', file='help/reply_to_paste.png') }}" class="standalone" alt="{% trans %}screenshot of the paste detail box{% endtrans %}">
+  <p>{% trans %}
+    A new editor window will open with the contents of the old paste. Just
+    do your changes and click "paste" to submit them.{% endtrans %}
+  </p>
+  <p>{% trans url=url('static/help', topic='advanced') %}
+    If you use the reply feature a link to the parent paste is created
+    automatically. This allows you to compare those two pastes with one
+    click to find changes easily. For information about the diff view
+    head over to the <a href="{{ url }}">advanced features</a> page.{% endtrans %}
+  </p>
+{% endblock %}

lodgeit/templates/json.html

+{% extends "layout.html" %}
+{% set page_title = _('JSON') %}
+{% set active_page = 'about' %}
+{% block body %}
+  <div class="text">
+    <h3>{% trans %}JSON Entrypoint{% endtrans %}</h3>
+    <p>{% trans %}
+      This is the entrypoint for the JSON API. If you're interested
+      in using it head over to the <a href="{{ url('static/help', topic='api') }}">API documentation</a>.
+      {%- endtrans %}
+    </p>
+    <p>{% trans %}
+      Alternatively you can also use the <a href="{{ url('xmlrpc/handle_request') }}">XMLRPC</a> service.
+    {% endtrans %}</p>
+  </div>
+{% endblock %}

lodgeit/templates/layout.html

+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+  "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+  <head>
+    <title>{{ page_title|e }} | LodgeIt!</title>
+    <link rel="stylesheet" href="{{ url_for ('static', filename='style.css') }}" type="text/css">
+    <link rel="stylesheet" href="{{ url_for('static', filename='print.css') }}" type="text/css" media="print">
+    <link rel="stylesheet" href="{{ url_for('static', filename='redmond/jquery-ui-1.8.7.custom.css') }}" type="text/css">
+    <script type="text/javascript" src="{{ url_for ('static', filename='jquery-1.4.4.min.js') }}"></script>
+    <script type="text/javascript" src="{{ url_for ('static', filename='jquery-ui-1.8.7.custom.min.js') }}"></script>
+    <script type="text/javascript" src="{{ url_for ('static', filename='cookie.js') }}"></script>
+    <script type="text/javascript" src="{{ url_for ('static', filename='lodgeit.js') }}"></script>
+    {%- if css %}
+    <style type="text/css">
+      {{ css|e }}
+    </style>
+    {%- endif %}
+  </head>
+  <body>
+    <div class="page">
+      <div id="header"><h1>Lodge It</h1></div>
+      <ul id="navigation">
+      {%- for href, id, caption in [
+        (url_for('pastes.new_paste'), 'new', _('New')),
+        (url_for('pastes.show_all'), 'all', _('All')),
+        (url_for('static.about'), 'about', _('About')),
+        (url_for('static.help'), 'help', '?')
+      ] %}
+        <li{% if active_page == id %} class="active"{% endif %}>
+          <a href="{{ href|e }}">{{ caption|e }}</a>
+        </li>
+      {%- endfor %}
+      </ul>
+      {# <ul id="languages">
+      {% for lang, name in i18n_languages %}
+        <li{% if request.locale.language == lang %} class="active"{% endif %}>
+          <a href="{{ url_for('pastes.set_language', lang=format(lang)) }}"><img alt="{{ lang }}" src="{{ url_for('static', filename='flags/%s.png'|format(lang)) }}"></a>
+        </li>
+      {% endfor %}
+      </ul> #}
+      <div class="content">
+        <h2>{{ page_title|e }}</h2>
+        {%- if new_replies %}
+          <div class="notification">
+            <h3>{% trans %}Someone Replied To Your Paste{% endtrans %}</h3>
+            {% for paste in new_replies %}
+            <p>{% trans date=paste.pub_date|datetimeformat,
+                        parent=paste.parent.identifier,
+                        paste=paste.indentifier, 
+                        paste_url_for=url_for('pastes/show_paste', identifier=paste.identifier), 
+                        parent_url_for=url_for('pastes/show_paste', identifier=paste.parent.identifier),
+                        compare_url_for=url_for('pastes/compare_paste', new_id=paste.identifier, old_id=paste.parent.identifier) %}
+              on {{ date }} someone replied to your paste 
+              <a href="{{ parent_url_for }}">#{{ parent }}</a>,
+              in paste <a href="{{ paste_url_for }}">#{{ paste }}</a>. Click here to
+              <a href="{{ compare_url_for }}">compare those two pastes</a>.{% endtrans %}
+            </p>
+            {% endfor %}
+            <p><a href="javascript:LodgeIt.hideNotification()">{% trans %}hide this notification{% endtrans %}</a></p>
+          </div>
+        {% elif request.first_visit %}
+          <div class="notification">
+            <h3>{% trans %}Welcome On LodgeIt{% endtrans %}</h3>
+            <p>{%- trans url_for=url_for('static/about') -%}
+              Welcome to the LodgeIt pastebin. In order to use the notification feature
+              a 31 day cookie with an unique ID was created for you. The lodgeit database
+              does not store any information about you, it's just used for an advanced
+              pastebin experience :-). Read more on the <a href="{{ url_for }}#privacy">about
+              lodgeit</a> page. Have fun :-){%- endtrans -%}
+            </p>
+            <p><a href="javascript:LodgeIt.hideNotification()">{% trans %}hide this notification{% endtrans %}</a></p>
+          </div>
+        {% endif -%}
+        {% block body %}{% endblock -%}
+        <div class="footer"></div>
+      </div>
+    </div>
+  </body>
+</html>

lodgeit/templates/new_paste.html

+{% extends "layout.html" %}
+{% set page_title = _('New Paste') %}
+{% set active_page = 'new' %}
+{% block body %}
+  <form action="{{ url_for('pastes.new_paste') }}" method="post" class="submitform">
+    {%- if error %}
+      <div class="notification">
+        <h3>{% trans %}Error While Pasting{% endtrans %}</h3>
+        <p>{% trans error=error|e %}Could not submit your paste because {{ error }}.{% endtrans %}</p>
+        {%- if show_captcha %}
+        <div class="captcha">
+          <p>{% trans %}Please fill out the CAPTCHA to proceed:{% endtrans %}</p>
+          <img src="{{ url_for('pastes.show_captcha') }}" alt="{% trans %}a captcha you can't see.  Sorry :({% endtrans %}">
+          <input type="text" name="captcha" size="20">
+        </div>
+        {%- else %}
+        <p><a href="javascript:LodgeIt.hideNotification()">{% trans %}hide this message{% endtrans %}</a></p>
+        {%- endif %}
+      </div>
+    {%- endif %}
+    {%- if parent %}
+      <input type="hidden" name="parent" value="{{ parent.identifier }}">
+    {%- endif %}
+    <textarea name="code" rows="10" cols="80">{{ code|e }}</textarea>
+    <select name="language">
+    {%- for key, caption in languages %}
+      <option value="{{ key }}"{% if language == key
+        %} selected="selected"{% endif %}>{{ caption|e }}</option>
+    {%- endfor %}
+    </select>
+    <input type="text" value="" name="webpage" id="webpage">
+    <input type="submit" value="{% trans %}Paste!{% endtrans %}">
+    <input type="button" value="▲" onclick="LodgeIt.resizeTextarea(-100)">
+    <input type="button" value="▼" onclick="LodgeIt.resizeTextarea(100)">
+    <input type="checkbox" name="private" id="private"{% if private
+      %} checked{% endif %}> <label for="private">{% trans
+      %}Paste private{% endtrans %}</label>
+    <span id="insert_tabs">
+      <input type="checkbox" id="insert_tabs_input">
+      <label for="insert_tabs_input">{% trans
+        %}Tab-key inserts tabstops{% endtrans %}</label>
+    </span>
+    <div id="multi-file-information">{% trans url=url_for('static.help', topic='advacnced') %}
+      You have selected the multi-file highlighter.  This highlighter allows
+      you to paste multiple different files that belong together.  For more
+      information have a look at <a href="{{ url }}">the advanced
+      features help page</a>.
+    {% endtrans %}</div>
+  </form>
+{% endblock %}

lodgeit/templates/not_found.html

+{% extends "layout.html" %}
+{% set page_title = _('Page Not Found') %}
+{% block body %}
+  <p>
+    {% trans %}Sorry, but the page you requested was not found on this server.{% endtrans %}
+  </p>
+  <p>{% trans url=url('static/about') %}
+    We've recently updated this pastebin. While it is out goal for nothing to get
+    lost, you may have found a page that was mis-placed. Check your URL to ensure
+    you have gone where you intended. If everything looks OK and you still see
+    this error page, please consider <a href="{{ url }}">contacting us</a>.{% endtrans %}
+  </p>
+  <p>
+    {% trans url=url('pastes/new_paste') %}Click <a href="{{ url }}">here</a> to add a new paste.{% endtrans %}
+  </p>
+{% endblock %}

lodgeit/templates/paste_tree.html

+{% extends "layout.html" %}
+{% set page_title = _('Paste Tree') %}
+{% set active_page = 'all' %}
+{% block body %}
+  <p>{% trans %}
+    Here you can see the requested tree of paste replies. The paste you're
+    coming from is highlighted.{% endtrans %}
+  </p>
+  <ul class="paste_tree">
+  {%- for paste in [paste] recursive %}
+    <li{% if paste.identifier == current
+      %} class="highlighted"{% endif %}><a href="{{ url('pastes/show_paste', identifier=paste.identifier)
+      }}">Paste #{{ paste.identifier }}</a> &mdash; {{
+        paste.pub_date|datetimeformat }}
+      {%- if paste.children -%}
+        <ul>{{ loop(paste.children) }}</ul>
+      {%- endif -%}
+    </li>
+  {%- endfor %}
+  </ul>
+{% endblock %}

lodgeit/templates/show_all.html

+{% extends "layout.html" %}
+{% set page_title = _('All Pastes') %}
+{% set active_page = 'all' %}
+{% block body %}
+  {% if pastes %}
+  <ul class="paste_list">
+  {% for paste in pastes %}
+    <li class="{{ loop.cycle('even', 'odd') }}"><p><a href="{{ url('pastes/show_paste', identifier=paste.identifier)
+        }}">Paste #{{ paste.identifier }}</a>,
+        {% trans date=paste.pub_date|datetimeformat %}pasted on {{ date }}{% endtrans %}</p>
+      {{ paste.render_preview() }}</li>
+  {%- endfor %}
+  </ul>
+  {% else %}
+  <strong>{% trans %}No pastes found{% endtrans %}</strong>
+  {% endif %}
+  <div class="pagination">
+    {{ pagination }}
+  </div>
+{% endblock %}

lodgeit/templates/show_paste.html

+{% extends "layout.html" %}
+{% set page_title = 'Paste #' ~ paste.identifier %}
+{% set active_page = 'all' %}
+{% block body %}
+  <div class="related">
+    <h3><a href="javascript:LodgeIt.toggleRelatedBox()">{% trans %}Paste Details{% endtrans %}</a></h3>
+    <div class="quick">
+      <p><a href="{{ url('pastes/new_paste', reply_to=paste.identifier) }}">{% trans %}reply{% endtrans %}</a> |
+         <a href="{{ url('pastes/raw_paste', identifier=paste.identifier) }}">{% trans %}raw{% endtrans %}</a></p>
+    </div>
+    <div class="content">
+      <p>{% trans pub_date=paste.pub_date|datetimeformat %}posted on {{ pub_date }}{% endtrans %}</p>
+      <ul>
+        <li><a class="autoclose" href="{{ url('pastes/new_paste', reply_to=paste.identifier) }}">{% trans %}reply to this paste{% endtrans %}</a></li>
+        {% if paste.parent %}
+          <li><a class="autoclose" href="{{ url('pastes/compare_paste', new_id=paste.identifier, old_id=paste.parent.identifier) }}">{% trans %}compare it with the parent paste{% endtrans %}</a></li>
+          <li><a class="autoclose" href="{{ url('pastes/show_paste', identifier=paste.parent.identifier) }}">{% trans %}look at the parent paste{% endtrans %}</a></li>
+        {% endif %}
+        {% if paste.children %}
+          <li>{% trans %}the following pastes replied to this paste:{% endtrans %}
+          {% for child in paste.children %}
+            <a class="autoclose" href="{{ url('pastes/show_paste', identifier=child.identifier) }}">#{{ child.identifier }}</a>
+            {%- if not loop.last %},{% endif -%}
+          {% endfor %}
+          </li>
+        {% endif %}
+        {% if paste.parent or paste.children %}
+          <li><a href="{{ url('pastes/show_tree', identifier=paste.identifier) }}">{% trans %}show paste tree{% endtrans %}</a></li>
+        {% endif %}
+        <li><a href="{{ url('pastes/raw_paste', identifier=paste.identifier) }}">{% trans %}download paste{% endtrans %}</a></li>
+        <li>{% trans %}compare with paste{% endtrans %} <form action="{{ url('pastes/compare_paste') }}" method="post">
+          <input type="hidden" name="old" value="{{ paste.identifier }}">
+          <input type="text" name="new" value="#">
+          <input type="submit" value="{% trans %}compare{% endtrans %}">
+        </form></li>
+        <li>{% trans %}select different colorscheme{% endtrans %} <form action="{{ url('pastes/set_colorscheme') }}" method="post">
+          <select name="style">
+          {%- for key, caption in styles|dictsort %}
+            <option value="{{ key }}"{% if key == style
+              %} selected="selected"{% endif %}>{{ caption }}</option>
+          {%- endfor %}
+          </select>
+          <input type="submit" value="{% trans %}change{% endtrans %}">
+        </form></li>
+        <li><a href="?linenos={{ linenos and 'no' or 'yes' }}" onclick="LodgeIt.toggleLineNumbers(); return false;">{% trans %}toggle line numbers{% endtrans %}</a></li>
+      </ul>
+    </div>
+  </div>
+  <div id="paste" class="lang-{{ paste.language }} code{% if not linenos %} nolinenos{% endif %}">
+    {{ paste.parsed_code }}
+  </div>
+{% endblock %}

lodgeit/templates/utils/compiler-messages.html

+<div class="compiler-messages compiler-{{ compiler }}">
+  <table class="formatted">
+  {%- for line in lines %}
+    {%- if line.is_raw %}
+    <tr class="raw"><td colspan="3"><pre>{{ line.raw|e }}</pre></td></tr>
+    {%- else %}
+    <tr class="{{ line.level }}">
+      <td class="level">{{ line.level }}</td>
+      <td class="location">
+        <span class="filename">{{ line.filename|e }}</span>:
+        {%- if line.lineno or line.column -%}
+          <span class="position">
+            {{- line.lineno -}}
+            {% if line.column -%}
+              :{{ line.column }}
+            {%- endif -%}
+          </span>
+        {%- endif %}
+      </td>
+      <td class="message">{{ line.message|e }}</td>
+    </tr>
+    {% if line.context %}
+    <tr class="context">
+      <td>&nbsp;</td>
+      <td colspan="2"><pre>{{ line.context|e }}</pre></td>
+    </tr>
+    {% endif %}
+    {%- endif %}
+  {%- endfor %}
+  </table>
+</div>

lodgeit/templates/utils/filterable.html

+{% from 'utils/macros.html' import filterable %}
+{{ filterable(filters, fields, actions, args, inline) }}

lodgeit/templates/utils/macros.html

+{% macro filterable(filters, fields, actions, args, inline=False) %}
+  {% if not inline %}
+  <form action="" method="get">
+  {% endif %}
+    {%- for k, v in args.iteritems() %}
+    {%- if v %}
+    <input type="hidden" name="{{ k|e }}" value="{{ v|e }}">
+    {%- endif %}
+    {%- endfor %}
+    <table class="filterable">
+      {%- for field, _ in filters.iteritems() %}
+      {%- set action, value = _ %}
+      {%- set label, type = fields[field] %}
+      <tr class="filter_value">
+        {%- if type == 'bool' %}
+        <td class="field value" colspan="3">
+          <input type="hidden" name="{{ field }}_action" value="bool">
+          <select name="{{ field }}_value">
+            <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{% endif %}>
+              {{- v|e -}}
+            </option>
+            {%- endfor %}
+          </select>
+        </td>
+        <td class="value">
+          <input type="{{ fields[field][1] == 'date' and 'date' or 'text' }}"
+                 name="{{ field }}_value" value="{{ value|e }}">
+        </td>
+        {%- endif %}
+        <td class="action">
+          <button type="submit" name="remove_filter" value="{{ field }}">-</button>
+        </td>
+      </tr>
+      {%- endfor %}
+      <tr>
+        <td colspan="4">
+          <div class="add{% if not filters %} left{% endif %}">
+            {% trans %}new filter: {% endtrans %}<select name="new_filter">
+              <option></option>
+              {%- for k, v in fields.iteritems() %}
+              {%- if k not in filters %}
+              <option value="{{ k }}">{{ v[0]|e }}</option>
+              {%- endif %}
+              {%- endfor %}
+            </select>
+            <input type="submit" name="add_filter" value="{% trans %}ok{% endtrans %}">
+          </div>
+          {%- if filters and not inline %}
+          <input type="submit" value="{% trans %}update{% endtrans %}">
+          {%- endif %}
+        </td>
+      </tr>
+    </table>
+  {% if not inline %}
+  </form>
+  {% endif %}
+{% endmacro %}
+
+
+{% macro render_diff_part(diff) %}
+  <table class="diff">
+    {%- for chunk in diff.chunks -%}
+      {% if not loop.first -%}
+        <tr class="ellipsis">
+          <th colspan="3">…</th>
+        </tr>
+      {%- endif -%}
+      {% for line in chunk %}
+        <tr class="line {{ line.action }}">
+          <th class="old_rev">{{ line.old_lineno }}</th>
+          <th class="new_rev">{{ line.new_lineno }}</th>
+          <td class="code">{{ line.line }}</td>
+        </tr>
+      {%- endfor -%}
+    {% endfor %}
+  </table>
+{% endmacro %}

lodgeit/templates/utils/udiff.html

+{% from 'utils/macros.html' import render_diff_part %}
+<div class="diff-table">
+  {%- if info %}
+  <div class="diffinfo">
+    {%- for (k, v) in info %}
+    {% if k %}<b>{{ k }}:</b> {% endif %}{{ v|replace('\n', '<br>') }}
+    {%- if not loop.last %}<br>{% endif %}
+    {%- endfor %}
+  </div>
+  {%- endif %}
+  {% for diff in diffs %}
+    <div class="diff">
+      {% if diff.is_header %}
+        <pre class="header">{{ diff.lines|join("\n")|e }}</pre>
+      {% else %}
+        <div class="meta">
+          {% for key in 'old', 'new' %}
+          <div class="{{ key }}">
+            <span class="filename">{{ diff[key ~ '_filename']|e }}</span>
+            {% if diff[key ~ '_revision'] %}
+              <span class="revision">[{{ diff[key ~ '_revision']|e }}]</span>
+            {% endif %}
+          </div>
+          {% endfor %}
+        </div>
+        {{ render_diff_part(diff) }}
+      {% endif %}
+    </div>
+  {% endfor %}
+</div>

lodgeit/templates/xmlrpc.html

+{% extends "layout.html" %}
+{% set page_title = _('XMLRPC') %}
+{% set active_page = 'about' %}
+{% block body %}
+  <div class="text">
+    <h3>{% trans %}XMLRPC Entrypoint{% endtrans %}</h3>
+    <p>{% trans %}
+      This is the entrypoint for the XMLRPC system. If you're interested
+      in using it head over to the <a href="{{ url('static/help', topic='api') }}">API documentation</a>.
+      {%- endtrans %}
+    </p>
+    <p>{% trans %}
+      Alternatively you can also use the <a href="{{ url('json/handle_request') }}">JSON</a> API.
+    {% endtrans %}</p>
+  </div>
+{% endblock %}
 
 urlmap = Map([
     # paste interface
-    Rule('/', endpoint='pastes/new_paste'),
-    Rule('/+<language>', endpoint='pastes/new_paste'),
-    Rule('/show/<identifier>/', endpoint='pastes/show_paste'),
-    Rule('/raw/<identifier>/', endpoint='pastes/raw_paste'),
     Rule('/compare/', endpoint='pastes/compare_paste'),
     Rule('/compare/<new_id>/<old_id>/', endpoint='pastes/compare_paste'),
     Rule('/unidiff/<new_id>/<old_id>/', endpoint='pastes/unidiff_paste'),
 
 from babel import Locale
 
-from lodgeit import local
-from lodgeit.i18n import get_translations
 from lodgeit.lib.highlighting import get_style
 
 try:

lodgeit/views/about.html

-{% extends "layout.html" %}
-{% set page_title = _('About LodgeIt') %}
-{% set active_page = 'about' %}
-{% block body %}
-  <div class="text">
-    <h3 id="why-the-hell-another-pastebin">{% trans %} Why the hell another pastebin?{% endtrans %}</h3>
-    <p>{% trans %}
-      Good question. Basically the world doesn't need another pastebin.
-      There is <a href="http://pastie.caboo.se/">pastie</a> and
-      <a href="http://dpaste.com/">dpaste.com</a> which
-      both use kick-ass highlighting libraries for highlighting the
-      code and both have an	intuitive user interface. Nevertheless there
-      are some features which are unique to LodgeIt.{% endtrans %}
-    </p>
-    <h3 id="features">{% trans %}Features{% endtrans %}</h3>
-    <ul>
-       <li>{% trans %}clean user interface{% endtrans %}</li>
-       <li>{% trans %}different color schemes for the sourcecode{% endtrans %}</li>
-       <li>{% trans %}reply to pastes{% endtrans %}</li>
-       <li>{% trans %}diffs of two pastes{% endtrans %}</li>
-       <li>{% trans %}support for many python template languages{% endtrans %}</li>
-       <li>{% trans %}support for many scripting languages like Python and Ruby, even with
-           weird syntax (ruby *cough*){% endtrans %}</li>
-       <li><a href="{{ url('static/help', topic='api') }}">{% trans %}XMLRPC support{% endtrans %}</a></li>
-       <li><a href="{{ url('static/help', topic='integration' ) }}">{% trans %}command-line and editor integration{% endtrans %}</a></li>
-       <li>{% trans %}persistent pastes{% endtrans %}</li>
-       <li>{% trans %}reply notification{% endtrans %}</li>
-       <li>{% trans %}valid HTML 4.0{% endtrans %}</li>
-    </ul>
-    <h3 id="request-more-languages">{% trans %}Request More Languages{% endtrans %}</h3>
-    <p>{% trans %}
-      A language is missing in the list? File a ticket in the
-      <a href="http://dev.pocoo.org/projects/pygments">Pygments trac</a> and we add that as soon
-      as possible.{% endtrans %}
-    </p>
-    <h3 id="software-used">{% trans %}Software Used{% endtrans %}</h3>
-    <ul>
-      <li>{% trans %}<a href="http://pygments.pocoo.org/">Pygments</a> for syntax highlighting{% endtrans %}</li>
-      <li>{% trans %}<a href="http://www.python.org/">Python</a> as scripting language{% endtrans %}</li>
-      <li>{% trans %}<a href="http://jinja.pocoo.org/2">Jinja 2</a> for templating{% endtrans %}</li>
-      <li>{% trans %}<a href="http://werkzeug.pocoo.org/">Werkzeug</a> for the WSGI implementation{% endtrans %}</li>
-      <li>{% trans %}<a href="http://www.sqlalchemy.org">SQLAlchemy</a> as database layer{% endtrans %}</li>
-      <li>{% trans %}<a href="http://www.jquery.com/">jQuery</a> for scripting{% endtrans %}</li>
-    </ul>
-    <h3 id="who">{% trans %}Who?{% endtrans %}</h3>
-    <p>{% trans %}
-      This paste was founded by <a href="http://lucumr.pocoo.org/">Armin Ronacher</a>
-      from the Pocoo team and is now maintained by
-      <a href="http://webshox.org">Christopher Grebs</a>.  Pygments is a Pocoo project
-      led by Georg Brandl.{% endtrans %}
-    </p>
-    <h3 id="privacy">{% trans %}Privacy{% endtrans %}</h3>
-    <p>{% trans %}
-      LodgeIt does not use user accounts because it's logging in for using a
-      pastebin is useless. However this pastebin creates unique user ids for you
-      and for 31 days. Whenever you return to the pastebin it will notify you
-      about replies to your pastes.  If you don't want to have that feature you
-      can let Lodgeit forget about you by <a
-      href="javascript:LodgeIt.removeCookie()">removing the cookie</a>.
-      Please note that on the next request you will get a new id.{% endtrans %}
-    </p>
-  </div>
-{% endblock %}

lodgeit/views/compare_paste.html

-{% extends "layout.html" %}
-{% from 'utils/macros.html' import render_diff_part %}
-{% set page_title = 'Compare Pastes' %}
-{% set active_page = 'all' %}
-{% block body %}
-  <p>
-    Differences between the pastes
-    <a href="{{ url('pastes/show_paste', identifier=new.identifier) }}">#{{ new.identifier }}</a> ({{ new.pub_date|datetimeformat }})
-    and <a href="{{ url('pastes/show_paste', identifier=old.identifier) }}">#{{ old.identifier }}</a> ({{ old.pub_date|datetimeformat }}). Download as <a href="{{ url('pastes/unidiff_paste', new_id=new.identifier, old_id=old.identifier) }}">unified diff</a>.
-  </p>
-  {% if diff.chunks %}
-    {{ render_diff_part(diff) }}
-  {% else %}
-    <p>{% trans %}The two pastes are identical.{% endtrans %}</p>
-  {% endif %}
-{% endblock %}

lodgeit/views/help/advanced.html

-{% extends "help/layout.html" %}
-{% block help_body %}
-  <h3>{% trans %}Advanced Features{% endtrans %}</h3>
-  <p>{% trans %}
-    If you are looking at a paste you can toggle the paste detail
-    box by clicking on "paste detail". From there you have (depending on
-    the type of paste) a couple of options:{% endtrans %}
-  </p>
-  <img src="{{ url('static', file='help/advanced_features.png') }}" class="standalone" alt="{% trans %}screenshot of the paste detail box{% endtrans %}">
-  <p>{% trans %}
-    In any case you can reply to that paste by clicking on the
-    "reply to this paste" link. Also always possible is downloading the
-    paste, changing the color scheme and toggeling the line numbers.{% endtrans %}
-  </p>
-  <p>{% trans %}
-    If the paste you're looking at is a reply to another paste you can
-    compare it with the parent paste by clicking on the "compare it with
-    parent paste" link. If this paste has pastes that replied to you will
-    see a list of replies in the detail box.{% endtrans %}
-  </p>
-  <p>{% trans %}
-    Even if someone copied over the paste by hand to make changes you can
-    still compare those two pastes if you enter the id of the other paste
-    into the textfield and click compare.{% endtrans %}
-  </p>
-  <p>{% trans %}
-    If you want to see all pastes that are somehow related to the current
-    one, click on the "show paste tree" link:{% endtrans %}
-  </p>
-  <img src="{{ url('static', file='help/paste_tree.png') }}" class="standalone" alt="{% trans %}screenshot of the paste tree{% endtrans %}">
-  <h3>{% trans %}Comparing Pastes{% endtrans %}</h3>
-  <p>{% trans %}
-    In the diff view you can see the differences between two pastes. Deleted
-    lines have a redish background, added lines a bright green one. You can
-    also download the changes as unified diff.{% endtrans %}
-  </p>
-  <img src="{{ url('static', file='help/diff_view.png') }}" class="standalone" alt="{% trans %}screenshot of the diff viewer{% endtrans %}">
-  <h3>{% trans %}Paste Notifications{% endtrans %}</h3>
-  <p>{% trans %}
-    If someone replies to one of your pastes you will get a notification the
-    next time you visit the pastebin. This however doesn't work for pastes
-    older than 31 days because after that time you get a new cookie for
-    privacy reasons.{% endtrans %}
-  </p>
-  <h3>{% trans %}Multi-File Pastes{% endtrans %}</h3>
-  <p>{% trans %}
-    If you select the "Multi-File" formatter from the list you can combine
-    multiple files into one paste.  Each file has to be introduced with a
-    formatter line of the following format:
-  {% endtrans %}</p>
-  <pre class="sample">{{ _('### filename [formatter key]') }}</pre>
-  <p>{% trans %}
-    Both the filename and the formatter key is optional.  If no formatter
-    key is provided the formatter is guessed from the filename.  If the
-    filename is given it will be used as headline for the section.
-  {% endtrans %}</p>
-  <p>{{ _('The list of formatters is on the bottom of this page.') }}</p>
-  <h3>{{ _('Formatter Preselection') }}</h3>
-  <p>{% trans %}
-    If you want to use lodgeit on your project's IRC channel you can add
-    <code>+FORMATTER</code> to the URL where <code>FORMATTER</code> is the
-    name of the formatter to select from the list below:
-  {% endtrans %}</p>
-  <h3>{{ _('Supported Formatters') }}</h3>
-  <table>
-    <tr><th>{{ _('Key') }}</th><th>{{ _('Name') }}</th></tr>
-    {%- for key, name in formatters|dictsort(true, 'value') %}
-      <tr><td><code>{{ key }}</code></td><td>{{ name }}</td></tr>
-    {%- endfor %}
-  </table>
-{% endblock %}

lodgeit/views/help/api.html

-{% extends "help/layout.html" %}
-{% block help_body %}
-  <h3>{% trans %}Using the LodegeIt API{% endtrans %}</h3>
-  <p>{% trans %}
-    LodgeIt supports currently two APIs: XMLRPC and good old JSON.
-  {% endtrans %}</p>
-  <p>{{ _('API URLs:') }}</p>
-  <ul>
-    <li><strong>XMLRPC:</strong> <tt>{{ pastebin_url }}xmlrpc/</tt></li>
-    <li><strong>JSON:</strong> <tt>{{ pastebin_url }}json/</tt></li>
-  </ul>
-  <p><small>{{ _('Note the trailing slash in both URLs!') }}</small></p>
-  <h3>{% trans %}XMLRPC Quickstart{% endtrans %}</h3>
-  <p>{% trans %}
-    You can connect to the XMLRPC interface with any XMLRPC library. If you're
-    using Python the following piece of code connects you to the XMLRPC service:{% endtrans %}
-  </p>
-  <pre class="sample">{% filter escape %}
->>> from xmlrpclib import ServerProxy
->>> s = ServerProxy('{{ pastebin_url|escape }}xmlrpc/')
-{% endfilter %}</pre>  
-  <p>
-    {% trans %}For example if you want to fetch one paste from the server you can do this:{% endtrans %}
-  </p>
-<pre class="sample">{% filter escape %}
->>> paste = s.pastes.getPaste(23)
->>> print paste['code']
-'{{ "{% if users %}" }}\n...'
-{% endfilter %}</pre>
-  <h3>{% trans %}JSON Quickstart{% endtrans %}</h3>
-  <p>{% trans %}
-    Alternatively you can use the JSON API.  Basically what you do is sending
-    the function arguments as a serialized JSON object or array to the JSON URL
-    from above with the method name as URL parameter.  You can do this for
-    example by using the curl command line tool:
-  {% endtrans %}</p>
-  <pre class="sample">
-$ curl -d '{"paste_id": 23}' -H 'Content-Type: application/json'
-  '{{ pastebin_url|escape }}json/?method=pastes.getPaste'
-{
-"data": {
-"code": '{{ '{% if users %}' }}\n...',
-"parsed_code": ...,
-"language": 'html+django',
-"url": "/show/23/",
-"parent_id": null,
-"paste_id": 23
-},
-"error": null
-}</pre>
-  <h3>{% trans %}Methods{% endtrans %}</h3>
-  <p>{% trans %}For a list of all supported methods see the list below.{% endtrans %}</p>
-  <ul class="xmlrpc-method-list">
-  {% for method in xmlrpc_methods %}
-    <li class="{{ loop.cycle('even', 'odd') }}"><p class="signature"><strong>{{
-      method.name|escape }}</strong><em>{{ method.signature|escape }}</em></p>
-        <p class="docstring">{{ method.doc|e }}</p></li>
-  {% endfor %}
-  </ul>
-{% endblock %}

lodgeit/views/help/index.html

-{% extends "help/layout.html" %}
-{% block help_body %}
-  <h3>{% trans %}Welcome in the LodgeIt Help Section{% endtrans %}</h3>
-  <p>{% trans %}
-    Here you can read about the features of LodgeIt and how to use them
-    properly.{% endtrans %}
-  </p>
-  <p>
-    {% trans %}Select the topic you're interested in from the list on the right.{% endtrans %}
-  </p>
-{% endblock %}

lodgeit/views/help/integration.html

-{% extends "help/layout.html" %}
-{% block help_body %}
-  <h3>{% trans %}Scripts and Editor Integration{% endtrans %}</h3>
-  <p>{% trans %}
-    For some popular editors lodgeit integration scripts/plugins exist.
-    Additionally there is also a small script that allows pasting from the
-    command line.{% endtrans %}
-  </p>
-  <h3>{% trans %}Command Line Script{% endtrans %}</h3>
-  <p>
-    {% trans %}The usage is pretty simple, to paste a file use the following command{% endtrans %}
-  </p>
-  <pre class="sample">{% trans %}lodgeit.py /path/to/file{% endtrans %}</pre>
-  <p>{% trans %}
-    This will use various guessing methods to get the correct language of
-    the file. If all guessing fails it falls back to a normal text paste.
-    You can also provide the language yourself.{% endtrans %}
-  </p>
-  <pre class="sample">{% trans %}lodgeit.py -l LANGUAGE /path/to/file{% endtrans %}</pre>
-  <p>
-    {% trans %}For a list of supported languages use the following command:{% endtrans %}
-  </p>
-  <pre class="sample">{% trans %}lodgeit.py --languages{% endtrans %}</pre>
-  <p>{% trans %}If no file is given it will read from the standard input stream.{% endtrans %}</p>
-  <p>{% trans %}If multiple files are given, they will be put into one paste using the
-    "multi-file" formatter.{% endtrans %}</p>
-  <p>
-    <strong>{% trans %}Download:{% endtrans %}</strong>
-    <a href="http://dev.pocoo.org/hg/lodgeit-main/raw-file/tip/scripts/lodgeit.py">lodgeit.py</a>
-  </p>
-  <h3>{% trans %}Vim Support{% endtrans %}</h3>
-  <p>{% trans %}
-    If Vim is your editor you can paste and download pastes directly from
-    within Vim.{% endtrans %}
-  </p>
-  <p>{% trans %}
-    All you have to do to paste the current range or whole buffer to lodgeit
-    is executing <tt>:Lodgeit</tt>. If you want you can map this command to
-    a mapping like ctrl+p by adding this to your vimrc:{% endtrans %}
-  </p>
-  <pre class="sample">map ^P :Lodgeit&lt;CR&gt;</pre>
-  <p>{% trans %}(^P is entered using ctrl + v, ctrl + in vim){% endtrans %}</p>
-  <p>{% trans %}
-    If you want to reply to a paste from within Vim you can call
-    <tt>:Lodgeit PASTE_URL</tt> or <tt>:Lodgeit #PASTE_ID</tt> and load the
-    paste into a new tab. After modifing it you can push the new version to
-    the server using <tt>:Lodgeit</tt>.{% endtrans %}
-  </p>
-  <p>
-    <strong>{% trans %}Download:{% endtrans %}</strong>
-    <a href="http://www.vim.org/scripts/script.php?script_id=1965">lodgeit.vim</a>
-  </p>
-  <h3>{% trans %}Emacs Support{% endtrans %}</h3>
-  <p>{% trans %}
-    You need a working installation of <a href="http://pymacs.progiciels-bpi.ca/">Pymacs</a>.
-    For Linux users, many distributions already include a package; otherwise, refer to the
-    <a href="http://pymacs.progiciels-bpi.ca/manual/Installation.html#Installation">Pymacs documentation</a>
-    for help. If Pymacs is working, you just need to put <tt>paste.py</tt> into a directory where
-    Pymacs can find it (see the variable <tt>pymacs-load-path</tt>), and add the line
-    <tt>(pymacs-load "paste")</tt> to your <tt>.emacs</tt> file. If you want a Pastebin menu in
-    your menu bar, you also need to add the line <tt>(paste-menu)</tt>.{% endtrans %}
-  </p>
-  <p>
-    {% trans %}Detailed usage instructions are located at <a href="http://lunaryorn.de/projects/paste/">on the project page{% endtrans %}</a>.
-  </p>
-  <p>
-    <strong>{% trans %}Download:{% endtrans %}</strong>
-    <a href="http://lunaryorn.de/projects/paste/">paste.py</a>
-  </p>
-{% endblock %}

lodgeit/views/help/layout.html

-{% extends "layout.html" %}
-{% set page_title = _('Help') %}
-{% set active_page = 'help' %}
-{% block body %}
-  <ul id="help-navigation">
-  {%- for topic, title in help_topics %}
-    <li{% if current_topic == topic %} class="active"{% endif
-      %}><a href="{{ url('static/help', topic=topic) }}">{{ title|e }}</a></li>
-  {%- endfor %}
-  </ul>
-  <div class="text">
-    {% block help_body %}{% endblock %}
-  </div>
-{% endblock %}

lodgeit/views/help/pasting.html

-{% extends "help/layout.html" %}
-{% block help_body %}
-  <h3>{% trans %}Creating New Pastes{% endtrans %}</h3>
-  <p>{% trans url=url('pastes/new_paste') %}
-    If you use the web interface to create new pastes the process is
-    straightforward. All you have to do is to click on the <a href="{{ url }}">new</a>
-    tab and fill in the text field. Additionally you should select a proper
-    highlighter from the list below to make it easier to read your paste.{% endtrans %}
-  </p>
-  <img src="{{ url('static', file='help/new_paste.png') }}" class="standalone" alt="{% trans %}screenshot of the form{% endtrans %}">
-  <p>
-    {% trans %}After you have finished just hit "paste" to submit the paste.{% endtrans %}
-  </p>
-  <h3>{% trans %}Replying to Pastes{% endtrans %}</h3>
-  <p>{% trans %}
-    Another way of creating a new paste is to reply to an existing paste.
-    When looking at a paste click on the "Paste Details" link to open the
-    paste menu. From there select the "reply to this paste" link.{% endtrans %}
-  </p>
-  <img src="{{ url('static', file='help/reply_to_paste.png') }}" class="standalone" alt="{% trans %}screenshot of the paste detail box{% endtrans %}">
-  <p>{% trans %}
-    A new editor window will open with the contents of the old paste. Just
-    do your changes and click "paste" to submit them.{% endtrans %}
-  </p>
-  <p>{% trans url=url('static/help', topic='advanced') %}
-    If you use the reply feature a link to the parent paste is created
-    automatically. This allows you to compare those two pastes with one
-    click to find changes easily. For information about the diff view
-    head over to the <a href="{{ url }}">advanced features</a> page.{% endtrans %}
-  </p>
-{% endblock %}

lodgeit/views/json.html

-{% extends "layout.html" %}
-{% set page_title = _('JSON') %}
-{% set active_page = 'about' %}
-{% block body %}
-  <div class="text">
-    <h3>{% trans %}JSON Entrypoint{% endtrans %}</h3>
-    <p>{% trans %}
-      This is the entrypoint for the JSON API. If you're interested
-      in using it head over to the <a href="{{ url('static/help', topic='api') }}">API documentation</a>.
-      {%- endtrans %}
-    </p>
-    <p>{% trans %}
-      Alternatively you can also use the <a href="{{ url('xmlrpc/handle_request') }}">XMLRPC</a> service.
-    {% endtrans %}</p>
-  </div>
-{% endblock %}

lodgeit/views/layout.html

-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-  "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-  <head>
-    <title>{{ page_title|e }} | LodgeIt!</title>
-    <link rel="stylesheet" href="{{ url ('static', file='style.css') }}" type="text/css">
-    <link rel="stylesheet" href="{{ url('static', file='print.css') }}" type="text/css" media="print">
-    <link rel="stylesheet" href="{{ url('static', file='redmond/jquery-ui-1.8.7.custom.css') }}" type="text/css">
-    <script type="text/javascript" src="{{ url ('static', file='jquery-1.4.4.min.js') }}"></script>
-    <script type="text/javascript" src="{{ url ('static', file='jquery-ui-1.8.7.custom.min.js') }}"></script>