Today, I have merged the new_admin branch into the 1.2 one, which means that symfony 1.2 now sports a brand new admin generator, based on the form framework.

In this post, I will only describe the general concepts of the new admin generator. The chapter about the admin generator in the symfony book has already been updated, so you can start reading it right away.

The first good news is that the new admin generator is very similar to the previous one. Even if it is not backward compatible in the sense that it uses the new form framework, the configuration is still handled by the generator.yml configuration file, and the configuration possibilities are quite similar. I have also tried to keep the same philosophy to help current users learn the new tool more easily.

A simple CMS as an example

To illustrate this post, let's take the example I have already used in a previous post:

database schema

propel:
  demo_article:
    id:             ~
    author_id:      { type: integer, foreignReference: id, foreignTable: demo_author, onDelete: cascade, onUpdate: cascade, required: true }
    status:         { type: varchar(255), required: true }
    title:          { type: varchar(255), required: true }
    content:        { type: longvarchar, required: true }
    is_on_homepage: boolean
    published_at:   timestamp
    created_at:     timestamp
    updated_at:     timestamp
 
  demo_category:
    id:          ~
    name:        varchar(255)
 
  demo_author:
    id:          ~
    name:        varchar(255)
 
  demo_tag:
    id:          ~
    name:        varchar(255)
 
  demo_tag_article:
    tag_id:      { type: integer, primaryKey: true, foreignReference: id, foreignTable: demo_tag, onDelete: cascade, onUpdate: cascade, required: true }
    article_id:  { type: integer, primaryKey: true, foreignReference: id, foreignTable: demo_article, onDelete: cascade, onUpdate: cascade, required: true }
 
  demo_category_article:
    category_id: { type: integer, primaryKey: true, foreignReference: id, foreignTable: demo_category, onDelete: cascade, onUpdate: cascade, required: true }
    article_id:  { type: integer, primaryKey: true, foreignReference: id, foreignTable: demo_article, onDelete: cascade, onUpdate: cascade, required: true }
 

This is a classic schema for a simple CMS. Articles have an author and can have many tags and categories.

A REST architecture

Based on a Propel model, symfony is able to generate the associated admin module:

$ php symfony propel:generate-admin backend DemoArticle --module=article

The propel:generate-admin task creates an article module in the backend application modules directory.

We can do the same to generate a module for the DemoCategory model:

$ php symfony propel:generate-admin backend DemoCategory --module=category

More out of the box

Even before configuring the generated modules, let's have a look at the features that are available out of the box.

Default category list

The Category list has several interesting features:

  • Each category id is a link to the edit view
  • The 'New' link goes to the new view to create a new category
  • Each category has an 'Edit' and a 'Delete' links
  • The possibility to mass-delete categories by selecting several categories at once

Default article filters

The above screenshot is the default filter box created for the Article model. Notice that the new admin generator has automatically created filters for foreign-keys and many to many relationships.

Default article edit form

The edit view is also quite interesting as all the fields are editable, even the many to many relationships between the Article model and the Tag and Category models.

As this view uses the default form class generated for the Article class, the validation is also enabled by default:

Default errors for the article edit form

For better usability for the end user, the new admin generator also uses a lot of flash messages on the list and edit views:

Flash when saving a record Flash when deleting a record Flash when deleting records Flash when an error occured

More configurability

Out of the box, the generated modules are already quite powerful, but the real power of the admin generator has always been its configurability, the way you can change the display of the admin views without writing a single line of code. The new admin generator is no different. Let's see some options you can use in the generator.yml configuration file.

First of all, the generator.yml file is more secure than before as symfony now validates the format of the file. It will save you a lot of times in case of a typo or a wrong indentation. For this validation to work, we have moved all the configuration under a config entry. Here is the default generator.yml configuration file for the category module:

generator:
  class: sfPropelGenerator
  param:
    model_class:           DemoCategory
    theme:                 admin
    non_verbose_templates: true
    with_show:             false
    singular:              ~
    plural:                ~
    route_prefix:          categories
    with_propel_route:     1
 
    config:
      actions: ~
      fields:  ~
      list:    ~
      filter:  ~
      form:    ~
      edit:    ~
      new:     ~
 

You might have noticed the new entry. The new admin generator implements one of the more requested feature, the possibility to have a different configuration for the edit and the new views. Yes, that's now possible, and both views inherits from the virtual form view:

config:
  form:
    display:
      NONE:    [author_id, status, published_at, demo_category_article_list, demo_tag_article_list]
      Content: [title, content, is_on_homepage]
 
  new:
    title: New Article
 
  edit:
    title: Editing Article %%title%% (#%%id%%)
 

So, the admin generator has now seven main entries:

  • actions: To define the attributes of all actions, and especially the credentials
  • fields: To define the default fields configuration
  • list: To define the list view configuration
  • filter: The filter has now its own entry for its configuration
  • form: This is a virtual view as it is only used as the default configuration for the new and edit configurations
  • new: To define the new view configuration
  • edit: To define the edit view configuration

The generator.yml configuration file implements some inheritance rules between these entries:

  • new and edit inherits from form which inherits from fields
  • list inherits from fields
  • filter inherits from fields

Here is an example for the fields definition:

config:
  fields:
    title:     { label: Article Title }
    content:   { label: Body }
 
  list:
    fields:
      title:   { label: Title }
 
  form:
    fields:
      content: { label: Body of the article }
 

If you are used to the admin generator of symfony 1.0, you will notice that the name key has been renamed to label.

All the features of the old configuration file are also still supported (see Chapter 14 for more details).

Also, even if the generator.yml configuration file is the recommended way to customize the modules, the new admin generator can also be entirely customized with PHP code for a more dynamic configuration (apps/backend/modules/article/lib/articleGeneratorConfiguration.class.php). To have an idea of what is possible, just have a look at the generated BaseArticleGeneratorConfiguration class in the cache (cache/backend/dev/modules/autoArticle/lib/BaseArticleGeneratorConfiguration.class.php). You can even mix configuration via the generator.yml file and the articleGeneratorConfiguration class.

Extensibility

The new admin generator really shines when it comes to extending the default behaviors. It is much more flexible and extensible than before.

First, there are more template partials than before, and each partial is much more simple, allowing you to tweak each part of the system easily:

_assets.php
_filters.php
_filters_field.php
_flashes.php
_form.php
_form_actions.php
_form_field.php
_form_fieldset.php
_form_footer.php
_form_header.php
_list.php
_list_actions.php
_list_batch_actions.php
_list_field_boolean.php
_list_footer.php
_list_header.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
_pagination.php
editSuccess.php
indexSuccess.php
newSuccess.php

The action template has been split into a lot of partials for better readability and extensibility:

actionsConfiguration.php
batchAction.php
configuration.php
createAction.php
deleteAction.php
editAction.php
fieldsConfiguration.php
filterAction.php
filtersAction.php
filtersConfiguration.php
indexAction.php
newAction.php
paginationAction.php
paginationConfiguration.php
processFormAction.php
sortingAction.php
sortingConfiguration.php
updateAction.php

If you want to tweak the admin generator to create your own theme, or to bundle your extensions in a plugin, you will find that it is much more easier now:

  • You don't need to copy all the files of the default theme to create a new one. Just copy the files you need to override.
  • Several events have been added to add behaviors without the need for creating a new theme. This allows several plugins to add or change the default behaviors:

    • admin.pre_execute: This event is notified before any action is executed. This is a great place to tweak the configuration or check something before anything is executed.
    • admin.build_criteria: This event filters the Criteria used for the list view.
    • admin.save_object: This event is notified just after an object is saved.
    • admin.delete_object: This event is notified just before an object will be deleted.
  • The generated actions module has been refactored to provided more useful methods:

    • getFilters()
    • setFilters()
    • getPager()
    • getPage()
    • setPage()
    • buildCriteria()
    • addSortCriteria()
    • getSort()
    • setSort()

The best way to learn how you can push the limits of the new admin generator is to browse the generated modules in the cache. You will find a lot of goodness there (have a look at the helper class for example).

Internationalization

The new admin generator support internationalization of forms out of the box, thanks to the usage of the form framework.

The admin generator interface is also translated in several languages. In less than 24 hours, we already have translations for 21 languages:

  • English
  • Bulgarian
  • German
  • Danish
  • Spanish
  • Spanish (Argentina)
  • French
  • Italian
  • Japanese
  • Dutch
  • Novergian
  • Polish
  • Brasilian
  • Russian
  • Chinese simplified
  • Slovak
  • Romanian
  • Indonesian
  • Turkish
  • Finnish
  • Portuguese

If you want to contribute a translation for your language, the process is quite easy and will take you about 10 minutes:

  • Download the French file and replace all the French strings with your translations (the file also contains the English strings)
  • Rename the file with your language ISO code
  • Send the translated file to my email address

Leverage the form framework

The filters, new, and edit views are powered by the form framework, which means that you can leverage all the features of the form framework to tweak your admin generated modules.

That was a very quick technical overview of the new admin generator. It you want to learn more, you can read the generator chapter of the symfony book.

Published in #Living on the edge