0

I want to force all content to be created using my primary site theme. I want to do this because I am using a renderer in MYMODULE_node_presave() like this:

function MYMODULE_node_presave(NodeInterface $node) {
  $renderer = \Drupal::service('renderer');

  $content_type = $node->getType();
  if ($content_type == 'page') {
    $viewmode_render = $node->get('field_text_main_to_render')
      ->view('rendered_output');
    $processed_display = $renderer->renderPlain($viewmode_render);
    $node->set('field_text_main_display', "$processed_display");
    $node->field_text_main_display->format = 'processed';
}

My site uses Bartik as the main theme and Seven as the admin theme.

Under Appearance settings (/admin/appearance), I have checked the preference Use the administration theme when editing or creating content. This ensures that nodes are rendered in Bartik upon creation in the UI.

However, when I resave nodes on /admin/content, the nodes are re-saved with Seven, instead of Bartik. So I added a ThemeNegotiator:

/**
 * Select the correct theme for various routes.
 */
class ThemeNegotiator implements ThemeNegotiatorInterface {

  /**
   * {@inheritDoc}
   */
  public function applies(RouteMatchInterface $route_match) {
    return $this->negotiateRoute($route_match) ? TRUE : FALSE;
  }

  /**
   * {@inheritDoc}
   */
  public function determineActiveTheme(RouteMatchInterface $route_match) {
    return $this->negotiateRoute($route_match) ?: NULL;
  }

  /**
   * Select the theme for special cases.
   *
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The currently matched route.
   *
   * @return bool|string
   *   The theme name to use (string) or false (bool).
   */
  private function negotiateRoute(RouteMatchInterface $route_match) {
    $route_name = $route_match->getRouteName();
    // Admin content page must use node render theme.
    // Why: "Save content" action will use the theme of this page.
    if ($route_name === 'system.admin_content') {
      return 'bartik';
    }
    else {
      return FALSE;
    }
  }

}

Now, when I run a bulk node resave on /admin/content, nodes are rendered correctly with Bartik.

Next, I installed the Feeds module. Now, when I import nodes via CSV using Feeds, they are rendered using Seven, not Bartik. I want to force these nodes to also be rendered using Bartik, but I don't know how to do that. (For example, if there was a way to use negotiateRoute in the ThemeNegotiator, that would be fine, but I don't know how to set that up.) Any ideas?

1
  • 1
    I would use the theme negotiator in a sub-request, where the controller returns a response with the rendered node. See this as example how to make a sub-request and also how to avoid a core bug: drupal.stackexchange.com/questions/303396/…
    – 4k4
    Aug 8 at 18:40
0

Content can be rendered in any theme, and is rendered in the current theme at any given time. You do not save content as belonging to a theme. Rather, if you want different themes to show content, you can try the Switch Page Theme module.

2
  • "You do not save content as belonging to a theme." Yes, generally this is the case. But as stated in my question, I'm using hook_node_presave() to render some fields and save the rendered output, which is saving the content as belonging to a specific theme. So I need to control which theme is used to render the content for this specific content save. Aug 7 at 19:49
  • Those elements will be rendered in the current theme at the time of rendering. In your case, that is probably on the path at which the import happens, so you could use the above module to set the theme for the feed path. That said, it doesn't seem like a great architectural design to be storing the rendered HTML - what if you want to change your theme in the future, or search on that field. Usually you'll want to store data, and render on output, caching the rendered output if it's a costly build. I personally would consider architectural restructuring over theme manipulation.
    – Jaypan
    Aug 7 at 21:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.