jinja2 form render does not allow attribute which contains "-" - google-app-engine

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.

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">

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...
}

AngularJS-Twig conflict with double curly braces

As you know, both angular and twig has common control construction - double curly braces. How can I change default value of Angular?
I know that I can do it in Twig, but in some projects I can't, only JS.
You can change the start and end interpolation tags using interpolateProvider service. One convenient place for this is at the module initialization time.
angular.module('myApp', []).config(function($interpolateProvider){
$interpolateProvider.startSymbol('{[{').endSymbol('}]}');
});
https://docs.angularjs.org/api/ng/provider/$interpolateProvider
This question appears answered, but a more elegant solution that hasn't been mentioned is to simply enclose the curly braces in quote marks between the twig curly braces, like so:
{{ '{{myModelName}}' }}
If you are using a variable for the contents, do this instead:
{{ '{{' ~ yourvariable ~ '}}' }}
You should use single quotes, not double quotes. Double quotes enable string interpolation by Twig so you have to be more careful with the contents, especially if you are using expressions.
If you still hate seeing all those curly braces, you can also create a simple macro to automate the process:
{% macro curly(contents) %}
{{ '{{' ~ contents ~ '}}' }}
{% endmacro %}
Save it as a file and import it into your template. I am using ng for the name because it is short and sweet.
{% import "forms.html" as ng %}
Or you can put the macro at the top of your template and import it as _self (see here):
{% import _self as ng %}
Then use it as follows:
{{ ng.curly('myModelName') }}
This outputs:
{{myModelName}}
...and a follow up for those that use MtHaml alongside Twig. MtHaml enables the use of AngularJS curlies in the normal manner because any Twig code is accessed though - and = instead of {{ }}. For example:
Plain HTML + AngularJS:
<tr ng-repeat="product in products">
<td> {{ product.name }} </td>
</tr>
MtHaml + AngularJS:
%tr(ng-repeat="product in products")
%td {{ product.name }}
MtHaml + AngularJS with MtHaml-style Twig:
- set twigVariable = "somevalue"
= twigVariable
%tr(ng-repeat="product in products")
%td {{ product.name }}
As mentioned in similar question about Django and AngularJS, trick with changing default symbols (in Twig or AngularJS) can provide incompatibility with third-party software, which will use these symbols.
So best advice I found in google: https://groups.google.com/d/msg/symfony2/kyebufz4M00/8VhF1KWsSAEJ
TwigBundle does not provide a configuration for the lexer delimiters
as changing them would forbid you to use any templates provided by
shared bundles (including the exception templates provided by
TwigBundle itself).
However, you could use the raw tag around your angular templates to
avoid the pain of escaping all curly braces:
http://twig.sensiolabs.org/doc/tags/raw.html
-- Christophe | Stof
Tag was renamed to verbatim
You can use too the attribute-based directive <p ng-bind="yourText"></p> is the same as <p>{{yourText}}</p>
You can use \{{product.name}} to get the expression ignored by Handlebars and used by Angular instead.
This is a compiled version of the best answers and a example for verbatim blocks:
For single insertions, use:
{{ '{{model}}' }}
or if you use a twig variable
{{ '{{' ~ twigVariableWitModelName ~ '}}' }}
Verbatim, is very elegant and readable for several angular variables:
<table ng-table>
{% verbatim %}
<tr ng-repeat="user in $data">
<td data-title="'Name'">{{user.name}}</td>
<td data-title="'Age'">{{user.age}}</td>
</tr>
{% endverbatim %}
</table>
If you're not interested in changing the template tags of the existing angular syntax which would require some confusing rewriting of your existing angular templates.
One can just use the twig template tags with angular tags like so:
{% verbatim %}{{yourName}}{% endverbatim %}
Found this on another similar thread answer: Angularjs on a symfony2 application
Alternatively you can change the characters used by Twig. This is controlled by the Twig_Lexer.
$twig = new Twig_Environment();
$lexer = new Twig_Lexer($twig, array(
'tag_comment' => array('[#', '#]'),
'tag_block' => array('[%', '%]'),
'tag_variable' => array('[[', ']]'),
'interpolation' => array('#[', ']'),
));
$twig->setLexer($lexer);
According to this post you should be able to do it like this :
angular.module('app', [])
.config(['$interpolateProvider', function ($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
}]);
I like #pabloRN, but I would prefer to use span instead of p, because for me p will add line to the result.
I will use this:
<span ng-bind="yourName"></span>
I also use aText with the cursor inside the double quote so I don't have to rewrite the whole thing over and over again.
You can create a function in twig to surround your angular directives, so like instead of going ...
{{"angular"}}
you go ...
{{angular_parser("angular stuff here output curlies around it")}}

Google App Engine model for Select Box

I have category model, in which I want to load some default data. How can I achieve it? This is model is for a select box, which is extensible for different applications later
This is the model I have designed it, I tried verifying choice
class Category(db.Model):
categorylist=db.StringListProperty()
Please help.
Thank You
Select Box Model
Class Category (db.Model):
name = db.StringProperty()
Right now, I use this in this fashion (I'm using Django Framework).
In the views.py I make an array
options =["Car", "Motor Bikes", "Bikes", "Apparel"]
and in the templates I populate it this way
{% for option in options %}
{% ifequal edit_nw.category option %}
{{option}}
{% else %}
{{option}}
{% endifequal %}
{% endfor %}
All I want is to use this options to be a result of model like Category.all(), should have some default data loaded for the entire app. If necessary, Ill add categories from admin panel
Check out the docs. There is default attribute for property.
default
A default value for the
property. If the property value is
never given a value, or is given a
value of None, then the value is
considered to be the default value.

Resources