prodigious /( sonata-menu-bundle
此组件提供通过sonata admin bundle(兼容sonata page bundle)进行菜单管理的功能。
3.0.7
2021-03-22 23:48 UTC
Requires
- php: >=7.1.3
- doctrine/doctrine-bundle: ^1.8 || ^2.0
- sonata-project/admin-bundle: ^3.63
- sonata-project/doctrine-orm-admin-bundle: ^3.10
- symfony/config: ^4.3
- symfony/framework-bundle: ^4.3
README
此组件提供通过sonata admin bundle(兼容sonata page bundle)进行菜单管理的功能。
兼容性
- 对于Symfony 2,请安装2.x版本
- 对于Symfony 3和Symfony 4,请安装3.x版本
先决条件
- SonataAdminBundle
- SonataPageBundle(可选)
屏幕截图
安装
composer require prodigious/sonata-menu-bundle
配置
// Symfony 2
// app/AppKernel.php
new Prodigious\Sonata\MenuBundle\ProdigiousSonataMenuBundle(),
php app/console cache:clear
php app/console doctrine:schema:update --force
php app/console assets:install
// Symfony 3
// app/AppKernel.php
new Prodigious\Sonata\MenuBundle\ProdigiousSonataMenuBundle(),
php bin/console cache:clear
php bin/console doctrine:schema:update --force
php bin/console assets:install
// Symfony 4
// config/bundles.php
Prodigious\Sonata\MenuBundle\ProdigiousSonataMenuBundle::class => ['all' => true],
php bin/console cache:clear
php bin/console doctrine:migration:diff
php bin/console doctrine:migration:migrate
php bin/console assets:install
sonata_admin.yml
将菜单添加到您的sonata admin菜单列表中。对于symfony 4,您也可以将其留空,菜单将自动添加
sonata_admin:
dashboard:
groups:
// Optional for symfony 4
sonata.admin.group.menu_builder:
label: config.label_menu
label_catalogue: ProdigiousSonataMenuBundle
icon: '<i class="fa fa-magic"></i>'
items:
- prodigious_sonata_menu.admin.menu
// Sonata page menu
# sonata.admin.group.site_builder:
# label: site
# label_catalogue: SonataPageBundle
# icon: '<i class="fa fa-puzzle-piece"></i>'
# items:
# - sonata.page.admin.site
# - sonata.page.admin.page
高级配置(Symfony 3 / Syfmony 4)
创建自定义实体
编辑配置
- prodigious_sonata_menu.yaml
prodigious_sonata_menu:
entities:
menu: AppBundle\Entity\Menu
menu_item: AppBundle\Entity\MenuItem
然后创建相关实体菜单和菜单项。您可以添加额外的字段
- 菜单
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Prodigious\Sonata\MenuBundle\Model\Menu as BaseMenu;
/**
* Class Menu
*
* @ORM\Table(name="sonata_menu")
* @ORM\Entity(repositoryClass="AppBundle\Repository\Menu\MenuRepository")
*/
class Menu extends BaseMenu
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* Class constructor
*
*/
public function __construct()
{
parent::__construct();
}
public function getId(): ?int
{
return $this->id;
}
}
- 菜单项
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Prodigious\Sonata\MenuBundle\Model\MenuItem as BaseMenuItem;
/**
* Class MenuItem
*
* @ORM\Table(name="sonata_menu_item")
* @ORM\Entity(repositoryClass="AppBundle\Repository\MenuItemRepository")
*/
class MenuItem extends BaseMenuItem
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
*
* @ORM\Column(type="string", nullable=true)
*/
protected $icon;
/**
* Class constructor
*
*/
public function __construct()
{
parent::__construct();
}
public function getId(): ?int
{
return $this->id;
}
/**
* @return string
*/
public function getIcon()
{
return $this->icon;
}
/**
* @param string $icon
* @return $this
*/
public function setIcon($icon)
{
$this->icon = $icon;
return $this;
}
}
清除缓存并更新数据库
// Symfony 3
php bin/console cache:clear
php bin/console doctrine:schema:update --force
// Symfony 4
php bin/console cache:clear
php bin/console doctrine:migration:diff
php bin/console doctrine:migration:migrate
请记住通过扩展原始类来更新admin类
编辑配置
- prodigious_sonata_menu.yaml
prodigious_sonata_menu:
entities:
menu: AppBundle\Entity\Menu
menu_item: AppBundle\Entity\MenuItem
admins:
menu: AppBundle\Admin\MyMenuAdmin
menu_item: AppBundle\Admin\MyMenuItemAdmin
并创建您的admin类
namespace AppBundle\Admin;
use Prodigious\Sonata\MenuBundle\Admin\MenuAdmin as BaseAdmin;
use Sonata\AdminBundle\Form\FormMapper;
class MyMenuAdmin extends BaseAdmin
{
/**
* {@inheritdoc}
*/
protected function configureFormFields(FormMapper $formMapper)
{
parent::configureFormFields($formMapper);
}
}
namespace AppBundle\Admin;
use Prodigious\Sonata\MenuBundle\Admin\MenuItemAdmin as BaseAdmin;
use Sonata\AdminBundle\Form\FormMapper;
use Symfony\Component\Form\Extension\Core\Type\TextType;
class MyMenuItemAdmin extends BaseAdmin
{
/**
* {@inheritdoc}
*/
protected function configureFormFields(FormMapper $formMapper)
{
parent::configureFormFields($formMapper);
$formMapper
->with('config.label_menu_item')
->add('icon', TextType::class, [
'label' => 'config.label_icon'
]
)
->end()
->end();
}
}
开始使用菜单管理器
控制器
$mm = $this->container->get('prodigious_sonata_menu.manager');
$menuId = 1; // Example
$menu = $mm->load($menuId);
// $status = true (Get enabled menu items)
// $status = false (Get disabled menu items)
// getMenuItems($menu, $root = MenuManager::ITEM_CHILD, $status = MenuManager::STATUS_ALL)
$menuItems = $mm->getMenuItems($menu, true);
return $this->render('menu/menu.html.twig', [
'$menuItems' => $menuItems,
]);
然后,就是您的展示时间。对于前端,您可以按需输出结果。
例如
- menu.html.twig
{% if menuItems is not null and menuItems|length > 0 %}
{% import 'AppBundle:Menu:menu_tree_macro.html.twig' as tree %}
{% set currentPath = app.request.requestUri %}
{{ tree.menu(menuItems, currentPath) }}
{% endif %}
- menu_tree_macro.html.twig
{% macro menu(items, currentPath) %}
{% import _self as self %}
<ul>
{% for menuItem in items %}
{% set url = menuItem.url %}
{% set attributes = "menu-item" %}
{% if menuItem.classAttribute %}
{% set attributes = attributes ~ ' ' ~ menuItem.classAttribute %}
{% endif %}
{% if menuItem.hasChild() %}
{% set attributes = attributes ~ ' has-child' %}
{% for childItem in menuItem.children %}
{% set childUrl = childItem.url %}
{% if childUrl == currentPath %}
{% set attributes = attributes ~ ' current-parent' %}
{% endif %}
{% endfor %}
{% endif %}
<li class="{{ attributes }}" role="menu-item">
{% if menuItem.hasChild() %}
<a href="{{ url }}" class="parent" {% if currentPath == url %} class="current"{% endif %}" {% if menuItem.target %} target="_blank"{% endif %}>{{ menuItem.name }}</a>
{{ self.menu(menuItem.children, currentPath) }}
{% else %}
<a href="{{ url }}" {% if currentPath == url %} class="current"{% endif %}" {% if menuItem.target %} target="_blank"{% endif %}>{{ menuItem.name }}</a>
{% endif %}
</li>
{% endfor %}
</ul>
{% endmacro %}
变更日志
3.0.0
- 添加Symfony 4支持
2.0.4
- 修复Symfony 3兼容性错误
- 移除自定义路由配置
2.0.5
- 修复菜单项Admin错误
2.0.6
- 向菜单Admin添加列
附加信息
作者:Nan GUO
公司:Prodigious

