Sometimes you don't want to commit to a complete admin system. But you would like to have a nice admin panel structure ready to be extended.
composer require braunstetter/control-panel-bundle
yarn install --force
- layouts/base.html.twig (Mobile structure - but empty)
- base.html.twig (contains structure with template hooks)
You can extend these templates, but you can also use
the braunstetter/template-hooks-bundle whose hooks are used
inside of the base.html.twig
file.
This bundle comes with several custom form types. To show you how you can use it, I want to show you an example.
To make this work you need an OrangePuppy
Entity with a title and a description property on it.
symfony new --full my_project
composer install
For this simple test just use a sqlite database by changing the .env
file to:
DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db"
# DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=5.7"
#DATABASE_URL="postgresql://db_user:db_password@127.0.0.1:5432/db_name?serverVersion=13&charset=utf8"
###< doctrine/doctrine-bundle ###
symfony console doctrine:database:create
symfony console make:controller
Choose a name for your controller class (e.g. DeliciousElephantController):
> SiteController
created: src/Controller/SiteController.php
created: templates/site/index.html.twig
Success!
Change templates/site/index.html.twig
:
{% extends '@ControlPanel/base.html.twig' %}
{% block title %}Hello SiteController!{% endblock %}
{% block content %}
Note: don't forget to change the block name from
body
tocontent
symfony serve -d
Now you can see the result by visiting the /site
url.
<?php
namespace App\Form;
use App\Entity\OrangePuppy;
use Braunstetter\ControlPanel\Form\PageType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class OrangePuppyType extends PageType
{
public function buildBodyForm(FormInterface $builder, array $options)
{
$builder
->add('title');
}
public function buildSidebarForm(FormInterface $builder, array $options)
{
$builder->add('sideBox', TestBoxType::class);
}
public function buildToplineRightForm(FormInterface $builder, array $options)
{
$builder->add('submit', SubmitType::class, ['attr' => ['class' => 'cp-button-default']]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'title' => 'Create a new OrangePuppy',
'data_class' => OrangePuppy::class,
]);
}
public function getParent()
{
return PageType::class;
}
}
And here comes the explanation.
- Extend
Braunstetter\ControlPanel\Form\PageType;
(for additional build-methods) - Set the title as an option (Either by submitting the option when creating the form, or by setting it inside
the
configureOptions
method) - Overwrite
public function getParent()
to get view variables and the theme block_prefix inheritance (basically make the styling working ;) - Use the public
buildBodyForm
,buildSidebarForm
,buildToplineRightForm
,buildToplineLeftForm
methods to fill the form.
The
cp-button-default
is a custom button class this bundle provides.
The nice menu on the left side is provided by the braunstetter/menu-bundle.
Maybe you ask yourself where the nice sidebar box is coming from. And probably you recognized the TestBoxType
inside the buildSidebarForm
method.
This is the second custom FormType this bundle provides. Here is an example:
<?php
namespace App\Form;
use Braunstetter\ControlPanel\Form\BoxType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class TestBoxType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('description', TextType::class);
}
public function getParent(): string
{
return BoxType::class;
}
}
This time you just have to overwrite the getParent()
and return the Braunstetter\ControlPanel\Form\BoxType
. (Because this FormType has no special methods.)
The BoxType has the symfony inherit_data option active by default. This way you can just use it just like you put the forms inside the parent class themselves.