What circumstances could make setting a title to a regular custom entity edit form fail completely? The title displayed is the result of calling $entity->label(). _title or _title_callback in routing.yaml are completely ignored, the first isn't used, the second isn't called at all. There's no title resolver, route subscriber, special controller, theme manipulating #title, or any other trickery involved. A dozen or so similar entities all work as expected in their edit form. The entity is simply extending ContentEntityBase, adding a few fields, nothing different from all other entities in the module. The form extends ContentEntityForm and the problem remains if I remove whatever small task I used buildForm() and processForm() for, leaving it with nothing but a save() to save the entity in the end.
1 Answer
A module for a custom entity can add entity routes in two ways. In a *.routing.yml file as stated in the question and in a route-provider as discussed in the comments. If you use both methods one method could overwrite the other so that changing for example *.routing.yml would have no effect.
There are of course many other ways to change either the routing table or later the title until it is finally rendered.
The routing table is built when you install the module or for already installed modules when you clear the cache. You can check the result with the Devel module /devel/routes.
Additonally, there are two ways the page title is determined. A #title in the main content has priority over the title from the routing information.
Edit:
@Gábor found out it is connected to translatable entities. The #title is added by the content translation module:
Drupal\content_translation\ContentTranslationHandler::entityFormAlter
public function entityFormAlter(array &$form, FormStateInterface $form_state, EntityInterface $entity) {
...
// Adjust page title to specify the current language being edited, if we
// have at least one translation.
$languages = $this->languageManager->getLanguages();
if (isset($languages[$form_langcode]) && ($has_translations || $new_translation)) {
$title = $this->entityFormTitle($entity);
// When editing the original values display just the entity label.
if ($is_translation) {
$t_args = ['%language' => $languages[$form_langcode]->getName(), '%title' => $entity->label(), '@title' => $title];
$title = $new_translation ? t('Create %language translation of %title', $t_args) : t('@title [%language translation]', $t_args);
}
$form['#title'] = $title;
}
-
That's not the problem I described. I have a completely functional module with many entities, all set up correctly, title callbacks, routing in place, where some entities use neither the
_titlenor the_title_callbackset in the routing. Obviously, I can't copy a whole module here (and couldn't do it because it's internal source code, not public, anyway) but believe me, I have more than a decade of D development under my belt, so I know how to set up a custom entity. :-)Gábor– Gábor2025-08-31 09:58:57 +00:00Commented Aug 31 at 9:58 -
In these particular entities, while they have nothing different to the ones that behave properly, the edit form title always falls back to an automatic call to
label(), no matter how I specify title or callback. I checked six ways to Sunday, all possible debug printouts show that the title callback is properly in place, just not called by the system. So, I didn't really ask in the OP to debug it for me, just pointers to what circumstances might lead to such an anomaly.Gábor– Gábor2025-08-31 09:59:03 +00:00Commented Aug 31 at 9:59 -
In my quest to find a possible reason, I tried all of the above, a title provider to provide a title, a route subscriber to modify the route, a route provider to provide the route, all ideas. I don't plan to use any of those normally in the module, the normal operation is regular routes and a title callback in
routing.yml, nothing else. All the rest was just for debugging.Gábor– Gábor2025-08-31 12:27:33 +00:00Commented Aug 31 at 12:27 -
I think I've addressed everything in the question. The conclusion: First check that the route details you put in routing.yml ends up in the routing table. Second, every place in Drupal adding or changing form/render arrays can put a title in #title which overrides the route title.4uk4– 4uk42025-08-31 15:57:22 +00:00Commented Aug 31 at 15:57
-
OK, then we conclude without conclusion. As I said, all debug printouts show that that title callback or the title string is in the route details, where it belongs. Still, Drupal shows the
label(). As to the second, there's no assignment to a $form['#title'] anywhere in the module: not only not with these entities, but nowhere. There are#titles of the various form elements but those belong to the elements themselves and none of those receive the value of $entity->label(). So, I'm still stuck. I know it's nigh impossible to solve it from afar but — we didn't solve it.Gábor– Gábor2025-08-31 18:18:29 +00:00Commented Aug 31 at 18:18
route_providerhandler above the class. This handler class is an extra PHP file which implements EntityRouteProviderInterface. And with debugging I assumed you look for existing code overwriting the content of the module routing.yml, not add new code.