Each day, between migrations and new projects, more and more features are becoming available for Drupal 8, the Drupal community’s latest major release. In this series, the Acquia Developer Center is profiling some prominent, useful, and interesting projects--modules, themes, distros, and more--available for Drupal 8. This week: Inline Entity Form.
The Drupal 8 port of Inline Entity Form was started by Florian Weber (webflo) in January 2014. His work was continued by Janez Urevc (slashrsm) roughly a year later. The big, final round of round of porting efforts happened in February 2016, when Ted Bowman (tedbow), Bojan Živanović (bojanz) and Janez Urevc collaborated, spending more than 3 months of developer time bringing the port to its first Drupal 8 beta release.
Their work was sponsored by Ueberbit, Examiner.com, Commerce Guys, and Acquia’s D8 Module Acceleration Program. Many hours of volunteer work were contributed over and above the sponsored time. Thank you!
I spoke with Bojan Živanović and Janez Urevc about the module and the porting process. Bojan works for Commerce Guys as the development lead for Commerce 2.x. He has been working with Drupal since 2007 and has left his mark on Views, Views Bulk Operations, Inline Entity Form, and many Drupal Commerce contributed modules. Janez Urevc was one of the initial founders and leads of the Drupal 8 media initiative and is a senior engineer and team lead at Zürich-based MD Systems--themselves heavy contributors to Drupal 8.
What does the Inline Entity Form Module do? And why is that important?
Inline Entity Form (aka “IEF”) extends the functionality of entity reference fields in Drupal, to allow referenced entities to be created, edited, deleted on the fly. Changes to the referenced entities are only saved when the main form is saved.
Though the problem space sounded a little dry and abstract to me at first, understanding it also helped me understand why IEF is installed on roughly 68,000 Drupal sites. :-)
This is a solution to Drupal’s UX being “inside out” for some purposes. Doing things the “traditional Drupal way,” if a node needs to reference another entity or category, that needs to be created first. This can be frustrating, since it feels like one has to start from the end and work towards the beginning. IEF can reduce frustration by providing a more intuitive UX.
eCommerce listings are a good example. In shopping catalogs, it’s common for a Product (“My T-Shirt”) to have a set of varying Attributes (size and color in this case). Each combination of Product Attribute values is called a Product Variation (red/small, blue/small, green/medium, etc.). Each Product Variation has a price and a SKU (“Stock Keeping Unit”, a unique ID code).
Drupal Commerce 1.x followed the unintuitive “Drupal way” pattern: To make a t-shirt product listing with all available options, you had to an entity for each SKU (in our case: red/small, blue/small, green/medium, etc.) first before you could create the t-shirt catalog form. Once you had created all the necessary SKU’s, you could then reference those entities manually on the parent form. Bojan admits, “Naturally, people were not happy about using two different UIs to accomplish what was essentially a single operation.”
Now, using IEF, you can create, edit, and delete the relevant entities directly in the parent form (or even refer to existing ones if you already have them in your catalog). In our eCommerce example, I can create the main t-shirt form I need, add all of my SKU variations to it, and save it--all in the same UI.
Modeling this sort of data and relationships is one of Drupal’s strengths. Bojan gets to the heart of the matter, “Data models are full of 1:n relationships (“order has multiple line items”, “page has multiple paragraphs”). Implementing this in Drupal without IEF is a challenge. IEF is important because it allows proper data models to be implemented without sacrificing UX for the site’s administrative end users. The entities are also aware of the fact that they are embedded, via parents, same way the field widgets are. This allows them to be nested as many times as needed.”
Simple and Complex IEF Widgets
Inline Entity Form provides two widgets for administrative users, the “simple” widget and the “complex” widget.
The simple widget shows a row for each reference, with the entity form inside. This is the “field collection” UX.
The complex widget shows a table with a row per reference, with edit/delete links that open the edit form / delete confirmation form in the row underneath it. It can also have additional available operations like referencing existing entities.
“Bojhan Somers (the UX lead for Drupal 7) designed the current complex widget, modeling it after the formatter settings form (where the formatter settings get loaded underneath the formatter itself). Ryan Szrama used that mockup to create a sandbox module called “Inline Product Form”. Once we started Commerce Kickstart v2, I picked up that code and rewrote it to make the entity form handling pluggable, separating the Commerce-specific parts. Inline Entity Form was born!” continues Bojan, “The key difference between Inline Entity Form and other solutions is keep the inline changes (created/updated/deleted entities) in one place and then save them only when the parent form is saved. This pattern matches users’ expectations about such forms, rather than trying to bend them to our “perfectly logical” but counterintuitive Drupal data-modeling concepts.”
Has Drupal 8 changed this module?
Bojan summarized one of the big challenges they faced and gave me three examples of how IEF has changed in Drupal 8:
- Getting it right: Inline Entity Form has to do a lot of work behind the scenes, which results in complex code. Drupal 8 changed and introduced many concepts, such as entity validation, form modes and displays. These changes influenced the implementation, and added many challenging problems which sometimes took several rewrites to get right.
- Usability: We clarified the purpose of the two field widgets. They used to be called “Single” and “Multiple”. Once it became obvious that there’s no reason to limit the single widget UX to single cardinality fields (and multiple to multiple), we renamed them “Simple” and “Complex”. By expanding the scope of the “Single” widget, we matched the UX of the Field Collection module, allowing it to one day rebase itself on top of Inline Entity Form.
- Abstraction: We decoupled the actual inline entity form (used to edit a single entity) into a stand-alone form element, which can now be used outside of the field widget scope. The first module that took advantage of this was Entity browser, that was able to implement “Entity form” widget plugin using this feature. This matches what core did with the Autocomplete widget -> form element separation (see: https://www.drupal.org/node/2418529).
- Separation of logic and presentation: We did a lot of work to separate the inline form processing code from the actual widgets. There is still a lot of cleanup to be done, but the idea is for widgets to be as slim as possible, allowing people and projects to implement alternative widgets with their own UX.
Janez picked up here, “The biggest change that we needed to adapt to was entity validation. In Drupal 7 we relied on form validation, while now we needed to build and validate the entities themselves. As with other complex Drupal modules, porting IEF to Drupal 8 took a long time due to three primary factors:
- Adapting to and keeping up with changes throughout Drupal core betas.
- Dealing with technical debt from the previous module branches.
- Porting to new APIs and ensuring complete test coverage. I have to say, writing the tests sometimes took as long as writing the code in question.
A bright future for IEF and Drupal
“Inline Entity Form is a great example of community collaboration,” Janez explains, “Something that was born to solve problems in eCommerce was made broadly useful thanks to visionary planning and good software design. This is why the module got on our radar in the Media Initiative, which resulted in more resources being dedicated to it and a more sustainable development process. Many other parts of the community have identified Inline Entity Form as something that might be useful to them. This could result even more exciting use-cases and a bright future for the module.”
“IEF is also a taste of how the future of the Drupal contributed module space might look. Instead of having a lot of narrow-scoped modules that do one little thing in an idiomatic, non-collaborative way, I’m hoping we’ll see more and more generalist modules sharing the standard tools that Drupal 8’s core offers (entities, fields, etc.) to solve similar problems in different areas.”