I'm working on a contrib module port to D8 and can't seem to find appropriate Entity API documentation to figure out how to get a rendered field in a specific language. I have a controller that needs to generate some custom XML based on field data, and I would like to be able to use core's language detection to get an appropriately translated field that can be used to generate this XML.
(As an aside -- I realize that core services could be leveraged to get field data in a RESTful way, but the XML schema needed here is quite custom and warrents its own REST endpoint and controller.)
Consider a route for a REST endpoint, that simply accepts the entity and field specifics needed, via the path like:
mymodule.xml_field:
path: '/mymodule/xml/field/{entityType}/{entityId}/{fieldName}/{displayName}'
defaults:
_controller: '\Drupal\mymodule\Controller\MymoduleXmlControllerField::xmlController'
requirements:
_access: 'TRUE'
And a matching controller method like:
class MymoduleXmlControllerField implements ContainerInjectionInterface {
// ... Entity manager and other services are injected ...
public function xmlController($entityType, $entityId, $fieldName, $displayName) {
$entity = $this->entityManager->getStorage($entityType)->load($entityId);
$field = $entity->{$fieldName}->view($displayName);
// ... Extract needed data from $field, generate XML and return it in new Response() object ...
}
}
This works great until I try to leverage content translations. If I use default URL language detection and then request the XML via a language specific path (with a prefix, like: /es/mymodule/xml/field/...
) the default lanaguage is always still used in the $field output instead of the spanish (es) translation (which I've confirmed is available on the entity).
My initial expectation was that the entity load call, or the field view call, would internally trigger language detection (as in D7), but I see that it's now up to my controller to manually specify and set a langcode somehow as the loaded entity object seems to be language neutral. I'm just wondering how I do this given that the high-level entity/field interfaces I'm using don't take a langcode paramater, and (at the time of writing) the entity API docs don't seem to address this.
I'm assuming that I need to use a setter method somewhere on the entity or fieldlist object to declare a langcode before calling the view method. It looks like I can get the detected language easily via an injected language manager:
$langcode = $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
But I'm not sure where to go from there.