List your entities
In this PR a simple list for the Example entity is implemented. The crucial part here is that the API is described using our list-builder metadata. The metadata has now to be written using the XML format and replace the current FieldDescriptors (actually not really replacing, they are using them under the hood).
The file contains a few of the above properties, explaining the name, which translation should be used for the frontend and also from which field of which entity the data can be retrieved. This is necessary because we also build the query for the database based on this definition.
This metadata will be transformed for our generic list component, which will only retrieve the values important for it to save bandwidth. The other important thing is to create an Admin class, which was already existing in the 1.x series of Sulu, although some of the interfaces did slightly change.
Lets have a look at the new getRoutes function in the Admin first. It will return all the routes for the administration interface offered by this bundle. A route receives an ID (example_event.event_datagrid), a path (/events) and a view (sulu_admin.datagrid) as mandatory arguments. The view is registered in the frontend and will be rendered in the main area of our admin if the route is requested.
The cool thing is that we have some predefined views, which can be further customized using options on the route. So our datagrid view accepts a resourceKey option that tells the datagrid which kind of entities it should load using the previously defined metadata (which also have to be registered in the sulu_admin config, the example uses a PrependExtension for that). The other options let you decide which title to show and what adapter the list uses. The adapters for the Datagrid are another interesting topic on its own because besides the few predefined ones it is easily possible to add your own ones, but that's again a topic for a separate blog post.
The NavigationItems are now simply returned by the getNavigation method instead of being created in the constructor. The reason for this is that it should give you less headache when overwriting an Admin service.
Otherwise the code is quite similar, except for the NavigationItem which has a new setMainRoute function that takes the ID of one of the previously defined routes. A click on this NavigationItem in the frontend will then redirect the user to the given route.
Make your entity editable
The second PR shows how to implement an add and edit form for the custom Event entity. There are a few more routes added to the Admin class:
There are two separte forms for adding and editing registered, because they should also have a separate route. Each form is split into two different kind of views: The ResourceTabs already receives a resourceKey and loads the entity using this key and the ID from the route. We have decided to implement it this way to avoid reloading the same entity on every single tab.
Each tab in the form (in the above example there is only one per form) is a form view and will receive the loaded entity from the ResourceTabs view. The form view then defines the title of the tab it is shown in and the backRoute defining to which route a click on the back button redirects.
Then the form will display the loaded entity using some metadata. We have decided to use the properties part of the template XML files, so we extracted that and they can be put into the Resources/config/forms directory (or whatever you have defined in the mentioned PrependExtension).
This XML should look fairly familiar to Sulu users. The properties only define a name, type and a title to display this information in a form. All the other tags from the template XML also work in here since the form for content and for any other entity now uses the same mechanism. That means no more templates to render on the server have to be created for datagrids or forms.
Offer a field type to assign your entity
Since it doesn't make a lot of sense to only have a list and a form on its own we have decided to make it easily possible to create a new field type for forms to assign the entities. This is what's being used in the last PR of this blog post.
And again there is only some configuration to add to retrieve this functionality.
Using the prependExtension every bundle can hook some more configuration into the sulu_admin configuration. Here you have to pass some more fieldTypeOptions. There are some "abstract" field types that can be customized when useing with your entity. In this example we say that we'd like to have a selection for our event, the selection being the "abstract" field type and event_selection the name of the registered field type. The array that is indexed by this key contains some properties which will be passed to the "abstract" field type.
E.g. the auto_complete version of the event_selection only needs to know which entity to load, which of its property should be used to display in the result set and after which properties should be searched.
The event_selection field type is a little bit more complicated. It has similar properties but in addition it also needs to know which datagrid adapter to use since it shows a datagrid internally. It also allows to customize some texts and icons as well.