Score:0

How can I confirm a path is internal?

au flag

In my theme's theme file I'm using preprocess_node to create variables for a node based on the section of my site its in, and that's figured out by checking the path's alias.

So for example a path like: /events/this_is_my_node

It'll see that this node is in the events section of the site and the variables provided to the twig template facilitate theming the node page based on the section it's in.

Everything works great if the node and the node that's the section's landing page have their aliases generated, but if they don't, I get an error like:

UnexpectedValueException: External URLs do not have internal route parameters. in Drupal\Core\Url->getRouteParameters() (line 583 of core/lib/Drupal/Core/Url.php).

So basically I'm trying to figure out a conditional I can use so that I'm only getting Route parameters from a path it recognizes as being internal and should something go wrong and a path alias isn't set I don't get a WSOD.

I've tried using UrlHelper::isExternal but that doesn't seem to help as it just seems to look at the path structure to determine if its external or not vs actually check the page.

This is my code:

function THEME_preprocess_node(&$variables) {
  $route_name = \Drupal::routeMatch()->getRouteName();
  $variables['#cache']['contexts'][] = 'route.name.is_layout_builder_ui';
  $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 ($route_name ) {
    $node = $variables['node'];
    // check if layout builder is active
    if (isset($int_exp[3])) {
      if ($int_exp[3] == 'layout' or $int_exp[1] == 'layout_builder')
      {
        $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;
        }
      }
    }

  }
}
4uk4 avatar
cn flag
The code should be based on the route match, which you use only to determine whether a route name was matched, but you don't use the route name or the route parameters from there. You don't need to write code trying to match the current path again, it is already matched.
apaderno avatar
us flag
Truly, what returned by `\Drupal::service('path_alias.manager')->getAliasByPath($internal_path)` is a path alias, and what returned by `\Drupal::service('path_alias.manager')->getPathByAlias($int_exp[1])` is the path matching the path alias. The code assigns the value returned by `\Drupal::service('path_alias.manager')->getAliasByPath($internal_path)` to `$current_path`, and the value returned from `\Drupal::service('path_alias.manager')->getPathByAlias($int_exp[1])` to `$alias`.
Score:1
ru flag

You should not check for internal. An url like internal:/robots.txt is internal, but it is no route and has no route parameters.

So before you do Url::getRouteParameters() you should check for Url::isRouted()

I sit in a Tesla and translated this thread with Ai:

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.