У меня была панель меню в symfony, которая загружалась на каждый сайт в моем проекте. Обычно я загружаю данные следующим образом:
/**
* @Route("", name = "main")
*
*
*/
public function main()
{
$category_rep = $_om->getRepository(Category::class);
$this->categories = $category_rep->findAll();
....
}
Это нормально, но я ищу лучшее решение для загрузки данных во весь контроллер или проект. Я нашел решение для автозагрузки данных:
@Entity("category", expr = "repository.find($id)")
public function index(Category $category)
но это может дать мне только один результат из объекта категории (в строке меню я хочу показать все категории в репозитории). Вторая идея заключалась в том, чтобы сделать конструктор в контроллере, который загружает эти данные следующим образом:
private $categories;
public function __construct(ObjectManager $_om)
{
$category_rep = $_om->getRepository(Category::class);
$this->categories = $category_rep->findAll();
}
или создайте службу, которая будет загружать эти данные и запускать эту службу в каждом методе. Я хочу спросить, какая из этих идей является лучшим («самым чистым») решением. Может быть, это другой лучший вариант??
Спасибо за помощь, Крис
У меня был файл base.html.twig, в котором у меня был основной шаблон с css и html, которые не меняются (одинаковое для каждого сайта в проекте, и у него не было метода контроллера), и я загружаю данные из других шаблонов блоком twig: {% body блока %}{% endblock %}. Хм, а идея сделать контроллер для базового шаблона и загружать туда эти данные... Я такой тупой :(
Код базы в ярлыке выглядит так: <div class = "main-cointainer" ><div class = "menubar"></div> <div class = "content">{% block content %}{% endblock %}</div> </div>
и я загружаю контент, используя '{% extends 'base.html.twig' %} {% block content %}{% endblock %}{% block content %}my content{% конечный блок %} '
Спасибо за примеры кода. И не корите себя так, с такими знаниями никто не рождается ;) И если мой первый комментарий прозвучал немного снисходительно - извините.
Простым решением может быть отдельное действие контроллера для получения категорий для меню, например:
class MenuController extends AbstractController
{
public function displayMainMenu()
{
$categories = $this->getDoctrine()->getRepository(Category::class)->findAll();
return $this->render('menu/main.html.twig', [
'categories' => $categories,
]);
}
}
который вернет частичный шаблон только с HTML-кодом меню, примерно так:
# menu/main.html.twig
{% for category in categories %}
<div>
<a href = "{{ path('/url/to/view/category/with/id', { id: category.id }) }}">
{{ category.name }}
</a>
</div>
{% endfor %}
Теперь вам нужно только включить этот отрендеренный шаблон в свой base.html.twig
от встраивание контроллера:
<div class = "menubar">
{{ render(controller('App\\Controller\\MenuController\\displayMainMenu')) }}
</div>
Для более сложных меню вы можете рассмотреть возможность использования специального пакета, например KnpMenuBundle.
Большое спасибо... Я не думал сделать это таким образом
Другим, также простым, но гораздо более элегантным (имхо) было бы создание пользовательская функция Twig, например:
class MenuExtension extends AbstractExtension
{
private $categories;
public function __construct(CategoryRepository $categories)
{
$this->categories = $categories;
}
public function getFunctions()
{
return [
new TwigFunction(
'main_menu',
[$this, 'mainMenu'],
['needs_environment' => true]
),
];
}
public function mainMenu(\Twig_Environment $environment)
{
$categories = $this->categories->findAll();
return $environment->render('menu/main.html.twig', [
'categories' => $categories,
]);
}
}
Конечно, вам также нужен шаблон для самого меню, как в предыдущем ответе:
# menu/main.html.twig
{% for category in categories %}
<div>
<a href = "{{ path('/url/to/view/category/with/id', { id: category.id }) }}">
{{ category.name }}
</a>
</div>
{% endfor %}
Теперь вы можете использовать пользовательскую функцию в своем base.html.twig
:
<div class = "menubar">
{{ main_menu() }}
</div>
Если вы хотите показать категории в строке меню, зачем вам все категории в
whole controller or project
? Разве недостаточно иметь его в действии контроллера, которое создает меню? Кстати, как вы строите свое меню? Можете ли вы вставить код для этого?