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:
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.
The Category
list has several interesting features:
- Each category
id
is a link to theedit
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
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.
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:
For better usability for the end user, the new admin generator also uses a lot of flash messages on the list
and edit
views:
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 credentialsfields
: To define the default fields configurationlist
: To define the list view configurationfilter
: The filter has now its own entry for its configurationform
: This is a virtual view as it is only used as the default configuration for thenew
andedit
configurationsnew
: To define the new view configurationedit
: To define the edit view configuration
The generator.yml
configuration file implements some inheritance rules between these entries:
new
andedit
inherits fromform
which inherits fromfields
list
inherits fromfields
filter
inherits fromfields
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 theCriteria
used for thelist
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.
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?
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.
@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.
Wow very nice ! I will try it this week-end :)
Thanks Fabien !
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":
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?
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!
Great work fabien. Any idea when the Doctrine version will be available?
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!
@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#
@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
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.
@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.
I'm interested are nested sets supported in new admin generator (as mentioned in concept)?
@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 :)
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.
Very nice! Waiting for 1.2 relase.
@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
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.
@Praveen Prasoon: In the routing.yml configuration file. I have updated the post.
GREAT ! GREAT ! GREAT ! GREAT ! GREAT ! GREAT ! GREAT ! NOW i can start my project!!!
I hope read more articles about SF 1.2!!!
Cheers
@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 :)
Wouah, nice feature. Looks impressive.
Is it me or Fabien was inspired by the newforms/newforms-admin branch of Django (now in 1.0) ?
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
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.
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?
@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
@GaryFx: You are right. I'm working on a way to make it more simple for newcomers. Any idea is greatly appreciated ;)
is there any estimation for the doctrine implementation?
@dereck: the first implementation has already been commited. So, it will be in beta2
@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
@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.
Hi, i am not expert, but does REST mean that new generator can be used as full remote api to project ?
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
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.
Istvan> The best place to ask for help is the symfony-users mailing list on google groups : http://groups.google.com/group/symfony-users