Detecting a URL in a Django wizard_form.html template - django

I have three SurveyWizardViews all of which use the same standard wizard_form.html which is located at templates/formtools/wizard/wizard_form.html as per the documentation
I have added some basic logic to this template which is designed to detect which page of the form the user is on so that I can include a non standard page/step, this is an image with a JS slider bar underneath. This all works perfectly.
{% if wizard.steps.current == '6' %}
<img src="{% static "survey/images/pathtwo/" %}{{display_image}}"/>
<section>
<span class="tooltip"></span>
<div id="slider"></div>
<span class="volume"></span>
</section>
{% endif %}
However I now want to have a slightly different experience for the user depending on which View/URL they are coming from.
Question Is it possible to detect which URL the view is currently using to look at the page? e.g.
{% if URL.current == 'www.mywebsite.com/experiment/surveyone/' %}
do X
{% if URL.current == 'www.mywebsite.com/experiment/surveytwo/' %}
do y
I have done some searching but Im not even sure what I'm searching for to be honest. Any help would be much appreciated.

You can use the request context variable. Something like:
{% if 'experiment/surveyone' in request.path %}
do this
{% endif %}
I prefer using in instead of == to ignore trailing and leading slashes. If you want the whole thing try the build_absolute_uri method. Also check what options does request offer to you (https://docs.djangoproject.com/en/dev/ref/request-response/#httprequest-objects).
Finally, don't forget to add django.core.context_processors.request to your TEMPLATE_CONTEXT_PROCESSORS (I think it is added by default).

Related

Repeating HTML blocks in Django

Not sure what technical term it is I'm looking for, but I have a set of HTML elements that are repeated and wondering if there is an easy way to do this.
Very simplified HTML, if I have the following:
<div class='container'>
{{ django.dataFromORM }}
</div>
I need to add to base.html in a certain section
<div id='main-container'>
all elements go here
</div>
So on run, I want to add the generated HTML the main-container. I've done this before by building in JS, but wondering if there is a way to smoothly do this in Django?
I looked at templates and partials, but not sure that's the proper way or not?
You can use include in template to include your repeated html file.
ie
<div id='main-container'>
{% include "container.html" %}
</div>
if you want to repeat it several times you can add it inside a for loop
eg:
{% for element in elements %}
{% include "container.html" %}
{% endfor %}

Django templates - Formatting strings

I've these variables:
#Int
user.id
#Float (e.g. X.YYYY)
profile.rating
I need these formatted like so (the ` is delimiter):
`profile.rating`
I've tried numerous ways to format them, but none worked. For example, concatenating them: ""|add:profile.rating|add:"" gave me nothing (literally, nothing).
I suspect that this is because add: is numbers-first, but converting the numbers into string with either slugify or stringformat:"" gave me, again, nothing.
How do I do this?
Do note: I need to do this with filters since the result will be passed as a parameter to an include.
Update:
Basically, I'm building a sort of modular include. It include looks like this:
<section>
...
{% if custom_section %}
<section id="{{ custom_section_id }}">
{{ custom_section }}
</section>
{% endif %}
...
</section>
which means that I can't just directly include the values in a parameter, I need the markup that will go inside the nested section.
I managed to solve this issue with this piece of markup:
{% with "<a href="\"/user/" as link_start %}
{% with profile.rating|stringformat:".1f" as rating %}
{% with user.id|slugify as id %}
{% with link_start|add:id|add:"/\">" as link %}
{% with link|add:rating|add:"/5</a>" as data %}
{% include "XX" with custom_data:data|safe %}
{% endwith %} a couple of times
Key here is the |stringformat:".1f" and the user.id|slugify since without them, djangos worthless templating language defaults on the belief all values are numerical, and thus crap comes out.
Of note is the |safe as well, as without it the language escapes the value.
Do note: I need to do this with filters since the result will be
passed as a parameter to an include.
You can pass them directly to include, as it will take context correctly.
{% include user.id %}

Adding an if statement to django-cms template tag

I'm probably missing something very obvious but can't see anything in the documentation. I have a carousel with a and each will hold an image. However I've added 6 but I want to add an if statement so if an Image has not been added you don't see a blank space, where there is no content inside the .
Here is what i've tried so far:
{% if "Carousel 1" %}
<li>
{% placeholder "Carousel 1" %}
</li>
{% endif %}
Attempt 2:
{% placeholder "Carousel 1" as cara1 %}
{% if cara1 %}
<li>
{{ cara1 }}
</li>
{% endif %}
Not sure if there is something differnt i need to be doing for the django-cms template tags?
Any help would be much appreciated. Docs here - http://docs.django-cms.org/en/latest/advanced/templatetags.html#placeholder
Not to be rude, but your approach is way, way off :)
Placeholders hold Content Plugins. Content Plugins are responsible for how they render their contents.
My advice would be to create or find a carousel content type plugin. This plugin will hold multiple images or "CarouselImage" model instances that you can iterate over, and also specify a template with which to render itself.
In this template resides the conditional statement you're wanting to check for. Placeholders are just that - places held for content plugins.

Indeterminite number of apps/widgets in Django template

I'm working on a site that will have a bunch of pages with an indeterminate amount of "apps" on each page. Something like a calendar app, and a random picture app, or whatever, each in a neat little box. While it's possible to write a template with a bunch of if tags that include other templates, this is a bit of a hassle. I'd like to pass in some variables and have forms on some of these apps, so it would get out of hand quickly. Writing custom inclusion tags will be better than {% include x %}, but it would still be a lot of if statements and writing out every possible app for each page.
Is there any way to loop over something like inclusion tags and include only those that are relevant? Any other completely different solution that I'm missing?
What I'm trying to avoid, whether I use {% include %} or inclusion tags, is this:
{% if apps.calendar %}
{% include "calendar.html" %}
{% endif %}
{% if apps.pictures %}
{% include "pictures.html" %}
{% endif %}
This would mean we'd have to update templates any time a new app was added. What would be nice is something like:
{% for app in apps %}
{% call appropriate include or inclusion tag %}
{% endfor %}
With very few exceptions we use our custom tags all over the place, so we deal with this by simply placing the following in the app/__init__.py file.
from django import template
template.add_to_builtins('content.templatetags.local_tags')
template.add_to_builtins('utils.cachetemplate')
So all of the pages have them available by default. Doesn't seem to impact performance and we use tag names that are unlikely to interfere with other stuff we might include. It's lazy but it works.
Update: OK, I think I better understand what you want. One way of doing this (although I don't really recommend it) is to put the check for the variables inside the included templates. This means you will always have the overhead of including the template, but it will make your other pages marginally less cluttered.
So instead of this in your main file:
{% if apps.calendar %}
{% include "calendar.html" %}
{% endif %}
you simply have:
{% include "calendar.html" %}
and in "calendar.html" you have:
{% if apps.calendar %}
whatever you do for your calendar app
{% endif %}
Update 2:
The last bit of code you show could be done as follows. This takes advantage of the the fact that {% include arg %} "resolves" its argument. This means it can be a variable or a method reference that returns a usable string value that is a template name.
{% for app in apps %}
{% include app %} <!-- or perhaps {% include app.template %} -->
{% endfor %}
Note: Django's template code does not handle top level callables correctly. This means your context cannot pass a reference to a function and expect it to be called and it's output inserted when referenced in a template. Ie. in the example above your list of apps may not be simple functions which you wish to be called. To work as expected a function reference must be either a member of a list or dict, or it must be a method of an object that is passed. We MonkeyPatched this problem long ago because we use curried functions in cached template fragments to defer some heavy DB work. This ticket has been open for over 2 years.

How do I DRY up common text in a Django template?

I have some static text that needs to show up at 2 locations within a template.
For example:
<div>
{% if something %}
This is a static text
{% else %}
Something else happened
{% endif %}
</div>
... more html
<span>
{% if something %}
This is a static text
{% else %}
Something else happend
{% endif %}
</span>
I can do the above by duplicating the above text at 2 different locations in my template file(as shown above).
I could also create a model which will store the text(This is DRY but cost a call to the DB for a simple task)
I'm thinking of using include template but that's probably not the best way to achieve my goal.
What's the best way to do it?
Definitely use Inclusion Tags:
http://docs.djangoproject.com/en/dev/howto/custom-template-tags/#inclusion-tags
The tag file would either be something super simple like just the text "This is a static text" or the entire block:
{% if something %}
This is a static text
{% else %}
Something else happened
{% endif %}
"something" can be passed as a variable to the template tag so you can use that entire block in a variable way.
I use the django internationalization to do that. So in my apps/template I just write the key, and in the .po files is the value of the keys.
{% load i18n %}
<div>
{% if something %}
{% trans "static" %}
{% else %}
{% trans "something else" %}
{% endif %}
</div>
And in my .po file:
msgid "static"
msgstr "This is a static text"
msgid "something else"
msgstr "Something else happened
Besides useful for multi-language, it's much easier for copy writing just in case you want to change it in the future because you can just look unto one file instead of browsing several templates.
There are several ways, but it probably depends on what the text is and how often it will be used. It's hard to recommend a specific choice without full details
Create a custom template tag (this one makes the most sense based on how you've described your problem above).
Create a base template which has the text in it at the correct location and then inherit off of it for your "2 locations"
Put the static piece of text in a settings file and pass it to the template renderer via Context (probably not the best idea, but depending on what you're doing it could be a possibility)
You could use flatblocks : http://github.com/zerok/django-flatblocks
or chunks : http://code.google.com/p/django-chunks/
Those may be overkill for your problem, since they store your snippets in the database, but they add the benefit of making it possible to edit them via the admin.
{% load chunks %}
<div>
{% if something %}
{% chunk "something" %}
{% else %}
{% chunk "something_else" %}
{% endif %}
</div>
There are lots of forks or similar projects, for example:
http://bitbucket.org/hakanw/django-better-chunks/
http://github.com/bartTC/django-generic-flatblocks
I have a file like Java properties that I use for all of my resource strings. I just serve up the one that I want. Keeping these in one place also makes translating easy.
Ex.:
welcome_msg="hello user!"
thank_you="thank you"
goodbye_msg="goodbye, " + thank_you
If the included text gets bigger, use an 'include' tag.
{% include "myapp/helptext.html" %}
GrtzG