Applying CSS classes to table rows with Sphinx and reStructuredText - python

We have a website that is generated using Sphinx and reStructuredText. Albeit not ideal (I have inherited this code), it's something that so far has worked and serves the purpose. We're trying to extend it slightly and one request was to highlight better certain rows in a table based on a condition (just a bit of context).
What we noticed is that if the element that needs the style applied is the first one in the for-loop, the style gets instead applied to the parent (<tbody>) element.
This is the relevant piece of code that does not seem to be working as intended:
{% for codelist_item in codelist_json.data %}
{% if codelist_item.status == 'withdrawn' %}
.. rst-class:: withdrawn
* - {{codelist_item.code + " (withdrawn)"}}
{% else %}
* - {{codelist_item.code}}
{% endif %}
- {{codelist_item.name}}
...
{% endfor %}
NB: indentation is correct (as in it matches what's in our rst file)
Non working example: http://reference.iatistandard.org/202/codelists/BudgetIdentifierVocabulary/
whose HTML is:
<tbody class="withdrawn" valign="top">
<tr class="row-even">
<td>1 (withdrawn)</td>
<td>IATI</td>
<td>The budget identifier reported uses IATI budget identifier categories</td>
</tr>
Working example: http://reference.iatistandard.org/202/codelists/Currency/
<tr class="withdrawn row-even">
<td>BYR (withdrawn)</td>
<td>Belarussian Ruble</td>
<td>Withdrawn from ISO Currency codelist. Use code BYN.</td>
</tr>
While exploring the Sphinx docs, I stumbled across this bit that might be (or at least sounds) relevant
http://docutils.sourceforge.net/docs/ref/rst/directives.html#id12
This allows the "classification" of individual list items (except the first, as a preceding class directive applies to the list as a whole)
That seems to fit our problem, although like I said I'm not entirely sure it does relate to it.
So far, we tried checking {% forloop.first %}, moving the rst-class:: around, but nothing seems to work.
Any advice?

Related

django - multiplication and templates

I hope you can help me on this one. I have a template that shows the price of a, lets say a Banana, and for example the banana costs $400 and i have to calculate the 21% of this price and show it on a box of a table. I was tempted to do something like:
{% for banana in bananas %}
{{banana.price}}*(21%)
{% endfor %}
but obviously that failed miserably.
So, is there a way to do this type of simple equations in a template or i need to make a custom template tag to handle it.
its a very basic question but i would really appreciate the help.
Thank you.
You do need a custom template tag, but you could install django-mathfilters, which provides such basic operations:
{% load mathfilters %}
...
{{banana.price|mul:0.21}}
Taken from the mathfilters page, the included operations are:
sub – subtraction
mul – multiplication
div – division
abs – absolute value
mod – modulo
'Add' is provided in Django as standard.
You can use built-in widthratio template tag:
For creating bar charts and such, this tag calculates the ratio of a
given value to a maximum value, and then applies that ratio to a
constant.
{% widthratio banana.price 100 21 %}

Django templating - accessing dictionary value using a template variable

This is the data coming from my views.py:
gradebook_data = {
'G5A': [...],
'G5B': [...],
...
}
sections = [
('G5A': '5-Einstein'),
('G5B': '5-Bohr'),
...
]
In my template, I want to iterate the sections and display gradebook data inside a for loop like this...
{% for code, section in sections %}
<td>{{ gradebook_data.code }}</td>
{% endfor %}
This doesn't work since in Django it tries to do a dictionary lookup for gradebook_data['code'] when what I want to do is to get gradebook_data['G5A'].
Does anybody know a workaround or can point to my mistake? I have spent a whole day just for this already.
This was quite easy to do with PHP's Twig templating library.
If you're using the Django templating system you can register a custom filter, which has been documented several times on SO for exactly this purpose. For example, here.

Is there a way to clean up the html that jinja2 produces?

We are using jinja2 to create our html but, because of the many loops and other things we do in jinja to produce the html, the html 'looks' ugly....(note: this is just for aesthetics). Is there anything we can do to clean up the html? (Other than the obvious of cleaning up our jinja2 code, which would make our template somewhat unreadable to us staffers)
Something like beautiful soup's prettify?
(Yes, I realize this question is a pretty nit-picky question...the ocd in me says to clean it up).
for instance:
<table>
<tbody>
<tr>
<td>
a column
</td>
<td>
a value
</td>
</tr>
</tbody>
</table>
Pretty ugly, eeh?
Add '-' to the tags:
{%- if 'this'=='this' -%}
{{ blah }}
{%- endif -%}
It looks like someone out there created a library to do just what need. See this library which I found attached to this question (whom you should upvote).
You can also configure Jinja to replace tags with nothing (instead of an empty line) by setting trim_blocks and lstrip_blocks to True. For example, in a Flask app, you might write:
app.jinja_env.trim_blocks = True
app.jinja_env.lstrip_blocks = True
The documentation explains whitespace control further.

two or more dots in a django template after the variable

In a django template, is it possible to have two (or more) dots after a variable? For example, say I have a list of objects that I first want to use a list-index lookup for and then once I have the object, I want to call its method for getting the absolute url, should that work?
For example:
{% for entry in myList %}
{{ entry.0.get_absolute_url }}
{% endfor %}
So the 0 is asking for the first item in the list which is an object, then I want to get the absolute url. It doesn't work when I try it but it doesn't return an error either. Is there a better way to accomplish what I'm trying to do?
To clarify it, what's strange is that:
This works:
{{ singleObject.get_absolute_url }}
In that case if I just try {{ singleObject }}, I get the unicode value of that object so something like: John Smith
This doesn't work:
{% for object in objectList %}
{{ object.get_absolute_url }}
{% endfor %}
But in this case, if I put in {{ object }}, I no longer get the unicode value. I get: [<Name: John Smith>] (name being the name of the model)
Basically, the method works when it's outside of a loop. Could there be any reason for that?
more than one dot absolutely works.
based on your comment, there is no entry.0 because entry IS the first item in the list cause you are already looping through `myList'
just use entry.get_absolute_url instead
but if you only want to print out the url for the first entry, forgo the for loop and just use myList.0.get_absolute_url
UPDATE:
there's a tip from 'the pragmatic programmer' that says:
``select’’ Isn’t Broken
It is rare to find a bug in the OS or the
compiler, or even a third-party product or library. The bug is most
likely in the application.
i think you assumed that django templates were behaving weird, when the truth is you were not building your list correctly. don't be afraid to show some of your actual code, by abstracting the problem for us, you removed the part that included the problem
I got it. I had brackets around each item in my list like so:
objectList = [['John Smith'], ['Jim Jones'], ['Bill White']]
Silly me! Thanks so much for your all your input
What you are doing is perfectly acceptable in Django templates. There is no better way to accomplish what you're trying to do.

Django internationalization (i18n) lint checker? Tell me what hasn't been _()'ed or {% trans %}'ed

I have to internationalize (i18n) a django project. It's combined of many in house django apps. It is partially i18n'ed already, i.e. some of the strings are _(), but some are bare. Some of the templates use {% blocktrans %} or {% trans %}, but sometimes the english text is in there direct. It will take a lot of manual work for me to change all this. Oh well.
Is there some way to see what strings in the python code and what text in the html templates hasn't been passed through _()/{% trans %}? A 'i18n lint' checker? A command that'll print out the line & filename of strings that haven't been _()'ed yet, or that aren't in {% trans %} I'm OK with it throwing up false positives (& false negatives), I just want some way to make sure I haven't missed anything.
I couldn't find anything like this, so I had to make my own.
A plugin for pylint that finds strings that aren't in _()/ugettext()
A script to find non-translated/i18n'ed strings in django templates
You could grep through all the Python files to get yourself a list of strings and see which ones lack a _(). Something like this but probably a little bit more sophisticated:
grep "[\"\'][A-Za-z]" */*py -R
Unfortunately, I have no idea on how to look through template files as I don't see any way to distinguish between strings in a {% blocktrans %} or {% trans %} environment and those without.

Categories