7

I'm currently importing data from a database to create nodes based on them. My node save code looks like this

$node = \Drupal\node\Entity\Node::create([
        'type'                 => 'issue',
        'title'                => $title,
        'body'                 => $body,
        'field_issue_category' => $term,
        'field_issue_type'     => 'publication',
        'field_pub_id'         => [
            'target_id'           => $publication_id,
        ],
        'field_issue_group' => $group_id,
        'field_date'        => $date,
    ]);
$node->save();

I also want to create a url alias based on the title of this node, which I create like this,

$nid       = $node->id();
$title     = preg_replace("/[\s_]/", "-", $title);
$path      = \Drupal::service('path.alias_storage')->save('/node/'.$nid, '/mypath/'.$title);

This successfully create a url alias that shows up in the URL aliases list in the URL alias config. However it doesn't show up in the URL alias field on the node edit page.

url alias field

This creates a problem. One, the user can't see what the actual alias is. Also I have a block plugin that puts every node of that type in a list on a page. It also displays the url to that node. I'd like the url displayed to be the alias like '/mypath/title' but Drupal only seems to know about the '/node/nid' path.

Is there a proper way to programmatically set a nodes url alias so that it still appears in the url alias field?

10

The node widget currently only shows aliases that have the same langcode as the node. https://www.drupal.org/node/2511968 will change that and also display aliases without a specific language.

But if the alias also doesn't work on the site then that sounds like something else also isn't correct yet. Does it work in that block if you create an alias manually in the UI? If so, compare the two records in the url_alias table, do you see a difference?

You can create an alias as part of saving the node, there is a path pseudo/computed field. Try adding this to your array:

'path' => [
  'alias' => '/mypath/' . $title,
  'pathauto' => PathautoState::SKIP,
]

That should create the alias correctly as well.

And last, if your alias is so predictable, you should look at Pathauto. That allows you to set up rules for creating aliases. Among other things, it has a ton of logic to deal with special characters and duplicates, your code will have a problem if you have two nodes with the same title, for example.

  • Does pathauto work when a node is being created programmatically? – Matt Dec 8 '16 at 20:35
  • Yes, should work fine, it works with entity hooks – Berdir Dec 8 '16 at 20:38
  • 1
    looks like the issue was that it needed to be 'alias' => '/mypath/' instead of 'alias' > '/mypath/ – Matt Dec 8 '16 at 20:56
  • 3
    Yeah, having valid PHP helps. Fixed in my answer. – Berdir Dec 8 '16 at 21:00
  • 1
    Use 'path' => ['alias' => '/mypath/' . $title, 'pathauto' => Drupal\pathauto\PathautoState::SKIP] to skip pathauto generation. – milkovsky Dec 20 '17 at 16:20

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.