Extending Bake

    As a view class, emits the same events as any other view class,plus one extra initialize event. However, whereas standard view classes use theevent prefix “View.”, BakeView uses the event prefix “Bake.”.

    The initialize event can be used to make changes which apply to all bakedoutput, for example to add another helper to the bake view class this event canbe used:

    If you want to modify bake from within another plugin, putting your plugin’sbake events in the plugin config/bootstrap.php file is a good idea.

    Bake events can be handy for making small changes to existing templates.For example, to change the variable names used when baking controller/templatefiles one can use a function listening for Bake.beforeRender to modify thevariables used in the bake templates:

    1. <?php
    2. // config/bootstrap_cli.php
    3.  
    4. use Cake\Event\Event;
    5. use Cake\Event\EventManager;
    6.  
    7. EventManager::instance()->on('Bake.beforeRender', function (Event $event) {
    8. $view = $event->getSubject();
    9.  
    10. // Use $rows for the main data variable in indexes
    11. if ($view->get('pluralName')) {
    12. $view->set('pluralName', 'rows');
    13. }
    14. if ($view->get('pluralVar')) {
    15. $view->set('pluralVar', 'rows');
    16. }
    17.  
    18. // Use $theOne for the main data variable in view/edit
    19. if ($view->get('singularName')) {
    20. $view->set('singularName', 'theOne');
    21. }
    22. if ($view->get('singularVar')) {
    23. $view->set('singularVar', 'theOne');
    24. }
    25.  
    26. });

    You may also scope the Bake.beforeRender and Bake.afterRender events toa specific generated file. For instance, if you want to add specific actions toyour UsersController when generating from a Controller/controller.twig file,you can use the following event:

    1. <?php
    2. // config/bootstrap_cli.php
    3.  
    4. use Cake\Event\Event;
    5. use Cake\Event\EventManager;
    6. use Cake\Utility\Hash;
    7.  
    8. EventManager::instance()->on(
    9. 'Bake.beforeRender.Controller.controller',
    10. function (Event $event) {
    11. $view = $event->getSubject();
    12. if ($view->viewVars['name'] == 'Users') {
    13. // add the login and logout actions to the Users controller
    14. $view->set('actions', [
    15. 'login',
    16. 'logout',
    17. 'view',
    18. 'add',
    19. 'edit',
    20. 'delete'
    21. ]);
    22. }
    23. }
    24. );

    By scoping event listeners to specific bake templates, you can simplify yourbake related event logic and provide callbacks that are easier to test.

    Bake template files use the Twig template syntax.

    So, for example, when baking a shell like so:

    The template used (vendor/cakephp/bake/src/Template/Bake/Shell/shell.twig)looks like this:

    1. <?php
    2. namespace {{ namespace }}\Shell;
    3.  
    4. use Cake\Console\Shell;
    5.  
    6. /**
    7. * {{ name }} shell command.
    8. */
    9. class {{ name }}Shell extends Shell
    10. {
    11. /**
    12. * main() method.
    13. *
    14. * @return bool|int Success or error code.
    15. */
    16. public function main()
    17. {
    18. }
    19.  
    20. }

    And the resultant baked class (src/Shell/FooShell.php) looks like this:

    1. <?php
    2. namespace App\Shell;
    3.  
    4. use Cake\Console\Shell;
    5.  
    6. /**
    7. * Foo shell command.
    8. */
    9. class FooShell extends Shell
    10. {
    11. /**
    12. * main() method.
    13. *
    14. * @return bool|int Success or error code.
    15. */
    16. public function main()
    17. {
    18. }
    19.  

    Note

    Prior to version 1.5.0 bake used a custom erb-style tags inside .ctp template files.

    • <% A Bake template php open tag
    • %> A Bake template php close tag
    • A Bake template php short-echo tag
    • <%- A Bake template php open tag, stripping any leading whitespacebefore the tag
    • -%> A Bake template php close tag, stripping trailing whitespace afterthe tag

    If you wish to modify the output produced by the “bake” command, you cancreate your own bake ‘theme’ which allows you to replace some or all of thetemplates that bake uses. The best way to do this is:

    • Bake a new plugin. The name of the plugin is the bake ‘theme’ name

    • Copy any templates you want to override fromvendor/cakephp/bake/src/Template/Bake/Template to matching files in yourplugin.

    • When running bake use the —theme option to specify the bake-theme youwant to use. To avoid having to specify this option in each call, you can alsoset your custom theme to be used as default theme:

    If you wish to modify the default output produced by the “bake” command, you cancreate your own bake templates in your application. This way does not use the—theme option in the command line when baking. The best way to do this is:

    • Create a new directory /src/Template/Bake/.
    • Copy any templates you want to override fromvendor/cakephp/bake/src/Template/Bake/ to matching files in yourapplication.

    It’s possible to add new bake command options, or override the ones provided byCakePHP by creating tasks in your application or plugins. By extendingBake\Shell\Task\BakeTask, bake will find your new task and include it aspart of bake.

    As an example, we’ll make a task that creates an arbitrary foo class. First,create the task file src/Shell/Task/FooTask.php. We’ll extend theSimpleBakeTask for now as our shell task will be simple. SimpleBakeTaskis abstract and requires us to define 3 methods that tell bake what the task iscalled, where the files it generates should go, and what template to use. OurFooTask.php file should look like:

    1. <?php
    2. namespace App\Shell\Task;
    3.  
    4. use Bake\Shell\Task\SimpleBakeTask;
    5.  
    6. class FooTask extends SimpleBakeTask
    7. {
    8. public $pathFragment = 'Foo/';
    9.  
    10. public function name()
    11. {
    12. return 'foo';
    13. }
    14.  
    15. public function fileName($name)
    16. {
    17. return $name . 'Foo.php';
    18. }
    19.  
    20. public function template()
    21. {
    22. return 'foo';
    23. }
    24.  
    25. }

    Once this file has been created, we need to create a template that bake can usewhen generating code. Create src/Template/Bake/foo.twig. In this file we’lladd the following content:

    1. <?php
    2. namespace {{ namespace }}\Foo;
    3.  
    4. /**
    5. * {{ name }} foo
    6. */
    7. class {{ name }}Foo
    8. {
    9. // Add code.
    10. }

    You should now see your new task in the output of . You canrun your new task by running bin/cake bake foo Example.This will generate a new ExampleFoo class in src/Foo/ExampleFoo.phpfor your application to use.

    • The class suffix will be appened to the name provided in your bakecall. In the previous example, it would create a file.