I use the D8 core render service for generating markup that is indexed in an external search service. The indexing is happening on hook_entity_update
, where I call my indexing service. My custom indexing service is then using the core render service for creating the markup.
Example with static service call:
// Get the render array for the teaser.
$viewBuilder = \Drupal::entityTypeManager()
->getViewBuilder($entity->getEntityTypeId());
$render_array_teaser = $viewBuilder->view($entity, 'teaser');
// Generate the markup from the render_array.
$renderer = \Drupal::service('renderer');
$rendered_teaser = $renderer->renderPlain($render_array_teaser);
// When called in hook_entity_update $rendered teaser has a crappy
// default markup in it as a 'teaser' view mode and the correct twig
// templates don't exist in the backend theme.
This works fine when called from drush. But when called from hook_entity_update()
the renderer has the wrong theme context. As the node edit form that triggers the update uses the backend theme, the renderer gets also the backend theme as context instead of the default theme.
The renderer gets the current theme injected with the ThemeManager
object.
See core services:
renderer:
class: Drupal\Core\Render\Renderer
arguments: ['@controller_resolver', '@theme.manager','@plugin.manager.element_info', '@render_placeholder_generator', '@render_cache', '@request_stack', '%renderer.config%']
How can I initialize the service but provide my own version of the ThemeManager object?
There is a setter method on the ThemeManager
object where I could easily set the right theme. But I need to hand this over to the renderer.
e.g.:
$my_theme_manager = \Drupal::service('theme.manager');
$my_theme_manager->setActiveTheme('my_frontend_theme');
// How to get the service with this alternative context?
// e.g. something like that.
$service = \Drupal::Service();
$service->setService('renderer');
$service->setArgument(['@theme_manager' => $my_theme_manager]);
$default_theme_renderer = $service->getService();
Or is there some way to alter the ThemeManager Object when it is initialized? Before it is injected into the render service? So I can set the correct theme in an event or alter hook?
I know that I can alter the service in general by implementing the ServiceModifierInterface
but this will modify the container when it gets created as far as I know, and is not a way for manipulation during runtime.