I am using the KNP Paginator bundle for pagination. Does anyone know how to append parameters to the generated url?
Here is my set up:
{{ knp_pagination_sortable(supplierProducts, 'Product Sku', 'p.name') }}
I want to add §ion=supplier to the end of the URL, I just have no clue how to do it. I looked through the docs but did not find any info.
Please help if you can.
Thanks.
According to the KnpPaginator documentation, you can append query parameters as follows:
$paginator = $this->get('knp_paginator');
...
$pagination->setParam('section', 'supplier');
You could extend the kn_pagination_sortable template. When you run "knp_pagination_sortable" behind the scenes, it will basically generate an HTML according to your specifications. However, you can extend that. Instead of using the bundle's generated HTML for that element, you can write your own template for that pagination_sortable. This is a snippet from the project I'm working on. This is at my pagination_sortable.html.twig:
<a id="table_sorteable_{{ options['title']|lower }}" {% for attr, value in options %} {{ attr }}="{{ value }}"{% endfor %}>
{{ title }}
<b class="caret {{ options['class'] }}"></b>
</a>
Get it? You can have a template like that and change it according to your needs.
You can find more information on the link below.
Overriding default pagination template
As of 2020, and KnpPaginatorBundle v5.3, the solution proposed by #likeitlikeit doesn't work because the setParam method doesn't exist any more.
But you can append parameters to the sort and pagination links directly in the knp helpers in twig:
{# 4th parameter for sortable helper #}
{{ knp_pagination_sortable(results, column.title, column.alias, {}, params) }}
{# 3rd parameter for pagination helper #}
{{ knp_pagination_render(results, '', params) }}
For example, if you want to include the query parameters in the sort and pagination links, you can do:
{# Sort - pass all query parameters except sort column and direction #}
{% set params=app.request.query.all | filter((v, k) => (k != 'direction' and k != 'sort'))%}
{% for column in ... %}
{{ knp_pagination_sortable(results, column.title, column.alias, {}, params) }}
{% endfor %}
{# Pagination #}
{{ knp_pagination_render(results, '', app.request.query.all) }}
To add parameters in the url, I proceeded like this:
in Front:
{{ knp_pagination_render(clients, ('annuaire/my_pagination.html.twig'), {"type": type ? type : '' ,"city": city ? city : ''}) }}
Related
For a project which uses symfony2 and the SonataAdminBundle, I am trying to figure out how to embed complete related entities in the show action.
To get more into detail, let's say I have a Article and a Comment. On the show view for the Article, I'd like to show each Comment with multiple properties as well as an EDIT on each and a CREATE to add another comment to that Article.
I was able to get it to get it to display a list of Comment entities which link to the Entity by using ->add('comments'), but that's not enough. I need to have the entity really embedded!
Is there a way to do this without coding it on our own? And if doing it manually is the only way, what's the best approach? Rewriting the template?
Simplest way is to specify a template for the collection:
$showMapper->add('comments', 'collection', [
'template' => 'YourBundle:SomePath:SubPath/show_comment_collection.html.twig',
]);
Look to SonataAdminBundle:CRUD:base_show_field.html.twig for a template to use as an example. And, in that template, you can loop over the value variable. For example:
{% block field %}
<ul>
{% for comment in value %}
<li><a href="{{ path('some_route', {'id': comment.id}) }}">
{{ comment.id }} - {{ comment.otherProperty}}</a>
</li>
{% else %}
<li>No comments</li>
{% endfor %}
</ul>
{% endblock %}
In my Twig template I have a FOR LOOP that creates a multiple number of forms like so:
{% for thing in things %}
{% set form_id = 'myform_' ~ thing.Id %}
{% set form_name = attribute(form, 'myform_' ~ thing.Id) %}
{{ form_widget(form_id) }}
{{ form_widget(form_name) }}
{% endfor %}
I would like this to generate the following:
{{ form_widget(myform_1) }}
{{ form_widget(myform_2) }}
.... and so on.
I left my 2 failed attempts in there, (form_id and form_name), to save anyone from suggesting those as possible solutions.
To summarize; I need to insert the dynamically created value (myform_1, myform_2) inside of {{ form_widget() }}
You can render dynamic fields form with dynamic name in Twig with special function of Twig :
{{ attribute(object, method) }}
{{ attribute(object, method, arguments) }}
{{ attribute(array, item) }}
With this function you can easily generate dynamic string name for your field dynamic into your form like this
{{ form_widget(attribute(form, 'myfielddynamicname' ~ var ~ ' lastchar')) }}
With this variable "var" (array or others type) you can render lot of dynamic form name like :
myfielddynamicnamefoolastchar
myfielddynamicnamebarlastchar
myfielddynamicnameneolastchar
For more understanding you can read this official twig documentation function
here : attribute twig function documentation
The things myform_1 and myform_2 simply are variables with FormView object as you define in your controller.
I don't know if Twig allows on dynamic variables call, although you can collect these form objects in array in controller before passing to view. After this step, you can just iterate thought this array It will manage the problem you are facing with.
Don't create a loop in your Twig: the layout should only render a single form. Then you can build the forms in your controller and render each one of them.
See this documentation on the Symfony book on how to get the result of a rendered template. You can concatenate the single render results and return a response with the full content.
In phalcon templating engine volt (which is similar to twig) you can fetch all records by :
{% for product in products %}
Name: {{ product.name }}
Description: {{ product.description }}
price: {{ product.price}}
{% endfor %}
So, in my scenario, I'm building a crud template which will be used for different kind of models. What I wanted to achieve in this template is that every columns in this view are not hard-coded. So I store the columns I wanted to show into an array (defined in the controller, passed to the view) :
$cols = ['name','description','price']
In the view, to make it display all columns :
{% for product in products %}
{% for col in cols %}
{{ col }}: {{ product.col }}
{% endfor %}
{% endfor %}
Obviously, this will result in error, because there is no "col" in product.
Is there any solution or alternative for this ?
While frustrated tinkering with volt extension, I found a simpler solution :
Convert the model object into array. In the controller : $products->toArray()
Simply, in the view, to display specific value of specific key from an array : {{ product[key] }}
Problem solved, though because it is now not in form of object, I can't access object property using dot like {{ product.some_field }}, instead {{ product['some_field'] }}.
You should use the readAttribute() function:
http://forum.phalconphp.com/discussion/1231/volt-access-to-object-property-using-variable
{{ product.readAttribute(col) }}
Setup:
Twig 1.13.1
PHP 5.4.3
Problem:
I have 10,000 articles in my DB. I need a way to only allow X amount of stories to display on the page. I know I can limit the number in the controller before i call the template but that number will be different depending on the template that is used. I will have one controller to handles all the articles. I need a way to pass the number from the template to the controller to limit the array. I don't want to pull down all 10,000 articles then use twig "slice" filter/func.
I know in django you can use the below. That will only load the top 3 stories.
{% get_latest_stories 3 sports as story_list %}
{% for story in story_list %}
{{ story.title }}
{% endfor %}
Here is my current files.
Controller
<?php
$stories = news_stories::getStories("sports",5); //getStories(section,limit);
?>
<?=$twig->render("storyList.html", array('stories' => $stories))?>
View/Template
{% for story in story_list %}
{{ story.title }}
{% endfor %}
Summary
I would like a way to pass a number from the template to the controller so that i can limit the about of rows returned from the DB
Logically speaking, it would be impossible for the view to pass something to controller since the view is being processed at the end of the stack, after everything else.
You can however, pass a function into the view. You would want to create some sort of getViewStories function that you can access from your twig template. Since you have this already in your controller:
<?php
$stories = news_stories::getStories("sports",5); //getStories(section,limit);
?>
<?=$twig->render("storyList.html", array('stories' => $stories))?>
All you would need to do is change it around a bit, like this:
<?php
$function = new Twig_SimpleFunction('getViewStories', function (section, limit) {
return news_stories::getStories(section,limit);
});
$twig->addFunction($function);
?>
<?=$twig->render("storyList.html")?>
Now, from inside your template, you can call this function, like so:
{% set story_list = getViewStories('sports',5) %}
{% for story in story_list %}
{{ story.title }}
{% endfor %}
And change the getViewStories parameters around in each template.
And while you can use the slice filter, I would recommend against it in your case, as it makes for unnecessarily long database calls. This is the most optimized method (that I'm aware of).
You want to use the slice filter I think this should work for you
http://twig.sensiolabs.org/doc/filters/slice.html
{% for story in story_list|slice(1,5) %}
{{ story.title }}
{% endfor %}
should only return the elements 1 - > 5 of the loop then break loop. You can also do it like this
{% for story in story_list|[start:5] %}
{{ story.title }}
{% endfor %}
Disclaimer: I've never actually used twig though this was just a quick browse through its docs
You can embedded controllers ( or render other urls ) from inside a twig template. This means you could have a main layout template for your site, and keep your storyList.html template very plain - just to iterate over the stories and any markup they might need.
In your main layout you would render the action for the news stories:
<div id="stories">
{% render url('...') with { section: 'sports', limit: 5}, {'standalone': 'js'} %}
</div>
This way requires hindclude.js included on your page. Check these docs. If you are also using symfony ( you mention MVC but not the framework ) - even better. Scroll up a bit and look at Embedded controllers.
Otherwise, I believe this way essentially uses ajax.
I'm in a Twig template, and I have a "form" variable that represents a Doctrine2 Entity Form.
This Entity has properties that are mapped into the form, but the Entity has also some methods that I would like to access from my Twig template.
I would love to do something like this:
{{ form.myMethod }}
or maybe something like this:
{{ form.getEntity.myMethod }}
but unfortunately it doesn't work.
How could I achieve what I need?
To access your entity from your FormView in a twig template you can use the following code
{{ form.get('value') }}
Where form is your FormView object. This will return your entity and from there you can call any methods on it. If you embed a collection of entities or a single entity in your form you can access it the same way
{{ form.someembedform.get('value') }}
or
{% for obj in form.mycollection %}
{{ obj.get('value').someMethod }}
{% endif %}
An even more convenient syntax to get the underlying entity instead of:
{{ form.get('value') }}
is this:
{{ form.vars.value }}
Then you can call any entity method like this:
{{ form.vars.value.someMethod }}
See also the Form chapter in the Symfony documentation.
Just in order to update the subject:
form.get('value')
is deprecated since symfony 2.1. Copy from Symfony\Component\Form\FormView :
/*
* #deprecated Deprecated since version 2.1, to be removed in 2.3. Access
* the public property {#link vars} instead.
*/
public function get($name, $default = null) ....
so, I guess
form.vars.value.youMethod()
should be the way to go. It has worked form me.
... and there it goes my first post here. hope it helps!
Lost few hours trying to figure out what's going on and why
{{ form.vars.value }}
is NULL.
If you have form.element (not the form object itself) object, for example if you are overriding a form_row template that has passed the form.row object, you can get the Entity like this:
{{ form.getParent().vars.value.MyEntityMethod }}
hope that helps someone!
EDIT: Year and so later - another useful tip:
{% block sonata_type_collection_widget %}
{% for child in form %}
{{ child.vars.form.vars.value.name }}
{% endfor %}
{% endblock %}
object methods should work in twig, I know I used them in some project.
try to use ()
like {{ form.myMethod() }}
It seems that at some point the value is actually null. So you can use
{{ (form.vars.value != null) ? form.vars.value.yourEntityMethod():'' }}
tested in SF v3.0.6.
None of the above worked for me in version 2.6.7. I used customised form widgets to achieve this:
{# src/AppBundle/Resources/views/Form/fields.html.twig #}
{% extends 'form_div_layout.html.twig' %}
{%- block entity_widget -%}
<div {{ block('widget_container_attributes') }}>
{%- for n, child in form %}
{{- form_widget(child, {
'entity': form.vars.choices[n].data
}) -}}
{{- form_label(child) -}}
{% endfor -%}
</div>
{%- endblock %-}
{%- block radio_widget -%}
{# You now have access to entity #}
{%- endblock %-}
use {{ form.getData.myMethod }}.