I have written a Twig custom function (in a Twig custom extension). I notice the template does not read the function and keeps throwing me the "Method Exists" error.
Was wondering if you have faced this before. Any ideas ?
The custom extension file; $post and $list are both objects:
<?php
namespace App\Twig;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
class ShowContentExtension extends AbstractExtension
{
public function getFunctions()
{
return [
new TwigFunction('ShowList', [$this, 'ShowList']),
new TwigFunction('ShowPost', [$this, 'ShowPost'])
];
}
public function ShowList($list) {
foreach ($list->post as $post) {
$this->ShowPost($post);
}
}
public function ShowPost($post) {
return !((count(array_keys($post->documents))) < 2 && array_key_exists('header', $post->documents));
}
}
and this is where they are being called:
{% if ShowList(list) %}
<h2 >{{ title }}</h2>
<div>
<div>
{% for post in list %}
{% if post|length > 0 %}
{% include ./_links.html.twig' with { 'list': list} %}
{% endif %}
{% endfor %}
</div>
</div>
{% endif %}
and :
{% if ShowPost(post) %}
<div>
<div>
<a href="{{ post.link }}">
<span>{{ post.title }}</span>
</a>
</div>
</div>
{% endif %}
and this is the screenshot of the error :
error screenshot
Related
I created a global Action :
public function export(
Admin $user,
StructureRepository $structureRepository,
ExportCsvEntity $exportCsvEntity,
string $entityClass
): HttpFoundationResponse {
$zipcodes = $structureRepository->getZipcodesByStructureFromAdmin($user->getId());
$exportCsvEntity->export(
$zipcodes,
$entityClass
);
return $exportCsvEntity->download($entityClass);
}
public function exportButton(): Action
{
return Action::new('export', 'admin.crud.user.field.activities_tracking.button.export')
->linkToCrudAction('export')
->displayAsLink()
->setCssClass('btn btn-primary')
->createAsGlobalAction()
;
}
Then in my Crud Controller I call it :
if ($this->getUser() instanceof Admin) {
$export = $this->exportAction->exportButton();
$actions->add(Crud::PAGE_INDEX, $export);
}
In the doc its written => Global actions are displayed above the listed entries.
But in my case the button is underneath the table
Have a look here
My template is extending '#!EasyAdmin/crud/index.html.twig'then I override the global_actions block :
{% block global_actions %}
{{ parent() }}
{% endblock global_actions %}
Now my button is above the table but also underneath :
Have a look here
What do I do wrong ?
You are correct when trying to do this by overriding the index template.
An easy way to do this considering how the template is organized is to modify the global_actions block by filtering actions you do not want to show above the list. For example by using a css class to not show a global action above the list.
{% block global_actions %}
<div class="global-actions">
{% for action in global_actions|filter(a => 'under-list' not in a.cssClass) %}
{{ include(action.templatePath, { action: action }, with_context = false) }}
{% endfor %}
</div>
{% endblock global_actions %}
And in your crud controller:
Action::new('customAction', $label, $icon)
->addCssClass('under-list')
->createAsGlobalAction()
->linkToCrudAction('customAction');
And you need to add your new list of actions under your list by overriding the main block.
{% block main %}
{{ parent() }}
{% block under_list_global_actions %}
<div class="under-list-global-actions">
{% for action in global_actions|filter(a => 'under-list' in a.cssClass) %}
{{ include(action.templatePath, { action: action }, with_context = false) }}
{% endfor %}
</div>
{% endblock under_list_global_actions %}
{% endblock main %}
And you should get your custom global action (with the css class under-list) under your list.
This is my view:
<div class="CSlider">
<div class="CProducts" >
<table>
<tr>
{% for count in 1..result|length %}
<td>
{% block tile %}
{% include 'tile.twig' %}
{% endblock %}
<h1>
{{ result[ count - 1 ].id }}
</h1>
</td>
{% if count is divisible by (6) %}
</tr>
<tr>
{% endif %}
{% endfor %}
</table>
</div>
</div>
And this is my controller:
class COlxMyAdsController extends COlxDatabaseHandler {
protected $view;
public function __construct($container){
parent::__construct($container);
$this->view=$container->view;
}
public function fetchMyLiveAdIdsByUserId( Request $request, Response $response ) {
$args=$request->getParams();
$args=$args['id'];
$results = $this->m_objOlxUserDetails->fetchMyLiveAdIdsByUserId($args);
return $this->view->render($response,'profile.twig',['result' => $results]);
}
}
I want to call a function of the controller from the view. How can I do this using Twig?
Here we can Use Exit_Tags
Through which we can assign a URL to that exit_tag to call this function
In my app I'm trying to display form help block using tips from official Symfony2 cookbook. Here is my code:
{% extends 'form_div_layout.html.twig' %}
{% block form_widget_simple %}
{{ block('base_form_widget_simple') }}
{{ dump(help) }}
{% if help is defined %}
<span class="help">{{ help }}</span>
{% endif %}
{% endblock %}
And using this theme:
{{ form_row(form.pageTitle, {'help': 'some help'}) }}
With this I'm getting error Variable "help" does not exist. Any ideas what have I missed?
P.S. I use Symfony 2.7.1.
Create a Form type extension extending the form type:
namespace Acme\AppBundle\Form\Extension;
use ...
class FieldTypeHelpExtension extends AbstractTypeExtension
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->setAttribute('help', $options['help']);
}
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['help'] = $options['help'];
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'help' => null
]);
}
public function getExtendedType()
{
return 'form';
}
}
Define the extension as a service:
acme_app.form.extension.field_type_help:
class: Acme\AppBundle\Form\Extension\FieldTypeHelpExtension
tags:
- { name: form.type_extension, alias: form }
Create a template extending form div layout:
{% extends 'form_div_layout.html.twig' %}
{% block field_help %}
{% if help is defined and help %}
<p class="help-block">{{ help|trans }}</p>
{% endif %}
{% endblock field_help %}
{% block integer_widget %}
{{ parent() }}
{{ block('field_help') }}
{% endblock integer_widget %}
{% block form_widget %}
{{ parent() }}
{{ block('field_help') }}
{% endblock form_widget %}
Configure this template as form theme on config.yml
twig:
form_themes:
- 'Form/fields.html.twig'
Now you can use it when render the a field on a template:
{{ form_widget(form.name, { 'help': 'this is help' }) }}
Or in your Form type:
$form->add('name', 'text', ['help' => 'this is help']);
I'm integrating Sonata Admin Bundle into my Symfony 2.6 application by following Symfony 2 jobeet tutorial. Everything is fine except the Show action. I have an entiry "Job" and so I have src/Ibw/JobeetBundle/Admin/JobAdmin.php which have a function configurShowField(ShowMapper $showMapper) like below
<?php
namespace Ibw\JobeetBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Validator\ErrorElement;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Ibw\JobeetBundle\Entity\Job;
class JobAdmin extends Admin
{
// ....
protected function configureShowField(ShowMapper $showMapper)
{
$showMapper
->add('category')
->add('type')
->add('company')
->add('webPath', 'string', array('template' => 'IbwJobeetBundle:JobAdmin:list_image.html.twig'))
->add('url')
->add('position')
->add('location')
->add('description')
->add('how_to_apply')
->add('is_public')
->add('is_activated')
->add('token')
->add('email')
->add('expires_at')
;
}
// ....
}
When I click the Show button and go to the view page (admin/ibw/jobeet/job/xxx/show), it shows none of the fields. The original template processed is /vendor/sonata-project/admin-bundle/Resources/views/CRUD/base_show.html.twig:
{% extends base_template %}
{% block actions %}
<li>{% include 'SonataAdminBundle:Button:edit_button.html.twig' %}</li>
<li>{% include 'SonataAdminBundle:Button:history_button.html.twig' %}</li>
<li>{% include 'SonataAdminBundle:Button:list_button.html.twig' %}</li>
<li>{% include 'SonataAdminBundle:Button:create_button.html.twig' %}</li>
{% endblock %}
{% block tab_menu %}{{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active', 'template': admin_pool.getTemplate('tab_menu_template')}, 'twig') }}{% endblock %}
{% block show %}
<div class="sonata-ba-view">
***
{{ sonata_block_render_event('sonata.admin.show.top', { 'admin': admin, 'object': object }) }}
{% for name, view_group in admin.showgroups %}
<table class="table table-bordered">
{% if name %}
<thead>
{% block show_title %}
<tr class="sonata-ba-view-title">
<th colspan="2">
{{ admin.trans(name) }}
</th>
</tr>
{% endblock %}
</thead>
{% endif %}
<tbody>
{% for field_name in view_group.fields %}
{% block show_field %}
<tr class="sonata-ba-view-container">
{% if elements[field_name] is defined %}
{{ elements[field_name]|render_view_element(object) }}
{% endif %}
</tr>
{% endblock %}
{% endfor %}
</tbody>
</table>
{% endfor %}
{{ sonata_block_render_event('sonata.admin.show.bottom', { 'admin': admin, 'object': object }) }}
</div>
{% endblock %}
The inner content of <div class="sonata-ba-view"></div> is not shown except three asterisks I printed. Is there any configuration I'm missing?
You're missing a s in your function's name.
it's
configureShowFields(FormMapper $formMapper)
not
configureShowField(FormMapper $formMapper)
Try to add call in your admin.yml
ibw_jobbeet.admin.jobadmin:
class: Ibw\JobeetBundle\Admin\JobAdmin
...
calls:
- [ setTemplate, ['show', path_to_your_view.html.twig]]
Read more about templates in SonataAdmin
I am using Symfony2.3 for my project and for pagination I am using KNP paginator Bundle.
I want to know that How I can implement rel=prev and rel=next in our page ?
My Controller :
<?php
namespace XXX\ABCBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Session\Session;
use Doctrine\ORM\EntityManager;
/**
* author Siddharth Singh (siddharth.find#gmail.com)
*/
class ArcController extends Controller {
/**
* #Route("/arch", name="_arch")
* #Template()
*/
public function indexAction() {
$em = $this->getDoctrine()->getEntityManager();
$AArtEntity = $em->getRepository('XXXABCBundle:Arc')->findAll(array('updated'=>'DESC'));
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$AArtEntity, $this->get('request')->query->get('page', 1)/* page number */, 10/* limit per page */
);
return array('article' => $pagination);
}
}
Twig File :-
{% extends 'XXXABCBundle::layout.html.twig' %}
{% block body %}
{% for artic in article %}
<div class="txt">
<p>{{artic.description|striptags|titletruncate(250)}}</p>
</div>
{% endfor %}
<div class="arcive_Paging">
<ul class="ul_paging">
<span class="acitve">{{ knp_pagination_render(article) }}</span>
</ul>
</div>
{% endblock %}
Thanks !
Accepted answer does not work because rel=prev and rel=next must be inside head tag.
I use this macros:
{% macro pagination_meta(pagination) %}
{% set total = pagination.totalItemCount %}
{% set items_per_age = pagination.itemNumberPerPage %}
{% set current = pagination.currentPageNumber %}
{% set last = (total / items_per_age) | round(0, 'ceil') %}
{% set page_parameter = pagination.paginatorOption('pageParameterName') %}
{% if current != 1 %}
<link rel="prev" href="{{ path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params') | merge({ (page_parameter): (current - 1) })) }}" />
{% endif %}
{% if current != last %}
<link rel="next" href="{{ path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params') | merge({ (page_parameter): (current + 1) })) }}" />
{% endif %}
{% endmacro %}
Inside a template usage looks like this:
{% import 'AppBundle::macros.html.twig' as macros %}
{% block head %}
{{ parent() }}
{{ macros.pagination_meta(entities) }}
{% endblock %}
You can do it by overriding default pagination template. Check Templates part of the official documentation:
https://github.com/KnpLabs/KnpPaginatorBundle/blob/master/Resources/doc/templates.md
for example:
Tell KnpPaginatorBundle to load your template for rendering pagination, add these lines of code to config.yml:
knp_paginator:
template:
pagination: YourBundle::pagination.html.twig
And copy default pagination template code to your template in src/YourBundle/Resources/views/pagination.html.twig. You can get the code here:
https://github.com/KnpLabs/KnpPaginatorBundle/blob/master/Resources/views/Pagination/sliding.html.twig