liberating jingo from zamboni
This commit is contained in:
commit
5caec33a4d
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
docs/_build
|
||||
.py[co]
|
27
LICENSE
Normal file
27
LICENSE
Normal file
@ -0,0 +1,27 @@
|
||||
Copyright (c) 2010, Jeff Balogh.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of jingo nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
3
MANIFEST.in
Normal file
3
MANIFEST.in
Normal file
@ -0,0 +1,3 @@
|
||||
include LICENSE
|
||||
include README.rst
|
||||
prune examples
|
10
README.rst
Normal file
10
README.rst
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
=====
|
||||
Jingo
|
||||
=====
|
||||
|
||||
``jingo`` is an adapter for using
|
||||
`Jinja2 <http://jinja.pocoo.org/2/documentation/>`_ templates within Django.
|
||||
|
||||
|
||||
See the full docs at http://jbalogh.me/projects/jingo.
|
89
docs/Makefile
Normal file
89
docs/Makefile
Normal file
@ -0,0 +1,89 @@
|
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = _build
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
|
||||
clean:
|
||||
-rm -rf $(BUILDDIR)/*
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/zamboni.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/zamboni.qhc"
|
||||
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
|
||||
"run these through (pdf)latex."
|
||||
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
30
docs/conf.py
Normal file
30
docs/conf.py
Normal file
@ -0,0 +1,30 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.append(os.path.abspath('..'))
|
||||
|
||||
import jingo
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
extensions = ['sphinx.ext.autodoc']
|
||||
|
||||
# General information about the project.
|
||||
project = u'Jingo'
|
||||
copyright = u'2010, The Zamboni Collective'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# version: The short X.Y version.
|
||||
# release: The full version, including alpha/beta/rc tags.
|
||||
version = release = jingo.__version__
|
||||
|
||||
# List of directories, relative to source directory, that shouldn't be searched
|
||||
# for source files.
|
||||
exclude_trees = ['_build']
|
100
docs/index.rst
Normal file
100
docs/index.rst
Normal file
@ -0,0 +1,100 @@
|
||||
.. _jingo:
|
||||
.. module:: jingo
|
||||
|
||||
A page about Jingo.
|
||||
===================
|
||||
|
||||
Jingo is an adapter for using
|
||||
`Jinja2 <http://jinja.pocoo.org/2/documentation/>`_ templates within Django.
|
||||
Why are we already replacing the templates? AMO's current PHP templates let you
|
||||
go hog-wild with logic in the templates, while Django is extremely restrictive.
|
||||
Jinja loosens those restrictions somewhat, providing a more powerful engine with
|
||||
the beauty of Django's templates. The tipping point for me was the verbosity of
|
||||
doing L10n in Django templates.
|
||||
|
||||
|
||||
Settings
|
||||
--------
|
||||
|
||||
If you want to configure the Jinja environment, use ``JINJA_CONFIG`` in
|
||||
``settings.py``. It can be a dict or a function that returns a dict. ::
|
||||
|
||||
JINJA_CONFIG = {'autoescape': False}
|
||||
|
||||
or ::
|
||||
|
||||
def JINJA_CONFIG():
|
||||
return {'the_answer': 41 + 1}
|
||||
|
||||
|
||||
Rendering
|
||||
---------
|
||||
|
||||
At this point, Jingo only provides two shortcuts for rendering templates.
|
||||
|
||||
.. autofunction:: jingo.render
|
||||
|
||||
The basic usage is to pass an ``HttpRequest`` and a template name. All the
|
||||
processors in ``settings.CONTEXT_PROCESSORS`` will be applied to the
|
||||
context, just like when you use a ``RequestContext`` in Django. Any extra
|
||||
keyword arguments are passed directly to ``http.HttpResponse``.
|
||||
|
||||
.. autofunction:: jingo.views.direct_to_template
|
||||
|
||||
|
||||
Template Helpers
|
||||
----------------
|
||||
|
||||
Instead of template tags, Jinja encourages you to add functions and filters to
|
||||
the templating environment. In ``jingo``, we call these helpers. When the
|
||||
Jinja environment is initialized, ``jingo`` will try to open a ``helpers.py``
|
||||
file from every app in ``INSTALLED_APPS``. Two decorators are provided to ease
|
||||
the environment extension:
|
||||
|
||||
.. function:: jingo.register.filter
|
||||
|
||||
Adds the decorated function to Jinja's filter library.
|
||||
|
||||
.. function:: jingo.register.function
|
||||
|
||||
Adds the decorated function to Jinja's global namespace.
|
||||
|
||||
|
||||
.. highlight:: jinja
|
||||
|
||||
Default Helpers
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Helpers are available in all templates automatically, without any extra
|
||||
loading.
|
||||
|
||||
.. automodule:: jingo.helpers
|
||||
:members:
|
||||
|
||||
|
||||
Template Environment
|
||||
--------------------
|
||||
|
||||
A single Jinja ``Environment`` is created for use in all templates. This is
|
||||
available as ``jingo.env`` if you need to work with the ``Environment``.
|
||||
|
||||
|
||||
Localization
|
||||
------------
|
||||
|
||||
Since we all love L10n, let's see what it looks like in Jinja templates::
|
||||
|
||||
<h2>{{ _('Reviews for {0}')|f(addon.name) }}</h2>
|
||||
|
||||
The simple way is to use the familiar underscore and string within a ``{{ }}``
|
||||
moustache block. ``f`` is an interpolation filter documented below. Sphinx
|
||||
could create a link if I knew how to do that.
|
||||
|
||||
The other method uses Jinja's ``trans`` tag::
|
||||
|
||||
{% trans user=review.user|user_link, date=review.created|datetime %}
|
||||
by {{ user }} on {{ date }}
|
||||
{% endtrans %}
|
||||
|
||||
``trans`` is nice when you have a lot of text or want to inject some variables
|
||||
directly. Both methods are useful, pick the one that makes you happy.
|
0
examples/jingo-project/__init__.py
Normal file
0
examples/jingo-project/__init__.py
Normal file
1
examples/jingo-project/settings.py
Normal file
1
examples/jingo-project/settings.py
Normal file
@ -0,0 +1 @@
|
||||
JINJA_CONFIG = {}
|
36
fabfile.py
vendored
Normal file
36
fabfile.py
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
"""
|
||||
Creating standalone Django apps is a PITA because you're not in a project, so
|
||||
you don't have a settings.py file. I can never remember to define
|
||||
DJANGO_SETTINGS_MODULE, so I run these commands which get the right env
|
||||
automatically.
|
||||
"""
|
||||
import functools
|
||||
import os
|
||||
|
||||
from fabric.api import local, cd, env
|
||||
from fabric.contrib.project import rsync_project
|
||||
|
||||
NAME = os.path.basename(os.path.dirname(__file__))
|
||||
ROOT = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = '%s-project.settings' % NAME
|
||||
os.environ['PYTHONPATH'] = os.pathsep.join([ROOT,
|
||||
os.path.join(ROOT, 'examples')])
|
||||
|
||||
env.hosts = ['jbalogh.me']
|
||||
|
||||
local = functools.partial(local, capture=False)
|
||||
|
||||
|
||||
def doc(kind='html'):
|
||||
with cd('docs'):
|
||||
local('make clean %s' % kind)
|
||||
|
||||
|
||||
def test():
|
||||
local('nosetests')
|
||||
|
||||
|
||||
def updoc():
|
||||
doc('dirhtml')
|
||||
rsync_project('p/%s' % NAME, 'docs/_build/dirhtml/', delete=True)
|
94
jingo/__init__.py
Normal file
94
jingo/__init__.py
Normal file
@ -0,0 +1,94 @@
|
||||
"""Adapter for using Jinja2 with Django."""
|
||||
|
||||
from django import http
|
||||
from django.conf import settings
|
||||
from django.template.context import get_standard_processors
|
||||
|
||||
import jinja2
|
||||
|
||||
VERSION = (0, 3)
|
||||
__version__ = '.'.join(map(str, VERSION))
|
||||
|
||||
|
||||
def get_env():
|
||||
"""Configure and return a jinja2 Environment."""
|
||||
# Mimic Django's setup by loading templates from directories in
|
||||
# TEMPLATE_DIRS and packages in INSTALLED_APPS.
|
||||
x = ((jinja2.FileSystemLoader, settings.TEMPLATE_DIRS),
|
||||
(jinja2.PackageLoader, settings.INSTALLED_APPS))
|
||||
loaders = [loader(p) for loader, places in x for p in places]
|
||||
|
||||
opts = {'trim_blocks': True,
|
||||
'extensions': ['jinja2.ext.i18n'],
|
||||
'autoescape': True,
|
||||
'auto_reload': settings.DEBUG,
|
||||
'loader': jinja2.ChoiceLoader(loaders),
|
||||
}
|
||||
|
||||
if hasattr(settings, 'JINJA_CONFIG'):
|
||||
if hasattr(settings.JINJA_CONFIG, '__call__'):
|
||||
config = settings.JINJA_CONFIG()
|
||||
else:
|
||||
config = settings.JINJA_CONFIG
|
||||
opts.update(config)
|
||||
|
||||
e = jinja2.Environment(**opts)
|
||||
# TODO: use real translations
|
||||
e.install_null_translations()
|
||||
return e
|
||||
|
||||
|
||||
def render(request, template, context=None, **kwargs):
|
||||
"""
|
||||
Shortcut like Django's ``render_to_response``, but better.
|
||||
|
||||
Minimal usage, with only a request object and a template name::
|
||||
|
||||
return jingo.render(request, 'template.html')
|
||||
|
||||
With template context and keywords passed to
|
||||
:class:`django.http.HttpResponse`::
|
||||
|
||||
return jingo.render(request, 'template.html',
|
||||
{'some_var': 42}, status=209)
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
for processor in get_standard_processors():
|
||||
context.update(processor(request))
|
||||
rendered = env.get_template(template).render(**context)
|
||||
return http.HttpResponse(rendered, **kwargs)
|
||||
|
||||
|
||||
def load_helpers():
|
||||
"""Try to import ``helpers.py`` from each app in INSTALLED_APPS."""
|
||||
for app in settings.INSTALLED_APPS:
|
||||
try:
|
||||
__import__('%s.helpers' % app)
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
class Register(object):
|
||||
"""Decorators to add filters and functions to the template Environment."""
|
||||
|
||||
def __init__(self, env):
|
||||
self.env = env
|
||||
|
||||
def filter(self, f):
|
||||
"""Adds the decorated function to Jinja's filter library."""
|
||||
self.env.filters[f.__name__] = f
|
||||
return f
|
||||
|
||||
def function(self, f):
|
||||
"""Adds the decorated function to Jinja's global namespace."""
|
||||
self.env.globals[f.__name__] = f
|
||||
return f
|
||||
|
||||
|
||||
env = get_env()
|
||||
register = Register(env)
|
||||
|
||||
# Import down here after the env is initialized.
|
||||
from . import helpers
|
||||
load_helpers()
|
48
jingo/helpers.py
Normal file
48
jingo/helpers.py
Normal file
@ -0,0 +1,48 @@
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.template.defaulttags import CsrfTokenNode
|
||||
|
||||
import jinja2
|
||||
|
||||
from jingo import register
|
||||
|
||||
|
||||
@register.function
|
||||
@jinja2.contextfunction
|
||||
def csrf(context):
|
||||
return jinja2.Markup(CsrfTokenNode().render(context))
|
||||
|
||||
|
||||
@register.filter
|
||||
def f(string, *args, **kwargs):
|
||||
"""
|
||||
Uses ``str.format`` for string interpolation.
|
||||
|
||||
>>> {{ "{0} arguments and {x} arguments"|f('positional', x='keyword') }}
|
||||
"positional arguments and keyword arguments"
|
||||
"""
|
||||
string = unicode(string)
|
||||
return string.format(*args, **kwargs)
|
||||
|
||||
|
||||
@register.filter
|
||||
def nl2br(string):
|
||||
"""Turn newlines into <br>."""
|
||||
return jinja2.Markup('<br>'.join(jinja2.escape(string).splitlines()))
|
||||
|
||||
|
||||
@register.filter
|
||||
def datetime(t, format=_('%B %d, %Y')):
|
||||
"""Call ``datetime.strftime`` with the given format string."""
|
||||
return t.strftime(format)
|
||||
|
||||
|
||||
@register.filter
|
||||
def ifeq(a, b, text):
|
||||
"""Return ``text`` if ``a == b``."""
|
||||
return jinja2.Markup(text if a == b else '')
|
||||
|
||||
|
||||
@register.filter
|
||||
def class_selected(a, b):
|
||||
"""Return ``'class="selected"'`` if ``a == b``."""
|
||||
return ifeq(a, b, 'class="selected"')
|
16
jingo/tests/test_basics.py
Normal file
16
jingo/tests/test_basics.py
Normal file
@ -0,0 +1,16 @@
|
||||
from nose.tools import eq_
|
||||
from mock import Mock, patch, sentinel
|
||||
|
||||
import jingo
|
||||
|
||||
|
||||
@patch('jingo.env')
|
||||
def test_render(mock_env):
|
||||
mock_template = Mock()
|
||||
mock_env.get_template.return_value = mock_template
|
||||
|
||||
response = jingo.render(Mock(), sentinel.template, status=32)
|
||||
mock_env.get_template.assert_called_with(sentinel.template)
|
||||
assert mock_template.render.called
|
||||
|
||||
eq_(response.status_code, 32)
|
60
jingo/tests/test_helpers.py
Normal file
60
jingo/tests/test_helpers.py
Normal file
@ -0,0 +1,60 @@
|
||||
"""Tests for the jingo's builtin helpers."""
|
||||
from datetime import datetime
|
||||
|
||||
from nose.tools import eq_
|
||||
|
||||
import jingo
|
||||
|
||||
|
||||
def render(s, context={}):
|
||||
t = jingo.env.from_string(s)
|
||||
return t.render(**context)
|
||||
|
||||
|
||||
def test_f():
|
||||
s = render('{{ "{0} : {z}"|f("a", z="b") }}')
|
||||
eq_(s, 'a : b')
|
||||
|
||||
|
||||
def test_nl2br():
|
||||
text = "some\ntext\n\nwith\nnewlines"
|
||||
s = render('{{ x|nl2br }}', {'x': text})
|
||||
eq_(s, "some<br>text<br><br>with<br>newlines")
|
||||
|
||||
|
||||
def test_datetime():
|
||||
time = datetime(2009, 12, 25, 10, 11, 12)
|
||||
s = render('{{ d|datetime }}', {'d': time})
|
||||
eq_(s, 'December 25, 2009')
|
||||
|
||||
s = render('{{ d|datetime("%Y-%m-%d %H:%M:%S") }}', {'d': time})
|
||||
eq_(s, '2009-12-25 10:11:12')
|
||||
|
||||
|
||||
def test_ifeq():
|
||||
eq_context = {'a': 1, 'b': 1}
|
||||
neq_context = {'a': 1, 'b': 2}
|
||||
|
||||
s = render('{{ a|ifeq(b, "<b>something</b>") }}', eq_context)
|
||||
eq_(s, '<b>something</b>')
|
||||
|
||||
s = render('{{ a|ifeq(b, "<b>something</b>") }}', neq_context)
|
||||
eq_(s, '')
|
||||
|
||||
|
||||
def test_class_selected():
|
||||
eq_context = {'a': 1, 'b': 1}
|
||||
neq_context = {'a': 1, 'b': 2}
|
||||
|
||||
s = render('{{ a|class_selected(b) }}', eq_context)
|
||||
eq_(s, 'class="selected"')
|
||||
|
||||
s = render('{{ a|class_selected(b) }}', neq_context)
|
||||
eq_(s, '')
|
||||
|
||||
|
||||
def test_csrf():
|
||||
s = render('{{ csrf() }}', {'csrf_token': 'fffuuu'})
|
||||
eq_(s, "<div style='display:none'>"
|
||||
"<input type='hidden' name='csrfmiddlewaretoken' value='fffuuu' />"
|
||||
"</div>")
|
10
jingo/tests/test_views.py
Normal file
10
jingo/tests/test_views.py
Normal file
@ -0,0 +1,10 @@
|
||||
from mock import patch, sentinel
|
||||
|
||||
import jingo.views
|
||||
|
||||
|
||||
@patch('jingo.render')
|
||||
def test_direct_to_template(mock_render):
|
||||
request = sentinel.request
|
||||
jingo.views.direct_to_template(request, 'base.html', x=1)
|
||||
mock_render.assert_called_with(request, 'base.html', {'x': 1})
|
5
jingo/views.py
Normal file
5
jingo/views.py
Normal file
@ -0,0 +1,5 @@
|
||||
import jingo
|
||||
|
||||
|
||||
def direct_to_template(request, template, **kwargs):
|
||||
return jingo.render(request, template, kwargs)
|
7
requirements.txt
Normal file
7
requirements.txt
Normal file
@ -0,0 +1,7 @@
|
||||
# These are the reqs to build docs and run tests.
|
||||
sphinx
|
||||
jinja2
|
||||
nose
|
||||
mock
|
||||
-e svn+http://code.djangoproject.com/svn/django/trunk@12335#egg=Django
|
||||
fabric
|
29
setup.py
Normal file
29
setup.py
Normal file
@ -0,0 +1,29 @@
|
||||
from setuptools import setup
|
||||
|
||||
|
||||
setup(
|
||||
name='jingo',
|
||||
version='0.3',
|
||||
description='An adapter for using Jinja2 templates with Django.',
|
||||
long_description=open('README.rst').read(),
|
||||
author='Jeff Balogh',
|
||||
author_email='jbalogh@mozilla.com',
|
||||
url='http://github.com/jbalogh/jingo',
|
||||
license='BSD',
|
||||
packages=['jingo'],
|
||||
include_package_data=True,
|
||||
zip_safe=False,
|
||||
install_requires=['jinja2'],
|
||||
classifiers=[
|
||||
'Development Status :: 4 - Beta',
|
||||
'Environment :: Web Environment',
|
||||
# I don't know what exactly this means, but why not?
|
||||
'Environment :: Web Environment :: Mozilla',
|
||||
'Framework :: Django',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: BSD License',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python',
|
||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||
]
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user