Extending Bake ############## Bake features an extensible architecture that allows your application or plugins to modify or add-to the base functionality. Bake makes use of a dedicated view class which uses the `Twig `_ template engine. Bake Events =========== As a view class, ``BakeView`` emits the same events as any other view class, plus one extra initialize event. However, whereas standard view classes use the event prefix "View.", ``BakeView`` uses the event prefix "Bake.". The initialize event can be used to make changes which apply to all baked output, for example to add another helper to the bake view class this event can be used:: on('Bake.initialize', function (Event $event) { $view = $event->getSubject(); // In my bake templates, allow the use of the MySpecial helper $view->loadHelper('MySpecial', ['some' => 'config']); // And add an $author variable so it's always available $view->set('author', 'Andy'); }); If you want to modify bake from within another plugin, putting your plugin's bake 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/template files one can use a function listening for ``Bake.beforeRender`` to modify the variables used in the bake templates:: on('Bake.beforeRender', function (Event $event) { $view = $event->getSubject(); // Use $rows for the main data variable in indexes if ($view->get('pluralName')) { $view->set('pluralName', 'rows'); } if ($view->get('pluralVar')) { $view->set('pluralVar', 'rows'); } // Use $theOne for the main data variable in view/edit if ($view->get('singularName')) { $view->set('singularName', 'theOne'); } if ($view->get('singularVar')) { $view->set('singularVar', 'theOne'); } }); You may also scope the ``Bake.beforeRender`` and ``Bake.afterRender`` events to a specific generated file. For instance, if you want to add specific actions to your UsersController when generating from a **Controller/controller.twig** file, you can use the following event:: on( 'Bake.beforeRender.Controller.controller', function (Event $event) { $view = $event->getSubject(); if ($view->viewVars['name'] == 'Users') { // add the login and logout actions to the Users controller $view->set('actions', [ 'login', 'logout', 'index', 'view', 'add', 'edit', 'delete' ]); } } ); By scoping event listeners to specific bake templates, you can simplify your bake related event logic and provide callbacks that are easier to test. Bake Template Syntax ==================== Bake template files use the `Twig `__ template syntax. One way to see/understand how bake templates works, especially when attempting to modify bake template files, is to bake a class and compare the template used with the pre-processed template file which is left in the application's **tmp/bake** folder. So, for example, when baking a shell like so: .. code-block:: bash bin/cake bake shell Foo The template used (**vendor/cakephp/bake/src/Template/Bake/Shell/shell.twig**) looks like this:: `` A Bake template php close tag * ``<%=`` A Bake template php short-echo tag * ``<%-`` A Bake template php open tag, stripping any leading whitespace before the tag * ``-%>`` A Bake template php close tag, stripping trailing whitespace after the tag .. _creating-a-bake-theme: Creating a Bake Theme ===================== If you wish to modify the output produced by the "bake" command, you can create your own bake 'theme' which allows you to replace some or all of the templates that bake uses. The best way to do this is: #. Bake a new plugin. The name of the plugin is the bake 'theme' name #. Create a new directory **plugins/[name]/src/Template/Bake/Template/**. #. Copy any templates you want to override from **vendor/cakephp/bake/src/Template/Bake/Template** to matching files in your plugin. #. When running bake use the ``--theme`` option to specify the bake-theme you want to use. To avoid having to specify this option in each call, you can also set your custom theme to be used as default theme:: Test->classSuffixes[$this->name()])) { $this->Test->classSuffixes[$this->name()] = 'Foo'; } $name = ucfirst($this->name()); if (!isset($this->Test->classTypes[$name])) { $this->Test->classTypes[$name] = 'Foo'; } return parent::bakeTest($className); } * The **class suffix** will be appened to the name provided in your ``bake`` call. In the previous example, it would create a ``ExampleFooTest.php`` file. * The **class type** will be the sub-namespace used that will lead to your file (relative to the app or the plugin you are baking into). In the previous example, it would create your test with the namespace ``App\Test\TestCase\Foo`` . .. meta:: :title lang=en: Extending Bake :keywords lang=en: command line interface,development,bake view, bake template syntax,twig,erb tags,percent tags