In PHP I can designate which element / property to use simply by passing a variable with the name of it, such as:
$array[$name]
$object -> $name
How to do this with Twig?
For instance, with an array row read from MySQL database whose primary key field can be id, ItemId, Serial, number, or anything, how can I pass in the column name of the primary key so Twig correctly displays the primary key of the row?
{{ row.id }}
{{ row.ItemId }}
{{ row.Serial }}
{{ row.number }}
But just something like:
{{ row.primary }}
Wherein primary is the name of the actual column name of the primary key, be it id, ItemId, or whatever.
Any way I can do this?
Seems rather simple, just use attribute().
Pass:
array(
'primaryKey' => 'id'
'row' => array(
'id' => 1,
'title' => 'some title'
)
)
In twig template:
{{ attribute(row, primaryKey) }}
Which would have the same effect as:
{{ row.id }}
Related
I'm trying to set the default value for a CKEditor html text input based on an existing object. The use case is for updating an existing row using flask-sqlalchemy so the user doesn't have to retype all of the existing rich text. As the code is written, the default value for form.description is blank even when object.description is not.
The relevant part of the form looks something like this:
<form method="POST">
{{ ckeditor.load() }}
{{ form.hidden_tag }}
{{ form.name.label }}
{{ form.name(class="form-control", value=object.name) }}
{{ form.description.label }}
{{ form.description(class="form-control", value=object.description) }}
{{ edit_loc_form.submit(class="btn btn-primary") }}
</form>
{{ ckeditor.config(name='description') }}
Thanks!
From the docs:
If you are using Flask-WTF/WTForms, it’s even more simple, just pass
the value to the form field’s data attribute:
#app.route('/edit')
def edit_post():
form = EditForm()
form.body.data = "default value" # default value entered here.
return render_template('edit.html', form=form)
I know twig can count elements of an array using {{ array|length}}, but is there a way to combine this feature with an if or where statement?
Something like {{ array|length|array.key is null }}, where it would count all the instances where key is null.
The filter filter should help you achieve this.
Something like
{% set array = [null, 42, null, null, 42] %}
{{ array | filter(item => item is null) | length }}
Outputs 3
And so if I understand your data structure correctly:
{% set array = [{key: null}, {key: 42}, {key: null}, {key: null}, {key:
42}] %}
{{ array | filter(item => item.key is null) | length }}
I have the following page structure in Grav:
# Title
## Subtitle
### Subsubtitle
The page structure is always the same and it has just those three items.
How can I retrieve each item (Title/Subtitle/Subsubtitle) separately in Twig template?
The twig template will then do things like:
<p> You typed {{ page.whatever_retrieves_the_title_# }} as title, then {{ page.whatever_retrieves_the_subtitle_## }} as subtitle and finally {{ page.whatever_retrieves_the_subsubtitle_### }} as subsubtitle</p>
What if instead of the above structure I have:
- Title
- Subtitle
- Subsubtitle
The objective is that the user adds just that structure of three items and the twig template use each item to display a more complex layout.
This is Markdown, right?
# Title
## Subtitle
### Subsubtitle
You can get the HTML version of the page's Markdown in Twig with {{ page.content }}, as described in Grav's documentation. So you should get something like this:
<h1>Title</h1>
<h2>Subtitle</h2>
<h3>Subsubtitle</h3>
You can use the split and raw filters to extract the contents of those tags. I'm also using the default filter so that there won't be an error if the extraction of the tag contents fails:
Title is:
{{ page.content|split('<h1>')[1]|default|raw|split('</h1>')[0] }}
Subtitle is:
{{ page.content|split('<h2>')[1]|default|raw|split('</h2>')[0] }}
Subsubtitle is:
{{ page.content|split('<h3>')[1]|default|raw|split('</h3>')[0] }}
Or because Grav seems to provide a regex_replace filter, you could also use it:
Title is:
{{ page.content|regex_replace('~.*<h1>(.*)</h1>.*~s', '$1') }}
Subtitle is:
{{ page.content|regex_replace('~.*<h2>(.*)</h2>.*~s', '$1') }}
Subsubtitle is:
{{ page.content|regex_replace('~.*<h3>(.*)</h3>.*~s', '$1') }}
If instead you have this:
- Title
- Subtitle
- Subsubtitle
You can again use the split, default and raw filters:
Title is:
{{ page.content|split('<li>')[1]|default|raw|split('</li>')[0] }}
Subtitle is:
{{ page.content|split('<li>')[2]|default|raw|split('</li>')[0] }}
Subsubtitle is:
{{ page.content|split('<li>')[3]|default|raw|split('</li>')[0] }}
Not very beautiful. :-) If the titles can contain HTML (e.g. ## Hello **world**! → <h2>Hello <strong>world</strong>!</h2>) or special characters, you probably need to append |raw to the already long magic spells.
Others provided good solution with markdown manipulation. However, you could use grav features and provide your own blueprints, and have your user fills some fields.
Let's say this is for a page that uses the template blog_article.html.twig, you can therefore create a file named blog_article.yaml inside user/themes/yourtheme/blueprints and fill it with the following blueprint:
title: Blog_Article
'#extends':
type: default
context: blueprints://pages
form:
fields:
tabs:
fields:
content:
fields:
header.mytitle:
type: text
label: My Label
header.mysubtitle:
type: text
label: Type Subtitle
header.mysubsubtitle
type: text
label: Type subsubtitle
Now, if you try to edit your page from admin, you will see three new fields added to the page, under the page medias.
You can then display these fields in your template with the following twig:
{{ page.header.mytitle }}
{{ page.header.mysubtitle }}
{{ page.header.mysubsubtitle }}
Hope it helps
In my symfony3 project, I have a form field with label "I accept the cgu" with a link on the 'cgu'.
How can I translate the label containing the link, as I must generate the link with {{path('')}} in twig ?
I tried something like that :
{{ form_row(form.valid, {'label' : 'annonces.form.valide_cgu_cgv' | trans ({'cgu_link' : {{ path('page_statique', {'page' : 'cgu'})}}, 'cgv_link' : {{ path('page_statique', {'page' : 'cgv'})}} }) |raw }) }}
but it does not work...
Any idea ?
Thanks all !
When you are under {{ }}, you're writting an expression, so you can't put nested {{ }}.
You can try with:
{{
form_row(form.valid, {
'label' : 'annonces.form.valide_cgu_cgv' | trans({
'cgu_link' : path('page_statique', {'page' : 'cgu'})
'cgv_link': path('page_statique', {'page' : 'cgv'})
})
})
}}
I have a series of templates which target the Twig variable {{ file }}, which currently outputs the file's src e.g. "/path/to/file.jpg".
I want to update the contents of file to an array so that it stores multiple properties e.g. {{ file.src }} {{ file.size }}.
If I make this change then all uses of {{ file }} will output Array.
Is it possible to set Twig so that it will instead target the first property of the array? In this case {{ file.src }}.
Many thanks!
You can't if your variable is a pure array, but you can do it with objects.
If you want your object to be usable like an array, you need to extend ArrayObject in your class.
You can implement the magic method __toString to make your object printable as a string (in your case, $this['src']).
Let's have an example.
1) Create the following class :
class File extends \ArrayObject
{
public function __toString()
{
if (isset($this['src']))
{
return $this['src'];
}
}
}
2) In a controller, initialize your object.
$file = new File();
$file['src'] = 'my_file.png';
$file['size'] = 42;
3) In your twig file, try it :
{{ file }}<br/>
{{ file.src }}<br/>
{{ file.size }}<br/>
4) Enjoy