Archives


Master Symfony2 fundamentals

Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).
trainings.sensiolabs.com

Discover the SensioLabs Support

Access to the SensioLabs Competency Center for an exclusive and tailor-made support on Symfony
sensiolabs.com

Fabien Potencier
New in symfony 1.2: The admin generator
by Fabien Potencier – October 31, 2008 – 36 comments

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.

Comments RSS

  • gravatar
    #1 Matthias said on the 2008/10/31 at 22:50
    wow..!

    I didn't have a look at the generated stuff. From this post, the chapter in the book and watching some of the changesets I wonder if the cool more advanced features are already possible, if they are planned or if you think that they must be implemented by plugins/widgets/whatever?

    - "inline editing" of records of foreign key tables
    - multi column sort
    - I also was hoping to get a better way of configuring the redirect routes.

    probably the only way to really get what I want is creating my own generator and theme ;-)

    anyway, it looks like a big step forward!
    great news! thank you.
  • gravatar
    #2 Fabien said on the 2008/10/31 at 22:54
    @Matthias: I have tried to be very backward compatible with the new admin generator. That said, a lot of advanced features are planned for symfony 1.3 as the foundations are already quite powerful for 1.2.

    So, expect more great things like better format support (HTML, XML, JSON, ...), multi-column sort, inline editing, adding foreign record in pop-ups, ...

    symfony 1.2 will now enter its beta state, but it is still possible to make the admin generator more powerful and more configurable if possible before the final release. So, feel free to create tickets, "re-activate" old ones, or discuss on the dev mailing-lists changes you want to see in this release or the next one.

  • gravatar
    #3 Hugo said on the 2008/10/31 at 23:58
    Wow very nice ! I will try it this week-end :)

    Thanks Fabien !
  • gravatar
    #4 Luciano said on the 2008/11/01 at 00:18
    Well, I hope this post to be the first of a large list of posts about the new symfony version!!
    I think there are some mistakes in the post, under the section "More configurability":
    * form: This is a virtual view as it is only used as the default configuration for the new and view configurations
    * view: To define the edit view configuration
    Where it says "... view configurations" and "view:" shouldn't it say "... edit configurations" and "edit:"
    Keep working and I'm looking forward to the new version, I really hope it'll be out soon.
  • gravatar
    #5 J. Philip said on the 2008/11/01 at 00:19
    That looks great Fabien, thank you for the hard work.
    Is there a chance the generator could handle many to many relations with payload (Fields in the relation table), I asked about this in the forum but got no answer?
  • gravatar
    #6 Beau said on the 2008/11/01 at 00:32
    This is incredible. Soon we're barely going to have to write our applications at all, because symfony will generate 90% of them for us!
  • gravatar
    #7 Tiago Ribeiro said on the 2008/11/01 at 00:51
    Great work fabien. Any idea when the Doctrine version will be available?
  • gravatar
    #8 denderello said on the 2008/11/01 at 01:34
    I love the new sfPropelRouteCollection object although it's not the main feature in this article. tried it shortly after reading and now my controllers are so damn skinny!
  • gravatar
    #9 Matthias said on the 2008/11/01 at 01:36
    @Fabien: I'm also a bit confused as I thought the new admin generator would be based on the 'data grid' [1]. I this data grid planned for 1.2? or is this obsolete now?

    Some more information about what is planned and what is WIP (for 1.2 / 1.3) would be pretty nice. :-)

    [1] http://groups.google.de/group/symfony-devs/browse_thread/thread/b9e4a8592f608c76?hl=de#
  • gravatar
    #10 Fabien said on the 2008/11/01 at 07:26
    @Luciano: Thanks, typos fixed

    @Tiago Ribeiro: We will wait 1 day or 2 to really stabilize the Propel version, and then we will work on the Doctrine one. So, symfony 1.2 will have the new admin generator for both Propel and Doctrine

    @Matthias: The Grid is not obsolete. We have just decided to timeframe the symfony 1.2 release and so, we had to make some choices. The Grid widget is still on our todo list and is now planned for symfony 1.3.

    @Enlightened: You can send the file to fabien.potencier [at] symfony-project.com
  • gravatar
    #11 Kiril Angov said on the 2008/11/01 at 19:30
    Fabien, I have been using Symfony 1.2 on a current project and I had to use the admin generator for a pretty complex administration of a site which will have a frontend too. Now, if I understand correctly, if I do a svn up on my symfony-1.2/ I will checkout the new admin generator and thus my backend will stop working. Is it/will it be possible to use symfony 1.2 with the old admin generator and switch to the new one for certain modules? That would really really easy the transition as I do not mind moving old modules to the new generator but I cannot do it overnight and people want progress. What are the options for people like me? Thanks for everything.
  • gravatar
    #12 Fabien said on the 2008/11/01 at 20:03
    @Kiril Angov: Have no fear. The old admin generator is still there. The new one exists along side the old one. The task name is not the same and all the classes have different names.
  • gravatar
    #13 Dragan Bosnjak said on the 2008/11/01 at 21:04
    I'm interested are nested sets supported in new admin generator (as mentioned in concept)?
  • gravatar
    #14 Kiril Angov said on the 2008/11/01 at 21:54
    @Fabien
    Perfect, could have not expected anything less, I am sure I am not the only one feeling bad when seeing how much stuff you get done and me... oh well :)
  • gravatar
    #15 IvanK said on the 2008/11/02 at 11:01
    This is a really great foundation you've built, but as with the old admin generator it has one major miss which forced me to do heavy customization before - there is no easy way to administrate hierarchical structures. For example if 'Article' has many 'Image', how do you have a list with only the images of the article? - I know you can achieve this with filters, but it feels a bit hackish. Also if this was a feature of the default generator, we could have auto generated breadcrumbs and tree view lists... I've seen some proposals for this in the wiki, but I fear they're left only as that.
  • gravatar
    #16 Kazimieras said on the 2008/11/02 at 12:08
    Very nice! Waiting for 1.2 relase.
  • gravatar
    #17 Fabien said on the 2008/11/02 at 12:09
    @IvanK: The goal for 1.2 was to build the foundation. For 1.3, we will add a lot of features, like inline editing. It was not possible with 1.0, it will be quite easy with the new admin gen of 1.2
  • gravatar
    #18 Dragan Bosnjak said on the 2008/11/02 at 13:44
    > For 1.3, we will add a lot of features
    :O
    Stop teasing us!
  • gravatar
    #19 Praveen Prasoon said on the 2008/11/03 at 11:54
    Thanks for the new admin generator.
    I am facing a problem with it.

    A REST architecture

    The new admin generator is based on a REST architecture. This means that you need to create a REST collection route to bootstrap a new admin module. Here is an example for the DemoArticle model with all the needed options:

    Where we need to define the rout rule?

    Please sugegst.
  • gravatar
    #20 Fabien said on the 2008/11/03 at 13:56
    @Praveen Prasoon: In the routing.yml configuration file. I have updated the post.
  • gravatar
    #21 puentesdiaz said on the 2008/11/03 at 14:27
    GREAT ! GREAT ! GREAT ! GREAT ! GREAT ! GREAT ! GREAT !
    NOW i can start my project!!!

    I hope read more articles about SF 1.2!!!

    Cheers
  • gravatar
    #22 IvanK said on the 2008/11/03 at 17:27
    @Fabien - yeah, i though as much, but the thing is - I've seen inline editing implemented in other cms-es (namely rails' streamlined) and if it's what I think it's going to be (like an ajax window) I don't think it'll solve the problem of deep hierarchical trees as it'll break at the secound level of nesting. This is very common problem for me (virtually every admin I do has at least 3 level nesting ( like category -> project -> image for example). How does one solve this with the current setup (1.2) or with the proposed features? Am I missing something or is there an easier way. I'm going to do some customization anyway and with the great foundation like this I doubt it'll be all that hard, but it'll be awesome if it could do it for me :)
  • gravatar
    #23 NiCoS said on the 2008/11/03 at 23:22
    Wouah, nice feature. Looks impressive.

    Is it me or Fabien was inspired by the newforms/newforms-admin branch of Django (now in 1.0) ?
  • gravatar
    #24 NiKo said on the 2008/11/04 at 07:55
    NiCoS> Of course, symfony takes inspiration from everywhere something interesting exists. Checkout this blog post for example http://www.symfony-project.org/blog/2008/09/23/open-source-cross-pollination
  • gravatar
    #25 NiCoS said on the 2008/11/04 at 15:24
    This "of course" is really great for Symfony as such a strategy (to be inspired by / to borrow pieces of code from other projects and to say this officialy) is unfortunately not so obvious in a lot of projects.

    Pragmastism over integrism/paradigm (PHP is better than X & so on) is definitely a great value for SF.
  • gravatar
    #26 GaryFx said on the 2008/11/04 at 18:56
    I find "The new admin generator is based on a REST architecture. This means that you need to create a REST collection route" to be a non-sequitur. Routes are presented in chapter 9 as a usability and maintenance tool, not an architectural tool. It even suggests worrying about routes after development, making me think that many symfony users don't bother with routing.yml at all.

    I believe you can't assume the reader is familiar with REST, you can't even assume the reader is familiar with routes.

    On the implementation side, my initial reaction is that the admin generator ought to function out of the box, without making me do anything about routes. Can't it just use the example here as the default?
  • gravatar
    #27 fabien said on the 2008/11/05 at 20:47
    @Ivank: I have implemented deep nested forms in symfony 1.2 and in the admin generator. Read http://www.symfony-project.org/blog/2008/11/05/new-in-symfony-1-2-god-save-the-nested-forms for more information
  • gravatar
    #28 Fabien said on the 2008/11/05 at 20:48
    @GaryFx: You are right. I'm working on a way to make it more simple for newcomers. Any idea is greatly appreciated ;)
  • gravatar
    #29 dereck said on the 2008/11/05 at 22:37
    is there any estimation for the doctrine implementation?
  • gravatar
    #30 Fabien said on the 2008/11/05 at 23:11
    @dereck: the first implementation has already been commited. So, it will be in beta2
  • gravatar
    #31 IvanK said on the 2008/11/06 at 17:17
    @Fabien - I've read that and its really cool stuff but that's not what I had in mind - the use case I'm trying to solve is for example a category that has a lot of products. I want to add/remove products to a category and list all products in one category. This is not that hard to achieve with the current setup using filters, but what happens when I want to, for example add images to products? What I hope to be able to do is define relationships between modules in the admin - imagine telling it that "categories have products and products have images and details, and each detail has options" and it'll create the appropriate tree view for this in a side menu, and each of those elements will have some breadcrumbs telling the user exactly where he is. If this could be done, I think quite a lot of people will find this useful, if not, I think I'll be able to make a plugin with this functionality
  • gravatar
    #32 Fabien said on the 2008/11/08 at 12:06
    @GaryFx: I have updated the propel:generate-admin task to accept a route name or a model class name as it was the case with the old admin generator. In the latter case, the task will automatically create a route for you.
  • gravatar
    #33 SZ said on the 2008/11/13 at 17:22
    Hi, i am not expert, but does REST mean that new generator can be used as full remote api to project ?
  • gravatar
    #34 rccc said on the 2008/11/19 at 19:42
    Hello, thanks for this article. But what about the 'with_show' option : are you sure that it really runs with the admin-generator ?

    thanks
    rccc
  • gravatar
    #35 Istvan said on the 2008/12/07 at 00:00
    Hi!
    I'm new in symfony (and in any other php frameworks) but I like it and I want to make my next project in it.
    I've got a problem with the admin generator and the tutorials: I can't find out how to make the column names to be link to sort its columns. Can I ask for help here? (I asked in the forum as well)
    And it would be wonderful if the tutorials keep step with the newest stable version of Symfony.
    This framework is great, I hope I can help later in the develop somehow.
  • gravatar
    #36 NiKo said on the 2008/12/07 at 10:25
    Istvan> The best place to ask for help is the symfony-users mailing list on google groups : http://groups.google.com/group/symfony-users