Though
SensioGeneratorBundle
copes with its task pretty well it has one drawback: there is no easy mechanism of extending generation commands with custom generation templates (aka skeletons). Since I had to create a lot of rest CRUD controllers of the same type and there were no way to generate them via SensioGeneratorBundle
I decided to create my own BasGeneratorBundle.BasGeneratorBundle
is designed in such a way that it is really easy to create your own generation skeletons or extend existing ones. Generation skeletons, just like in the SensioGeneratorBundle
, are twig templates.
Table of contents
Create custom skeleton
For the sake of example imagine that you have the following controller in your bundle:Skeletons are stored inside
Resources/bas-skeletons
folder of the bundle. If your skeleton is going to be called mycustomskeleton
create corresponding folder Resources/bas-skeletons/mycustomskeleton
. Now let's create skeleton template for our controller and put it in mycustomskeleton
folder:
Assuming that this skeleton will be generated for the entity
Acme\DemoBundle\Entity\Example\SomeEntity
variables namespace, entity_class, etc will be substituted with:
There is alsonamespace = Acme\DemoBundle entity_namespace = Example entity = Example\SomeEntity entity_class = SomeEntity bundle = AcmeDemoBundle
entity_relpath, fields, path
variables available (check out built-in skeleton templates: one, two and three)
We've created generation skeleton for our controller. But how generation Command will know that it should put generated contents into
Controller/Example/SomeEntityController.php
file. Well, there is special twig template file for this purpose called main.twig that has to be put into skeleton folder:
skeleton.start('someFile.php')
says that everything after this macro and up to skeleton.end()
macro will be put into someFile.php file. Though there is only one file in my main.twig example you can include there as many templates as you want. Just don't forget to mark scope of the file with skeleton.start and skeleton.end macros.
Running command:
will generate controller from the first code listing.$ app/console bas:generate:using-entity The Entity shortcut name: AcmeDemoBundle:Example/SomeEntity Skeleton name: mycustomskeleton
Interaction with user
bas:generate:using-entity
asks user only Entity shortcut and skeleton name by default. Not very flexible, right? What if more information is needed from user. For example you want to add route prefix annotation to your controller skeleton and you want to let user enter this prefix in interaction process. Well, BasGeneratorBundle enables you to do that.
There is special file called options.twig that resides in skeleton folder. So, if you want to ask user some variable (for example route prefix) add the following lines into options.twig:
skeleton.option()
registers variable. And now you can use {{ route_prefix }}
variable in your skeleton. And if you run bas:generate:using-entity
the command will ask you the route_prefix variable:
The skeleton.option macro has the following syntax$ app/console bas:generate:using-entity The Entity shortcut name: AcmeDemoBundle:Example/SomeEntity Skeleton name: mycustomskeleton Please provide route_prefix (Route prefix to use in controller):
skeleton.option(name, description, devault_value)
.
Easy to extend
It is really easy to extend skeletons with BasGeneratorBundle. You just use twig extension mechanism and extend main.twig and options.twig templates.Let's say you want to create
othercustomskeleton
skeleton and it is almost identical to mycustomskeleton
. The only thing that is different is the code inside someaction_body block of the controller.php.twig template. In order to extend mycustomskeleton
put the following lines into othercustomskeleton
's main.twig template:
No comments:
Post a Comment