Hi, thanks for the great work on this module.

I wonder if it is possible to export the URL alias configuration for nodes? The configuration was not present in my export. Is it because this is a setting not present in all entities and purposely omitted from the export?

Comments

dinarcon created an issue. See original summary.

larowlan’s picture

dinarcon’s picture

Thanks for the reference @larowlan

yannisc’s picture

Is there any workaround for this? Not having the url path is critical. Is there a way to set it e.g. via a drush command?

bartk’s picture

@yannisc:

It can be done from Drush. You can also do it in your module's hook_install function, like this:

  $query = \Drupal::entityQuery('node');
  $query->condition('uuid', '8330c0e3-4cae-48df-a68e-82b481bbda77');
  $nids = $query->execute();
  $oldpath = '/node/' . reset($nids);
  \Drupal::service('path.alias_storage')->save($oldpath, '/home');

EDIT: THIS DOES NOT WORK IN YOUR MODULE'S HOOK_INSTALL(), because it executes before the content is inserted. You'll have to do it elsewhere, perhaps in response to default_content's ImportEvent.

The Drush command, as long as you know the nid (1, in this example), would be:

drush php-eval "\Drupal::service('path.alias_storage')->save('/node/1, '/home');"

yannisc’s picture

thank you, @bartk!

ygerasimov’s picture

You can do this with hook_node_insert.

<?php
/**
 * Implements hook_node_insert().
 */
function MODULE_node_insert(EntityInterface $node) {
  $url_aliases = array(
    '2ef96a79-9f91-47f2-b59b-110ad2ed34f8' => '/abc',
    '0266803e-87ab-4f77-b564-70bc1143fd33' => '/abc/def',
  );

  $node_uuid = $node->uuid();
  if (isset($url_aliases[$node_uuid])) {
    \Drupal::service('path.alias_storage')->save('/node/' . $node->id(), $url_aliases[$node_uuid]);
  }
}
?>
pguillard’s picture

I suggest renaming the title of this one to "Export URL contributed alias for nodes"
as URL alias Configuration (admin/config/search/path/patterns) is CMI / Config

Thanks @ygerasimov, really usefull.

pguillard’s picture

I guess we should use hook_entity_insert instead :

/**
 * Implements hook_entity_insert().
 */
function MODULE_entity_insert(Drupal\Core\Entity\EntityInterface $entity){
  $url_aliases = array(
    '2ef96a79-9f91-47f2-b59b-110ad2ed34f8' => '/abc',
    '0266803e-87ab-4f77-b564-70bc1143fd33' => '/abc/def',
  );

  $entity_uuid = $entity->uuid();

  if (isset($url_aliases[$entity_uuid])) {
    \Drupal::service('path.alias_storage')->save('/node/' . $entity->id(), $url_aliases[$entity_uuid]);
  }
}
badjava’s picture

I created an experimental module called Default Content Extras that supports this feature.

larowlan’s picture

sigh, why not collaborate with patches here?

badjava’s picture

Category: Support request » Bug report
Status: Postponed » Needs review
StatusFileSize
new3.48 KB

Yes, I should've posted a patch here first. I made the assumption that this issue was going to get fixed when the underlying core issue was fixed.

Here is a patch that adds a node normalizer and expands the existing term normalizer to include path alias data in $entity['path']['alias'].

Status: Needs review » Needs work

The last submitted patch, 12: default_content-path-alias-2710421-12.patch, failed testing.

larowlan’s picture

I don't think hard-coding support for Node and Taxonomy is the right approach.

a) you cannot assume node URIs are node/{X} because the D8 routing system allows changing that
b) what if another entity type has a path field.

Instead I think we should use the PathItem normalizer approach as per https://www.drupal.org/node/2649646#comment-10752008

badjava’s picture

Status: Needs work » Postponed

Agreed, it's a solution, not a great one. I suspect this will get resolved properly in #2846554: Make the PathItem field type actually computed and auto-load stored aliases so setting this to postponed.

chi’s picture

Another workaround is exporting Pathauto patterns instead instead of aliases. This works only if your aliases are not relying on entity IDs.

tanc’s picture

@Chi can you elaborate? I have set a pathauto pattern for my content type but when default_content inserts a node the pathauto pattern is not generated for that node. Any idea how to get it to trigger?

tanc’s picture

Oh, my mistake, my tests were incorrect. The pathauto url does get generated fine.

JvE’s picture

Issue #2846554: Make the PathItem field type actually computed and auto-load stored aliases has been fixed in 8.4 for a while now.
What needs to happen to get this default content issue resolved?

yannisc’s picture

Any progress on that?

larowlan’s picture

If the core issue doesn't resolve it, then we need a new normalizer for the PathItem fields

bburg’s picture

Should a PathItem normalizer be added to this module then? Or perhaps Better Normalizers?

Are these two separate issues? Using an exported path Vs. using pathauto to generate a path? I'd like to contribute, but I'm still unfamiliar with Normalizers in D8.

bburg’s picture

This is a dirty hack, but for anyone else trying to get their paths importing correctly, I dropped this in Importer::importContent() just after the entity->save() calls. It seems to work for me, but will most certainly not work for all use cases.

          // Set path for nodes, since the normalizers don't seem to work.
          if ($entity->getEntityType()->getProvider() == 'node') {
            $path = $entity->get('path')->get(0)->get('alias')->getValue();
            if ($path) {
              \Drupal::service('path.alias_storage')->save('/node/' . $entity->id(), $path, 'en');
            }
          }

Note the hard-coded 'en' language parameter.

manuel.adan’s picture

And why only for nodes?

andypost’s picture

Status: Postponed » Needs work

Core issue resolved, anything left here? or one more normalizer needed for better normalizers?

manuel.adan’s picture

The fixed_path_alias module may help on this. It allows to export/import selected path aliases to/from config.

rob230’s picture

StatusFileSize
new635 bytes

Patch for anyone wanting to use bburg's hack (which imports paths for nodes in the English language).

It would be great to have a real solution for this because I feel that the alias is an important aspect of pages.

berdir’s picture

Status: Needs work » Closed (won't fix)

I've recently created the 2.0.x branch, see the project page on all the improvements in the 2.0.x branch. Testing that and providing feedback would be very welcome. The 1.x branch isn't actively maintained and won't receive new features anymore, so I'm closing this and other issues as won't fix.

path import should work in 1.x but you need to manually adjust the exported content, remove the pid column and when using pathauto, add the pathauto ignore flag. This is supported by default in 2.0.x and aliases should just work.

stefan.korn’s picture

Hm, still having trouble with 2.x and path aliases (maybe I have overlooked something, but I can not get a clean solution with path_aliases. Tried different things, exporting path_alias, removing the 'pid' entry from node export etc.).

Based on #7 (path.alias_storage is gone now) one could use something like this:

$url_aliases = array(
  'b64cb122-d96c-467d-b22d-901d8ad3232c' => '/home',
  '90382fbc-d908-4a27-99e9-2e7017eb2853' => '/api',
  '75590ebe-b559-4080-9467-c7ff7579cba3' => '/about'
);

foreach ($url_aliases as $uuid => $url_alias) {
  $node = \Drupal::entityTypeManager()->getStorage('node')->loadByProperties([
    'uuid' => $uuid
  ]);
  $node = reset($node);

  if ($node instanceof \Drupal\node\Entity\Node && isset($url_aliases[$uuid])) {
    \Drupal::entityTypeManager()->getStorage('path_alias')->create(
      [
        'path' => '/node/' . $node->id(),
        'alias' => $url_aliases[$uuid]
      ]
    )->save();
  }

You can for example put this in a .php file and then execute this via drush scr after the default content has been imported.

Could have also use it in hook_node_insert as per #7, but seems not the cleanest way to run through this every time a node is inserted, though this is kind of a one time task.