There is currently no way to explicitly define a path alias on a node being imported.

Attempting to define both an alias and disable pathauto as shown below produces the error shown below:

  path:
    alias: '/article-2'
    pathauto: false
InvalidArgumentException: 'path' cannot hold more than 1 values. 2 values were parsed from the YAML file. in /drupal/web/root/modules/contrib/yaml_content/src/ContentLoader/ContentLoader.php:353

Attempting to define just the alias instead using the pattern below produces a separate error:

  path:
    alias: '/article-2'
Drupal\Core\Entity\EntityMalformedException: The "node" entity cannot have a URI as it does not have an ID in /drupal/web/root/core/lib/Drupal/Core/Entity/Entity.php:179 

Finally, trying to assign the alias directly to the path attempts to process it as a node property producing the error below:

  path: '/article-2'
Drupal\Core\Entity\Query\QueryException: 'path' not found in /drupal/web/root/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php:316
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

slucero created an issue. See original summary.

kedramon’s picture

Hi,
same behavior

the correct input is:

path:
    - pathauto: false
      alias: '/some-cool-alias'

by the way, if nid is also passed it works

lamp5’s picture

Hey. I have a question. Is there a way to update an alias instead of creating it again when I update my nodes ??

drupalninja99’s picture

Drupal\Core\Entity\EntityMalformedException: The "node" entity cannot have a URI as it does not have an ID     [error]
in /home/vagrant/docroot/web/core/lib/Drupal/Core/Entity/Entity.php:180
Stack trace:

I get this error even with this syntax:

path:
    - pathauto: false
      alias: '/some-cool-alias'
bjlewis2’s picture

If I pass a node id in manually, I'm able to get the alias to work, but that's really not ideal...

e.g.

- entity: 'node'
  type: 'landing_page'
  title: 'Example Homepage'
  status: 1
  nid: 5000
  path:
    - alias: '/example-homepage'
      pathauto: true
lamp5’s picture

@drupalninja99 When you importing your nodes, NIDs are not exist and path can not be created. It is similar to menu item Menu item YAML content
First you have to create node and next add path to it.

- entity: 'node'
  type: 'landing_page'
  title: 'Example Homepage'
  status: 1

- entity: 'node'
  type: 'landing_page'
  title: 'Example Homepage'
  path:
    - alias: '/example-homepage'
      pathauto: true

Now YAML content has acces to node ID.

drupalninja99’s picture

@bjlewis2 I am using this method right now bc I couldn't get the other one to work. Its not great but it works and the nid is arbitrary anyway

slucero’s picture

Issue tags: +Needs tests
kedramon’s picture

What is strange if a pattern for url is like [node:content-type]/[node:title] then it fail. only the case with passing nid works.

DamienMcKenna’s picture

This should work without requiring the magic steps described in #5 or #6.

macganibo’s picture

When adding path to a node, contentLoader.php triggers populateField function and tries to delete existing fields, but when "Drupal\pathauto\PathautoFieldItemList" is pass, it triggers this line of code from Drupal\path\Plugin\Field\FieldType\PathFieldItemList.php:

  /**
   * {@inheritdoc}
   */
  public function delete() {
    // Delete all aliases associated with this entity in the current language.
    $entity = $this->getEntity();
    $conditions = [
      'source' => '/' . $entity->toUrl()->getInternalPath(),
      'langcode' => $entity->language()->getId(),
    ];
    \Drupal::service('path.alias_storage')->delete($conditions);
  }

The line of code assumes that current entity is existing thus throws EntityMalformedException.

Proposed work around:

Skip deleting fields for new entity.

DamienMcKenna’s picture

Status: Active » Needs review

Thanks macganibo!

Let's see what the testbot says.

I'll also test it out today.

DamienMcKenna’s picture

Status: Needs review » Reviewed & tested by the community

The patch in #11 works great, I can now do imports like this:

- entity: "node"
  type: "page"
  title: "Organization Chart"
  status: 1
  path:
    - pathauto: 0
      alias: '/about/organization-chart'

Whereas before the alias would be "/organization-chart", after either updating the existing node or deleting & rerunning the import the path is now set correctly.

Great work, macganibo!

DamienMcKenna’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
1.07 KB
1.37 KB

This adds a Pathauto alias to one of the example nodes.

DamienMcKenna’s picture

Status: Needs review » Needs work

Ok, it turns out this doesn't work when it's triggered by an installation profile, you end up getting this screenful:

Drupal\Core\Entity\EntityMalformedException: The "node" entity cannot have a URI as it does not have an ID in web/core/lib/Drupal/Core/Entity/EntityBase.php:191
Stack trace:
#0 web/core/modules/path/src/Plugin/Field/FieldType/PathFieldItemList.php(68): Drupal\Core\Entity\EntityBase->toUrl()
#1 web/modules/contrib/yaml_content/src/ContentLoader/ContentLoader.php(507): Drupal\path\Plugin\Field\FieldType\PathFieldItemList->delete()
#2 web/modules/contrib/yaml_content/src/ContentLoader/ContentLoader.php(457): Drupal\yaml_content\ContentLoader\ContentLoader->populateField(Object(Drupal\pathauto\PathautoFieldItemList), Array)
#3 web/modules/contrib/yaml_content/src/ContentLoader/ContentLoader.php(367): Drupal\yaml_content\ContentLoader\ContentLoader->populateEntityFields(Object(Drupal\node\Entity\Node), Array)
#4 web/modules/contrib/yaml_content/src/ContentLoader/ContentLoader.php(310): Drupal\yaml_content\ContentLoader\ContentLoader->buildEntity('node', Array)
#5 web/modules/contrib/yaml_content/src/Service/LoadHelper.php(171): Drupal\yaml_content\ContentLoader\ContentLoader->loadContent('node.01-homepag...')
#6 web/modules/contrib/yaml_content/src/Service/LoadHelper.php(116): Drupal\yaml_content\Service\LoadHelper->importFiles(Array)
#7 web/profiles/custom/myinstallprofile/myinstallprofile.profile(38): Drupal\yaml_content\Service\LoadHelper->importProfile('myinstallprofile')
#8 web/core/includes/install.core.inc(708): myinstallprofile_install_content(Array)
#9 web/core/includes/install.core.inc(583): install_run_task(Array, Array)
#10 web/core/includes/install.core.inc(118): install_run_tasks(Array, NULL)
#11 vendor/drush/drush/includes/drush.inc(728): install_drupal(Object(Composer\Autoload\ClassLoader), Array)
#12 vendor/drush/drush/includes/drush.inc(713): drush_call_user_func_array('install_drupal', Array)
#13 vendor/drush/drush/commands/core/drupal/site_install.inc(82): drush_op('install_drupal', Object(Composer\Autoload\ClassLoader), Array)
#14 vendor/drush/drush/commands/core/site_install.drush.inc(271): drush_core_site_install_version('myinstallprofile', Array)
#15 vendor/drush/drush/includes/command.inc(422): drush_core_site_install('myinstallprofile')
#16 vendor/drush/drush/includes/command.inc(231): _drush_invoke_hooks(Array, Array)
#17 vendor/drush/drush/includes/command.inc(199): drush_command('myinstallprofile')
#18 vendor/drush/drush/lib/Drush/Boot/BaseBoot.php(67): drush_dispatch(Array)
#19 vendor/drush/drush/includes/preflight.inc(67): Drush\Boot\BaseBoot->bootstrap_and_dispatch()
#20 vendor/drush/drush/drush.php(12): drush_main()
#21 {main}
DamienMcKenna’s picture

Just to be clear - the import works correctly after an installation profile has ran, but it does not work when the import is triggered via an installation profile's install tasks.

DamienMcKenna’s picture

The fact that the error only happens during the installation profile but does work after the site is installed makes me wonder if it's a caching problem?

DamienMcKenna’s picture

Status: Needs work » Reviewed & tested by the community

I destroyed my vagrant install, reran the build and the patch worked. So I'm not sure what was going on last week. Thanks Wilmark!

  • slucero committed efb631a on 8.x-1.x authored by macganibo
    Issue #2883434 by DamienMcKenna, macganibo: Nodes Cannot Create Path...
slucero’s picture

Merged! Thank you all for the help on this!

slucero’s picture

Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.