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 :)
I am currently writing a website via Clojure code that runs on a Luminus based framework.
I have a database that stores users and uploaded files (and routes which allow me to do both).
The routes call SQL functions that I have written, altering the database.
I currently am printing out the list of files like such (in HTML):
<ul class="users">
{% for item in users %}
<li>
<p>{{item.file_name}}</p>
</br> </br>
</li>
{% endfor %}
</ul>
I want to edit it to have a link to each file as well.
For example, under the <p>{{item.file_name}</p> line I could write something like:
Home
This generates me a link to "/home" for every file_name in the database.
Instead, I would like to create a link to each file_name in the database.
For example, if the first listed item was "test.txt" I would want a link to "/test.txt" and so on, through the whole list.
Is this possible to do? Thank you in advance.
You just need to change your template to create the link HTML that is specific to an item. Something like this:
<ul class="users">
{% for item in users %}
<li>
<p>{{item.file_name}}</p>
</br> </br>
</li>
{% endfor %}
</ul>
It's hard to be any more specific than that without more information. You just have to determine how to create a URL for an item. In the code above I used "/{{item.file_name}}" based on your examples, but if the URL is more complicated than that, you could add it as a separate key to the item and do something like "{{item.url}}".
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.
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")}}
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).