symfony6 install KnpMenuBundle

210 Views Asked by At

I want to install KnpMenuBundle into an empty Symfony project (--webapp project).

I make steps from KnpMenuBundle documentation but it does not work.

configuration

  • symfony 6.1.7

  • KnpMenuBundle downloaded: 3.2

Here are my different files:

composer.json

{
    "type": "project",
    "license": "proprietary",
    "minimum-stability": "stable",
    "prefer-stable": true,
    "require": {
        "php": ">=8.1",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "doctrine/annotations": "^1.0",
        "doctrine/doctrine-bundle": "^2.7",
        "doctrine/doctrine-migrations-bundle": "^3.2",
        "doctrine/orm": "^2.13",
        "knplabs/knp-menu-bundle": "^3.2",
        "phpdocumentor/reflection-docblock": "^5.3",
        "phpstan/phpdoc-parser": "^1.13",
        "sensio/framework-extra-bundle": "^6.1",
        "symfony/asset": "6.1.*",
        "symfony/console": "6.1.*",
        "symfony/doctrine-messenger": "6.1.*",
        "symfony/dotenv": "6.1.*",
        "symfony/expression-language": "6.1.*",
        "symfony/flex": "^2",
        "symfony/form": "6.1.*",
        "symfony/framework-bundle": "6.1.*",
        "symfony/http-client": "6.1.*",
        "symfony/intl": "6.1.*",
        "symfony/mailer": "6.1.*",
        "symfony/mime": "6.1.*",
        "symfony/monolog-bundle": "^3.0",
        "symfony/notifier": "6.1.*",
        "symfony/process": "6.1.*",
        "symfony/property-access": "6.1.*",
        "symfony/property-info": "6.1.*",
        "symfony/proxy-manager-bridge": "6.1.*",
        "symfony/runtime": "6.1.*",
        "symfony/security-bundle": "6.1.*",
        "symfony/serializer": "6.1.*",
        "symfony/string": "6.1.*",
        "symfony/translation": "6.1.*",
        "symfony/twig-bundle": "6.1.*",
        "symfony/validator": "6.1.*",
        "symfony/web-link": "6.1.*",
        "symfony/yaml": "6.1.*",
        "twig/extra-bundle": "^2.12|^3.0",
        "twig/twig": "^2.12|^3.0"
    },
    "config": {
        "allow-plugins": {
            "composer/package-versions-deprecated": true,
            "symfony/flex": true,
            "symfony/runtime": true
        },
        "optimize-autoloader": true,
        "preferred-install": {
            "*": "dist"
        },
        "sort-packages": true
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "App\\Tests\\": "tests/"
        }
    },
    "replace": {
        "symfony/polyfill-ctype": "*",
        "symfony/polyfill-iconv": "*",
        "symfony/polyfill-php72": "*",
        "symfony/polyfill-php73": "*",
        "symfony/polyfill-php74": "*",
        "symfony/polyfill-php80": "*",
        "symfony/polyfill-php81": "*"
    },
    "scripts": {
        "auto-scripts": {
            "cache:clear": "symfony-cmd",
            "assets:install %PUBLIC_DIR%": "symfony-cmd"
        },
        "post-install-cmd": [
            "@auto-scripts"
        ],
        "post-update-cmd": [
            "@auto-scripts"
        ]
    },
    "conflict": {
        "symfony/symfony": "*"
    },
    "extra": {
        "symfony": {
            "allow-contrib": false,
            "require": "6.1.*"
        }
    },
    "require-dev": {
        "phpunit/phpunit": "^9.5",
        "symfony/browser-kit": "6.1.*",
        "symfony/css-selector": "6.1.*",
        "symfony/debug-bundle": "6.1.*",
        "symfony/maker-bundle": "^1.0",
        "symfony/phpunit-bridge": "^6.1",
        "symfony/stopwatch": "6.1.*",
        "symfony/web-profiler-bundle": "6.1.*"
    }
}

config.bundles.php

<?php

return [
    Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
    Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
    Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
    Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true],
    Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
    Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
    Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
    Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
    Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
    Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
    Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true],
    Knp\Bundle\MenuBundle\KnpMenuBundle::class => ['all' => true],
];

config/packages/knp_menu.yaml

# config/packages/knp_menu.yaml
knp_menu:
    # use "twig: false" to disable the Twig extension and the TwigRenderer
    twig:
        template: KnpMenuBundle::menu.html.twig
    #  if true, enables the helper for PHP templates
    templating: false
    # the renderer to use, list is also available by default
    default_renderer: twig

src/Menu/Builder.php

<?php

// src/Menu/Builder.php
namespace App\Menu;

use App\Entity\Blog;
use Knp\Menu\FactoryInterface;
use Knp\Menu\ItemInterface;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;

final class Builder implements ContainerAwareInterface
{
    use ContainerAwareTrait;

    public function mainMenu(FactoryInterface $factory, array $options): ItemInterface
    {
        $menu = $factory->createItem('root');

        $menu->addChild('Home', ['route' => 'homepage']);

        // access services from the container!
        $em = $this->container->get('doctrine')->getManager();
        // findMostRecent and Blog are just imaginary examples
        $blog = $em->getRepository(Blog::class)->findMostRecent();

        $menu->addChild('Latest Blog Post', [
            'route' => 'blog_show',
            'routeParameters' => ['id' => $blog->getId()]
        ]);

        // create another menu item
        $menu->addChild('About Me', ['route' => 'about']);
        // you can also add sub levels to your menus as follows
        $menu['About Me']->addChild('Edit profile', ['route' => 'edit_profile']);

        // ... add more children

        return $menu;
    }
}

src/Controller/IndexController.php

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class IndexController extends AbstractController
{
    #[Route('/', name: 'app_index')]
    public function index(): Response
    {
        return $this->render('index/index.html.twig', [
            'controller_name' => 'IndexController',
        ]);
    }
}

templates/index/index.html.twig

{% extends 'base.html.twig' %}

{% block title %}Hello IndexController!{% endblock %}

{% block body %}
<style>
    .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; }
    .example-wrapper code { background: #F5F5F5; padding: 2px 6px; }
</style>

<div class="example-wrapper">
    <h1>Hello {{ controller_name }}! ✅</h1>

    This friendly message is coming from:
    <ul>
        <li>Your controller at <code><a href="{{ '/media/sambano/home_HDD_EXTERNE/Documents/php/projets_eclipse/php_symfony_projet03_test05/src/Controller/IndexController.php'|file_link(0) }}">src/Controller/IndexController.php</a></code></li>
        <li>Your template at <code><a href="{{ '/media/sambano/home_HDD_EXTERNE/Documents/php/projets_eclipse/php_symfony_projet03_test05/templates/index/index.html.twig'|file_link(0) }}">templates/index/index.html.twig</a></code></li>
    </ul>
</div>

{{ knp_menu_render('App:Builder:mainMenu') }}
{% endblock %}

NOTES:

  • when I install KnpMenuBundle, config/packages/knp_menu.yaml did not exist, I had to create it and paste inside the code.

  • src/Menu folder did not exist, I had to create it with Builder.php inside and paste the code.

  • when I added {{ knp_menu_render('App:Builder:mainMenu') }} into my templates/index/index.html.twig, I got the error:

    An exception has been thrown during the rendering of a template 
    ("Bundle "App" does not exist or it is not enabled. Maybe you 
    forgot to add it in the "registerBundles()" method of your 
    "App\Kernel.php" file?").
    

If you have any ideas, clues, or anything else, I'm listening because I don't know where the mistake is.

1

There are 1 best solutions below

1
Tomáš Skočdopole On

I am using method b: a menu builder as a service without any problems.

Look at the documentation page. So I recommend you do the same way.