Score:0

How to make it so theme function isn't used when editing a node with layout builder

au flag

I have the following two functions in my .theme file that I'm using to gleam various bits of information from both the path alias and internal URL of the page being viewed. They are:

function rtv_preprocess_block(&$variables) {
  $internal_path = \Drupal::service('path.current')->getPath();
  $current_path = \Drupal::service('path_alias.manager')->getAliasByPath($internal_path);
  $variables['current_path'] = $current_path;
  $variables['internal_path'] = $internal_path;
  $int_exp = explode("/", $current_path);
  $alias = \Drupal::service('path_alias.manager')->getPathByAlias($int_exp[1]);
  $is_layout = false;
  if (isset($int_exp[3]) and $int_exp[3] == 'layout') {
    $is_layout = true;
  }
  if (isset($internal_path) && !$is_layout) {
    $params = Url::fromUri("internal:/" . $alias)->getRouteParameters();
    $entity_type = key($params);
    if (isset($entity_type)) {
      $node = \Drupal::entityTypeManager()->getStorage($entity_type)->load($params[$entity_type]);
      $variables['section_nid'] = $node->nid->value;
      $variables['is_site_section'] = false;
      if ($node->type->target_id == 'sections') {
        $variables['is_site_section'] = true;
        $variables['current_section'] = $node->field_section_machine_name->value;
        $variables['current_section_title'] = $node->title->value;
      }
    }
  }
}

function rtv_preprocess_node(&$variables) {
  $internal_path = \Drupal::service('path.current')->getPath();
  $current_path = \Drupal::service('path_alias.manager')->getAliasByPath($internal_path);
  $variables['current_path'] = $current_path;
  $variables['internal_path'] = $internal_path;
  $int_exp = explode("/", $current_path);
  $alias = \Drupal::service('path_alias.manager')->getPathByAlias($int_exp[1]);
  $is_layout = false;
  if (isset($int_exp[3]) and $int_exp[3] == 'layout') {
    $is_layout = true;
  }
  if (isset($internal_path) && !$is_layout) {
    $params = Url::fromUri("internal:/" . $alias)->getRouteParameters();
    $entity_type = key($params);

    if (isset($entity_type)) {
      $node = \Drupal::entityTypeManager()->getStorage($entity_type)->load($params[$entity_type]);
      $variables['section_nid'] = $node->nid->value;
      $variables['is_site_section'] = false;
      if ($node->type->target_id == 'sections') {
        $variables['is_site_section'] = true;
        $variables['current_section'] = $node->field_section_machine_name->value;
        $variables['current_section_title'] = $node->title->value;
      }
    }
  }
}

While they work where I need them to, I'm having issues with errors related to the pages where the function is being run on a path that doesn't have an internal path... generally giving me an error that says "External URLs do not have internal route parameters."

You'll see in my above functions that I've been trying to set up various conditionals to try to avoid this error. I thought I had done so, but then I discovered that I was getting ajax errors when trying to use the Layout Builder that broke its functionality. I thought checking if the path had a third segment with "layout" in it that I could tell it not to fire the functions on the layout edit page, but it still is. Any thoughts on where my mistake is?

In addition, I'm open to recommendations on making these functions more streamline or perhaps merging them into a single function that works with both blocks and nodes.

More information: The site is broken up into sections and each section is defined by a node from a content type called "sections". The path aliases are setup so pages are domain.com/sectionname/pagename. These functions basically are creating some variables to be used in my twig templates so I can theme these different sections differently.

Here's the full ajax error:

Object { message: "\nAn AJAX HTTP error occurred.\nHTTP Result Code: 500\nDebugging information follows.\nPath: /layout_builder/update/block/overrides/node.3205/2/second/ce22e4bb-e72c-406e-a430-5b4a36267126?destination=/node/3205/layout&_wrapper_format=drupal_dialog.off_canvas&ajax_form=1\nStatusText: 500 Service unavailable (with message)\nResponseText: The website encountered an unexpected error. Please try again later.UnexpectedValueException: External URLs do not have internal route parameters. in Drupal\\Core\\Url->getRouteParameters() (line 583 of core/lib/Drupal/Core/Url.php). rtv_preprocess_block(Array, 'block', Array)\ncall_user_func_array('rtv_preprocess_block', Array) (Line: 287)\nDrupal\\Core\\Theme\\ThemeManager->render('block', Array) (Line: 433)\nDrupal\\Core\\Render\\Renderer->doRender(Array) (Line: 446)\nDrupal\\Core\\Render\\Renderer->doRender(Array, ) (Line: 204)\nDrupal\\Core\\Render\\Renderer->render(Array) (Line: 479)\nDrupal\\Core\\Template\\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 52)\n__TwigTemplate_3657feff99df006eb4f124e3a699561a084dfd8bb48a625bef56f6fce9484a7e->doDisplay(Array, Array) (Line: 405)\nTwig\\Template->displayWithErrorHandling(Array, Array) (Line: 378)\nTwig\\Template->display(Array) (Line: 390)\nTwig\\Template->render(Array) (Line: 55)\ntwig_render_template('core/themes/stable9/layouts/layout_discovery/onecol/layout--onecol.html.twig', Array) (Line: 384)\nDrupal\\Core\\Theme\\ThemeManager->render('layout__onecol', Array) (Line: 433)\nDrupal\\Core\\Render\\Renderer->doRender(Array) (Line: 446)\nDrupal\\Core\\Render\\Renderer->doRender(Array) (Line: 446)\nDrupal\\Core\\Render\\Renderer->doRender(Array) (Line: 446)\nDrupal\\Core\\Render\\Renderer->doRender(Array, 1) (Line: 204)\nDrupal\\Core\\Render\\Renderer->render(Array, 1) (Line: 148)\nDrupal\\Core\\Render\\Renderer->Drupal\\Core\\Render\\{closure}() (Line: 580)\nDrupal\\Core\\Render\\Renderer->executeInRenderContext(Object, Object) (Line: 149)\nDrupal\\Core\\Render\\Renderer->renderRoot(Array) (Line: 36)\nDrupal\\Core\\Ajax\\InsertCommand->getRenderedContent() (Line: 31)\nDrupal\\Core\\Ajax\\ReplaceCommand->render() (Line: 43)\nDrupal\\Core\\Ajax\\AjaxResponse->addCommand(Object) (Line: 47)\nDrupal\\layout_builder\\Form\\ConfigureBlockFormBase->rebuildLayout(Object) (Line: 26)\nDrupal\\layout_builder\\Form\\ConfigureBlockFormBase->rebuildAndClose(Object) (Line: 242)\nDrupal\\layout_builder\\Form\\ConfigureBlockFormBase->successfulAjaxSubmit(Array, Object) (Line: 39)\nDrupal\\layout_builder\\Form\\ConfigureBlockFormBase->ajaxSubmit(Array, Object, Object)\ncall_user_func_array(Array, Array) (Line: 69)\nDrupal\\Core\\Form\\FormAjaxResponseBuilder->buildResponse(Object, Array, Object, Array) (Line: 109)\nDrupal\\Core\\Form\\EventSubscriber\\FormAjaxSubscriber->onException(Object, 'kernel.exception', Object)\ncall_user_func(Array, Object, 'kernel.exception', Object) (Line: 142)\nDrupal\\Component\\EventDispatcher\\ContainerAwarForeEventDispatcher->dispatch(Object, 'kernel.exception') (Line: 229)\nSymfony\\Component\\HttpKernel\\HttpKernel->handleThrowable(Object, Object, 1) (Line: 92)\nSymfony\\Component\\HttpKernel\\HttpKernel->handle(Object, 1, 1) (Line: 58)\nDrupal\\Core\\StackMiddleware\\Session->handle(Object, 1, 1) (Line: 48)\nDrupal\\Core\\StackMiddleware\\KernelPreHandle->handle(Object, 1, 1) (Line: 106)\nDrupal\\page_cache\\StackMiddleware\\PageCache->pass(Object, 1, 1) (Line: 85)\nDrupal\\page_cache\\StackMiddleware\\PageCache->handle(Object, 1, 1) (Line: 48)\nDrupal\\Core\\StackMiddleware\\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)\nDrupal\\Core\\StackMiddleware\\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)\nStack\\StackedHttpKernel->handle(Object, 1, 1) (Line: 718)\nDrupal\\Core\\DrupalKernel->handle(Object) (Line: 19)\n", name: "AjaxError", stack: "@http://XXXXX.docksal/core/misc/ajax.js?v=9.5.5:92:32\n@http://XXXXX.docksal/core/misc/ajax.js?v=9.5.5:642:3\n" }
ajax.js:92:32

Thank you.

taggartJ avatar
cn flag
wrap $params = Url::fromUri("internal:/" . $alias)->getRouteParameters(); in a try catch seems $alias may not be what you expect ?
Score:1
cn flag

More general for the block, if you want to make sure the theme function is only used when viewing the node and not in other node routes like editing, then check the route name first:

function mytheme_preprocess_block(&$variables) {
  $route_match = \Drupal::routeMatch();
  $variables['#cache']['contexts'][] = 'route';
  if ($route_match->getRouteName() == 'entity.node.canonical') {
    $node = $route_match->getParameter('node');
    ...

More specific for the layout builder in node preprocess:

function mytheme_preprocess_node(&$variables) {
  $route_name = \Drupal::routeMatch()->getRouteName();
  $variables['#cache']['contexts'][] = 'route.name.is_layout_builder_ui';
  if ($route_name && !str_starts_with($route_name, 'layout_builder.')) {
    $node = $variables['node'];
    ...

I've also added the necessary cache data.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.