A common bootstrap layout, including menus and several components.
This bundle leverages several Symfony components, and as such loads several dependencies, and is a fairly opinionated bundles. Adhering to the coding suggestions offers several benefits.
All of the themes are based on Bootstrap 5.3, and tabler is the recommended one. The base layout has various menus: navbar, footer, page_header
The menu system is based on event listeners. While these are a bit complicated at first, benefits include:
- Context-specific menus (e.g. a separate menu for each entity, e.g. a Project menu, with its own navbar and footer.
- Automatic security -- does not render a menu item if IsGranted attribute blocks the user
- Automatic translation: uses the controller name (rather than route name) as the default label.
bin/console survos:make:menu App
#[AsEventListener(event: KnpMenuEvent::NAVBAR_MENU2, priority: 50)]
public function navarButtonsMenu(KnpMenuEvent $event): void
{
$menu = $event->getMenu();
$this->add($menu, 'app_homepage');
$this->add($menu, 'event_index');
}
#[AsEventListener(event: KnpMenuEvent::NAVBAR_MENU)]
public function navbarMenu(KnpMenuEvent $event): void
{
if (!$this->supports($event)) {
return;
}
}
Pass context-specific menu data by first configuring the allowable fields in menu_options of survos_bootstrap.yaml
survos_bootstrap:
routes:
login: app_login
logout: app_logout
register: app_register
homepage: app_homepage
menu_options:
entityClass: null
project: null
frontPage: false
showAppMenu: false
{% block footer %}
<twig:menu :type="FOOTER_MENU" :caller="_self"
:options="{owner: owner,
entityClass: ownerClass,
project:project|default(null)}"
>
</twig:menu>
Entity routes can be generated in the menu component without having to remember the parameters.
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
$subMenu = $this->addSubmenu($menu, 'super_admin_index');
$this->add($subMenu, 'owner_references', $owner);
$this->add($subMenu, 'owner_dump', $owner, external: true);
the $owner class must implement getUniqueParameters(), which is used by the getRp() method. At the moment, this requires implementing the listener which is clumbsy :-(
)
symfony new my-app --webapp && cd my-app
composer req survos/bootstrap-bundle
composer req survos/maker-bundle --dev
bin/console importmap:require @tabler/core
echo "import '@tabler/core';
import '@tabler/core/dist/css/tabler.min.css';
" >> assets/app.js
@todo:
{% extends "@SurvosBootstrap/%s/base.html.twig"|format(theme_option('theme')) %}
bin/console make:controller App
sed -i "s|'/app'|'/'|" src/Controller/AppController.php # the landing page controller
cat > templates/app/index.html.twig <<'END'
{% extends 'base.html.twig' %}
{% block body %}
<twig:alert message="hello" dismissible="true">
<twig:block name="alert_message">
I can override the alert_message block and access the {{ message }} too!
</twig:block>
</twig:alert>
{% endblock %}
END
- make:create-user-command
A simple template with a navbar and login for Symfony, using Bootstrap 5
composer req survos/bootstrap-bundle
composer req survos/maker-bundle --dev
To set default values (@todo: install recipe)
# config/packages/bootstrap.yaml
bootstrap:
widthFactor: 3
height: 120
foregroundColor: 'purple'
symfony new BootstrapDemo --webapp
bin/console make:controller AppController
composer req survos/bootstrap-bundle
echo "{{ 'test'|bootstrap }} or {{ bootstrap('test', 2, 80, 'red') }} " >> templates/app/index.html.twig
symfony server:start -d
symfony new menu7 --webapp --version=next && cd menu7
composer config minimum-stability dev
composer config prefer-stable false
composer config extra.symfony.allow-contrib true
#sed -i 's/"6.4.*"/"^7.0"/' composer.json
composer update
#composer config repositories.knp_menu_bundle '{"type": "vcs", "url": "git@github.com:tacman/KnpMenuBundle.git"}'
composer require knplabs/knp-menu-bundle
composer req symfony/asset-mapper
bin/console make:controller -i Menu
cat > templates/menu.html.twig <<END
{% extends 'base.html.twig' %}
{% block body %}
{{ knp_menu_render('App:Builder:mainMenu') }}
{% endblock %}
END
cat > src/Menu/Builder.php << 'END'
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
{
public function mainMenu(FactoryInterface $factory, array $options): ItemInterface
{
$menu = $factory->createItem('root');
$menu->addChild('Home', ['route' => 'app_app']);
return $menu;
}
}
END
symfony server:start -d
symfony open:local --path=/menu
symfony new test --webapp --version=7.0 && cd test
composer require symfony/ux-twig-component symfony/asset-mapper
composer req survos/bootstrap-bundle
composer req survos/api-grid-bundle
composer req survos/crawler-bundle
composer req survos/command-bundle
composer req survos/barcode-bundle
echo "import 'bootstrap/dist/css/bootstrap.min.css'" >> assets/app.js
bin/console make:controller App
sed -i "s|'/app'|'/'|" src/Controller/AppController.php # the landing page controller
cat > templates/app/index.html.twig <<'END'
{% extends 'base.html.twig' %}
{% block body %}
<twig:alert message="hello" dismissible="true">
<twig:block name="alert_message">
I can override the alert_message block and access the {{ message }} too!
</twig:block>
</twig:alert>
{% endblock %}
END
symfony server:start -d
symfony open:local --path=/app
cd ../ux
./link ../bug
cd ../bug
symfony open:local --path=/app