Code Monkey home page Code Monkey logo

django-jstemplate's Introduction

django-jstemplate

Build Status Coverage Status

A templatetag framework for easier integration of mustache.js, dust.js, handlebars.js, or other JavaScript templates with Django templates. Also will wrap your templates in elements expected for libraries such as ICanHaz.js. Django-jstemplates is extensible, so if your favorite template library is not included, it's easy to add. Inspired by django-icanhaz.

Quick Usage

(Read the full docs on Read the Docs)

Add "jstemplate" to your INSTALLED_APPS setting.

Download the templating library of your choice (I like to go straight mustache.js):

wget https://raw.github.com/janl/mustache.js/master/mustache.js
mv mustache.js app/static/libs/

app/jstemplates/main.mustache:

<div>
  <p>This is {{ name }}'s template</p>
</div>

app/templates/main.html:

{% load jstemplate %}

<html>
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js"></script>
  <script src="{{ STATIC_URL }}libs/mustache.js"></script>
  <script src="{{ STATIC_URL }}libs/django.mustache.js"></script>
</head>

<body>
  <div id="dynamic-area"></div>

  {% mustachejs "main" %}

  <script>
    $(document).ready(function() {

      var $area = $('#dynamic-area')
        , template;

      template = Mustache.template('main');
      $area.html(template.render());

    });
  </script>
</body>
</html>

Running tests

To run the tests (for development), install mock and six and run:

jstemplate/tests/project/manage.py test

Rationale

The collision between Django templates' use of {{ and }} as template variable markers and mustache.js' use of same has spawned a variety of solutions. One solution simply replaces [[ and ]] with {{ and }} inside an mustachejs template tag; another makes a valiant attempt to reconstruct verbatim text within a chunk of a Django template after it has already been mangled by the Django template tokenizer.

I prefer to keep my JavaScript templates in separate files in a dedicated directory anyway, to avoid confusion between server-side and client-side templating. So this solution is essentially just an "include" tag that avoids parsing the included file as a Django template.

Enjoy!

django-jstemplate's People

Contributors

mjumbewu avatar carljm avatar karlrl avatar atogle avatar achur avatar anttihirvonen avatar gehan avatar ghinch avatar psycojoker avatar movermeyer avatar slinkp avatar

Stargazers

Shane Chin avatar  avatar Victor Borisov avatar Luís Bastião Silva avatar Luke Swart avatar Andrew Velis avatar stahl avatar  avatar tim avatar ilya avatar Philip Roche avatar Tomasz Walotek avatar  avatar Douglas Meehan avatar Keryn Knight avatar Mark Skipper avatar Patrick Bassut avatar Derek Payton avatar Andrew Pashkin avatar  avatar  avatar Brian Dant avatar Kathryn Killebrew avatar Kindy Lin avatar Chris Barmonde avatar Branislav Jovanovic avatar Victor Kovtun avatar Amir H. Hajizamani avatar David Toy avatar Liqiu Huang avatar Cong Lin avatar  avatar Christopher Paolini avatar Trevor Joynson avatar Miguel avatar Leo Zhang avatar Eugene Datsky avatar Emily Marigold Klassen avatar Jonathan Barratt avatar Adrián Ribao avatar

Watchers

Nabib El-Rahman avatar  avatar Bula avatar James Cloos avatar Dimitris Garofalakis avatar

django-jstemplate's Issues

Makemessages doesn't support subdirectories

Hi!

First of all, this looks a great library! I'm trying to integrate it into a project which uses Handlebars templates. However, it seems that the patched makemessages command doesn't support subdirectories under Javascript template directories.

Example:
Let's say I have app test in INSTALLED_APPS, and test/jstemplates is my Javascript template directory for that app. Now, if I put a template handlebars_test.hbs to path test/jstemplates/handlebars_test.hbs, then {% handlebars 'handlebars_test.hbs' %} works beautifully in templates and python manage.py makemessages --all -e html,hbs finds the translation string inside the template correctly.

However, if I put my template to test/jstemplates/test/something/handlebars_test.hbs, {% handlebars 'test/something/handlebars_test.hbs' %} works as expected, but makemessages won't find the translation strings. This seems to be related to how templatize finds all Javascript templates with find("(.*)") (https://github.com/mjumbewu/django-jstemplate/blob/master/jstemplate/management/commands/makemessages.py#L45), which doesn't correctly capture templates in subdirectories.

Add support for TwigJS

I am just using doing this for now and parsing the template manually:

<script type="text/x-twig-template" id="example-template">
    {% rawjstemplate 'example-template' %}
</script>

But, formal support for Twig.js would be cool.

handlebarjs failing on non-debug deployments

When deploying to non-DEBUG builds, handlebarjs fails to inject handlebar code from a template file.
I'm at a loss to explain why, as it works locally.

Ie, when running the following code:

{% handlebarsjs 'handlebar_template' precompile %}

Locally I get the following result:

<script type="text/x-handlebars-template" id="handlebar_template">
...

But in production I get nothing.
I know it's not being stripped out by the server, as I can manually include the locally output tags inside a django {% verbatim %} tag and it works.

Question: How to use the {% icanhaz %} template tag

I don't have any particular setting set up to reference where my 'jstemplates' (mustache files are placed). I created a directory under my application called 'jstemplates' where i place all these files. After loading the jstemplates tag, how do i use the icanhaz template tag. It always errors and says it can't find the template passed. It however works when i use the {% mustache "main" %} tag?

makemessages with djangojs domain

Dear folks!

As I can see this django application is the only application that support i18n inside mustache templates. But I can't find automate way to use it with the JavaScriptCatalog view, which works with domain=djangojs. So the only way to use it that way is to copy-paste messages from django.mo to djangojs.mo.

Is it possible to change this?

DIR

Hello. I saw your repository, I wanted to ask you some questions

I want to access templates via ajax, I can't figure out where and what folder to create, so that access to mustache files will work

When I click on the button, I get a 404 error because the template was not found. How to call the mustache template with your library?

here is my example

loadTemplate(params.template, function(template_html) { rendered_html = Mustache.render(template_html); rendered_elements = $.parseHTML(rendered_html); )}

var loadTemplate() { ajax.get({url: path_to_templates + file_name + '.html'}) }

Allow comments for translators

(This was reported in django-mustachejs issue #4 a while back. Transferring it here and closing that issue)

I was in a messages file today and I saw this:

msgid "{{ prompt }}{{# optional }} (optional){{/ optional }}"
msgstr ""

I really wished I had some context. We should allow developers to give translator hints (like this). I imagine, in a template, it would look something like:

{{! Translators: This is the label for a survey form field. }}
{{#_}}{{ prompt }}{{# optional }} (optional){{/ optional }}{{/_}}

And in the .po file, it would show up like:

# Translators: This is the label for a survey form field.
# my/file.html:24
msgid "{{ prompt }}{{# optional }} (optional){{/ optional }}"
msgstr ""

Can't run app in Django 4.2, Python 3.9

After trying to install and use the app, I get an error when trying to start localhost manage.py runserver.

Running:

  • Django 4.2 LTS
  • Python 3.9.13
Exception in thread django-main-thread:
Traceback (most recent call last):
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\utils.py", line 69, in __getitem__
    return self._engines[alias]
KeyError: 'django'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\python39\lib\threading.py", line 980, in _bootstrap_inner
    self.run()
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\sentry_sdk\integrations\threading.py", line 72, in run
    reraise(*_capture_exception())
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\sentry_sdk\_compat.py", line 60, in reraise
    raise value
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\sentry_sdk\integrations\threading.py", line 70, in run
    return old_run_func(self, *a, **kw)
  File "c:\python39\lib\threading.py", line 917, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\utils\autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\daphne\management\commands\runserver.py", line 96, in inner_run
    self.check(display_num_errors=True)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\core\management\base.py", line 485, in check
    all_issues = checks.run_checks(
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\core\checks\registry.py", line 88, in run_checks
    new_errors = check(app_configs=app_configs, databases=databases)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\contrib\admin\checks.py", line 78, in check_dependencies
    for engine in engines.all():
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\utils.py", line 94, in all
    return [self[alias] for alias in self]
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\utils.py", line 94, in <listcomp>
    return [self[alias] for alias in self]
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\utils.py", line 85, in __getitem__
    engine = engine_cls(params)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\backends\django.py", line 24, in __init__
    options["libraries"] = self.get_templatetag_libraries(libraries)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\backends\django.py", line 42, in get_templatetag_libraries
    libraries = get_installed_libraries()
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\backends\django.py", line 116, in get_installed_libraries
    return {
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\backends\django.py", line 116, in <dictcomp>
    return {
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\backends\django.py", line 105, in get_template_tag_modules
    for name in get_package_libraries(pkg):
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\backends\django.py", line 128, in get_package_libraries
    module = import_module(entry[1])
  File "c:\python39\lib\importlib\__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 850, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\jstemplate\templatetags\base.py", line 3, in <module>
    from ..loading import find, preprocess, JSTemplateNotFound
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\jstemplate\loading.py", line 76, in <module>
    finders = _get_finders()
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\jstemplate\loading.py", line 68, in _get_finders
    return _get_classes(conf.JSTEMPLATE_FINDERS)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\jstemplate\loading.py", line 51, in _get_classes
    mod = import_module(modpath)
  File "c:\python39\lib\importlib\__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\jstemplate\finders.py", line 122, in <module>
    app_template_dirs = _get_app_template_dirs()
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\jstemplate\finders.py", line 112, in _get_app_template_dirs
    app_dir = os.path.dirname(os.path.abspath(mod.__file__))
  File "c:\python39\lib\ntpath.py", line 527, in abspath
    return normpath(_getfullpathname(path))
TypeError: _getfullpathname: path should be string, bytes or os.PathLike, not NoneType
Traceback (most recent call last):
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\utils.py", line 69, in __getitem__
    return self._engines[alias]
KeyError: 'django'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\xampp\htdocs\premind\manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\core\management\__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\core\management\__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\core\management\base.py", line 412, in run_from_argv
    self.execute(*args, **cmd_options)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\core\management\commands\runserver.py", line 74, in execute
    super().execute(*args, **options)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\core\management\base.py", line 458, in execute
    output = self.handle(*args, **options)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\daphne\management\commands\runserver.py", line 86, in handle
    super().handle(*args, **options)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\core\management\commands\runserver.py", line 111, in handle
    self.run(**options)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\core\management\commands\runserver.py", line 118, in run
    autoreload.run_with_reloader(self.inner_run, **options)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\utils\autoreload.py", line 671, in run_with_reloader
    start_django(reloader, main_func, *args, **kwargs)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\utils\autoreload.py", line 660, in start_django
    reloader.run(django_main_thread)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\utils\autoreload.py", line 343, in run
    autoreload_started.send(sender=self)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\dispatch\dispatcher.py", line 176, in send
    return [
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\dispatch\dispatcher.py", line 177, in <listcomp>
    (receiver, receiver(signal=self, sender=sender, **named))
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\sentry_sdk\integrations\django\signals_handlers.py", line 66, in wrapper
    return receiver(*args, **kwargs)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\autoreload.py", line 43, in watch_for_template_changes
    for directory in get_template_directories():
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\autoreload.py", line 16, in get_template_directories
    for backend in engines.all():
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\utils.py", line 94, in all
    return [self[alias] for alias in self]
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\utils.py", line 94, in <listcomp>
    return [self[alias] for alias in self]
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\utils.py", line 85, in __getitem__
    engine = engine_cls(params)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\backends\django.py", line 24, in __init__
    options["libraries"] = self.get_templatetag_libraries(libraries)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\backends\django.py", line 42, in get_templatetag_libraries
    libraries = get_installed_libraries()
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\backends\django.py", line 116, in get_installed_libraries
    return {
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\backends\django.py", line 116, in <dictcomp>
    return {
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\backends\django.py", line 105, in get_template_tag_modules
    for name in get_package_libraries(pkg):
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\django\template\backends\django.py", line 128, in get_package_libraries
    module = import_module(entry[1])
  File "c:\python39\lib\importlib\__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 850, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\jstemplate\templatetags\base.py", line 3, in <module>
    from ..loading import find, preprocess, JSTemplateNotFound
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\jstemplate\loading.py", line 76, in <module>
    finders = _get_finders()
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\jstemplate\loading.py", line 68, in _get_finders
    return _get_classes(conf.JSTEMPLATE_FINDERS)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\jstemplate\loading.py", line 51, in _get_classes
    mod = import_module(modpath)
  File "c:\python39\lib\importlib\__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\jstemplate\finders.py", line 122, in <module>
    app_template_dirs = _get_app_template_dirs()
  File "C:\Users\Owner\.virtualenvs\6P0nJig8\lib\site-packages\jstemplate\finders.py", line 112, in _get_app_template_dirs
    app_dir = os.path.dirname(os.path.abspath(mod.__file__))
  File "c:\python39\lib\ntpath.py", line 527, in abspath
    return normpath(_getfullpathname(path))
TypeError: _getfullpathname: path should be string, bytes or os.PathLike, not NoneType

Don't use __file__ (Windows)

Hello,

We had an issue with template loading on IIS for Windows and Python 3.4.
_ _ file _ _ (in AppLoader and AppRegexLoader) returns an absolute path which is directly read by IIS and where path separators are "/" and not "".
The workaround is to use os.path.abspath(_ _ file _ _), we monkeypatch it for our deployment, and it works fine with NGinx and Apache too.

All the best.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.