У меня есть вопрос по моему проекту Symfony.
У меня есть этот код, который показывает количество строк в данной таблице базы данных:
// BudgetRepository
public function countBudgets()
{
$qb = $this->createQueryBuilder('budget');
return $qb
->select('count(budget.id)')
->getQuery()
->getSingleScalarResult();
}
// BudgetController
public function all(EntityManagerInterface $entityManager)
{
$repository = $entityManager->getRepository(Budget::class);
$count = $repository->countBudgets();
return $this->render("budget/budget.html.twig", ['numberOfBudgets' => $count]);
}
Это работает, но работает только внутри budget/budget.html.twig
by usung {{ numberOfBudgets }}
.
Как я могу заставить его работать на каждой странице (в частности, я хочу, чтобы он был помещен в мой файл с именем _sidebar.html.twig
? Прямо сейчас, если я помещу {{ numberOfBudgets }}
на _sidebar.html.twig
, я получаю это сообщение об ошибке «Переменная «numberOfBudgets» не существует».
Как мне переписать код?
@yivi Отображается в начале страницы base.html.twig (сразу после открывающего тега body) с помощью {{ include('_sidebar.html.twig') }}
Тогда что-то не так. Если шаблон был включен именно так, как вы говорите, переменная тоже было бы видно. Из документов: «Включенные шаблоны имеют доступ к переменным активного контекста». (twig.symfony.com/doc/3.x/functions/include.html)
Вам нужно будет включить минимальные примеры веток, которые надежно воспроизводят проблему.
@yivi Я думаю, вы неправильно поняли - или, что более вероятно, я не совсем ясно выразился. Он работает как с базовым файлом, так и с файлом боковой панели, но если я помещаю {{ numberOfBudgets }}
на боковую панель и открываю другой URL-адрес, возникает ошибка «Переменная «numberOfBudgets». Возможно, потому, что для переменной задана только страница/URL. Должен ли я тогда использовать глобальные переменные ветки?
Здесь у вас есть несколько вариантов. Как внедрить глобальные переменные во все шаблоны?
Я бы выбрал переменную сеанса, взгляните на Симфоническая сессия, чтобы получить доступ к вашей переменной count, но обязательно обновите эту переменную в сеансе, если произойдет какое-либо изменение.
public function index(EntityManagerInterface $em)
{
$count = $em->getRepository(Budget::class)->countBudgets();
$session = $this->requestStack->getSession();
$session->set('budgetCount', $count);
}
Чтобы получить доступ к переменной сеанса в шаблоне ветки, взгляните на Глобальная переменная приложения.
<p>Total budgets: {{ app;session.budgetCount }}</p>
Не downvoter, но я боюсь, что это неправильно. Вопрос не в том, чтобы значение сохранялось между запросами (с чем мог бы помочь сеанс), а просто в видимости переменных во включенных шаблонах.
Ну, я думал, что сохранение его var в сеансе позволяло ему получить к нему доступ из любого шаблона ветки, что делает его видимым для любого шаблона, нет? (поправьте меня, если я ошибаюсь, это только для понимания!)
Вы должны использовать глобальную переменную ветки. Переместите Ваш код в сервис:
class BudgetService
{
public function all(EntityManagerInterface $entityManager)
{
$repository = $entityManager->getRepository(Budget::class);
return $repository->countBudgets();
}
}
Затем зарегистрируйте глобальную переменную в конфигурации ветки (config/packages/twig.yaml):
twig:
globals:
budget: '@App\Services\BudgetService'
Затем вы можете использовать его в любом шаблоне, например:
Total: {{ budget.all }}
Не downvoter, но я боюсь, что это не очень актуально здесь. Вопрос не в «глобальных переменных ветки», а просто в проблеме видимости среди включенных шаблонов (что-то, что вообще не требует создания глобальной переменной)
И если вопрос был о создании глобальных переменных ветки, есть масса дубликатов на выбор :)
Иногда люди не знают, что существуют глобальные переменные ветки :)
@BogdanKuštan Привет, Богдан! Спасибо за пример. Это работает - почти - я получаю следующую ошибку, и как ее решить? Too few arguments to function App\Service\BudgetService::all(), 0 passed in \budget\vendor\twig\twig\src\Extension\CoreExtension.php on line 1599 and exactly 1 expected
- Я понимаю ошибку, но как ее исправить? Как я могу пропустить аргумент во всех ()?
@FreePalestine Я бы использовал внедрение конструктора и внедрил EntityManager (или, что еще лучше, непосредственно BudgetRepository) в __construct(EntityManagerInterface $entityManager), а затем присвоил его некоторой частной переменной ($this->entityManager = $entityManager).
@BogdanKuštan Спасибо - я очень ценю помощь. Я исправил это, внедрив BudgetRepository напрямую :-)))
Какая связь между
budget.html.twig
и_sidebar.html.twig
? Когда и как вы рендерите эту боковую панель? Я бы предположил, что боковая панель не отображается независимо, верно?