Calling a method with the multiple arguments in a template - python

How can I call a method, pass multiple parameters to it and render the result in a html template? I can't find a simple solution which works in all circumstantials. I'm aware about #register.filter and #register.simple_tag but there's alway an error being thrown. If it's not thing, it's another. For example, simple_tag works when I render it, but throws an error when I call if.
So how can I call a method from an html template in the following ways:
{{method1(a, b)}}
{% if method1(a, b) == some_value %} {{method1(a, b)}} {%endif%}
Note I don't need advice like "you're doing something wrong, you should change your architecture" because that's not the case here. I just a simple way to do what I want. In Rails, for example, I can do it very, very easily.

You can use an assignment tag to assign the value received from the template tag into a variable which then can be used anywhere in the template.
#register.assignment_tag
def method1(a,b):
...
Then in your template you can call this template tag and assign its value to a variable method_value.
{% method1 a b as method_value %}
Then use this variable in the template.
{{method_value}}
{% if method_value == some_value %} {{method_value}} {%endif%}

Related

how to call a global variable in a function in flask?

Hello guys, small part of my code here, i have result and pred variables. And in the html part i have this code:
<div style = "margin-Top:100px;" class="container">
{{ results[pred] }}
</div>
And i get this error. So how can i fix it?
So i thought the variable in html calling like that in flask. Am i wrong?
results[pred] uses 2 variables to resolve:
results, dict
pred, the lookup in the dict
It seems, that u only need the value of pred in results. You can do this by using return render_template('index.html', var=results[pred]) and {{ var }}
Edit: In your case pred is static in python so you should only return the mandotory value of the results dict to the template.
You can’t pass parameter like this.
In render_template pass result=result
And then in the template you can use it like you write - result[pred]

Single View with Dynamic template

I've got modules that if enabled/disabled would require a different arrangement of tables and iframes on the frontend webpage. In order to do this I set up a function to check which modules are enabled/disabled and assigned a number to each 'set' and will be created separate templates for each "set1.html", "set2.html", "set3.html", etc...
I'd like to utilize one single view where I can pass the set number from from function I created but I can't seem to figure out how.
def homeset(request):
return render(request, 'app/set1.html', {})
Looking to figure out some way to make the "1" the return of the function I created to determine which set# to load as template and would prefer to not have to create a view for every single template needed.
Just taking a stab at this, do you have a problem with setting the template name before rendering?
def homeset(request):
# define 'my_set'
# define num
...
my_template_name = None
if num in my_set:
my_template_name = 'app/set{}.html'.format(num)
return render(request, my_template_name)
Looks like Scott Skiles answered your question, but an alternative way is to use a single base template and the "include" templatetag.
You can pass the set number to the template and use the "if" templatetag" to include the content from appropriate template(s) for each set number.
{% if set_num == 1 %}
{% include "foo/bar.html" %}
{% elif set_num == 2 %}
{% include "foo/two.html" %}
{% endif %}

Own {% trans %} tag for Django

I wrote a template tag for Django, that is used like, say, {% foo bar="foobar"%}. The tag takes the bar argument value, uses ugettext on it and renders the tag with translated string.
So, basically, the tag's implementation looks more or less like this:
#register.simple_tag
def foo(bar):
return "something something " + ugettext(bar)
Unfortunately, we are using ugettext with a variable, and that means that Django won't mark our bar argument's value for translation.
I was looking for a solution in Django makemessages as well as {% trans %} code, but didn't find anything that would clearly say how the "marking for translation" thing is done there. So, my question is: how to do it? How to force Django to think that my tag's bar argument value is supposed to be translated, so it appears in .po(t) file after executing manage.py makemessages?
Instead of creating "custom" trans tag, one can pass the string using _() syntax, so the argument gets an already translated string.
In case of the tag from question - that means that we can change the tag implementation to simple:
#register.simple_tag
def foo(bar):
return "something something " + bar
But one does not have to use something like this:
{% trans "foobar" as var %}
{% foo bar=var %}
And instead:
{% foo bar=_("foobar") %}
Which is convenient enough, does not waste lines and variables, and marks the string for translation.
See: https://docs.djangoproject.com/en/1.8/topics/i18n/translation/#string-literals-passed-to-tags-and-filters

In a jinja2 template, how do i check if an element in a mongo database is one of three possible strings?

My template has if/else functionality to handle displaying buttons on a page, I've managed to add an elif statement that displays the buttons only if an element in a mongo database is not one of three values. I'm trying to clean this up as the elif appears four times across two jinja2 templates. My code which works now looks like this:
{% elif (
('string1' not in database.category) and ('string2' not in database.category) and
('string3' not in database.category)) %}
I've tried declaring a tuple and doing a:
{% set hidebuttons = ['string1' , 'string2' , 'string3'] %} //sets tuple
{% elif not database.category in hidebuttons %} // checks if value not in tuple
and plenty of other methods to make this work but every time I reload the web page i keep seeing the buttons when i shouldn't be. Any advice is greatly appreciated.
I believe this should be in your view, not your template. If you need to do the query in more then one place, you can create a utility function that gets the results you need, then in your views, you can call the function and pass the data as context to your templates
if you're using a view_config decorator to render template, it could be something like:
#view_config(renderer='templates/foo.pt')
def my_view(request):
show_buttons = logic_to_determine_should_buttons_be_shown()
return {'show_buttons': show_buttons }
# your template
{% if show_buttons %}
show buttons
{% endif %}

Django -- how to use templatetags filter with multiple arguments

I have a few values that I would like to pass into a filter and get a URL out of it.
In my template I have:
{% if names %}
{% for name in names %}
<a href='{{name|slugify|add_args:"custid=name.id, sortid=2"}}'>{{name}}</a>
{%if not forloop.last %} | {% endif %}
{% endfor %}
{% endif %}
In my templatetags I have:
#register.filter
def add_args(value, args):
argz = value.strip() + '-' + 'ARGS'
arglist = args.split(',')
for arg in arglist:
keyval = arg.split('=')
argz.join(keyval[0] + 'ZZ' + keyval[1])
argz.join('QQ')
return argz
The output URL should look like:
http://foo.org/john-smith-ARGScustidZZ11QQsortidZZ2
Where ARGS is the start of the arguments, ZZ is '=' and QQ is an '&' equivalent.
First of all: This would work, but I get the custid=name.id coming in the add_args(), where I want to have custid=11 to come in. How pass in the id as an id and not text.
Also, is there a way to just send in an array of key=>value like in PHP.
In PHP I would build an array, let say:
arglist = array('custid' => $nameid, 'sortid' => $sortid );
Then I would pass the arglist as an argument to add_args() and in add_args() I would do
foreach( arglist as $key => $value)
$argstr .= $key . 'ZZ' . $value . 'QQ'.
Does anyone have a better way of making this work?
Note: if I have to pass all arguments as a string and split them up in the filter I don't mind. I just don't know how to pass the name.id as its value ...
This "smart" stuff logic should not be in the template.
Build your end-of-urls in your view and then pass them to template:
def the_view(request):
url_stuff = "custid=%s, sortid, ...." % (name.id, 2 ...)
return render_to_response('template.html',
{'url_stuff':url_stuff,},
context_instance = RequestContext(request))
In template.html:
....
<a href='{{url_stuff}}'>{{name}}</a>
....
If you need a url for a whole bunch of objects consider using get_absolute_url on the model.
You can't pass name.id to your filter. Filter arguments can be asingle value or a single literal. Python/Django doesn't attempt any "smart" variable replacement like PHP.
I suggest you to create a tag for this task:
<a href='{% add_args "custid" name.id "sortid" "2" %}{{name|slugify}}{% end_add_args %}'>{{name}}</a>
This way you can know which argument is a literal value and which should be taken fron context etc... Docs are quite clear about this, take a look at the example.
Also if this name is any way related to a model, say we want to get to the permalink, adding a method that returns the URL with the proper arguments might be the tidiest solution.
Overall, I would refrain putting too much logic into templates. Django is not PHP.
You're calling argz.join a couple times and never assigning the results to anything: maybe you're operating under the misconception that the join method of a string has some mysterious side effect, but it doesn't -- it just returns a new string, and if you don't do anything with that new string, poof, it's gone. Is that at least part of your problem...?

Categories

Resources