## Getting Started
### Minimal Setup
1. **Installation**:
```bash
composer require chamber-orchestra/cms-bundle
Ensure your project meets the requirements: PHP 8.5+, Symfony 8.0+.
Enable the Bundle:
Add to config/bundles.php:
return [
// ...
ChamberOrchestra\CmsBundle\ChamberOrchestraCmsBundle::class => ['all' => true],
];
First Use Case:
Generate a CRUD Controller:
Use the Generator component to scaffold a controller for an existing entity (e.g., Article).
Example CLI command (if bundled):
php bin/console generate:cms-controller Article
Check Generator/ControllerGenerator.php for customization.
Extend a Base Controller:
Create a custom controller extending AbstractCmsController and use traits like SupportsListOperation or SupportsCreateOperation:
use ChamberOrchestra\CmsBundle\Controller\AbstractCmsController;
use ChamberOrchestra\CmsBundle\Controller\SupportsListOperation;
class ArticleController extends AbstractCmsController
{
use SupportsListOperation;
// ...
}
Key Directories to Explore:
Resources/views/ for Twig templates (e.g., crud/list.html.twig).Form/Type/ for Symfony form types (e.g., ArticleType.php).Processor/ for CRUD logic (e.g., ListProcessor.php).Entity Integration:
ChamberOrchestra\CmsBundle\Entity\CmsEntityInterface (if required).Form/Dto/ (e.g., ArticleDto.php) extending AbstractDto:
namespace App\Form\Dto;
use ChamberOrchestra\CmsBundle\Form\Dto\AbstractDto;
class ArticleDto extends AbstractDto
{
public ?string $title = null;
public ?string $content = null;
}
Form/Type/ (e.g., ArticleType.php):
use ChamberOrchestra\CmsBundle\Form\Type\AbstractCmsType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
class ArticleType extends AbstractCmsType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', TextType::class)
->add('content', TextareaType::class);
}
}
Controller Composition:
create + list controller:
use ChamberOrchestra\CmsBundle\Controller\{
AbstractCmsController,
SupportsCreateOperation,
SupportsListOperation
};
class ArticleController extends AbstractCmsController
{
use SupportsCreateOperation, SupportsListOperation;
protected string $entityClass = Article::class;
protected string $formType = ArticleType::class;
protected string $dtoClass = ArticleDto::class;
}
@Route or use YAML/XML routing.Customizing Views:
vendor/chamber-orchestra/cms-bundle/Resources/views/ to your project’s templates/ directory.base.html.twig) in templates/base_cms.html.twig.Event-Driven Extensions:
CmsEntityCreatedEvent) via EventSubscriber:
use ChamberOrchestra\CmsBundle\Event\CmsEntityCreatedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ArticleSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
CmsEntityCreatedEvent::class => 'onArticleCreated',
];
}
public function onArticleCreated(CmsEntityCreatedEvent $event): void
{
if ($event->getEntity() instanceof Article) {
// Custom logic (e.g., send notification).
}
}
}
config/services.yaml:
services:
App\EventSubscriber\ArticleSubscriber:
tags: ['kernel.event_subscriber']
Asset Customization:
assets/scss/cms/_variables.scss (extends vendor/chamber-orchestra/cms-bundle/Resources/assets/scss/bootstrap/_variables.scss).assets/entry/cms.js:
import './custom-article-modal';
PHP 8.5+ Strictness:
declare(strict_types=1);
null to a non-nullable parameter in a DTO constructor.Entity Repository Assumptions:
EntityRepository extends ChamberOrchestra\CmsBundle\EntityRepository\AbstractEntityRepository.EntityRepository, wrap it or extend the abstract class.Twig Template Overrides:
php bin/console cache:clear
{{ dump(_context) }} in Twig to debug template variables.Form Type Inheritance:
AbstractCmsType requires implementing configureOptions() to set $this->entityClass and $this->dtoClass.parent::configureOptions($resolver) to avoid redefining common options.Event Dispatching:
CmsEntityCreatedEvent are dispatched after entity persistence. Use prePersist lifecycle callbacks for pre-save logic.EventSubscriber/CmsEventSubscriber.php for all dispatched events.Asset Pipeline:
Resources/assets/entry/cms.js/cms.scss to avoid 404s.npm install --save-dev @symfony/webpack-encore
Enable Debug Mode:
APP_ENV=dev APP_DEBUG=1 symfony serve
var/log/dev.log for exceptions.DD() in Controllers:
Use Symfony’s dump() or dd() for debugging:
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
$cloner = new VarCloner();
$dumper = new HtmlDumper();
$dumper->dump($cloner->cloneVar($this->getDto()));
Database Queries:
Enable Doctrine’s query logging in config/packages/dev/doctrine.yaml:
doctrine:
dbal:
logging: true
profiling: true
Form Errors:
configureOptions() doesn’t call parent::configureOptions().public function configureOptions(OptionsResolver $resolver): void
{
parent::configureOptions($resolver);
$resolver->setDefaults([
'csrf_protection' => true,
'csrf_field_name' => '_token',
'csrf_token_id' => 'article_create',
]);
}
Custom Processors:
ChamberOrchestra\CmsBundle\Processor\AbstractProcessor to add custom CRUD logic (e.g., ExportProcessor for CSV/Excel).namespace App\Processor;
use ChamberOrchestra\CmsBundle\Processor\AbstractProcessor;
class CustomExportProcessor extends AbstractProcessor
{
public function export(array $entities): string
{
// Custom export logic.
return $csvData;
}
}
services:
App\Processor\CustomExportProcessor:
tags: ['cms.processor']
**Dynamic
How can I help you explore Laravel packages today?