Recent changes, probably related to - https://www.drupal.org/node/2844466 - made the adding and editing a little less intuitive, as now the links are always show as /node/x or /media/x instead of being more friendly, say using the path alias instead.

CommentFileSizeAuthor
#64 linkit-2877535-64.patch3.46 KBarthur.baghdasar
#63 linkit-2877535-62.patch4.05 KBmark_fullmer
#50 linkit-n2877535-50.patch4.13 KBDamienMcKenna
#41 interdiff-35-41.txt3.02 KBLeon Kessler
#41 linkit-2877535-link-shown-after-autocomplete-is-bare-41.patch4.12 KBLeon Kessler
#39 interdiff_12-39.txt439 bytespghaemim
#39 2877535-39.patch470 bytespghaemim
#37 2877535-36_option_to_use_alias.patch1.62 KBakhoury
#35 2877535-34.patch4.92 KBSpadXIII
#35 interdiff-30-34.txt4.03 KBSpadXIII
#33 2877535-33.patch4.92 KBSpadXIII
#33 interdiff-30-33.txt4.03 KBSpadXIII
#32 2877535-32.patch4.83 KBSpadXIII
#32 interdiff-30-32.txt4.16 KBSpadXIII
#30 interdiff.2877535.24-30.txt764 bytespixelwhip
#30 2877535-30.linkit.Link-shown-after-the-autocomplete-selection-is-the-bare-nodexxx-link-not-the-alias.patch6.66 KBpixelwhip
#28 2877535_display_path_alias_in_autocomplete_input-28.patch31.54 KBmark_fullmer
#28 interdiff_24-28.txt764 bytesmark_fullmer
#24 2877535_display_path_alias_in_autocomplete_input.patch5.91 KBSimeonKesmev
#23 interdiff_16-23.txt1.52 KBkbrodej
#23 show-alias-with-language-and-path-prefix-2877535-23.patch5.17 KBkbrodej
#22 2877535_display_path_alias_in_autocomplete_input.patch5.4 KBSimeonKesmev
#20 2877535_display_path_alias_in_autocomplete_input.patch4.28 KBSimeonKesmev
#16 interdiff_15-16.txt3.31 KBmarco-s
#16 show_alias_in_autocomplete_selection-2877535-16.patch4.37 KBmarco-s
#15 interdiff_14-15.txt3.41 KBmarco-s
#15 show_alias_in_autocomplete_selection-2877535-15.patch3.35 KBmarco-s
#14 show_alias_in_autocomplete_selection-2877535-14.patch470 bytesmarco-s
#12 2877535-12.patch470 bytespfrenssen
#7 2877535-7.linkit.Link-shown-after-the-autocomplete-selection-is-the-bare-nodexxx-link-not-the-alias.patch668 bytesthierry.beeckmans
#5 2877535-4.linkit.Link-shown-after-the-autocomplete-selection-is-the-bare-nodexxx-link-not-the-alias.patch668 bytessingularo
#4 interdiff.2877535.4.txt659 bytessingularo
#2 2877535-2.linkit.Link-shown-after-the-autocomplete-selection-is-the-bare-nodexxx-link-not-the-alias.patch669 bytessingularo

Issue fork linkit-2877535

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

singularo created an issue. See original summary.

singularo’s picture

Attching patch to call the alias manager not just return the path.

Tsymi’s picture

Thanks, patch on #2 works for me and met to my need.

singularo’s picture

FileSize
659 bytes

Hmm it looks like there is a tiny change required for sites running on a non '/' base path.

singularo’s picture

anon’s picture

Status: Active » Needs work

Thanks for patch, we need a test for this tho.

thierry.beeckmans’s picture

sime’s picture

Shouldn't this be done in a text output filter?

sime’s picture

On that note, I think this needs to be an optional configuration if this gets applied. We don't want to all our content links breaking when aliases are updated.

dalemoore’s picture

I just ran into this issue setting up my first D8 site. I was expecting this module to work similarly to CKEditor Link with D7, where it uses the node/id link but outputs the alias for the end-user, so that when aliases change (renaming a title, for instance) the path gets updated. Instead, all URLs break if the alias is updated...
EDIT: Scratch this, I updated to the 5.x-beta10 version, and it works now like I thought it should. I see now that you all were working to fix this on that branch.

marco-s’s picture

I have updated from 4.3.0 to 5.0.0-beta10 and I was wondering why the links are shown as /node/x afterwards (that wasn't the case with 4.x). I found the filter 'Linkit URL converter' in the text formats settings, but this filter doesn't seem to work?! Patch #7 works for me for my current case. I also don't need the 'Linkit URL converter' filter with this patch. But I agree with slime that this variant doesn't recognize alias updates and you should use the patch deliberately.

moshe weitzman’s picture

Issue tags: +Needs tests

Patch works for me. FWIW, the link already has durable reference to the linked entity (uuid) so perhaps its OK for this href to be a bit brittle? An example [a] tag when using this patch is <a data-entity-substitution="canonical" data-entity-type="node" data-entity-uuid="66950305-f906-4f76-90e4-143a0eddc67e" href="/news/bulletin-2020-05-flexibility-in-the-issuance-and-administration-of-insurance-during-covid-19">dfdfdf</a>

marco-s’s picture

path.alias_manager in #12 needs to be changed to path_alias.manager for D9 compatibility. This patch will now require Drupal >=8.8. (see https://www.drupal.org/node/3092086)

marco-s’s picture

The patch #14 does not provide the url with a language prefix (because of 2772643).
I updated this patch for that case accordingly.

marco-s’s picture

The patch #15 does not consider a possible path prefix configuration. Updated it in this patch.

ciss’s picture

Status: Needs work » Needs review

lukus’s picture

I'm not sure I agree that this is a desirable feature.

- The `href`- will be replaced by the text input filter, once the text is filtered for display.
- The alias is subject to change.
- The system path is actually a true representation of the intended destination.

SimeonKesmev’s picture

Hello, I am having this feature requested as well, but I also disagree with the implementation as it introduces dependencies, tries to implement URL building by itself by requesting the path alias manager and breaks the logic by replacing the internal path with an alias which is not stable reference to the target. Here's my take on it where I'm modifying only the representation to the editors and not he saved input.

Status: Needs review » Needs work
SimeonKesmev’s picture

kbrodej’s picture

Patch from #16 worked for me. However did spot a few issues. Attached a patch with changes and interdiff from #16

If the language detection is domain based the path alias will still use language prefix:
- Added a explicit check if language negotiation source is path_prefix

if path alias does not exist for given language it will use /{entity_type}/{id}:
- Added a method to check the alias for current language and fallback to default langugage.

SimeonKesmev’s picture

Here's an updated patch with my approach which handles base_paths.
NOTE: It's a different approach from the patch in #23, summary in #20.

askibinski’s picture

@SimeonKesmev I agree with your approach since we already have input format LinkitFilter which will transform the internal node/# url for visitors of the content to the alias.

Remaining issue:
With patch#24 you will see the alias in the autocomplete, but after inserting in the editor the link label/text still is node/# (unless you select text before inserting the link).

I think if no text is selected in the editor the default text to insert should be the node title.

dbielke1986’s picture

Is there a chance to port this patch to version 6.*?

Because Iam facing the same issue:
If you type in "/node/<nid>" and you do not select the search result - it will input <a href="/node/nid".... and not the <a data-entity-substitution="canonical" data-entity-type="node" data-entity-uuid="<uuid>" href="/node/<nid>"... which is a big issue. Not everyone is clicking at the search result, which leads to an issue on multilanguage sites.

dbielke1986’s picture

I created a new issue for version 6.*

https://www.drupal.org/project/linkit/issues/3222939

mark_fullmer’s picture

Status: Needs work » Needs review
FileSize
764 bytes
31.54 KB

I agree with the approach stated in #20. The approach here should be **not** to overwrite the internal path with the URL alias, since the latter could change. The patch in #24 , which is the latest version of that implementation, works well but does not include logic for adjusting the autocomplete logic to properly query the internal url in parentheses. In other words, it successfully populates the input area, but upon triggering a subsequent autocomplete search by clicking the input area, the autocomplete query fails because it's trying to match
[alias] ([internal-url]), rather than [internal-url].

The attached patch accounts for that, and is otherwise identical to #24.

(I'm not quite clear what #25 is referring to, so I didn't address that.)

tvalimaa’s picture

#28 fix my issue so node/xxx links are working now as aliases

pixelwhip’s picture

Here's a re-roll of #28. That patch had some extra changes related to the license file that did not look intentional and were not represented in the interdiff.

After fixing that, I was able to apply this patch via composer to 6.0.0-beta3.

Sutharsan’s picture

+++ b/src/Controller/AutocompleteController.php
@@ -76,6 +76,13 @@ class AutocompleteController implements ContainerInjectionInterface {
+    $patch_match = [];

Just checking, is this variable name $patch_match intended or was it supposed to be $path_match.

SpadXIII’s picture

FileSize
4.16 KB
4.83 KB

I tried the patch in #30 and it seems to work, except that the wrong value is saved to the database. The alias (as internal url) is saved instead of the internal path. When selecting a node path, the form field shows "/alias-to-node" and the database contains "internal:/alias-to-node" instead of "entity:node/".

Here's a different patch that uses the #30 as starting point, but makes sure the correct value is saved to the database.

SpadXIII’s picture

FileSize
4.03 KB
4.92 KB

I seem to have uploaded a patch that doesn't apply. Here's a fresh one.

Status: Needs review » Needs work

The last submitted patch, 33: 2877535-33.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

SpadXIII’s picture

Status: Needs work » Needs review
FileSize
4.03 KB
4.92 KB

And I seem to have copied the deprecated service name :(
Fixed in new patch.

Status: Needs review » Needs work

The last submitted patch, 35: 2877535-34.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

akhoury’s picture

This patch adds a configurable option to use alias instead of internal path navigate to /admin/config/content/linkit/manage/{linkit_profile}/matchers/{plugin_instance_id} and check "use alias" checkbox

The autocomplete value and href attribute will contain the alias.

rossidrup’s picture

why dont you hardcode it into latest release?

pghaemim’s picture

FileSize
470 bytes
439 bytes

making the #12 D9 compatible.

seanB’s picture

Leon Kessler’s picture

Version: 8.x-5.x-dev » 6.0.x-dev
Status: Needs work » Needs review
FileSize
4.12 KB
3.02 KB

Lots going on this issue. Three separate patches in #35, #37 and #39. Very confusing.

I'm hiding patch #39 and #37, as they go against the agreed approach of storing the internal (node/id) url in the unprocessed text.

I tested patch from #35, all looks good. Except you still see the internal node/id url immediately after selecting the link. After closing the dialog and re-opening to edit, you then see the url alias. This seems a bit broken to me, the value should be consistent so the behaviour is predictable to the user.

After having a look into the patch, I realised that the added code in Drupal\linkit\Element::valueCallback means that the internal url will always be used when submitting the form. This means it's safe to use always use the alias on the suggestions.

Patch attached updates the matches to always use the alias.

Also, I've wrapped the use of \Drupal::service('path_alias.manager') in a check for the installation of the path_alias module. As otherwise we would need to add a hard dependency to this module. Also this should hopefully make the tests pass.

Status: Needs review » Needs work
GasparM’s picture

Had the issue on linkit 6.0.x-dev, patch #41 works for me. I'm on PHP 8.1, drupal core 9.5.1

mark_fullmer’s picture

Note: Linkit 6.0.0-beta4 was released on 5 March 2023. The patch from #41 still applies to the latest changes.

However, this only works with CKEditor 4 currently. CKEditor 5 support would need to be added.

mark_fullmer’s picture

Category: Task » Feature request

However, this only works with CKEditor 4 currently. CKEditor 5 support would need to be added.

I take it back! This *does* work with CKEditor 5 as-is (I was expecting a different display output, but the aliased path is what is displayed in the CKEditor 5 context, which makes sense based on what the change is targeting).

This should still be "Needs work" since the failing tests need to be addressed. Also, I think it makes more sense to classify this as a "Feature" rather than a "Task."

jds1 made their first commit to this issue’s fork.

jds1’s picture

Status: Needs work » Needs review

Rerolled #41 against 6.0.x https://git.drupalcode.org/project/linkit/-/merge_requests/16. Everything passes. Patch applies cleanly locally against both 6.0.x-dev and 6.0.0-beta4. Tested locally and now I'm getting aliases instead of node URLs! Marking as "Needs Review" – thank you!

dwisnousky made their first commit to this issue’s fork.

DamienMcKenna’s picture

FileSize
4.13 KB

The merge request in patch format.

lxpcfly’s picture

The linkit-n2877535-50.patch is successfully changed the URL Link field from "node/xxx" to URL Alias, but it still needs to do extra work, as the saved URL is still "node/xxx" rather than saved as its path alias, 'canonical' is not active.

eg:

1. put node/xxx into the link field and click save straight away without selecting the autocomplete result, it only saves node/xxx .
2. edit link, you can see the node/xxx has changed to its path alias, save as is, it is not changing the url, the url link on the mouse hover is still node/xxx.

DamienMcKenna’s picture

It's ok that the saved value is "node/xxx" because it's converted to the correct URL when the content is rendered; it's a feature.

lxpcfly’s picture

Thank you Damien, but I think once it has the path alias also it appears in the Link field, it should save as path alias with canonical active.

DamienMcKenna’s picture

That would need to be a separate discussion.

vladt’s picture

I'm encountering an issue after applying patch #50 to Linkit 6.0.0-rc1 (as well as Linkit 5.0-beta 13), the data-entity-substitution, data-entity-type, data-entity-uuid attributes are no longer being added to the link, so the LinkitFilter is no longer working.

This seems to be happening because $href !== $href_dirty_check on line 129 of linkit.module is unsetting the values.

moshe weitzman’s picture

Status: Needs review » Needs work

Sounds like this is right status.

moshe weitzman’s picture

Status: Needs work » Reviewed & tested by the community

In my instance, that check is preventing the values from being unset, not unsetting them. Changing status after my review.

mark_fullmer’s picture

Title: Link shown after the autocomplete selection is the bare node/xxx link, not the alias » Show URL alias after autocomplete selection instead of internal route (e.g., /node/123)
R_H-L’s picture

Testing this in 9.5, #50 breaks the a tag extra attributes. The tag gets put in as just the bare '/node/x' without any data attributes.

mark_fullmer’s picture

Addressing the comments in #51, #53, and #59, all of which are suggesting that the URL alias is what should be saved to the database, rather than the internal route, I agree with Damien McKenna's statement in #52:

It's ok that the saved value is "node/xxx" because it's converted to the correct URL when the content is rendered; it's a feature.

mark_fullmer’s picture

Status: Reviewed & tested by the community » Needs work

It's ok that the saved value is "node/xxx" because it's converted to the correct URL when the content is rendered

After testing to confirm, I take back my comment. Using the latest patch, the comments in #51, #52, and #59 are effectively pointing out a problem -- not that the internal URL is what is saved (that's fine), but that when the resulting page is rendering, the internal URL is what is rendered to the end-user, rather than the URL alias.

Changing status to "Needs work" to address this. I'm also surprised that there is apparently no test coverage to catch this. I'd like to add test coverage for this going forward: the URL alias should be rendered on the page after save.

moshe weitzman’s picture

This patch no longer applies to the most recent release (Sep 30) :(

mark_fullmer’s picture

This patch no longer applies to the most recent release (Sep 30)

Here's a revised patch that replicates verbatim what was in the patch in #50, and which will apply to the current development release for 6.0.x and 6.1.x.

Noting that the comments from #51, #52, and #59 still need to be addressed: when the resulting page is rendered, the internal URL should not be rendered to the end-user. The URL alias should. Test coverage needs to be added for this, too. Leaving status as "Needs work."

arthur.baghdasar’s picture

FileSize
3.46 KB

Ive removed this part from the patch everything seems to be working fine for me.
In the code below $input variable comes with an Alias and I don't understand why we should get the $path from it.
In My case the $path variable is converted back to the node/[nid] which is then being set to be the new input.

+    if (!empty($input) && \Drupal::moduleHandler()->moduleExists('path_alias')) {
+      /** @var \Drupal\path_alias\AliasManagerInterface $aliasManager */
+      $aliasManager = \Drupal::service('path_alias.manager');
+      $path = $aliasManager->getPathByAlias($input);
+      if ($path !== $input) {
+        $input = $path;
+      }
+    }
DamienMcKenna’s picture

Status: Needs work » Needs review
kthull’s picture

Patch from #64 applied to 6.1.2 for me and solved the generic node path on D10.1.5

greenSkin’s picture

Status: Needs review » Needs work

The LinkitFilter doesn't look to work with the patch. I'm not seeing the additional attributes getting added to the tag.

SpadXIII’s picture

I tried to get something working, but did not succeed.

My goal was to use the alias during editing and store the node-url in the database. The link would then show the node alias in the editor, but in the database the node/ was stored. By adding another data-property (data-entity-path) I tried adding a editorDowncast and dataDowncast in the plugin, but that didn't work correctly: it would create a new a-tag wrapping the one that was being made by the base link plugin.

By adding a general upcast conversion, the href is changed to the alias:

editor.conversion.for('upcast')
      .elementToAttribute( {
        view: {
          name: 'a',
          attributes: {
            href: true,
            ['data-entity-alias']: true
          }
        },
        model: {
          key: 'linkHref',
          value: viewElement => viewElement.getAttribute('data-entity-alias'),
        },
        converterPriority: 'high'
      } );

But I failed trying to move the other way around. I tried adding a dataDowncast (which would set the path back to the href), and an editorDowncast (which would use the alias as href). This didn't work, because when creating an element with the same attribute, would add another element to the html instead of merging them (effectively overwriting the href-attribute)
I also tried using a data downcastDispatcher, but that doesn't seem to be able to get the correct viewElement (or rather, it couldn't find any element at all).

ps. there are some other code changes required as well to not only pass but also use the alias and path in the links.

mrweiner’s picture

For anybody who needs a quick and dirty fix for this, I'm handling it in hook_preprocess_field() with:

function cc_gin_preprocess_field__node__body__article(&$variables) {
  // Assuming $text is the HTML content you're preprocessing
  $text = $variables["items"][0]["content"]["#text"];

  // Create a new DOMDocument and load the HTML content
  $dom = new DOMDocument();
  @$dom->loadHTML(mb_convert_encoding($text, 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

  $links = $dom->getElementsByTagName('a');

  foreach ($links as $link) {
    // Check if the link is an internal node link
    if ($link->hasAttribute('href') && str_starts_with($link->getAttribute('href'), '/node/')) {
      $path = $link->getAttribute('href');
      if ($path) {
        continue;
      }

      $alias = \Drupal::service('path_alias.manager')->getAliasByPath($path);
      if (!$alias) {
        continue;
      }

      // Replace the href attribute with the alias
      $link->setAttribute('href', $alias);
    }
  }

  // Save the updated HTML
  $variables["items"][0]["content"]["#text"] = $dom->saveHTML();
}

Note that this was generated by chatgpt, so I'm not sure that all of the args in $dom->loadHTML() are needed, but it seems to do the trick for me.