A recipe for editing & translating over 100 fields
I recently released a new contributed module to aid translation on Drupal 7 sites: Entity Translation: Separated Shared Elements Form (ETSSEF). Yes, it has a convoluted name! It finally resolves a suggestion from years ago in an Entity Translation project issue, to allow editing untranslatable fields separately to translatable ones. One of our clients has a multilingual product database site with a few hundred fields on their content, so anything like this that could reduce the size of their editing forms is useful. I figure the best way to demonstrate this is with a recipe that blends it together with some other super (but generally obscure) modules. I hope you can spot parts that may be helpful for your projects!
- Drupal 7, and at least PHP 5.6
- A content type, with well over a hundred fields
- The Entity translation module
- Several languages
- A nice admin theme, e.g. Adminimal
- My new ETSSEF module
- The Field SQL Blob Storage (from my colleague James Silver), Field Storage UI, Field SQL norevisions and Field SQL Storage Group Load modules
- The Field Attach Form Selective sandbox module (also from James)
- A generous helping of persistence and attention to detail
- A pinch of creative ambition
Take a look at each of these project pages linked above for a flavour of what each module will bring to the mix.
Recipe Difficulty Rating: Intended for experienced Drupal cooks only; others may prefer to try our takeaway service.
- Enable each of the modules listed above, and set the admin theme to be used.
- Configure the various Field storage modules. Try to understand what each of these is doing, and adjust appropriately for you if necessary:
// Turn off storage of revision info for your content type that has many fields. $bundle = 'farmer'; variable_set('field_sql_norevisions_entities', array( 'node' => array( $bundle => 1, ), )); // Default to using Blob storage (1 table instead of 1000s). variable_set('field_storage_default', 'field_sql_blob_storage'); // Relabel the options in the UI to make the distinction clear. variable_set('field_storage_ui_relabel_options', array( 'field_sql_blob_storage' => 'Retrievable only', 'field_sql_storage' => 'Sortable & Filterable', )); // Load default-sql-storage fields in batches of 20 (instead of 1 at a time). variable_set('field_sql_storage_group_load_max_fields', 20);
- Set up your content type with many many fields. Choose 'Retrievable only' for the storage type for any fields that don't really need to be used for querying against, or sorting/filtering in lists. This will improve performance, as all the field data for those is stored together in a 'blob' column in the database so can be loaded (& unserialized) in a single go, rather than requiring select queries from so many different individual database tables.
- Configure nodes of this type to use entity translation (field translation) and head to the entity translation settings at /admin/config/regional/entity-translation. Set their 'Shared elements on translation forms' setting to 'Only display on their own separate forms':
This ensures that untranslatable fields are just edited on the initial Edit tab (in a 'Shared' secondary tab); with just translatable fields in the translation forms. When there are so many fields, it's worth slimming down forms as much as possible! This also has the advantage that untranslatable data can be edited without needing to touch any specific translation.
- Override the edit form for your node type in a custom module, to use the Field Attach Form Selective module, so that fields are only shown on the form as they are filled in. This vastly reduces the amount of stuff on the form. I've written a gist that demonstrates this, and includes wiring it up to work nicely with ETSSEF. You must copy the entire contents of
node_form()from node.pages.inc in Drupal core into the
farmer_node_form()function, but replace the call to
field_attach_form()at the bottom, with a call to
field_attach_form_selective(). Use the same arguments.
- I then added some classes and CSS to the secondary tabs on the page to show the flag icons next to each language, as well as repeating the current tab name in the page title. I then added CSS to fix the page header in place so that editors easily retain that contextual information as they scroll down the giant forms. Otherwise it's too easy for them to forget which language they are editing!
Season to taste
Now when you edit your content type, your forms will be much slimmer and your site will run far smoother with hundreds of fields. As with any recipe, take the bits of this that are to your taste, ignore others, or blend it into your own creations! This was only for D7, so bringing the ideas over to Drupal 8/9 in some form would be an obvious thing to do. I’d love to hear of other ingredients you use to help when editing content forms with enormous amounts of fields, translatable or not.