jinja2 can not read self - google-app-engine

I have been using django for a while and I am now converting to jinja2 because GAE told me too. One of the short cuts I use for django is to pass "self" to django when rendering my template so that in my template I call {{ self.stuff }}. In jinja it seems that "self" represents something. Does this require me to change all my templates to use perhaps "this"?

self is actually used by Jinja2 to allow you to reference blocks:
<!-- In your layout.html file -->
<title>{%- block title %}{% endblock %}</title>
<!-- Some distance further down ... -->
<h1>{{self.title()}}</h1>
<!-- In a file that extends layout.html -->
{% block title %}The Title of the Page{% endblock %}
<!-- The above will render -->
<title>The Title of the Page</title>
<!-- Some other stuff ... -->
<h1>The Title of the Page</h1>
Simply use another name and everything will work (i.e., rather than self use this or obj as suggested by #Skirmantas).

Related

AngularJs - Pass angular argument to file twig

How can I pass an Angular item to twig file included?
This is my twig file that I want to include:
<a href="javascript:void(0)" title="[{ hostess.gender == 'F' ? 'Hostess top' : 'Steward top' }]">
<img src="{{ WBASE }}/assets/img/badge/top-profile.png" class="c-badge [{ extraClass }]"/>
</a>
Instead this is my twig file where I render data through angular loop. I need to include a twig file if the condition is true:
{% if hostess.top %}
{% include '_commons/elements/ng-badge-top.twig' with {'hostess': hostess} %}
{% endif %}
But it doesn't work. How can I do it?
I think that you won't be able to do it like that.
Take in consideration that angular is front-side rendered and twig server-side.
If you want to achive that, you will probably have to craete your ng-badge-top.twig as a html and include it with angular using "ng-include".
You can also try something like this:
<div ng-if="[{ hostess.top }]"
ng-include="'{{ path('view_route', { view: 'Content/test.html.twig' }) }}'"></div>
This last piece of code will do a call to the server to get a html file and render it. Take in consideration that this controller should serve HTML files, otherwise angular won't be able to process them. Didn't tested it, but if it doesn't work tell me and we will figure out what's wrong.
If those solutions doesn't fit your needs I can give you other options :)

Django template and angularjs filtering

I have some data on the page provided by standard django queryset {{ django_data }} there is about 100 objects inside and I display it on the standard way
{% for data in django_data %}
<div class="data_block">
<h1>{{ data.title }}</h1>
<div>{{ data.description }}</div>
</div>
{% endfor %}
Now as angularJS novice I want to add this filtering/search functionality to display less objects based on user input
Search:<input ng-model="query" type="text"/>
Also I think that to allow angular to make new request from the controller is wasting of resource to get data which is already on the page http.get('django_data.json') simply doesn't make sense. So the bast way will be to send django_data as dict from django view. If I do this, how to tell angular that data are on the page inside variable called django_data? Something like this do not work.
<div class="data_block" ng-repeat="data in django_data">

How to render pages those are related to user roles in angular

First of all I am very new in Angular JS. I am working in a project, where I have three types of users and all three users have different kind of views. Now My question is, can it be possible after login, render only pages/views those are belong to logged in user instead of all pages? If yes then how?
I would do it on the server side. Something like this. This will enject the right angular app based on what kind of user flag is set. Of course this would mean that you had a flag on each user that indicates what type of user they are. You could just use a unique attribute of the type of user and it would work the same. This will allow unique views, and controllers for each different kind of user. I'm assuming you want one url to serve up three different types of angular app based on what the user is. If you want to control what URLs are accessible, that's something else entirely and should be handled in your django views.
{% if user.is_staff %}
<div ng-app='staffApp'>
{% elif user.is_investor %}
<div ng-app='investorApp'>
{% elif user.is_founder %}
<div ng-app="founder">
{% endif %}
<div ng-view>
</div>
</div>
Another way is just have an attirbute that each user has like
#property
def ng-app(self):
return 'investorApp'
And then in your template do
<div ng-app='{{ user.ng-app }}'>
<div ng-view>
</div>
</div>
But any way, I think this would be the correct way to solve your question :)

jinja2 form render does not allow attribute which contains "-"

I am trying to customize the form template base on this tutorial. As I understand, render() just add some attributes to the tag. For example, I add placeholder = "abc" and it works well.
{% call inserttourbus(id = "formAddNewRow" ) %}
<div class="fieldWrapper">
{% if inserttourbus['bustype'].label() %}Bus Type{% endif %}
{{ inserttourbus['bustype'].render(placeholder="abc")|safe }}
{% if inserttourbus['bustype'].errors() %}Not filled yet!{% endif %}
</div>
{% endcall %}
Here is my problem:
- I use bootstrap typeahead for my template so I need to add the following attribute to the inserttourbus textbox
data-provide="typeahead" data-items="4" data-source='["Alabama","Alaska"]'
So it will become
{{ inserttourbus['bustype'].render(placeholder="abc", data-provide="typeahead", data-items="4", data-source='["Alabama","Alaska"]')|safe }}
But the jinja2 engine seems does not accept data-provide, data-items, so on because it contain "-" character. If I changed data-provide to dataprovide, the jinja2 engine can render the code well.
However, in bootstrap typeahead javascript, all variables are defined as data-provide, data-items. If I change them to dataprovide, dataitems, the javascipt stop working.
Please give me a solution:
- How to make jinja2 accept attribute which has "-"
- Other solutions, advices
Check out this snippet for doing this in Flask. I imagine it would work the same way for Django; pass HTML attributes with invalid Jinja2 (Python) syntax inside an ad-hoc dictionary:
{{ inserttourbus['bustype'].render(placeholder="abc",
**{'data-provide':'typeahead',
'data-items':'4',
'data-source':'["Alabama","Alaska"]'}) }}
A Hyphen is used as the subtraction operator in Python. So do not use it in names. You can use it ofcourse in strings.

google app engine comments and check dev environment in html views

I'm working with a basic *.html file in Google App Engine.
How can I put in comments that will not churn out an html comment? E.g. in Rails I would do <%# comment %>
Also, how can I detect it is a development environment (or check if the url is localhost) and hence only trigger a certain block of html? E.g. in Rails I would do:
<% if Rails.env.development? %>
<p>comment visible only in localhost!</p>
<% end %>
Thanks!
As for the comment piece, you can use similar syntax to what you have above:
{# some comment here #}
{{ variable }}
{% for some item in another_variable %}
<p>{{ item }}</p>
{% endfor %}
Regarding the hostname part, I'm not aware of any template built-in that would handle that. I would suggest making this check in your server-side code and passing the result to the template. Here is a question/answer that should accomplish what you need. Pilfering code from that answer, you could define a variable in you code such as (using Python, as I'm not sure which runtime you are using):
dev_server = os.environ['SERVER_SOFTWARE'].startswith('Development')
You could then reference this in your template (assuming you pass the variable into the template as dev_server) as follows:
{% if dev_server %}
<p>comment visible only in localhost!</p>
{% endif %}
If you want to have conditional code using Java on App Engine, you could write your html as a JSP file. Then you can use conditional blocks, and have comments that don't show up in the final output e.g.,
<%-- This comment will get removed by the JSP compiler --%>
<!-- This is a regular html comment and will survive the JSP compiler untouched -->
<p>Just some ordinary html in a JSP file here...</p>
<h1>Hello StackOverflow!</h1>
<% if ( isSayGoodbye ) { %>
<h3>Goodbye!</h3>
<% } %>
As for testing if you are on AppEngine vs. dev environment, check these (Java) docs from Google: https://developers.google.com/appengine/docs/java/runtime#The_Environment
if (SystemProperty.environment.value() ==
SystemProperty.Environment.Value.Production) {
// The app is running on App Engine...
}

Resources