Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Renamed the app from icanhaz to mustachejs;

Modified the tag output to not use icanhaz;
  • Loading branch information...
commit 7fb086ccb924909059ee9ab6fb5060852b9ca4ee 1 parent 9ec5485
Mjumbe Poe authored
45 README.rst
View
@@ -1,11 +1,13 @@
-==============
-django-icanhaz
-==============
+=================
+django-mustachejs
+=================
-A templatetag for easier integration of `ICanHaz.js`_ JavaScript templates with
-Django templates.
+A templatetag for easier integration of `mustache.js`_ JavaScript templates with
+Django templates. Inspired by `ICanHaz.js`_ and `jquery.mustache`_.
-.. _ICanHaz.js: http://icanhazjs.com
+.. _mustache.js: http://mustache.github.com/
+.. _ICanHaz.js: http://icanhazjs.com/
+.. _jquery.mustache: https://github.com/AF83/jquery.mustache
Quickstart
==========
@@ -24,31 +26,34 @@ Installation
Install from PyPI with ``pip``::
- pip install django-icanhaz
+ pip install django-mustachejs
or get the `in-development version`_::
- pip install django-icanhaz==dev
+ pip install django-mustachejs==dev
-.. _in-development version: https://github.com/carljm/django-icanhaz/tarball/master#egg=django_secure-dev
+.. _in-development version: https://github.com/mjumbewu/django-mustache/tarball/master#egg=mustache
Usage
-----
-* Add ``"icanhaz"`` to your ``INSTALLED_APPS`` setting.
+* Add ``"mustachejs"`` to your ``INSTALLED_APPS`` setting.
-* Set the ``ICANHAZ_DIRS`` setting to a list of full (absolute) path to
+* Set the ``MUSTACHEJS_DIRS`` setting to a list of full (absolute) path to
directories where you will store your ICanHaz templates.
-* ``{% load icanhaz %}`` and use ``{% icanhaz "templatename" %}`` in your
- Django templates to safely embed the ICanHaz.js template at
- ``<ICANHAZ_DIRS-entry>/templatename.html`` into your Django template,
- automatically wrapped in ``<script id="templatename" type="text/html">``,
- ready for ``ich.templatename({...})`` in your JavaScript.
-
-``django-icanhaz`` does not bundle `ICanHaz.js`_ or provide any JavaScript
-utilities; it just helps you easily embed the templates in your HTML. Include
-`ICanHaz.js`_ in your project's static assets and use it in your JS as usual.
+* ``{% load mustachejs %}`` and use ``{% mustachejs "templatename" %}`` in your
+ Django templates to safely embed the mustache.js template at
+ ``<MUSTACHEJS_DIRS-entry>/templatename.html`` into your Django template. It
+ will be stored in the ``Mustache.TEMPLATES`` object as a string, accessible
+ as ``Mustache.TEMPLATES.templatename``.
+
+* In your JavaScript, use
+ ``Mustache.to_html(Mustache.TEMPLATES.templatename, {...}, Mustache.TEMPLATES)``
+ to render your mustache template. Alternatively, if you include the
+ ``django.mustache.js`` script in your HTML, you can use
+ ``Mustache.template('templatename').render({...})`` to render your mustache
+ template.
Advanced usage
47 icanhaz/templatetags/icanhaz.py
View
@@ -1,47 +0,0 @@
-from django import template
-
-from ..conf import conf
-from ..loading import find, ICanHazTemplateNotFound
-
-
-
-register = template.Library()
-
-
-
-class ICanHazNode(template.Node):
- def __init__(self, name):
- self.name = template.Variable(name)
-
-
- def render(self, context):
- name = self.name.resolve(context)
-
- try:
- filepath = find(name)
- fp = open(filepath, "r")
- output = fp.read()
- fp.close()
- output = ('<script id="%s" type="text/html">\n'
- % name) + output + "\n</script>\n"
- except (IOError, ICanHazTemplateNotFound):
- output = ""
- if conf.DEBUG:
- raise
-
- return output
-
-
-
-@register.tag
-def icanhaz(parser, token):
- """
- Finds the ICanHaz template for the given name and renders it surrounded by
- the requisite ICanHaz <script> tags.
-
- """
- bits = token.contents.split()
- if len(bits) not in [2, 3]:
- raise template.TemplateSyntaxError(
- "'icanhaz' tag takes one argument: the name/id of the template")
- return ICanHazNode(bits[1])
1  icanhaz/tests/templates/testtemplate.html
View
@@ -1 +0,0 @@
-<p>A template full of {{ foo }}.</p>
81 icanhaz/tests/test_ttag.py
View
@@ -1,81 +0,0 @@
-import os.path
-
-from django.template import Template, Context, TemplateSyntaxError
-from django.test import TestCase
-
-from .utils import override_settings
-
-
-
-__all__ = ["TemplateTagTest"]
-
-
-DIR = os.path.join(os.path.dirname(__file__), "templates")
-
-
-class TemplateTagTest(TestCase):
- @override_settings(ICANHAZ_DIRS=[DIR])
- def test_simple(self):
- res = Template(
- "{% load icanhaz %}{% icanhaz 'testtemplate' %}"
- ).render(Context())
-
- self.assertEqual(
- res,
- '<script id="testtemplate" type="text/html">\n'
- '<p>A template full of {{ foo }}.</p>\n\n</script>\n')
-
-
- @override_settings(ICANHAZ_DIRS=[DIR])
- def test_variable_template_name(self):
- res = Template(
- "{% load icanhaz %}{% icanhaz templatename %}").render(
- Context({"templatename": "testtemplate"}))
-
- self.assertEqual(
- res,
- '<script id="testtemplate" type="text/html">\n'
- '<p>A template full of {{ foo }}.</p>\n\n</script>\n')
-
-
- @override_settings(ICANHAZ_DIRS=[DIR], DEBUG=False)
- def test_no_template(self):
- res = Template(
- "{% load icanhaz %}{% icanhaz 'notemplate' %}"
- ).render(Context())
-
- self.assertEqual(res, "")
-
-
- @override_settings(ICANHAZ_DIRS=[DIR], DEBUG=True)
- def test_no_template_debug(self):
- from icanhaz.loading import ICanHazTemplateNotFound
- with self.assertRaises(ICanHazTemplateNotFound):
- Template(
- "{% load icanhaz %}{% icanhaz 'notemplate' %}"
- ).render(Context())
-
-
- @override_settings(ICANHAZ_DIRS=[DIR])
- def test_no_break_out(self):
- res = Template(
- "{% load icanhaz %}{% icanhaz '../outside_dir' %}"
- ).render(Context())
-
- self.assertEqual(res, "")
-
-
- @override_settings(ICANHAZ_DIRS=[DIR])
- def test_no_absolute(self):
- res = Template(
- "{% load icanhaz %}{% icanhaz '/testtemplate' %}"
- ).render(Context())
-
- self.assertEqual(res, "")
-
-
- def test_bad_args(self):
- with self.assertRaises(TemplateSyntaxError):
- Template(
- "{% load icanhaz %}{% icanhaz %}"
- ).render(Context())
0  icanhaz/__init__.py → mustachejs/__init__.py
View
File renamed without changes
10 icanhaz/conf.py → mustachejs/conf.py
View
@@ -18,10 +18,10 @@ def __getattr__(self, k):
conf = Configuration(
- ICANHAZ_FINDERS=[
- "icanhaz.finders.FilesystemFinder",
- "icanhaz.finders.AppFinder",
+ MUSTACHEJS_FINDERS=[
+ "mustachejs.finders.FilesystemFinder",
+ "mustachejs.finders.AppFinder",
],
- ICANHAZ_DIRS=[],
- ICANHAZ_APP_DIRNAMES=["jstemplates"],
+ MUSTACHEJS_DIRS=[],
+ MUSTACHEJS_APP_DIRNAMES=["jstemplates"],
)
4 icanhaz/finders.py → mustachejs/finders.py
View
@@ -16,7 +16,7 @@ def find(self, name):
class FilesystemFinder(BaseFinder):
@property
def directories(self):
- return conf.ICANHAZ_DIRS
+ return conf.MUSTACHEJS_DIRS
def find(self, name):
@@ -41,7 +41,7 @@ def _get_app_template_dirs():
except ImportError, e:
raise ImproperlyConfigured("ImportError %s: %s" % (app, e.args[0]))
app_dir = os.path.dirname(mod.__file__)
- for dirname in conf.ICANHAZ_APP_DIRNAMES:
+ for dirname in conf.MUSTACHEJS_APP_DIRNAMES:
template_dir = os.path.join(app_dir, dirname)
if os.path.isdir(template_dir):
ret.append(template_dir.decode(fs_encoding))
6 icanhaz/loading.py → mustachejs/loading.py
View
@@ -11,13 +11,13 @@ def find(name):
if filepath is not None:
return filepath
- raise ICanHazTemplateNotFound(name)
+ raise MustacheJSTemplateNotFound(name)
def _get_finders():
ret = []
- for finder_path in conf.ICANHAZ_FINDERS:
+ for finder_path in conf.MUSTACHEJS_FINDERS:
modpath, cls_name = finder_path.rsplit(".", 1)
try:
mod = import_module(modpath)
@@ -42,5 +42,5 @@ def _get_finders():
-class ICanHazTemplateNotFound(Exception):
+class MustacheJSTemplateNotFound(Exception):
pass
0  icanhaz/models.py → mustachejs/models.py
View
File renamed without changes
29 mustachejs/static/mustache/js/django.mustache.js
View
@@ -0,0 +1,29 @@
+(function(Mustache) {
+
+ var CachedTemplate = function(template) {
+ this.template = template;
+ };
+
+ CachedTemplate.prototype = {
+ /*
+ Turns this template into HTML using the given view data.
+ */
+ render: function(view, partials, send_fun) {
+
+ // Use either the parials specified, or the entire set of templates
+ // stored in Mustache.TEMPLATES
+ partials = partials || Mustache.TEMPLATES;
+
+ return Mustache.to_html(this.template, view, partials, send_fun);
+ }
+ }
+
+ /*
+ Creates a new Template object.
+ */
+ Mustache.template = function(name) {
+ var template = Mustache.TEMPLATES[name];
+ return new CachedTemplate(template)
+ };
+
+})(Mustache);
0  icanhaz/templatetags/__init__.py → mustachejs/templatetags/__init__.py
View
File renamed without changes
52 mustachejs/templatetags/mustachejs.py
View
@@ -0,0 +1,52 @@
+from django import template
+
+from ..conf import conf
+from ..loading import find, MustacheJSTemplateNotFound
+
+
+
+register = template.Library()
+
+
+
+class MustacheJSNode(template.Node):
+ def __init__(self, name):
+ self.name = template.Variable(name)
+
+
+ def render(self, context):
+ name = self.name.resolve(context)
+
+ try:
+ filepath = find(name)
+ fp = open(filepath, "r")
+ output = fp.read()
+
+ output = output.replace('\\', r'\\')
+ output = output.replace('\n', r'\n')
+ output = output.replace("'", r"\'")
+ fp.close()
+
+ output = ("<script>Mustache.TEMPLATES['{0}']='".format(name)
+ + output + "'</script>\n")
+ except (IOError, MustacheJSTemplateNotFound):
+ output = ""
+ if conf.DEBUG:
+ raise
+
+ return output
+
+
+
+@register.tag
+def mustachejs(parser, token):
+ """
+ Finds the MustacheJS template for the given name and renders it surrounded by
+ the requisite MustacheJS <script> tags.
+
+ """
+ bits = token.contents.split()
+ if len(bits) not in [2, 3]:
+ raise template.TemplateSyntaxError(
+ "'mustachejs' tag takes one argument: the name/id of the template")
+ return MustacheJSNode(bits[1])
0  icanhaz/tests/__init__.py → mustachejs/tests/__init__.py
View
File renamed without changes
0  icanhaz/tests/mockfinders.py → mustachejs/tests/mockfinders.py
View
File renamed without changes
0  icanhaz/tests/outside_dir.html → mustachejs/tests/outside_dir.html
View
File renamed without changes
1  mustachejs/tests/templates/testtemplate.html
View
@@ -0,0 +1 @@
+<p>Mustache's template full of {{ foo }} and \.</p>
22 icanhaz/tests/test_finders.py → mustachejs/tests/test_finders.py
View
@@ -19,7 +19,7 @@
class BaseFinderTest(TestCase):
@property
def finder(self):
- from icanhaz.finders import BaseFinder
+ from mustachejs.finders import BaseFinder
return BaseFinder()
@@ -32,25 +32,25 @@ def test_find_not_implemented(self):
class FilesystemFinderTest(TestCase):
@property
def finder(self):
- from icanhaz.finders import FilesystemFinder
+ from mustachejs.finders import FilesystemFinder
return FilesystemFinder()
- @override_settings(ICANHAZ_DIRS=["/one/path", "/another/path"])
+ @override_settings(MUSTACHEJS_DIRS=["/one/path", "/another/path"])
def test_directories(self):
self.assertEqual(
self.finder.directories,
["/one/path", "/another/path"])
- @override_settings(ICANHAZ_DIRS=[os.path.join(here, "templates")])
+ @override_settings(MUSTACHEJS_DIRS=[os.path.join(here, "templates")])
def test_find(self):
self.assertEqual(
self.finder.find("testtemplate"),
os.path.join(here, "templates", "testtemplate.html"))
- @override_settings(ICANHAZ_DIRS=[os.path.join(here, "templates")])
+ @override_settings(MUSTACHEJS_DIRS=[os.path.join(here, "templates")])
def test_find_non_existing(self):
self.assertEqual(self.finder.find("doesntexist"), None)
@@ -59,13 +59,13 @@ def test_find_non_existing(self):
class AppFinderTest(TestCase):
@property
def finder(self):
- from icanhaz.finders import AppFinder
+ from mustachejs.finders import AppFinder
return AppFinder()
def test_directories(self):
with patch(
- "icanhaz.finders.app_template_dirs",
+ "mustachejs.finders.app_template_dirs",
[os.path.join(here, "templates")]):
dirs = self.finder.directories
@@ -74,18 +74,18 @@ def test_directories(self):
@property
def func(self):
- from icanhaz.finders import _get_app_template_dirs
+ from mustachejs.finders import _get_app_template_dirs
return _get_app_template_dirs
@override_settings(
- INSTALLED_APPS=["icanhaz.tests"],
- ICANHAZ_APP_DIRNAMES=["templates", "jstemplates"])
+ INSTALLED_APPS=["mustachejs.tests"],
+ MUSTACHEJS_APP_DIRNAMES=["templates", "jstemplates"])
def test_get_app_template_dirs(self):
self.assertEqual(self.func(), [os.path.join(here, "templates")])
- @override_settings(INSTALLED_APPS=["icanhaz.nonexistent"])
+ @override_settings(INSTALLED_APPS=["mustachejs.nonexistent"])
def test_bad_app(self):
with self.assertRaises(ImproperlyConfigured):
self.func()
20 icanhaz/tests/test_loading.py → mustachejs/tests/test_loading.py
View
@@ -15,26 +15,26 @@
class FindTest(TestCase):
@property
def func(self):
- from icanhaz.loading import find
+ from mustachejs.loading import find
return find
- @patch("icanhaz.loading.finders", [MockFinder("/path/to/a/file.html")])
+ @patch("mustachejs.loading.finders", [MockFinder("/path/to/a/file.html")])
def test_find(self):
self.assertEqual(self.func("file"), "/path/to/a/file.html")
@patch(
- "icanhaz.loading.finders",
+ "mustachejs.loading.finders",
[MockFinder(), MockFinder("/path/to/a/file.html")])
def test_find_fallback(self):
self.assertEqual(self.func("file"), "/path/to/a/file.html")
- @patch("icanhaz.loading.finders", [MockFinder()])
+ @patch("mustachejs.loading.finders", [MockFinder()])
def test_none_found(self):
- from icanhaz.loading import ICanHazTemplateNotFound
- with self.assertRaises(ICanHazTemplateNotFound):
+ from mustachejs.loading import MustacheJSTemplateNotFound
+ with self.assertRaises(MustacheJSTemplateNotFound):
self.func("file")
@@ -42,11 +42,11 @@ def test_none_found(self):
class GetFindersTest(TestCase):
@property
def func(self):
- from icanhaz.loading import _get_finders
+ from mustachejs.loading import _get_finders
return _get_finders
- @override_settings(ICANHAZ_FINDERS=["icanhaz.tests.mockfinders.MockFinder"])
+ @override_settings(MUSTACHEJS_FINDERS=["mustachejs.tests.mockfinders.MockFinder"])
def test_get_finders(self):
finders = self.func()
@@ -54,14 +54,14 @@ def test_get_finders(self):
self.assertIsInstance(finders[0], MockFinder)
- @override_settings(ICANHAZ_FINDERS=["icanhaz.tests.doesntexist.MockFinder"])
+ @override_settings(MUSTACHEJS_FINDERS=["mustachejs.tests.doesntexist.MockFinder"])
def test_bad_module(self):
with self.assertRaises(ImproperlyConfigured):
self.func()
@override_settings(
- ICANHAZ_FINDERS=["icanhaz.tests.mockfinders.DoesntExist"])
+ MUSTACHEJS_FINDERS=["mustachejs.tests.mockfinders.DoesntExist"])
def test_bad_attribute(self):
with self.assertRaises(ImproperlyConfigured):
self.func()
83 mustachejs/tests/test_ttag.py
View
@@ -0,0 +1,83 @@
+import os.path
+
+from django.template import Template, Context, TemplateSyntaxError
+from django.test import TestCase
+
+from .utils import override_settings
+
+
+
+__all__ = ["TemplateTagTest"]
+
+
+DIR = os.path.join(os.path.dirname(__file__), "templates")
+
+
+class TemplateTagTest(TestCase):
+ @override_settings(MUSTACHEJS_DIRS=[DIR])
+ def test_simple(self):
+ res = Template(
+ "{% load mustachejs %}{% mustachejs 'testtemplate' %}"
+ ).render(Context())
+
+ self.assertEqual(
+ res,
+ "<script>Mustache.TEMPLATES['testtemplate']='"
+ r"<p>Mustache\'s template full of {{ foo }} and \\.</p>\n"
+ "'</script>\n")
+
+
+ @override_settings(MUSTACHEJS_DIRS=[DIR])
+ def test_variable_template_name(self):
+ res = Template(
+ "{% load mustachejs %}{% mustachejs templatename %}").render(
+ Context({"templatename": "testtemplate"}))
+
+ self.assertEqual(
+ res,
+ "<script>Mustache.TEMPLATES['testtemplate']='"
+ r"<p>Mustache\'s template full of {{ foo }} and \\.</p>\n"
+ "'</script>\n")
+
+
+ @override_settings(MUSTACHEJS_DIRS=[DIR], DEBUG=False)
+ def test_no_template(self):
+ res = Template(
+ "{% load mustachejs %}{% mustachejs 'notemplate' %}"
+ ).render(Context())
+
+ self.assertEqual(res, "")
+
+
+ @override_settings(MUSTACHEJS_DIRS=[DIR], DEBUG=True)
+ def test_no_template_debug(self):
+ from mustachejs.loading import MustacheJSTemplateNotFound
+ with self.assertRaises(MustacheJSTemplateNotFound):
+ Template(
+ "{% load mustachejs %}{% mustachejs 'notemplate' %}"
+ ).render(Context())
+
+
+ @override_settings(MUSTACHEJS_DIRS=[DIR])
+ def test_no_break_out(self):
+ res = Template(
+ "{% load mustachejs %}{% mustachejs '../outside_dir' %}"
+ ).render(Context())
+
+ self.assertEqual(res, "")
+
+
+ @override_settings(MUSTACHEJS_DIRS=[DIR])
+ def test_no_absolute(self):
+ res = Template(
+ "{% load mustachejs %}{% mustachejs '/testtemplate' %}"
+ ).render(Context())
+
+ self.assertEqual(res, "")
+
+
+ def test_bad_args(self):
+ with self.assertRaises(TemplateSyntaxError):
+ Template(
+ "{% load mustachejs %}{% mustachejs %}"
+ ).render(Context())
0  icanhaz/tests/utils.py → mustachejs/tests/utils.py
View
File renamed without changes
4 runtests.py
View
@@ -7,13 +7,13 @@
if not settings.configured:
settings.configure(
- INSTALLED_APPS=["icanhaz"],
+ INSTALLED_APPS=["mustachejs"],
DATABASES={"default": {"ENGINE": "django.db.backends.sqlite3"}})
def runtests(*test_args):
if not test_args:
- test_args = ["icanhaz"]
+ test_args = ["mustachejs"]
parent = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, parent)
8 setup.py
View
@@ -9,7 +9,7 @@
open(join(here, "TODO.rst")).read())
def get_version():
- fh = open(join(here, "icanhaz", "__init__.py"))
+ fh = open(join(here, "mustachejs", "__init__.py"))
try:
for line in fh.readlines():
if line.startswith("__version__ ="):
@@ -18,13 +18,13 @@ def get_version():
fh.close()
setup(
- name="django-icanhaz",
+ name="django-mustachejs",
version=get_version(),
- description="A Django template tag for embedding ICanHaz.js templates safely.",
+ description="A Django template tag for embedding Mustache.js templates safely.",
long_description=long_description,
author="Carl Meyer",
author_email="carl@oddbird.net",
- url="https://github.com/carljm/django-icanhaz/",
+ url="https://github.com/carljm/django-mustachejs/",
packages=find_packages(),
classifiers=[
"Development Status :: 3 - Alpha",
Please sign in to comment.
Something went wrong with that request. Please try again.