JST through Django-Pipeline - django

I am creating a Backbone / Django application and I am wondering how to implement templates that reside in different files in for the Backbone views. From Rails I am used to using JST which allowed me to have a folder structure like
-js
-backbone
-templates
template1.jst
template2.jst
As far as I understand then it should be possible to the same using Django-Pipeline
but I find the implementation difficult.
I have added the following lines to my settings.py
STATICFILES_STORAGE = "pipeline.storage.PipelineStorage"
PIPELINE_CSS_COMPRESSOR = None
PIPELINE_JS_COMPRESSOR = None
PIPELINE_JS = {
'application': {
'source_filenames': (
'js/backbone/templates/**/*.jst',
)
}
}
and I added this to base.html
{% load compressed %}
{% compressed_js 'application' %}
I figured this would allow me to reference my templates through a JST object on the client, but it is not defined. Did I misunderstand the purpose of Django-Pipeline or am I simply missing something in the configuration?

No you did not misunderstand django-pipeline. You will be able to access the javascript templates in your backbone code. Before I give you the answer lets take a look at what the django-pipeline docs have to say.
Pipeline allows you to use javascript templates along with your javascript views. To use your javascript templates, just add them to your PIPELINE_JS group
So you can add your templates to the pipeline in the settings file like:
PIPELINE_JS = {
'templates': {
'source_filenames': (
'js/templates/**/*.jst',
),
'output_filename': 'js/templates.js'
}
}
Now you have to load these javascript templates in your browser.
Please Note: You have to make sure that you load the templates before your load any javascript code which uses the templates. Otherwise you will get an undefined error.
{% load compressed %}
{% compressed_js 'templates' %}
{% compressed_js 'other_backbone_files' %}
Now the docs say:
It will be available from your javascript code via window.JST
So you will have a global object named 'window' and you will be able to access the templates using its 'JST' property. The value of the JST property is another javascript object. The properties of this object are the names of your templates and its values are the templates. The names of your templates will depend on how you have included the templates in your settings file.
For example, if in your settings file you included the template as:
'source_filenames': (
'js/templates/**/*.jst',
)
and you had a template at 'js/templates/app/footer.jst', you can access the template in your javascript code in the following manner:
template: window.JST['app_footer']
Or if you did something like:
'source_filenames': (
'js/templates/app/*.jst',
)
OR
'source_filenames': (
'js/templates/app/footer.jst',
)
and you had a template at 'js/templates/app/footer.jst', you can access the template in your javascript code in the following manner:
template: window.JST['footer']
Notice that you need to include the name of the template from the first '*'
If you are still not sure then you can inspect the window.JST object in your javascript console to examine its properties.
If you want to use some other attribute name other than 'JST' then you can change it using the following setting in your settings.py
PIPELINE_TEMPLATE_NAMESPACE = 'window.Templates'
Now you can access your templates will be in the window.Templates objects instead of being in window.JST

Seems you should add also 'js/backbone/templates/.jst' as 'js/backbone/templates/*/*.jst' will match only templates in subfolder.

Related

Using Nunjucks in flask app - Trying to include HTML

I'm using Nunjucks apart from Jinja2 in my Flask application so I can pass in some variables through JS that I want to render in an HTML template.
-- Here's what I do --
JS controller:
this.element = DomHelper.htmlToDom( slideTemplate.render({ slide : this.model }));
{% include "presentation/slide/layouts/layout-1.html/" %}
What I have working:
Nunjucks compiles & render works properly without the {% include..}
slide variable is being passed and used fine
Any thoughts or suggestions would be nice. Thanks!
So I found that I had overlooked a simple thing. My nunjucks was configured to work only for the client side but the templates are served through flask. The relative path will only work for the client side data.
Solution: I placed the template layouts inside the static/ directory instead of in server-side templates/
Based on your question, you might have a typo. You have:
{% include "presentation/slide/layouts/layout-1.html" %}
but you say:
The desired html template I want to includes is in
templates/presentations/slide/layouts/ - Here's my folder structure
Is the path templates/presentations OR templates/presentation ?

Django-CMS apphooked templates showing same placeholder content

I've got a django-cms site on which I have created a page at /managers-home/ with an app hook so that I can use myapp from that page.
myapp renders various templates at various URLs beneath /managers-home/ and I would like each of these templates to have a section editable via the django-cms content plugin. Therefore I have added {% staticplaceholder "content" site %} to these templates, because, as I understand it, you can't use a standard {% placeholder "" %} from within a hooked application.
I made a start with this and added some text to the placeholder on /managers-home/page-1/ which uses page-1.html and then when I got to the placeholder on /managers-home/page-2 I could already see the content from page-1 despite now using page-2.html so the placeholder on these two individual templates is being shared.
How can I correctly add django-cms placeholders throughout my application templates?
Turns out my problem was that a static_placeholder is exactly that, just a placeholder identified by the name given and anywhere you reference that name you get the same content.
So in order to allow each of my templates to display custom text, I've created a static_placeholder for each template.
# page-1.html
{% static_placeholder "page-1" site or %}
Default text goes here
{% endstatic_placeholder %}
# settings.py
CMS_PLACEHOLDER_CONF = {
'page-1': {
'plugins': ['TextPlugin', 'UploadedPicturePlugin'],
'text_only_plugins': ['LinkPlugin'],
'extra_context': {"width": 640},
'name': gettext("Content"),
}
}

Django admin custom template tag

I try to customize my admin panel. I have copied change_list.html to the proper subfolder which is templates -> admin -> model -> change_list.html
While I customize the change_list.html I'd like to use a templatetag but I am not sure where should I put my custom template tag library.
When I put it under django/contrib/admin/templatetags/ it works fine but I want to keep it in my own project tree.
Do you have any idea ?
Note: I have also load my template tag in change_list.html as
{% load adminmedia admin_list i18n grp_tags myproject_tags %}
Thanks
Do not modify or add anything to directory containing Django (do not modify Django!). Keep everything in your project directory (like in the manual).
Admin templates are exactly the same as non-admin templates and you use custom template tags exactly the same way. Put your template tags in yourapp/templatetags/ directory. If your app is in the settings.INSTALLED_APPS that you can load it's tags by passing the module name to the load tag. It accepts also package.module syntax, so: {% load somelibrary %} or {% load package.otherlibrary %}

Django - Admin - Mandatory fields with ' * '

At present, Django admin will show all the mandatory fields with a bold labels. Is it possible mark with * in the label instead of bold labels?
The Django admin uses templates to render the add/edit page for a model. It is possible to replace that template with one of your own (which extends from the original template) overriding the template blocks you need to in order to make the changes you want to.
Check out the Django docs regarding overriding admin templates for more information.
It's the admin/change_form.html template which you would need to alter in some way (since this template renders the page shown when you add a new instance or edit an existing one). The existing templates already apply a required class to the appropriate labels, so I would create a new template which looks like this:
{% extends "admin/change_form.html" %}
{% block extrastyle %}
{{ block.super }}
<style type="text/css">
/* add an asterisk using CSS */
.required:after {
content: " *";
}
</style>
{% endblock %}
Apply to a Single Model
You should use a model admin class if you want this template to be used for specific models, setting the change_form_template attribute, as described in this section of the docs to the location of the template file you have created.
Apply to a Single App
If you want template to apply to models in an entire app create a templates folder inside the root of the app. Django will automatically look for templates there, so if you create a folder called admin and place a file in there called change_form.html it will automatically override the default Django template of that name (admin/change_form.html).
Project Wide
In order to apply this template project wide create a folder somewhere (not inside an app) called templates. Again place your new template in this directory at admin/change_form.html.
Next edit the template directories Django setting specifying the location of this directory in order to allow Django to find the template and override the default templates in the same way as before only project wide and not just app wide.
This is quite a complex set of things to do, especially for such a simple change and you may find it tricky if you have not worked with admin templates before (or even if you have).
Hopefully you now understand what is required to change an admin template, its actually fairly elagant (as is Django) but in my opinion not worth the effort just to change to some asterisks.

Django template dir switching

Does anyone know a way to switch the TEMPLATE_DIR in django dynamically.
I need to create a set of templates for a mobile version and would like the templates to sit inside there own dir instead of inside the root template dir ie: I would like 2 template dirs 'templates' and 'mobile_templates' and not have to use 'templates/mobile' for the latter.
Do I have to write my own template loader?
You can set multiple template directories in your settings file and Django will search them in the order that you list them. Problem is that it doesn't care if you want template_x.html from directory a or b. If you have the same template_x in directory a and in b, it'll pull from which ever is listed first which can be confusing. A good way would be as follows:
Have only 1 template directory somewhere called 'templates'. Inside of this folder have a folder called 'mobile' and a template called 'default' (or whatever). Then when you call your template you just have to use the directory path as well.
In your view:
# some mobile view (everything omitted brevity)
get_template('mobile/some_template.html')
# some normal view (everything omitted brevity)
get_template('default/some_template.html')
In your templates:
Mobile Template:
{% extends 'mobile/base.html' %}
Normal Template:
{% extends 'default/base.html' %}
Settings File:
TEMPLATE_DIRS = (
'D:/some/path/to/templates',
)