Let's talk about how to stop copy-paste between projects and transfer the code to a re-usable symfony 5 plug-in bundle. A series of articles summarizing my experience with bundles will lead in practice from creating a minimal bundle and refactoring a demo application to tests and the bundle release cycle.
In the previous article, we created a minimal bundle of two files and included it in the project.
In this article:
- Porting code to bundle
- Dependency Injection: registering bundle services in a DI container
- Migrating controllers and setting up routing
- Resource Path Determination Mechanism
- Transferring templates to bundles
If you are not completing the tutorial sequentially, then download the application from the repository and switch to the 1-bundle-mockup branch .
Instructions for installing and starting the project in a file README.md.
You will find the final version of the code for this article in the 2-basic-refactoring branch .
Let's proceed to refactoring.
We move the main files
A bundle can contain everything the same as regular Symfony applications: entities, controllers and commands, templates, assets, tests and any other code.
, , bundles/CalendarBundle/src ( ):
# Crate dirs
cd bundles/CalendarBundle/src/
mkdir Controller Entity Service
cd ../../../src
# Move files
mv Form Repository ../bundles/CalendarBundle/src/
mv Controller/EditorController.php Controller/EventController.php ../bundles/CalendarBundle/src/Controller
mv Entity/Event.php ../bundles/CalendarBundle/src/Entity
mv Service/EventExporter ../bundles/CalendarBundle/src/Service/EventExporter
mv Twig ../bundles/CalendarBundle/src/Twig

, . namespace use App\ bravik\CalendarBundle\.
App\: .
IDE .
IDE PhpStorm Ctrl/Cmd + Shift + R.
use App\Repository\EventRepository SiteController

.
:

SiteController : EventRepository. autowiring Symfony typehints DI-.
src/Services , .
Dependency Injection
, DI- , .
, .
, Symfony- services.yaml, DI-.
src config/services.yaml:
parameters:
#
services:
#
_defaults:
#
# typehints ( )
# https://symfony.com/doc/current/service_container.html#the-autowire-option
autowire: true
# :
#
# https://symfony.com/doc/current/service_container.html#the-autoconfigure-option
autoconfigure: true
# DI-
bravik\CalendarBundle\Repository\EventRepository: ~
bravik\CalendarBundle\Controller\EventController: ~
bravik\CalendarBundle\Controller\EditorController: ~
3 .
- config/services.yaml , .
@todo :
# Twig
bravik\CalendarBundle\Twig\TwigRuDateFilter: ~
# EventExporter DI-
bravik\CalendarBundle\Service\EventExporter\:
resource: '../src/Service/EventExporter/*'
# ExporterProvider DI-
# 2
bravik\CalendarBundle\Service\EventExporter\ExporterManager:
arguments:
$exporters:
- '@bravik\CalendarBundle\Service\EventExporter\Exporters\GoogleCalendarExporter'
- '@bravik\CalendarBundle\Service\EventExporter\Exporters\ICalendarExporter'
, , . , . src DependencyInjection/CalendarExtension.php:
<?php
namespace bravik\CalendarBundle\DependencyInjection;
use Exception;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
class CalendarExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
}
}
. <BundleName>Extension, src/DependencyInjection Symfony\Component\DependencyInjection\Extension\Extension.
Symfony DI-, Extension-. , Extension::load() .
, . , PHP-. .
services.yaml :
public function load(array $configs, ContainerBuilder $container)
{
$loader = new YamlFileLoader(
$container,
new FileLocator(__DIR__.'/../../config')
);
$loader->load('services.yaml');
}
, :

.
Symfony :
config/routes.yaml #
config/routes/annotations.yaml # ,
#
. annotations.yaml:
controllers: #
type: annotation #
resource: ../../src/Controller/ # ,
: config/routes.yaml.
calendar_routes:
type: annotation
resource: '../src/Controller/'
config/routes/annotations.yaml.
:
calendar_bundle:
resource: '@CalendarBundle/config/routes.yaml'
.
@CalendarBundle β .
Symfony .
, /admin - : /admin ?
, :
calendar_bundle:
resource: '@CalendarBundle/config/routes.yaml'
prefix: /admin
name_prefix: cms.
security . , .
, Symfony vendor_name_. .
, Twig «» .
:
@<BundleName>Bundle/path/to/config β@<BundleName>/path/to/template β .
Symfony Β« Β». . .
./src. , Symfony 4 src/Resources. 4 Symfony , β . , .
CalendarBundle getPath():
public function getPath(): string
{
return dirname(__DIR__);
}
@CalendarBundle .
, !

? .
. , , -.
templates templates/event :
mkdir bundles/CalendarBundle/templates
mv templates/event/* bundles/CalendarBundle/templates
β , . .
Β« Β» IDE . event/ @Calendar/.

@Calendar Twig , namespace Twig. templates , Symfony namespace, templates Resources/views ( ).
site/index.html.twig twig-. :

, β .
: base.html.twig -:
{% extends 'base.html.twig' %}
.
, , DI-. Example Project 2-basic-refactoring.
- , β namespace .
App - , β Extension-. DI- . , .
- . . .
- , , .., «» , . .
, JS -.
:
1.
2.
3. : , , JS
4.
5.
6. ,
7. ,