Monday, September 26, 2011

How to create a custom admin theme for the symfony/doctrine admin generator

this works for symfony 1.4

I am currently working heavily on the gjPositionsPlugin which concept and idea I blogged about earlier. One part that I didn't like too much and that als Ryan Weaver pointed out to me is that I limited its use to a single model class.

Now I wanted to change that and turned the functionality from being attached to a model to being a behaviour instead. I then realised that being model independant will not easily allow me to provide functionality in an admin module. Then I remebered admin generator themes. And started building one.


To start you basically just copy the existing default theme admin and give it a new name. You can place this in the /data folder of your project or like me in your plugin. (This can be applied to Propel as well of course).

 
$ mkdir -p data/generator/sfDoctrineModule/THEME_NAME
$ cp -r /path/to/symfony/lib/plugins/sfDoctrinePlugin/data/generator/sfDoctrineModule/admin/* \
data/generator/sfDoctrineModule/THEME_NAME/

Note that there is no fallback mechanism. Files that you delete from your theme will not be taken from the default theme!

Lets have a look at what was being copied.

 
data/generator/sfDoctrineModule/THEME_NAME/
+- /parts/
| `- /actionsConfiguration.php
| `- /batchAction.php
| `- /configuration.php
| `- /createAction.php
| `- /deleteAction.php
| `- /editAction.php
| `- /fieldsConfiguration.php
| `- /filterAction.php
| `- /filtersAction.php
| `- /indexAction.php
| `- /newAction.php
| `- /paginationAction.php
| `- /paginationConfiguration.php
| `- /processFormAction.php
| `- /sortingAction.php
| `- /sortingConfiguration.php
| `- /updateAction.php
|
+- /skeleton/
| `- /actions/
| `- /actions.class.php
| `- /config/
| `- /configuration.php
| `- /helper.php
| `- /lib/
| `- /generator.yml
| `- /view.yml
| `- /templates/
| `- /.sf
|
`- /template/
  `- /actions/
    `- /actions.class.php
  `- /config/
    `- /helper.php
  `- /lib/
    `- /generator.yml
  `- /templates/
    `- /_assets.php
    `- /editSuccess.php
    `- /_filters_field.php
    `- /_filters.php
    `- /_flashes.php
    `- /_form_actions.php
    `- /_form_field.php
    `- /_form_fieldset.php
    `- /_form_footer.php
    `- /_form_header.php
    `- /_form.php
    `- /indexSuccess.php
    `- /_list_actions.php
    `- /_list_batch_actions.php
    `- /_list_field_boolean.php
    `- /_list_footer.php
    `- /_list_header.php
    `- /_list.php
    `- /_list_td_actions.php
    `- /_list_td_batch_actions.php
    `- /_list_td_stacked.php
    `- /_list_td_tabular.php
    `- /_list_th_stacked.php
    `- /_list_th_tabular.php
    `- /newSuccess.php
    `- /_pagination.php

The parts folder

The parts folder is actually part of the templates folder. You can find two kinds of files in it: action files and configuration files.

The action files contain one action method each that will be included from the appropriate action class from the templates folder.

The configuration files will be included when the actual module in the cachedirectory will be generated (after every clear-cache). They will consider the settings the user has chosen in his generator.yml and configuration class!

If you make changes in the parts folder they will not take effect until you cleared the cache.

The template folder

The template folder holds the skeleton for the admin module that will be generated into the cache dir. This includes an actions class, templates and partials, configuration and helpers.

This is the folder you want to work in to provide functionality to the user.

If you make changes in the template folder they will not take effect until you cleared the cache.

The skeleton folder

The skeleton folder holds the skeleton for the module that will be generated into the users application.

This module is meant to be edited by the user and you should not add any fancy stuff here. The only sensible change I can think of is to set a different default configuration.

If you make changes in the skeleton folder they will not take effect until you re-generated the module!

Because the admin module needs to be re-generated in order to consider your changes I propose that the best practice workflows for changes in this folder is to work on the generated module itself and "packport" the changes to the skeleton folder when you're done. Please also note that every change in this folder requires the user to reproduce it when he wants to use your theme on an existing module. This means you have to document it!

PHP inside PHP

The files we discussed are processed by PHP when the generation is taking place. But the resulting module code needs to include PHP as well. This is why there are two different PHP notations present in almost all the above files. Consider the following example:

 
<h1>[?php echo <?php echo "$barfoo->getValue()" ?> ?]</h1>

// will produce

<h1><?php echo $barfoo->getValue() ?></h1>

view rawexample.phpThis Gist brought to you by GitHub.

How to apply the theme

There are two ways to apply your new theme. The most common one is to change the generator.yml of your existing admin module.

 
generator:
  param:
    ...
    theme: THEME_NAME
    ...

Don't forget to clear the cache afterwards!

The other method will generate not only the cache files from your theme but the admin module on the application level as well.

 
$ php symfony doctrine:generate-admin --theme=THEME_NAME frontend YourModel

If you need to re-generate the module you have to delete the module from the application first and also remove the route collection generated in the applications routing.yml.

No comments: