Provide a new autocomplete form widget for link fields to query entities from a chosen Linkit profile.

CommentFileSizeAuthor
#340 2712951_331_3.6.x.patch46.88 KBinoodle
#338 2712951_331_2.6.x.patch8.3 KBinoodle
#337 2712951_331_1.6.x.patch8.3 KBinoodle
#331 2712951_329.6.x.diff47.43 KBschiavone
#327 2712951-326.patch5.52 KBschiavone
#325 2712951-325.patch8.27 KBschiavone
#322 differences-5x_6x_linkitforlinkfield.diff12.26 KBmark_fullmer
#317 2712951_316.6.x.diff47.78 KBmark_fullmer
#315 interdiff-293-315.txt1.02 KBspadxiii
#315 2712951-315.patch48.71 KBspadxiii
#308 reroll_diff_293-306.txt44.68 KBAnkit.Gupta
#306 2712951-306.patch8.48 KBAnkit.Gupta
#293 2712951-293.patch48.48 KBseanb
#293 interdiff-291-293.txt1.17 KBseanb
#291 2712951-291.patch48.25 KBseanb
#291 interdiff-289-291.txt781 bytesseanb
#289 2712951-289.patch47.49 KBseanb
#289 interdiff-286-289.txt8.81 KBseanb
#286 2712951-286.patch50.56 KBseanb
#286 interdiff-274-286.txt1.81 KBseanb
#278 Screenshot 2022-02-22 at 12.21.39.png104.51 KBomnia.ibrahim
#274 interdiff_273-274.txt945 bytesclement.ferrier
#274 2712951-274.patch49.9 KBclement.ferrier
#273 rerolled-270-without-8.1-deprecation-notice.patch50.29 KBakasake
#273 interdiff-270-273.txt885 bytesakasake
#270 interdiff-256-270.txt5.67 KBspadxiii
#270 2712951-270.patch49.8 KBspadxiii
#267 interdiff-256-267.txt5.44 KBspadxiii
#267 2712951-267.patch49.58 KBspadxiii
#264 interdiff-256-264.txt23.92 KBspadxiii
#264 2712951-264.patch68.34 KBspadxiii
#261 interdiff-256-261.txt5.43 KBspadxiii
#261 2712951-261.patch49.56 KBspadxiii
#256 2712951-256.patch46.71 KBtessa bakker
#256 interdiff-254-256.txt501 bytestessa bakker
#255 core-link-explained.png104.12 KBtessa bakker
#254 interdiff2712951-252-254.txt5.61 KBjeroent
#254 2712951-254.patch46.75 KBjeroent
#252 interdiff-2712951-243-252.txt3.67 KBjeroent
#252 2712951-252.patch46.68 KBjeroent
#247 avoid-linkit-CI-issue.patch53.1 KBbetoaveiga
#243 interdiff-2172951-241-243.txt1.44 KBjeroent
#243 2172951-243.patch46.61 KBjeroent
#241 interdiff-2172951-239-241.txt749 bytesjeroent
#241 2172951-241.patch46.52 KBjeroent
#239 interdiff-2172951-237-239.txt2.26 KBjeroent
#239 2712951-239.patch46.46 KBjeroent
#237 interdiff-2172951-236-237.txt11.72 KBjeroent
#237 2172951-237.patch46.9 KBjeroent
#236 interdiff_231-236.txt1.08 KBphilltran
#236 linkit-for-link-field-2712951-236.patch53.36 KBphilltran
#231 reroll_diff_229-231.txt8.05 KBcainaru
#231 reroll_diff_216-231.txt10.41 KBcainaru
#231 linkit-for-link-field-2712951-231.patch54.58 KBcainaru
#229 interdiff-2712951-216-229.txt9.34 KBjeroent
#229 2712951-229.patch53.28 KBjeroent
#216 reroll_interdiff_211-216.txt3.07 KBcainaru
#216 linkit-for-link-field-2712951-216.patch53.05 KBcainaru
#211 linkit-for-link-field-2712951-211.patch52.55 KBsanduhrs
#207 linkit-for-link-field-2712951-207.patch52.48 KBsanduhrs
#205 interdiff.txt3.58 KBdylan donkersgoed
#205 linkit-for-link-field-2712951-205.patch107.26 KBdylan donkersgoed
#201 2712951_interdiff_199-201.txt1.31 KBnadavoid
#201 2712951_interdiff_196-201.txt1.99 KBnadavoid
#201 linkit-for-link-field-2712951-201.patch51.05 KBnadavoid
#199 2712951_interdiff_196-199.txt858 bytesnadavoid
#199 2712951_interdiff_194-199.txt3.33 KBnadavoid
#199 linkit-for-link-field-2712951-199.patch50.99 KBnadavoid
#197 interdiff_194-196.txt2.65 KBnadavoid
#196 linkit-for-link-field-2712951-196.patch50.87 KBnadavoid
#194 interdiff_190-194.txt4.29 KBgodotislate
#194 linkit-for-link-field-2712951-194.patch50.18 KBgodotislate
#191 interdiff-186-190.txt562 bytesrichardgaunt
#191 linkit-for-link-field-2712951-190.patch51.86 KBrichardgaunt
#189 linkit-for-link-field-2712951-189.patch12.73 KBrichardgaunt
#188 interdiff-184-186.txt3.09 KBidebr
#186 linkit-for-link-field-2712951-186.patch52.13 KBadinac
#184 2712951-184.patch51.62 KBhudri
#184 interdiff_182-184.txt863 byteshudri
#182 2712951-182.patch51.49 KBhudri
#182 interdiff_179-182.txt364 byteshudri
#179 2712951-179.patch51.49 KBhudri
#179 interdiff_177-179.txt897 byteshudri
#178 interdiff_174-177.txt1.7 KBhudri
#178 2712951-177.patch51.14 KBhudri
#176 2712951-176.patch51.13 KBhudri
#176 interdiff_174-176.txt1.69 KBhudri
#174 2712951-174-interdiff.txt2.83 KBberdir
#174 2712951-174.patch51 KBberdir
#171 2712951-171..patch50.92 KBprimsi
#171 2712951-171.testonly.patch50.85 KBprimsi
#170 2712951-169.patch49.85 KBprimsi
#169 2712951-169.interdiff.txt664 bytesprimsi
#166 2712951-166.patch49.78 KBlammensj
#164 2712951-164.patch58.12 KBeyilmaz
#164 interdiff.txt1.98 KBeyilmaz
#162 interdiff.txt592 byteseyilmaz
#162 2712951-162.patch57.61 KBeyilmaz
#158 2712951-158.patch57.58 KBidebr
#158 interdiff-157-158.txt654 bytesidebr
#157 linkit_for_link_field-2712951-157-interdiff.txt787 bytesberdir
#157 linkit_for_link_field-2712951-157.patch57.57 KBberdir
#154 linkit_for_link_field-2712951-154.patch49.22 KBprimsi
#154 linkit_for_link_field-2712951-154.interdiff.txt2.23 KBprimsi
#152 linkit_for_link_field-2712951-152.patch48.41 KBprimsi
#152 linkit_for_link_field-2712951-152.interdiff.txt561 bytesprimsi
#151 linkit-widget-without-maxlength.png107.62 KBsaseedharan
#151 link-field-with-maxlength.png188 KBsaseedharan
#148 linkit_for_link_field-2712951-148.patch48.34 KBprimsi
#148 linkit_for_link_field-2712951-148.interdiff.txt1.64 KBprimsi
#147 linkit_for_link_field-2712951-147.patch47.69 KBprimsi
#147 linkit_for_link_field-2712951-147.interdiff.txt1.17 KBprimsi
#146 linkit_for_link_field-2712951-146.patch47.67 KBprimsi
#146 linkit_for_link_field-2712951-146.interdiff.txt1.74 KBprimsi
#144 linkit_for_link_field-2712951-144.patch46.83 KBpaulmartin84
#143 linkit_for_link_field-2712951-143.patch46.83 KBpaulmartin84
#142 linkit_for_link_field-2712951-142.patch.txt46.83 KBpaulmartin84
#140 interdiff-2712951-139-140.txt2.23 KBarpad.rozsa
#140 linkit_for_link_field-2712951-140.patch47.41 KBarpad.rozsa
#139 interdiff-2712951-137-139.txt1.45 KBarpad.rozsa
#139 linkit_for_link_field-2712951-139.patch47.48 KBarpad.rozsa
#137 interdiff-2712951-135-137.txt1.16 KBarpad.rozsa
#137 linkit_for_link_field-2712951-137.patch47.42 KBarpad.rozsa
#135 linkit_for_link_field-2712951-135.patch47.39 KBarpad.rozsa
#135 interdiff-2712951-131-135.txt4.08 KBarpad.rozsa
#131 linkit_for_link_field-2712951-131.patch47.69 KBkarlshea
#128 interdiff-2712951-125-128.txt17.89 KBarpad.rozsa
#128 linkit_for_link_field-2712951-128.patch47.67 KBarpad.rozsa
#125 linkit_modified_patch-118-124.patch42.42 KBesdrasterrero
#123 linkit_modified_patch-118-123.patch42.05 KBstefan.hartono
#122 linkit_modified_patch-118-122.diff530 bytesstefan.hartono
#122 linkit_modified_complete.patch41.89 KBstefan.hartono
#118 2712951-118.patch41.77 KBblazey
#118 interdiff-116-118.txt2.58 KBblazey
#116 2712951-116.patch41.65 KBblazey
#116 interdiff-113-116.txt1.46 KBblazey
#113 2712951-113.patch41.57 KBblazey
#113 interdiff-111-113.txt10.18 KBblazey
#111 2712951-111.patch42.37 KBblazey
#111 interdiff-108-111.txt7.45 KBblazey
#108 linkit-linked-entity.png19.38 KBblazey
#108 2712951-108.patch41.72 KBblazey
#108 interdiff-106-108.txt7.9 KBblazey
#106 interdiff-104-105.txt653 bytesblazey
#106 2712951-105.patch40.16 KBblazey
#104 interdiff-103-104.txt3.69 KBblazey
#104 2712951-104.patch40.14 KBblazey
#103 interdiff_102_103.txt738 bytesblazey
#103 2712951-103-linkit-field-widget.patch38.13 KBblazey
#102 interdiff_100_102.txt1.1 KBxenophyle
#102 linkit_for_link_field-2712951-102.patch37.96 KBxenophyle
#100 interdiff-2712951-99-100.txt10.25 KBarpad.rozsa
#100 linkit_for_link_field-2712951-100.patch37.22 KBarpad.rozsa
#99 interdiff-2712951-95-99.txt1.31 KBarpad.rozsa
#99 linkit_for_link_field-2712951-99.patch40.41 KBarpad.rozsa
#95 linkit_for_link_field-2712951-95.patch39.74 KBahebrank
#94 linkit_for_link_field-2712951-94.patch39.72 KBahebrank
#93 interdiff-2712951-91-93.txt716 bytesarpad.rozsa
#93 linkit_for_link_field-2712951-93.patch39.7 KBarpad.rozsa
#91 interdiff-2712951-90-91.txt6.28 KBarpad.rozsa
#91 linkit_for_link_field-2712951-91.patch39.57 KBarpad.rozsa
#90 linkit_for_link_field-2712951-90.patch35.02 KBahebrank
#88 image (5).png101.23 KBjesconstantine
#88 linkit-default.png153.08 KBjesconstantine
#88 image (4).png19.2 KBjesconstantine
#88 image (3).png26.95 KBjesconstantine
#88 linkit-nodes-profile.png95.61 KBjesconstantine
#84 interdiff-81-84.txt912 bytesahebrank
#84 linkit_for_link_field-2712951-84.patch34.52 KBahebrank
#81 linkit_for_link_field-2712951-81.patch34.48 KBrudins
#78 interdiff.txt871 bytesidflood
#78 linkit_for_link_field-2712951-78.patch34.7 KBidflood
#77 fix-non-entity-path.interdiff.patch582 bytesahebrank
#67 interdiff-59-67.txt1.69 KBmarcoscano
#67 2712951-67.patch34.6 KBmarcoscano
#63 interdiff-59-63.txt1.41 KBmarcoscano
#63 2712951-63.patch35.62 KBmarcoscano
#59 interdiff-57-59.txt883 bytesmarcoscano
#59 2712951-59.patch34.54 KBmarcoscano
#57 interdiff-55-57.txt2.58 KBmarcoscano
#57 2712951-57.patch33.67 KBmarcoscano
#55 interdiff-54-55.txt6.14 KBmarcoscano
#55 2712951-55.patch31.09 KBmarcoscano
#54 interdiff-52-54.txt1.17 KBmarcoscano
#54 2712951-54.patch26.73 KBmarcoscano
#52 interdiff-50-52.txt2.54 KBmarcoscano
#52 2712951-52.patch26.9 KBmarcoscano
#50 interdiff-49-50.txt1.95 KBmarcoscano
#50 2712951-50.patch26.86 KBmarcoscano
#49 interdiff-48-49.txt5.99 KBmarcoscano
#49 2712951-49.patch26.36 KBmarcoscano
#48 interdiff-43-48.txt6.11 KBmarcoscano
#48 2712951-48.patch20.37 KBmarcoscano
#43 Bildschirmfoto_2017-11-30_um_11.46.57.png36.09 KBjohnchque
#43 interdiff-2712951-42-43.txt978 bytesjohnchque
#43 linkit_for_link_field-2712951-43.patch20.74 KBjohnchque
#43 linkit_for_link_field-2712951-43-prev-dev.patch20.68 KBjohnchque
#42 linkit_for_link_field-2712951-42.patch20.74 KBcameron prince
#37 interdiff-2712951-35-37.txt680 bytesjohnchque
#37 linkit_for_link_field-2712951-37.patch20.78 KBjohnchque
#35 interdiff-2712951-30-35.txt576 bytesjohnchque
#35 linkit_for_link_field-2712951-35.patch20.78 KBjohnchque
#30 linkit_for_link_field-2712951-30.patch20.68 KBpivica
#30 linkit_for_link_field-2712951-27-30-interdiff.txt779 bytespivica
#27 linkit_for_link_field-2712951-27-interdiff.txt2.43 KBmbovan
#27 linkit_for_link_field-2712951-27.patch20.66 KBmbovan
#26 linkit_for_link_field-2712951-26-interdiff.txt1.04 KBmbovan
#26 linkit_for_link_field-2712951-26.patch20.62 KBmbovan
#23 linkit_for_link_field-2712951-23-interdiff.txt765 bytesmbovan
#23 linkit_for_link_field-2712951-23.patch20.53 KBmbovan
#22 linkit_for_link_field-2712951-22-interdiff.txt12.42 KBmbovan
#22 linkit_for_link_field-2712951-22.patch19.78 KBmbovan
#21 linkit_for_link_field-2712951-21-interdiff.txt798 bytesmbovan
#21 linkit_for_link_field-2712951-21.patch13 KBmbovan
#20 interdiff-2712951-20-19.txt2.54 KBrecrit
#20 linkit_for_link_field-2712951-20.patch12.22 KBrecrit
#19 interdiff-2712951-19-18.txt451 bytesrecrit
#19 linkit_for_link_field-2712951-19.patch10.85 KBrecrit
#18 interdiff-2712951-18-16.txt444 bytesrecrit
#18 linkit_for_link_field-2712951-18.patch10.83 KBrecrit
#16 linkit_for_link_field-2712951-16.patch10.53 KBspadxiii
#9 interdiff-2712951-7-9.txt2.9 KBfrank.schalkwijk
#9 linkit_for_link_field-2712951-9.patch11.26 KBfrank.schalkwijk
#7 linkit_for_link_field-2712951-7.patch11.89 KBfrank.schalkwijk

Issue fork linkit-2712951

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:

Comments

MartinMa created an issue. See original summary.

anon’s picture

Status: Active » Closed (won't fix)

For internal links I think you should go for an entitiy reference field. Makes no sense to have that as a link field anymore.

beltofte’s picture

Version: 8.x-4.x-dev » 8.x-5.x-dev
Status: Closed (won't fix) » Active

I would say that it does still make sense to support Linkit for field types using autocomplete like entity reference fields, link fields (if you enabled links to local content).

Finding content using the native autocomplete in Drupal core can be really hard for editors if you have a lot of content and have multiple nodes with the same title. And this is where LinkIt makes the editor experience much better, because the profiles can be configured to show more info about the entity than just title and id.

I'm personally maintaining
https://www.drupal.org/project/linkit_references
and would like that moved to D8 for entity references, but not sure if that is possible at all without the field support in version 8.x-5.x of the Linkit core module.

dwkitchen’s picture

I would agree on the need for support for the Link field.

I have a Link field that can have either links to internal or external content. I can't change it to a reference field as that would block use of external links.

tne_’s picture

+1 for this feature in D8

thib’s picture

+1 for this feature in 8.x-5.x

frank.schalkwijk’s picture

StatusFileSize
new11.89 KB

I made my first Drupal 8 patch so it might not be very good, but it works for regular link fields and link fields in paragraphs.

I decided to make a new Linkit widget for link fields, so to use this widget you need to select it on the form display tab and select a profile in the widget settings.

frank.schalkwijk’s picture

I saw that my patch relies on file_entity. I'll try to fix it so that it doesn't rely on file_entity.

Update: I did not get my patch to work without file_entity.

frank.schalkwijk’s picture

StatusFileSize
new11.26 KB
new2.9 KB

I updated my patch a little because there was a problem.

When a user typed a url in the form of a internal url (like: 'google.com') and clicked the autocomplete result, the 'href' hidden field got set. The validation would fail, because this is an incorrect internal path. The form would be reloaded and when the user fixes his error by typing in 'https://google.com', but not click the autocomplete result, the hidden field would keep its previous value. I fixed this issue by not using the href hidden field, but instead use the value of the uri field.

I also fixed a wrongly indented array and removed the 'Selected link:' text, because it was redundant.

badrange’s picture

Status: Active » Needs review

I suppose the correct status for this issue is 'Needs review' now that there is a patch?

welly’s picture

Status: Needs review » Needs work

Tested the patch and it doesn't apply to the latest dev version. May try and fix it but if @frank.schalkwijk wants to take a look as the patch author, that would be great.

maio1980’s picture

+1 for this feature in 8.x-5.x

patch doesn't apply to the latest dev version

leo pitt’s picture

Ditto - this feature would be very useful. Entity reference is good for linking to only internal content - but does not work if you want to provide both internal and external links.

Attempted to amend the patch but it proved beyond my ability.

duncan.moo’s picture

I have taken the patch above, which I could not get to work, and created a module linkit_widget.

It would make far better sense for this to be incorporated into the Linkit module, perhaps as a sub-module? But I created a separate module to avoid the un-merged patch state we have on this ticket. (@anon any chance of getting this into Linkit, the use-case is solid).

There are some issues on the linkit widget, like if you have more than one on a page :); if it was a patch or a sub-module we could fix that in autocomplete.js (I think).

josh.fabean’s picture

This needs to be a thing! This module creates a better way for you to create links, so why shouldn't it work with the built in way to create links?

spadxiii’s picture

StatusFileSize
new10.53 KB

Rerolled the patch so that it applies on current dev again. The only changes that didn't apply were in the autocomplete.js.

tessa bakker’s picture

Status: Needs work » Needs review
recrit’s picture

With patch #16 if there are multiple link field items on the form, then all open up at the same time.
The attached patch ensure that the "click" event only operates on 1.

recrit’s picture

updated the element used to search upon the click event as well.

recrit’s picture

Added JS to auto-populate the link title if it has not been manually set.

mbovan’s picture

The above patch works fine with populating the link title but breaks the links placed via CKEditor.

Not sure about the unset logic in linkit_form_editor_link_dialog_submit() but removing it fixes the issues.

mbovan’s picture

As the substitution doesn't work for link fields, this patch aims to do so. It adds a new LinkitFormatter which overrides the URL and replaces it with the generated/substituted one.

Also, moved utility classes from the LinkitWidget into a new helper class.

Thoughts are very welcome.

mbovan’s picture

Added schema for the linkit widget and linkit formatter.

leo pitt’s picture

When I tested the other day it looked like the show/hide link text option in field settings was not being respected, will need to check again though.

dddbbb’s picture

Just tried the patch in #23 and it seemed fine. I haven't tried the formatter yet though (was using Link's "Separate link text and URL" instead).

mbovan’s picture

An improvement that adds a possibility to link multilingual content correctly.

Also, when touching LinkitHelper replaced $entity->GetEntityTypeId() with $entity->getEntityTypeId() call.

mbovan’s picture

mbovan’s picture

Missing comment from #27:

  1. +++ b/js/autocomplete.js
    @@ -75,12 +75,11 @@
    -
    -      $('input[name="attributes[href]"], input[name$="[attributes][href]"]', $context).val(ui.item.path);
    -      $('input[name="attributes[data-entity-type]"], input[name$="[attributes][data-entity-type]"]', $context).val(ui.item.entity_type_id);
    -      $('input[name="attributes[data-entity-uuid]"], input[name$="[attributes][data-entity-uuid]"]', $context).val(ui.item.entity_uuid);
    -      $('input[name="attributes[data-entity-substitution]"], input[name$="[attributes][data-entity-substitution]"]', $context).val(ui.item.substitution_id);
         }
    +    $('input[name="attributes[href]"], input[name$="[attributes][href]"]', $context).val(ui.item.path);
    +    $('input[name="attributes[data-entity-type]"], input[name$="[attributes][data-entity-type]"]', $context).val(ui.item.entity_type_id);
    +    $('input[name="attributes[data-entity-uuid]"], input[name$="[attributes][data-entity-uuid]"]', $context).val(ui.item.entity_uuid);
    +    $('input[name="attributes[data-entity-substitution]"], input[name$="[attributes][data-entity-substitution]"]', $context).val(ui.item.substitution_id);
    

    Having this inside if condition prevents updating a link from internal to external.

  2. +++ b/src/Plugin/Field/FieldFormatter/LinkitFormatter.php
    @@ -96,9 +96,10 @@ class LinkitFormatter extends LinkFormatter implements ContainerFactoryPluginInt
    +      $substituted_url = $this->getSubstitutedUrl($link_item);
    +      // Convert generated URL into a URL object.
    +      if ($substituted_url && ($url = \Drupal::pathValidator()->getUrlIfValid($substituted_url->getGeneratedUrl()))) {
    +        $item['#url'] = $url;
    

    Without conversion (generated URL to URL object) the formatted doesn't work for entities.
    However, a substitution plugin should return a URL object instead IMO. Not sure if that is going to work for files though...

One more thing I spotted, the linkit widget fails to select a file via autocomplete as Url::fromEntityUri() can't create a URL for file entities (There is no canonical link template for files).

We could think about writing test coverage for the current code.

hudri’s picture

+1 for this FR, for link fields allowing both internal and external links we can't use entity references, and LinkIt is a huge improvement in UX

pivica’s picture

StatusFileSize
new779 bytes
new20.68 KB

Made a bug report in #2916023: Deleted linkit entity produce fatal exception and when i started to create a patch i figured that we are using patched version of module from this issue.

We have a quite a big problem with a next scenario. We have a node with paragraphs which can have linkit field to other nodes. If linkit node is deleted then when you view parent node next PHP fatal error is generated:

The website encountered an unexpected error. Please try again later.
TypeError: Argument 1 passed to Drupal\Core\Entity\EntityRepository::getTranslationFromContext() must implement interface Drupal\Core\Entity\EntityInterface, null given, called in.../web/modules/contrib/linkit/src/Utility/LinkitHelper.php on line 21 in Drupal\Core\Entity\EntityRepository->getTranslationFromContext() (line 82 of core/lib/Drupal/Core/Entity/EntityRepository.php).
Drupal\Core\Entity\EntityRepository->getTranslationFromContext(NULL) (Line: 21)
Drupal\linkit\Utility\LinkitHelper::getEntityFromUri('entity:node/108') (Line: 121)
Drupal\linkit\Plugin\Field\FieldFormatter\LinkitFormatter->getSubstitutedUrl(Object) (Line: 99)
Drupal\linkit\Plugin\Field\FieldFormatter\LinkitFormatter->viewElements(Object, 'de') (Line: 80)
Drupal\Core\Field\FormatterBase->view(Object, 'de') (Line: 259)
Drupal\Core\Entity\Entity\EntityViewDisplay->buildMultiple(Array) (Line: 320)
Drupal\Core\Entity\EntityViewBuilder->buildComponents(Array, Array, Array, 'primer_teaser_grid') (Line: 263)
Drupal\Core\Entity\EntityViewBuilder->buildMultiple(Array) (Line: 18)
Drupal\paragraphs\ParagraphViewBuilder->buildMultiple(Array) (Line: 220)
Drupal\Core\Entity\EntityViewBuilder->build(Array)
call_user_func(Array, Array) (Line: 376)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 195)
...

The problem is in LinkitHelper::getEntityFromUri() method which will try to load entity that not exist and then pass it to the getTranslationFromContext() method, and this produce fatal error.

Here is a quick change for now that will fix this quickly until we figure better approach.

hudri’s picture

Adding another use case in hope to get some momentum on this issue: Linking to media entities.

The core link field autocomplete does not work with multiple different entity types, and the single entity-type is hardcoded to node.

miro_dietiker’s picture

The link field of Drupal supports providing a fragment to link targets. This linkit implementation always drops the fragment.
However, with the linkit UI, we also need to figure out how we would display / edit that fragment part. That's related to: #2902875: Make the selected item not look like text

miro_dietiker’s picture

From tests i discovered that if the link target title contains a special char like "&" it leads to double encoding in the link label.

johnchque’s picture

Assigned: Unassigned » johnchque

Working on this.

johnchque’s picture

After lots of research found the escaping problem. It basically escapes the label of the node and when building the suggestions it retrieves it in the same way, escaping. So when clicking the suggestion it just copies the raw value of the retrieved suggestion for the label.

The change should work for labels, keeping the URL as it was.

Status: Needs review » Needs work

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

johnchque’s picture

Status: Needs work » Needs review
StatusFileSize
new20.78 KB
new680 bytes

I don't see how this change might affect the current functionality. Using a better var name.

berdir’s picture

Are you sure that this issue specifically only affects the link field and not also the link button in WYSIWYG? If yes, then it should be a separate issue. I guess it will conflict though because the changes will also overlap.

Status: Needs review » Needs work

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

miro_dietiker’s picture

Yeah sorry, tested in WYSIWYG and it's the same.
Created dedicated issue.

cameron prince’s picture

For those interested, I've created an add-on for this feature at https://www.drupal.org/project/link_attributes/issues/2939514 which adds a new widget based on the one provided by this patch. The new widget combines the attributes provided by link_attributes module with the linkit selector for link fields.

The work there is based on the patch at comment #30.

cameron prince’s picture

StatusFileSize
new20.74 KB

Here's an updated version of #30 to address recent updates to dev.

johnchque’s picture

Status: Needs work » Needs review
StatusFileSize
new20.68 KB
new20.74 KB
new978 bytes
new36.09 KB

I think this should fix the tests.

Also removing a problem we had with inline form errors module:

Adding patch against old dev same as #30 and against current dev.

The last submitted patch, 43: linkit_for_link_field-2712951-43-prev-dev.patch, failed testing. View results

Status: Needs review » Needs work

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

johnchque’s picture

Assigned: johnchque » Unassigned

Not really sure why it fails, it basically says the 'data-entity-type' is added to the link but manual test says that it isn't.

marcoscano’s picture

Assigned: Unassigned » marcoscano
Issue tags: +Needs tests

Working on this.

marcoscano’s picture

StatusFileSize
new20.37 KB
new6.11 KB

This should fix the existing tests I think. Also changed some CS violations along the way.

Will be working on writting tests for the new widget/formatter next.

marcoscano’s picture

Assigned: marcoscano » Unassigned
Status: Needs work » Needs review
Issue tags: -Needs tests
StatusFileSize
new26.36 KB
new5.99 KB

This adds a test that should cover the most basic scenarios for the widget and formatter.

Anything else we should test?

marcoscano’s picture

StatusFileSize
new26.86 KB
new1.95 KB

A small improvement that preserves the fragment (#anchor) from entity URIs when used in the field widget.

berdir’s picture

Status: Needs review » Needs work

Looks pretty good, didn't really review the JS though.

  1. +++ b/js/autocomplete.js
    @@ -172,7 +187,26 @@
             $autocomplete.click(function () {
    -          $autocomplete.autocomplete('search', $autocomplete.val());
    +          var $t = $(this);
    +          $t.autocomplete('search', $t.val());
    +        });
    

    maybe we can use a better variable name for this, looks like it is related to translation but it isn't.

  2. +++ b/src/Plugin/Field/FieldWidget/LinkitWidget.php
    @@ -0,0 +1,211 @@
    +      '#description' => t('Start typing to find content or paste a URL.'),
    

    $this->t()

  3. +++ b/src/Utility/LinkitHelper.php
    @@ -0,0 +1,82 @@
    +  public static function getEntityFromUri($uri) {
    +    // Stripe out potential query and fragment from the uri.
    +    $uri = strtok(strtok($uri, "?"), "#");
    +    list($entity_type, $entity_id) = explode('/', substr($uri, 7), 2);
    +    $entity_manager = \Drupal::entityTypeManager();
    +    if ($entity_manager->getDefinition($entity_type, FALSE)) {
    +      if ($entity = $entity_manager->getStorage($entity_type)->load($entity_id)) {
    

    This helper uses quite a few services, seems like it should possibly be a service too that is injected into the widget (and formatter, if used there)?

  4. +++ b/tests/src/FunctionalJavascript/LinkFieldTest.php
    @@ -0,0 +1,162 @@
    +    // In order to prevent false failures in enviornments with url prefixes,
    +    // use a more robust way of checking if the href is what we expect.
    +    $this->assertTrue(strpos($href_value, '/entity_test_mul/') !== FALSE);
    

    I think phpunit has an assertcontains(), maybe also include the ID here in the check?

marcoscano’s picture

Status: Needs work » Needs review
StatusFileSize
new26.9 KB
new2.54 KB

@Berdir thanks for reviewing!

This addresses #51 except for #51.3:

This helper uses quite a few services, seems like it should possibly be a service too that is injected into the widget (and formatter, if used there)?

Both helper functions are declared as static, and one of them (getEntityFromUri()) is called in a static context from \Drupal\linkit\Plugin\Field\FieldWidget\LinkitWidget::getUriAsDisplayableString(), which is overriding core's \Drupal\link\Plugin\Field\FieldWidget\LinkWidget::getUriAsDisplayableString().

The other helper (::getUriFromSubmittedValue() is apparently not being called in a static context, not sure why it was initially created as static on this patch. Do you think it's worth making this a service and having only this method non-static?

berdir’s picture

+++ b/tests/src/FunctionalJavascript/LinkFieldTest.php
@@ -0,0 +1,165 @@
+
+    // Create a test entity to be used as target.
+    /** @var \Drupal\Core\Entity\EntityInterface $entity */
+    $entity = EntityTestMul::create(['name' => 'Foo']);
+    $entity->save();

You are creating the entity that you are using for tests here and have it in $entity, shouldn't be necessary to load it again with a query?

Ok, that one usage of the helper is static is a bit unfortunate, but we are using several services, so if we ever want to write unit tests for some logic in there, it would be a lot easier to do so when it is a service. The none call needs to use \Drupal::service() but that's not a big deal.

marcoscano’s picture

StatusFileSize
new26.73 KB
new1.17 KB

oops, that is indeed not necessary :)

Thanks!

marcoscano’s picture

StatusFileSize
new31.09 KB
new6.14 KB

This restores the behavior from patch 30 (that was lost at some point along the way) of showing the selected entity's label in the URL field, instead of /node/23 or something like that.

Also, improved the test coverage to cover external URLs and anchor fragments as well.

Status: Needs review » Needs work

The last submitted patch, 55: 2712951-55.patch, failed testing. View results

marcoscano’s picture

Status: Needs work » Needs review
StatusFileSize
new33.67 KB
new2.58 KB

OK, trying not to break it elsewhere now.

Status: Needs review » Needs work

The last submitted patch, 57: 2712951-57.patch, failed testing. View results

marcoscano’s picture

Status: Needs work » Needs review
StatusFileSize
new34.54 KB
new883 bytes
afoster’s picture

I've tested the patch in #59 against 8.x-5.0-beta7 and it worked for me. Thank you!

berdir’s picture

Status: Needs review » Reviewed & tested by the community
+++ b/tests/src/FunctionalJavascript/LinkitDialogTest.php
@@ -190,8 +190,8 @@ class LinkitDialogTest extends JavascriptTestBase {
 
-    // Make sure the linkit field field is populated with the node url.
-    $this->assertEquals($entity->toUrl()->toString(), $href_field->getValue(), 'The href field is populated with the node url.');
+    // Make sure the linkit field field is populated with the node label.
+    $this->assertEquals($entity->label(), $href_field->getValue(), 'The href field was not populated with the node label.');
 

the description seems backward, we are making that it is equal?

Could be fixed on commit but maybe @marcoscano has a minute to confirm and update the patch.

We also use this and it would be great if we could finally commit this. This issue has 53 followers, so lots of people are interested in this, would be amazing if we could finally get switch to a non-patched version of linkit. We've been using different patches from this issue for a year or so and have been testing it extensively.

marcoscano’s picture

+    $this->assertEquals($entity->label(), $href_field->getValue(), 'The href field was not populated with the node label.');

Yeah the assert* message parameter is always confusing... lately I've just stopped using them, they are IMHO hardly needed to understand a given failure anyways...

This message is actually shown when the test fails ( https://github.com/sebastianbergmann/phpunit/blob/6.5.7/src/Framework/Co... ), so in this case I believe the message should indicate that the label is *not* what it is expected, isn't it?

Maybe I'm missing something, let me know if that's the case!

marcoscano’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new35.62 KB
new1.41 KB

New bug (or arguably unexpected behavior) found here.

Steps to reproduce:
1) Apply this patch and configure a node link field to use this widget
2) Create a node with an internal route on the link field
3) Open the node edit form. Type an external route, such as "https://google.com"
4) Do not click on the dropdown suggestions. Instead click "Save" to save the node directly.

You would expect that "https://google.com" gets saved, but instead the internal route that was previously stored in the element attributes overrides that. If you click on the dropdown suggestion that says "Linkit could not find any suggestions. This URL will be used as is", however, everything works as expected.

I'm not very fond of my javascript skills, but I don't see any other option apart from resetting the attributes everytime a new key is pressed, once the user can write / select / write something different / etc several times, so we can never ensure the attributes are well defined, except when they click on the dropdown (after which no keyup should happen anymore).

Thoughts?

Status: Needs review » Needs work

The last submitted patch, 63: 2712951-63.patch, failed testing. View results

marcoscano’s picture

Tests++ :)

I had forgotten the anchor-feature... (too many features...)

So I guess we may have a conflict of expectations here...

In a node where a previous route to an internal link (for example "Related product Foo") exists:

- User A wants to be able to write "http://google.com#some-fancy-anchor" and then directly click save. He/she expects that this external URL will override the internal route previously saved.

- User B wants to be able to just add #some-anchor-text to the existing internal route title, so the link points to the correct fragment/anchor when saved. After writing the anchor in the text field (which would become then "Related product Foo#some-anchor-text"), he/she doesn't click on anything, only on "Save" to save the node. His/her expectation here is that the internal route is preserved and the anchor added.

Who should win?

cameron prince’s picture

I understand your predicament... You might consider expanding the "Link attributes" module to include a fragment field and use the patch I created in #41 to integrate "Link attributes" with "Linkit for link fields."

Good luck!

marcoscano’s picture

Status: Needs work » Needs review
StatusFileSize
new34.6 KB
new1.69 KB

OK, so after thinking about this for a while, we decided to prioritize the "current" functionality, and maybe just try to improve some descriptions.

This patch tries to make it a little bit clearer that you need to effectively click on the dropdown, even if there are no matches.

The interdiff is against #59 because we should then disregard patch #63.

erichomanchuk’s picture

I get an issue with using the patch and trying to link to an article that has an ampersand "&" in the title. Using version 8.x-5.0-beta7 when I link to an article using linkit in the wysiwyg everything works as expected. After applying the patch and linking to an article that has an ampersand in its title e.g. "Fees & Services". Then the title is used as the href for the link.

Before patch source code:

<p><a data-entity-substitution="canonical" data-entity-type="node" data-entity-uuid="8826c7a2-d761-4205-b565-fe2daad14944" href="/node/1">link</a></p>

After patch source code:

<p><a href="Fees &amp;amp; Services">link</a></p>

merilainen’s picture

I can confirm problem mentioned in #68.

idflood’s picture

I think that I have found another issue. I initially feature request since I would like to reference files from the link field (not part of a media). With the patch the files are shown in the autocomplete as expected but I can't save the node as it raise an error: "1 error has been found for: Links (value 3)".

The hidden inputs (entity-type, …) look correct.

edit: I disabled the "inline form errors" module and the error is more helpful I think: The path 'my_file.pdf' is invalid.
So the error come from LinkTypeConstraint.php from the core link field.

edit2: The error is in fact in LinkNotExistingInternalConstraintValidator.php, it raise a `RouteNotFoundException`. The Drupal\Core\Url object has a routeName "entity.file.canonical" and as a routeParameters `file` => `78` which looks right.

edit3: The "entity.file.canonical" is defined in the file_entity module but I have it disabled so that's why it doesn't work. I think it should not be a requirement for this module to work with files or I may have a strange config here.

edit4: The issue https://www.drupal.org/node/2423093 may be related to this.

edit5: So I compared the uri given by getUriFromSubmittedValue with a file loaded by id and using the "getFileUri" method on the entity.
The getUriFromSubmittedValue() return this: 'entity:file/86'
The getFileUri give me something like 'public://2018-06/myfile.pdf'
So the issue is in getUriFromSubmittedValue from LinkitHelper.php where if there is an entity the uri is "hardcoded" as this: '$entity_uri = 'entity:' . $entity->getEntityTypeId() . '/' . $entity->id();'

edit6: I tried to add this code to getUriFromSubmittedValue so that the uri returned for files look like the "public://" but I now get this LinkExternalProtocolsConstraintValidator from the link module.

$moduleHandler = \Drupal::service('module_handler');

$entity_uri = 'entity:' . $entity->getEntityTypeId() . '/' . $entity->id();
// File do not have the entity:file uri unless file_entity is enabled.
if ($entity->getEntityTypeId() == 'file' && !$moduleHandler->moduleExists('file_entity')){
  $entity_uri = $entity->getFileUri();
}
danjordan’s picture

I have installed the latest patch and when I try and link to a media file, the link points to the file media entity rather than a direct link to file.

I have double checked and my LinkIt profile has the "Direct URL to Media File Entity" selected.

Are others having the same issue or I am missing something?

idflood’s picture

I tried to enable the file_entity module and now it is working as expected : ) It would be great if this was not a requirement or if it is display a warning when we enable the "file" matcher about this.

@danjordan maybe check that you are using the "linkit" formatter on the manage display tab, by default it still use the standard link formatter.

danjordan’s picture

Thanks @idflood. That got it.

freddya21’s picture

@danjordan I ran into the same issue where

I have installed the latest patch and when I try and link to a media file, the link points to the file media entity rather than a direct link to file.

I have also double checked and my LinkIt profile has the "Direct URL to Media File Entity" selected. And that I am using the "linkit" formatter on the manage display tab.
Did you have to do anything else to get the Linkit Link to generate a direct link to file.

@Thread
What's strange is that the WYSWYG editors have an optional LinkIt filter that Runs if checked which Converts entity:node/1 into a "real" URL when rendering
the text but I'm not sure how that optional Filter is handled outside of the Content Editors; for instance, when the Link is just a field on a content type.

danjordan’s picture

@freddya21 that was all. I am using version 5.0-beta7 of Linkit module. Installed latest patch, cleared all caches and that got it to work for me.

freddya21’s picture

The problem was that I was using a Custom LinkIt Profile that I had added; and apparently the Custom LinkIt Profiles are Ignored when It comes to Leveraging LinkIt to publish Fields-based Links. I even made sure to select my custom profile under the Form Display Formatter. So in order to get it to work I ended up having to Make my desired selection within the Default LinkIt Profile.

Also Noticed that there is an issue where Field-based LinkIt Links that point directly to the underlying Media file; they require the cache to be flushed before it will show the new URL. This isn't the case with WYSWYG LinkIt Links, they show the latest media files without flushing the cache.

Issue Summary:

  • Custom LinkIt Profiles Ignored by LinkIt Fields
  • Newly Swapped Media Files Require Editors to Flush The Cache before showing up for LinkIt Fields
ahebrank’s picture

StatusFileSize
new582 bytes

Another quirk I noticed when using this in conjunction with simple (non-entity) matchers (i.e., Email), at least in the context of a wysiwyg: the returned href value is the autocomplete label, not the path. The attached interdiff against #67 sets the href to the raw path if entity matching is *not* used; I'm not at all confident this is the right fix or a good idea but it seems to fix the immediate problem.

idflood’s picture

StatusFileSize
new34.7 KB
new871 bytes

I found another issue. Our website is translated in 2 languages, german and french, with french as the default language.

Eventually when we edit a german page and try to link to a translated page in german the link is invalid (only the title in href, no data-* attributes).

The problem comes from this check in `linkit_form_editor_link_dialog_submit`:

if ($entity && strpos($href, $entity->label()) !== FALSE) {

The '$href' is correct as this correspond to the translated page title. But the $entity we compare against is not translated so the condition doesn't work here.

In the updated patch I added `$translation = \Drupal::service('entity.repository')->getTranslationFromContext($entity);`, but it might not be right in all situations I think. Ideally we should load the translation according to the selected item and not from context. For example the current approach might cause an issue when trying to link to a french page when editing a german page.

This condition has been added in #57 by @marcoscano, maybe you can help here?

Status: Needs review » Needs work

The last submitted patch, 78: linkit_for_link_field-2712951-78.patch, failed testing. View results

titouille’s picture

Hi,

Everyone can explain to me why don't using this :

$form_state->setValue(['attributes', 'href'], $href_dirty_check);

instead of this :

$form_state->setValue(['attributes', 'href'], $translation->toUrl()->toString());

in linkit_form_editor_link_dialog_submit handler from linkit.module.

By using the $href_dirty_check variable (ie node/1234), we are sure that the link will work in any language, even if the alias change after some modifications on the target entity. In this case, the multilingual support is ok and the target will remain because we map the internal link instead of an alias.
By using the alias, we can't assure that the link will become dead after modifications.

But maybe you have a good reason to do it like this ?

Thanks in advance for any explanation.

rudins’s picture

StatusFileSize
new34.48 KB

Hi,

New 8.x-5.x LinkitFilter makes sure new alias is rendered after alias changes. But it works only if links is added using new 8.x-5.x LinkitDrupalLink CKEditor plugin.
So, I ended up creating additional filter to process internal paths that are not created using new Linkit approach with data-entity attributes.

I agree with @titouille regarding setting href value as internal path, for consistency. LinkIt filter should be used in any case, let's generate url from internal path.

Adding modified patch with $href_dirty_check.

dddbbb’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 81: linkit_for_link_field-2712951-81.patch, failed testing. View results

ahebrank’s picture

StatusFileSize
new34.52 KB
new912 bytes

Should hopefully fix the null $entity testbot error in #81 and also deal with html entity encoding quirks as mentioned above a few times.

jesconstantine’s picture

Thanks for working on this! Is it possible to include the functionality of indicating the Link Text as required with an asterisk when there is a URL populated like the core link field widget does? I appreciate adding the referenced entity title automatically, but in the event that an author wants to overwrite it and they delete the title, it would be nice to have an indication that something is required. I can confirm that the post-submit validation does work, just looking to improve the UX in this respect.

jesconstantine’s picture

Have folks been able to implement this successfully with multiple instances of the linkit widget on a node edit form?

I'm getting an ajax error (whose symptom is the progress wheel spinning, but no dropdown of entities) with the following field setup on a node bundle:
* Link field on the node (linkit widget, functions as expected)
* Paragraphs field > Paragraphs field > Link field on paragraph (linkit widget, does not function)

To rule out Paragraphs ajax conflicts, I've also added an additional link field to the node directly and have gotten the same results:
* Link field on the node (linkit widget, functions as expected)
* Second link field on the node (linkit widget, does not function)

In both cases, I get the following ajax error in my console:

An AJAX HTTP error occurred.
HTTP Result Code: 500
Debugging information follows.
Path: /node/add/landing_page?ajax_form=1
StatusText: 500 Service unavailable (with message)
ResponseText: The website encountered an unexpected error. Please try again later.Drupal\Core\Entity\EntityMalformedException: The &quot;node&quot; entity cannot have a URI as it does not have an ID in Drupal\Core\Entity\Entity-&gt;toUrl() (line 190 of core/lib/Drupal/Core/Entity/Entity.php). Drupal\value\Normalizer\ContentEntityNormalizer-&gt;normalize(Object, &#039;value&#039;, Array) (Line: 143)
Symfony\Component\Serializer\Serializer-&gt;normalize(Object, &#039;value&#039;) (Line: 38)
Drupal\value\ThemeManager-&gt;buildValues(&#039;node&#039;, Array) (Line: 22)
Drupal\value\ThemeManager-&gt;render(&#039;node&#039;, Array) (Line: 437)
Drupal\Core\Render\Renderer-&gt;doRender(Array, 1) (Line: 195)
Drupal\Core\Render\Renderer-&gt;render(Array, 1) (Line: 139)
Drupal\Core\Render\Renderer-&gt;Drupal\Core\Render\{closure}() (Line: 582)
Drupal\Core\Render\Renderer-&gt;executeInRenderContext(Object, Object) (Line: 140)
Drupal\Core\Render\Renderer-&gt;renderRoot(Array) (Line: 133)
Drupal\yoast_seo\EntityAnalyser-&gt;renderEntity(Object) (Line: 69)
Drupal\yoast_seo\EntityAnalyser-&gt;createEntityPreview(Object) (Line: 78)
Drupal\yoast_seo\Form\AnalysisFormHandler-&gt;analysisSubmitAjax(Array, Object, Object)
call_user_func_array(Array, Array) (Line: 69)
Drupal\Core\Form\FormAjaxResponseBuilder-&gt;buildResponse(Object, Array, Object, Array) (Line: 98)
Drupal\Core\Form\EventSubscriber\FormAjaxSubscriber-&gt;onException(Object, &#039;kernel.exception&#039;, Object)
call_user_func(Array, Object, &#039;kernel.exception&#039;, Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher-&gt;dispatch(&#039;kernel.exception&#039;, Object) (Line: 228)
Symfony\Component\HttpKernel\HttpKernel-&gt;handleException(Object, Object, 1) (Line: 79)
Symfony\Component\HttpKernel\HttpKernel-&gt;handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session-&gt;handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle-&gt;handle(Object, 1, 1) (Line: 99)
Drupal\page_cache\StackMiddleware\PageCache-&gt;pass(Object, 1, 1) (Line: 78)
Drupal\page_cache\StackMiddleware\PageCache-&gt;handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware-&gt;handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware-&gt;handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel-&gt;handle(Object, 1, 1) (Line: 666)
Drupal\Core\DrupalKernel-&gt;handle(Object) (Line: 19)

I've applied this patch to the 8.x-5.x-dev version. Please let me know if I can provide any other context.

berdir’s picture

I don't think that has anything to do with this issue. It looks like yoast_seo is interfering there:

....
Drupal\yoast_seo\EntityAnalyser->renderEntity(Object) (Line: 69)
Drupal\yoast_seo\EntityAnalyser->createEntityPreview(Object) (Line: 78)
Drupal\yoast_seo\Form\AnalysisFormHandler->analysisSubmitAjax(Array, Object, Object)
....

Combined with this:

Drupal\value\ThemeManager->buildValues('node', Array) (Line: 22)

I don't know what that module is but it seems to be replacing the core theme manager and for whatever reason serialize it and you can't do that with unsaved/new entities...

jesconstantine’s picture

StatusFileSize
new95.61 KB
new26.95 KB
new19.2 KB
new153.08 KB
new101.23 KB

Thank you @Berdir I definitely missed that in the stacktrace. Sorry for crowding the thread with that noise.

I think I determined what was happening for me. When I switched the widget for the field on the node, I also checked the settings for the field widget which resulted in the linkit profile name being saved:

When linkit field widget has profile associated, ajax request uses that profile

And as a result the ajax request is made to the proper path for that linkit profile:

When linkit field widget settings interacted with the linkit profile is saved

When I switched the widget for a link field on my paragraph, I didn't need to see the widget settings so I never opened them and as a result, no linkit profile was saved:

When linkit field widget settings not interacted with, no profile saved

And as a result the ajax request is made to a path which returns nothing:

When linkit field widget has no profile associated, ajax request returns nothing

I only have 1 linkit profile, so it'd be great to have that set by default without needing to interact with the field widget settings - but at least now I have a workaround.

When only 1 profile, it should be set as the default without interacting with widget settings

Hope this helps.
Thanks

berdir’s picture

The recent changes fixed various problems, but for example the html encoding issue should instead be done by decoding in javascript (with https://api.jquery.com/jquery.parsehtml/) so that things like " also correctly show in the editor. I also think the dirty check is now broken, if you for example manually change to a path after selecting an entity, it will ignore that.

I'm wondering if we should remove the label stuff completely from this patch and leave that to issues like #2966320: Show entity title after autocomplete selection instead of internal route (e.g., /node/123). This patch is already doing too many things.

ahebrank’s picture

StatusFileSize
new35.02 KB

Adding in this combination of 84 and 77, with some additional checks to try to handle edits after the initial link is created.

In the submission callback:

  if (<linking to entity>)
    <snip>
  }
  elseif (empty($link_element) || isset($link_element['data-entity-type'])
          || (isset($link_element['href']) && ($link_element['href'] != $href_dirty_check))) {
    // No entity but also no manual change? Or maybe we're changing from an
    // entity to a non-entity?
    // Grab the raw path (presumably obtained by a simple matcher, like email),
    // and reset any entity attributes.
    $form_state->setValue(['attributes', 'href'], $href_dirty_check);
    $reset_attributes = TRUE;
  }

This is a mess... but seems to work so far.

arpad.rozsa’s picture

Status: Needs work » Needs review
StatusFileSize
new39.57 KB
new6.28 KB

Made some changes with the email matching:

  1. Removed the "E-mail" text from the suggestions label, to make matching easier and I think that text wasn't that useful anyway.
  2. For the link field, added a hidden href field to save the path of the email link there. Since it needs to have the mailto: prefix, but in the label we won't have that.
  3. Made some changes in the tests to make them work, according to the ones with the matcher.

Status: Needs review » Needs work

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

arpad.rozsa’s picture

Status: Needs work » Needs review
StatusFileSize
new39.7 KB
new716 bytes

Fixed the failing test, forgot to enable the email matcher.

ahebrank’s picture

StatusFileSize
new39.72 KB

This adds a minor tweak to 93 to do quote htmlentity conversion (the real fix is probably berdir's suggestion above for front-end processing of these characters).

ahebrank’s picture

StatusFileSize
new39.74 KB

(I don't know what the actual magic entity decode that matches the translation label, but here's another version that uses the top answer on http://php.net/manual/en/function.html-entity-decode.php)

johnchque’s picture

Please @ahebrank we need the interdiff agains the previous patch so we know what has been changed. Could you upload that please?

ahebrank’s picture

Won't Gitlab be nice, someday?

It's just this line in the .module file. Originally:

if (strpos(html_entity_decode($href), $translation->label()) !== FALSE)

vs. in 94:

if (strpos(html_entity_decode($href, ENT_QUOTES), $translation->label()) !== FALSE)

or in 95:

if (strpos(html_entity_decode($href, ENT_QUOTES | ENT_XML1, 'UTF-8'), $translation->label()) !== FALSE)
berdir’s picture

Status: Needs review » Needs work
+++ b/src/Utility/LinkitHelper.php
@@ -65,6 +65,11 @@ class LinkitHelper {
 
+    // For now only using this for email links.
+    if (!empty($value['attributes']['href']) && strpos($value['attributes']['href'], 'mailto:') !== FALSE) {
+      return $value['attributes']['href'];
+    }

I think we should always use the path field and drop the logic that resolves the label back to the entity.

arpad.rozsa’s picture

Fixing yet another problem, not related to the labels though. Basically what happened was that the linkit autocomplete conflicts with the core autocomplete when it initializing the field. This happened, with fields in paragraphs, but either way this could be a problem with fields directly on nodes as well.
I have a paragraph with a linkit field and another with a field that uses the core's autocomplete widget. Add the paragraph with the linkit first on a node form then the other one. There will be a javascript error in the console, which doesn't really break things, but in the second field with the autocomplete widget, the returned results will be rendered as in the linkit field, which is a problem, because the two should have different designs.
Hopefully this description is clear enough to see what my changes aim to fix.

arpad.rozsa’s picture

Status: Needs work » Needs review
StatusFileSize
new37.22 KB
new10.25 KB

As suggested dropped out a lot of code which corresponds to showing the labels. So we are back again at showing the paths in the url field.

xenophyle’s picture

I tried this patch and I'm having trouble getting it to use the Media Substitution. In LinkitFormatter::getSubstitutedUrl() the PHP URL scheme for a media link is internal, not entity. I am using the default Linkit profile both for the form display and the link field formatter. This is with Linkit 8.x-5.0-beta8.

Looking deeper I see LinkitHelper::getUriFromSubmittedValue() is setting everything except to "internal:".

xenophyle’s picture

StatusFileSize
new37.96 KB
new1.1 KB

I modified the previous patch by adding code to getUriFromSubmittedValue() from the patch in comment 99.

blazey’s picture

StatusFileSize
new38.13 KB
new738 bytes

Added query parsing. The patches so far only preserved the fragment and the query part wasn't saved.

blazey’s picture

StatusFileSize
new40.14 KB
new3.69 KB

Added query and fragment support when the user clicks on the popup.

Status: Needs review » Needs work

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

blazey’s picture

Status: Needs work » Needs review
StatusFileSize
new40.16 KB
new653 bytes

Fixed a regression introduced in #104.

Status: Needs review » Needs work

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

blazey’s picture

StatusFileSize
new7.9 KB
new41.72 KB
new19.38 KB

Ok, it turns out users are really confused with the input change, so here's a patch that shows the linked entity in a separate item and always shows the input as a url. It looks like this:

blazey’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

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

blazey’s picture

Status: Needs work » Needs review
StatusFileSize
new7.45 KB
new42.37 KB
  1. Moved the uri processing methods to LinkitHelper.
  2. Added a way to alter the url that will be presented in the textfield.
  3. Added uri normalization for absolute links that are really local.
miro_dietiker’s picture

Status: Needs review » Needs work

@blazey Thank you for the improvements.

IMHO we should keep the scope of this issue limited so that a commitable state is reached. Most importantly, all critical functionality added here was test covered while your additional extensibility points 2. / 3. seem not to be covered. For instance as a regression, the link does not open in a new tab, easily resulting in data loss if the user clicks it... We're now back to WIP.

blazey’s picture

StatusFileSize
new10.18 KB
new41.57 KB

Thank your for the review, sir! Good point about the link opening in the same tab. It's been addressed in the attached patch. Moreover:

  1. A few coding standards problems have been addressed.
  2. Some dead code has been removed.
  3. A regression in massageFormValues has been fixed. There was a problem when changing an existing value without clicking the autocomplete bubble.
  4. A new problem has been identified and fixed. Links to entities entered as aliases in languages other than the current one weren't identified correctly. Now they are and the entity association is saved.

So, to sum up, all of these inputs are now valid

/node/1
alias-to-node-1
/alias-to-node-1
/en/alias-to-node-1
/en/alias-to-node-1?with-a=query#and-fragment
/de/alias-to-node-1-in-a-different-language
http://same-domain.com/de/alias-to-node-1-in-a-different-language?with-a=query#and-fragment

and will be connected to the underlying entity. The decision whether to transform an absolute link to a relative version can be changed with hook_linkit_host_is_internal_alter().

Unfortunately, we don't have any additional resources to add test coverage at this point. We're sharing what we can, though.

johnchque’s picture

Status: Needs work » Needs review

Let's trigger testbot.

Status: Needs review » Needs work

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

blazey’s picture

Status: Needs work » Needs review
Issue tags: +Needs tests
StatusFileSize
new1.46 KB
new41.65 KB

Fixed the coding standards and the path alias matching logic.

Status: Needs review » Needs work

The last submitted patch, 116: 2712951-116.patch, failed testing. View results

blazey’s picture

StatusFileSize
new2.58 KB
new41.77 KB

Prevent an exception that was thrown for certain uris in a specific situation (when editing values that were created with the core link widget).

anon’s picture

First off, thank you all for the work and patiens on this issue.

I have read all the comments and there is many different things going on here, which is good, but at the same time I'm having a hard time wrapping my head around all of them.

I have tested the latest patch and it seems ok.

Some small things:

  • However I'm not sure about the changes in #108. That should be a separate issue I think, do you all agree?
  • Most importantly, all critical functionality added here was test covered while your additional extensibility points 2. / 3. seem not to be covered.

    This needs to be fixed.

Also the patch fails as the JS functional test class is extends JavascriptTestBase, but should now extend WebDriverTestBase.

anon’s picture

A test is also failing testLinkFieldWidgetAndFormatter

stefan.hartono’s picture

When I tried to enter mailto: link
it prevents me from entering it and it said the path is not valid
is there anyway to fix that ?

stefan.hartono’s picture

StatusFileSize
new41.89 KB
new530 bytes

I modified the validation so that the email link (mailto:) can be added.

stefan.hartono’s picture

StatusFileSize
new42.05 KB

Enable URL directing to add and edit form to be valid

bobbygryzynger’s picture

I can confirm #123 addresses validation issues with internal content creation paths.

esdrasterrero’s picture

StatusFileSize
new42.42 KB

Select first available linkit profile if there is any configured. (Instead of default)

hudri’s picture

I'm currently using #118, but it has a major issue with optional link texts:
Given a link field with an optional link text, when you select a node, then the link text field is prefilled with the node label.
A user can override the link text with a custom text, the custom text is stored correctly. But a user can not remove the link text and store an empty value, instead the link text is always filled with the node label on entity save.

Before #118 we have been using patch #59, which didn't have the optional link text issue, but we had to move forward due #78's multi-linguality issue.

I think this problem was introduced in #108 in LinkWidget::massageFormValues

      if (empty($value['title']) && $entity) {
        // Set the title here, otherwise it's set further down the chain with
        // a wrong (default) language.
        $value['title'] = $entity->label();
      }

I believe those lines prevent an optional, empty link text.

berdir’s picture

+++ b/src/Utility/LinkitHelper.php
@@ -0,0 +1,193 @@
+    if ($is_external) {
+      $host_is_internal = \Drupal::request()->getHost() === $host;
+      \Drupal::moduleHandler()->alter('linkit_host_is_internal', $host_is_internal, $host, $input);
+      if ($host_is_internal) {

I'm not sure why we have to add so much low-level logic and add (undocumented) hooks.

There is \Drupal\Component\Utility\UrlHelper::isExternal() and \Drupal\Component\Utility\UrlHelper::externalIsLocal(), can't we use that?

Again, as before when we've split off features from earlier patches, the more things we add here, the harder it is to get it committed.

I know it's hard because this introduces so many changes that it's very hard to combine it with other patches.

So lets try to keep not strictly related changes/improvements to a minimum and get this committed and then continue in smaller, more focused issues.

As commented in #119, all important functionality here needs to be covered with tests, and the more things we add, the harder that is as well.

arpad.rozsa’s picture

Status: Needs work » Needs review
StatusFileSize
new47.67 KB
new17.89 KB

As discussed before I removed that rendered 'Linked entity' feature introduced in #108 as it should be a separate feature and also it might conflict with the idea to show labels again in the url field, but this should remain outside of this patch.

Also removed the ability to alter the display url in the linkit widget and the alter to override if the url should be handled as internal or not. As discussed with @berdir, this was probably added for specific use case, but doesn't make much sense to use it as it could introduce some issues if the urls are not properly altered in the right format.

Refactored the changes from #122 as it add a new variable to store the host to check if the url is a mailto link, but there was already a host variable to use.

In the LinkitFormatter I added the linkit profile as a configurable setting, to be able to use profiles other than the default. Also added a description that says that the profile must be the same as on the widget, because different profiles can cause dissimilarities when editing or viewing a content. There was an attempt for this in #125, but the changes there weren't working properly, since it would always select the first available profile, which is mostly the default one.

As pointed out in #126 the link title shouldn't be set even if it's empty.

Set the title here, otherwise it's set further down the chain with a wrong (default) language.

@blazey added this, but I didn't experience such problems and it doesn't make sense to set the title after saving the widget.

The LinkitHelper is more functional now so I didn't change it too much. As it was suggested in #127 I changed the way we detect if the url is external or internal in LinkitHelper::uriFromUserInput().

Changed the FrontPageMatcher a little bit to match the front page by path as well.

Added new tests to test the url converting from an external url using the current website's host to a relative url. And also a test for the front page.

One, sort of new bug that I found is in the file matcher, but it might also make sense to leave this for a separate issue and I think there are already some issues on improving the file matcher. Anyway the problem is matching the relative path to the file, after users choose from the returned list. Searching is done by typing in the filename e.g. new-logo.png, which would return a path like /sites/default/files/new-logo.png. After having this path in the field, the file matcher won't give us any results, because it only searches by the filename.

jigarius’s picture

Status: Needs review » Reviewed & tested by the community

Tried the patch in comment 128 and it works very well for me. I still haven't put it on prod, but at first glance, it seems to be working correctly.

jeroent’s picture

Status: Reviewed & tested by the community » Needs work

Setting back to needs work since the tests are failing.

karlshea’s picture

StatusFileSize
new47.69 KB

Reroll for latest beta. Only change from #128 is changing js/autocomplete.js to js/linkit.autocomplete.js.

karlshea’s picture

Oops

miro_dietiker’s picture

Status: Needs work » Needs review

@KarlShea Interdiff is missing. Setting to Needs Review to trigger testbot.

kevinquillen’s picture

This patch appears to mostly work, but I noticed that if you have multiple query params of the same name that even though its saved in the database exactly as you entered it, when it is output on the page, you only get one of those parameters.

For example:

/search?facet=foo:bar&facet=baz:foobar&page=10&resultsPerPage=15

Displays on the page as:

/search?facet=baz:foobar&page=10&resultsPerPage=15

How can I change the behavior to not do that?

arpad.rozsa’s picture

Fixed the failing test, which was caused by the test case not finding page titles even though the title is present. So I removed those checks completely, since we have other checks to make sure we are on the right page.

Fixed a PHP warning in the FrontPageMatcher, when the url doesn't have a query or a fragment.

@kevinquillen What you discovered above is not an issue with this patch or module it is a core issue as of my testing. I think this is the issue for the bug: #2885351: Query string duplications

lendude’s picture

For the title test fail, see: https://www.drupal.org/project/drupal/issues/2870453#comment-12102425

If you change titleEquals to

  /**
   * Pass if the page title is the given string.
   *
   * @param string $expected_title
   *   The string the page title should be.
   *
   * @throws \Behat\Mink\Exception\ExpectationException
   *   Thrown when element doesn't exist, or the title is a different one.
   */
  public function titleEquals($expected_title) {
    $title_element = $this->session->getPage()->find('css', 'title');
    if (!$title_element) {
      throw new ExpectationException('No title element found on the page', $this->session->getDriver());
    }
    $actual_title = $title_element->getHtml();
    $this->assert($expected_title === $actual_title, 'Title found');
  }

(so ->getText() changed to ->getHtml()) the test is green. Not using that assertion in a JS test seems best I guess, or open a core issue to update titleEquals on \Drupal\FunctionalJavascriptTests\JSWebAssert

arpad.rozsa’s picture

Fixed the last test fail due to the test bot running in a subdirectory and the front page matcher test expected to see just /.

Not using that assertion in a JS test seems best I guess...

Regarding the title tests, I'm going with this option from @lendude's comment.

berdir’s picture

Status: Needs review » Needs work
+++ b/tests/src/FunctionalJavascript/LinkFieldTest.php
@@ -314,7 +314,7 @@ class LinkFieldTest extends WebDriverTestBase {
 
-    $this->assertEquals('/', $url_input->getValue());
+    $this->assertEquals('/subdirectory/', $url_input->getValue());
     // Check that the title was populated automatically.

We can't hardcode it, because now it fails when you don't have a subdirectly.

I'm also not sure that the fix needs to be in the test, it's more likely that the actual code is broken. The link field should always be relative to the drupal root, so the parsing logic need to make sure to not store the directly.

arpad.rozsa’s picture

Status: Needs work » Needs review
StatusFileSize
new47.48 KB
new1.45 KB

You are right about hardcoding, now I'm loading that URL from the route. The parsing logic doesn't have any problem with this though, because the drupal root will contain the subdirectory, if your server is setup like that.

Tested it locally and got the same results. Put drupal into a subdirectory e.g. /var/www/html/subdirectoryand setup apache virtualhost to have the doc root one directry above drupal's root i.e. /var/www/html and then Drupal's root url will be localhost/subdirectory/.

arpad.rozsa’s picture

StatusFileSize
new47.41 KB
new2.23 KB

Had a discussion with @berdir and the problem is using Url::fromRoute('<front>')->toString() which is good for display, but shouldn't be used for storing data. So my previous comment is irrelevant, changed back the test to check for / and in the FrontPageMatcher also saving that directly instead of using Url::fromRoute('<front>')->toString().

danjordan’s picture

Hi

When I try and add a tel: link to a link field using linkit, I receive the following error

InvalidArgumentException: A path was passed when a fully qualified domain was expected. in Drupal\Component\Utility\UrlHelper::externalIsLocal() (line 265 of /app/web/core/lib/Drupal/Component/Utility/UrlHelper.php).

I am experiencing the issue on several sites. Is anyone else experiencing a similar issue with the latest patch?

Thanks
Dan

paulmartin84’s picture

StatusFileSize
new46.83 KB

Im really not sure what the below code is trying to do, I have removed it in the attached patch because it is causing problems for me. Looking back it seems it was introduced in #108 without too much explanation.

If you add a page view with a contextual filter and a example path of "example-page/%taxonomy_term" where %taxonomy_term is a named route parameter, and then you try and link to this view using a link field with the linkit widget and an example link "/example-page/term1"

The below code finds the route correctly as a view and then it starts looking at the routes parameters which returns taxonomy_term and this results in an error whilst trying to save. Ideally it would just leave this manual link alone entirely.

I'm struggling to see why it is looking at what entity type a route's parameters might be. Does anyone have an example of when this might be useful?

+    try {
+      $route_name = Url::fromUri($input)->getRouteName();
+      if ($route_name != "entity.node.edit_form" && $route_name != "node.add") {
+        $params = Url::fromUri($input)->getRouteParameters();
+        $possibly_an_entity_type = key($params);
+        $entity = \Drupal::entityTypeManager()
+          ->getStorage($possibly_an_entity_type)
+          ->load($params[$possibly_an_entity_type]);
+        return \Drupal::service('entity.repository')
+          ->getTranslationFromContext($entity);
+      }
+    }
+    catch (\Exception $e) {
+      // Or not.
+    }
+
+    return NULL;
+  }
paulmartin84’s picture

StatusFileSize
new46.83 KB
paulmartin84’s picture

StatusFileSize
new46.83 KB
blazey’s picture

@kevinquillen that is a bug in PHP's parse_str function. See #3038774: Url only outputs the last value of a query parameter for details.

primsi’s picture

Small d9 compatibility related change. Patches from 143 or 144 did not apply and wasn't quite sure about the reroll, so this patch builds atop of #140.

primsi’s picture

Overlooked the form - view difference.

primsi’s picture

We noticed that submitting invalid input as link can lead to fatals on save, ie: tel:0123456. Adding that to patch.

berdir’s picture

Note: The deprecation updates here require 8.8, so that means this is basically blocked on #3042631: Drupal 9 Deprecated Code Report for LinkIt module, which in turn is blocked on the maintainer deciding to drop 8.7 support.

saseedharan’s picture

Ignore this comment, this was an issue in my local

I am trying to apply the patch #148 to linkit-8.x-5.x-dev, The files are getting added but final status is failed. Could not apply patch! Skipping. The error was: Cannot apply patch https://www.drupal.org/files/issues/2020-01-30/linkit_for_link_field-271.... I am using composer to apply patch. Adding patch entry in composer.json and then executing composer install

saseedharan’s picture

After changing the link field to linkit the Max Length & Count down messages were missing from widget settings. After exporting the config it got removed from YML file also. Seems linkit not inheriting properties like Max length & Count down messages from Link field.

Link with maxlength

Linkit without maxlength

primsi’s picture

Noticed the tel: case is not saved correctly. Not sure though if we should make this more general.

Status: Needs review » Needs work

The last submitted patch, 152: linkit_for_link_field-2712951-152.patch, failed testing. View results

primsi’s picture

Status: Needs work » Needs review
StatusFileSize
new2.23 KB
new49.22 KB
dieterholvoet’s picture

Can I add support for routes? Just returning ''route:" in case the input matches in LinkitHelper::uriFromUserInput. I can post an updated patch.

berdir’s picture

Status: Needs review » Needs work
+++ b/src/Utility/LinkitHelper.php
@@ -0,0 +1,198 @@
+  public static function getPathByAlias($input) {
+    $prefixes = \Drupal::config('language.negotiation')->get('url.prefixes');
+    /** @var \Drupal\Core\Path\AliasManagerInterface $path_alias_manager */
+    $path_alias_manager = \Drupal::service('path.alias_manager');
+    /** @var \Drupal\Core\Language\LanguageManagerInterface $language_manager */

this needs to be changed to path_alias.manager for D9 compatibility.

berdir’s picture

Status: Needs work » Needs review
StatusFileSize
new57.57 KB
new787 bytes

This will now require 8.8, so should be committed only after #3042631: Drupal 9 Deprecated Code Report for LinkIt module.

@DieterHolvoet: Concerned about this getting bigger and bigger and harder to get committed. Would require test coverage at least.

idebr’s picture

StatusFileSize
new654 bytes
new57.58 KB
+++ b/src/Utility/LinkitHelper.php
@@ -0,0 +1,198 @@
+    try {
+      $route_name = Url::fromUri($input)->getRouteName();
+      if ($route_name != "entity.node.edit_form" && $route_name != "node.add") {
+        $params = Url::fromUri($input)->getRouteParameters();
+        $possibly_an_entity_type = key($params);
+        $entity = \Drupal::entityTypeManager()
+          ->getStorage($possibly_an_entity_type)
+          ->load($params[$possibly_an_entity_type]);
+        return \Drupal::service('entity.repository')
+          ->getTranslationFromContext($entity);
+      }
+    }
+    catch (\Exception $e) {
+      // Or not.
+    }

The first key in the route parameters is not necessarily the entity parameter. Attached patch adds a sanity check to filter out empty values from the route parameters to increase the likelihood this will return an entity. For example, the Facets Pretty Paths module adds optional route parameters that are empty for internal:node/12 link URIs.

paulmartin84’s picture

I mentioned the above code previously in #142. Is this code actually needed? It seems to cause lots of problems.

The fix above wouldn't fix the issue I was having. Linking to a view that has a taxonomy term as a named parameter. I fail to see the connection between a route and what entity type the route parameter might be.

idebr’s picture

#159 It is the code path that resolves /node/[node id] links to entity:node/[node id]. Not sure how to solve your specific problem though, you would have to check the code in the default Link widget.

eyilmaz’s picture

+++ b/src/Utility/LinkitHelper.php
@@ -0,0 +1,198 @@
+    // It's a relative link. If it's a file, store it as `base:`. Otherwise it's
+    // most likely internal.
+    $public_files_dir = \Drupal::service('stream_wrapper_manager')
+      ->getViaScheme('public')
+      ->getDirectoryPath();
+
+    $protocol_matches = [];
+    preg_match('/^([a-z]*?):/', $input, $protocol_matches);
+    if (strpos($input, "/$public_files_dir") === 0) {
+      return "base:$input";
+    }
+    elseif (count($protocol_matches) > 1 && in_array($protocol_matches[1], UrlHelper::getAllowedProtocols())) {
+      return $input;
+    }
+    else {
+      return "internal:$input";
+    }
+  }

$public_files_dir might be empty here, i.e. when there is an external file system (like s3fs) is used. I guess we should also check for !empty($public_files_dir) in the first condition here.

eyilmaz’s picture

StatusFileSize
new57.61 KB
new592 bytes

Here is the patch updated which adds the check for empty public file directory.

paulmartin84’s picture

#160 My issue though is that the code is making a massive assumption that the entity type of the first(or any for that matter) of the routes parameters defines the entity that is being linked to. For a view route, the entity is the view and it is perfectly valid to want to link to a view page. What entity type the views parameters(contextual filters) are shouldn't make any difference.

If I link to a view that has a contextual filter of a taxonomy term. I don't want this changing it to a link to the taxonomy term itself.

eyilmaz’s picture

StatusFileSize
new1.98 KB
new58.12 KB

I noticed that the FieldFormatter does not honour the query params and fragment. Adjusted it to honour that.
Also addressed the issue from @paulmartin84. The entity is only returned, when the route is a canonical route.

bdanin’s picture

The patch in #164 worked well enough. However (at least in the Claro theme), the styling of the form with the linkit widget was blowing out the space. The link input field was too wide and pushed the other form elements out of the space. This was used in a paragraph in a node.

lammensj’s picture

StatusFileSize
new49.78 KB

I updated the patch according to the latest dev-release. I mostly removed parts of the patch which were included by Drupal 9 Deprecated Code Report for LinkIt module.

kkri’s picture

The patch #166 from @lammensj works well for me in the Seven theme.

I would definitely love to see this feature merged.

rwilson0429’s picture

The patch in #166 works good. Thanks.

primsi’s picture

StatusFileSize
new664 bytes

Anchors don't seem to work correctly: having #foobar for link would always lead you to the front page#foobar.

Adding a patch. Not sure if this is the correct way to approach this.

primsi’s picture

StatusFileSize
new49.85 KB

Didn't attach the patch...

primsi’s picture

StatusFileSize
new50.85 KB
new50.92 KB

Adding some test coverage for the latest patch.

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

alison’s picture

Patch works great for me overall!

In my case, the link title field is "required" in my field settings, and after applying the patch and enabling the "LinkIt" widget in the form settings, the red "required" asterisk disappears when I'm on my content editing form. (I think @jesconstantine mentioned this before.)

I think that's the only issue with the patch -- as far as I can tell, anyway. Thank you so much!!

berdir’s picture

StatusFileSize
new51 KB
new2.83 KB

This fixes notices when a site isn't multilingual, respects the title required setting and fixes some coding standards.

hudri’s picture

The latest patch #174 mostly works fine for me.

One issue still not addressed is the media entity file source substituion as reported in #74 and others.

I've been testing a bit, and found something within the stored field value in the database:
Using a multi-cardinality link field (--> guaranteed same field widget),
when I select and save a node, the path entity:node/123 is saved in field_fieldname_uri
when I select and save a media entity, the path internal:/media/456 is saved in field_fieldname_uri

This does not work with Drupal\linkit\Plugin\Field\FieldFormatter\LinkitFormatter.php

  protected function getSubstitutedUrl(LinkItemInterface $item) {
    if (parse_url($item->uri, PHP_URL_SCHEME) == 'entity') { //<-- not an entity url scheme
      if ($entity = LinkitHelper::getEntityFromUri($item->uri)) {
        ...

I've changed this function to

use Drupal\Core\Entity\EntityInterface;

  protected function getSubstitutedUrl(LinkItemInterface $item) {
    if (parse_url($item->uri, PHP_URL_SCHEME) == 'entity') {
      $entity = LinkitHelper::getEntityFromUri($item->uri);
    }
    elseif (parse_url($item->uri, PHP_URL_SCHEME) == 'internal') {
      $entity = LinkitHelper::getEntityFromUserInput($item->uri);
    }

    if ($entity instanceof EntityInterface) {
      $profile = Profile::load($this->getSettings()['linkit_profile']);

      /** @var \\Drupal\linkit\Plugin\Linkit\Matcher\EntityMatcher $matcher */
      $matcher = $profile->getMatcherByEntityType($entity->getEntityTypeId());
      $substitution_type = $matcher ? $matcher->getConfiguration()['settings']['substitution_type'] : SubstitutionManagerInterface::DEFAULT_SUBSTITUTION;
      return $this->substitutionManager->createInstance($substitution_type)->getUrl($entity);
    }

    return NULL;
  }

and this works for me. Sorry for posting the code here, but I don't know how to create a patch and interdiff.

hudri’s picture

StatusFileSize
new1.69 KB
new51.13 KB

This patch fixes the missing "direct link to file"-substitution for media entities by removing the unnecessary check for the entity:/ schema in the field formatter.

PS: This is the first time I've created an interdiff and a patch based on another patch, I hope I did get the workflow right, please take it with a grain of salt.

berdir’s picture

FWIW, if you select a media, it should also use use an entity: URI internally, or some things might not work as expected, e.g. entity_usage tracking. Not sure why it wouldn't, could be related about the back and forth on media urls with/without /edit suffix.

hudri’s picture

StatusFileSize
new51.14 KB
new1.7 KB

Please ignore patch #176, of course I forgot something. Recreated the patch again based upon Berdir's patch from #174.

Also keep in mind this patch assumes that media entities have their own canonical URL (Standalone media URL checked in /admin/config/media/media-settings). The substitution currently will not work without it. Not sure though if this behavior is good or bad.

hudri’s picture

StatusFileSize
new897 bytes
new51.49 KB

There is an issue with stale caches in the field formatter, which becomes especially visible when using media entities with "direct link to file"-substitution. I've added the cache tags of the referenced entity in case of a successful entity substituion.

tbsiqueira’s picture

Hi, I'm having the following error with this patch:

Error: Call to a member function getMatcherByEntityType() on null in Drupal\linkit\Plugin\Field\FieldFormatter\LinkitFormatter->getSubstitutedUrl()

This started to happen after I updated my drupal from 8.7 to 8.9 version, maybe there was some error that started causing it? I added a check to return null if the $profile variable was null from the Profile::load() function, but I guess this is not solving the root cause? I'm wondering if we are supposed to have profiles set as null?

Is there someone else having the same issue?

EDIT:

The issue is that on Drupal\linkit\Plugin\Field\FieldFormatter\LinkitFormatter::getMatcherByEntityType() the module is trying to load the "default" profile, that I don't have, never had..... don't know why is trying to load the "default" one now. Will continue the investigation.

mortarion’s picture

Hello there,
this is a nice patch. But it seems that it does not cover the support for <nolink> from the original LinkWidgetUI.

See https://www.drupal.org/project/drupal/issues/2698057

hudri’s picture

StatusFileSize
new364 bytes
new51.49 KB

The LinkitHelper has an issue when a link is a technically correct entity route, but the entity itself has been deleted. A case like this causes a WSOD with error message

TypeError: Argument 1 passed to Drupal\Core\Entity\EntityRepository::getTranslationFromContext() must implement interface Drupal\Core\Entity\EntityInterface, null given

In this case the surrounding catch Exception does not protect us from a plain error, I solved it by simply catching all throwables.

berdir’s picture

+++ b/src/Utility/LinkitHelper.php
@@ -140,7 +140,7 @@ class LinkitHelper {
       }
     }
-    catch (\Exception $e) {
+    catch (\Throwable $t) {
       // Or not.

I would suggest to instead check explicitly for successfully having loaded an entity. load() is documented to return an entity or NULL, it is an expected situtation. While we are not strictly speaking throwing the exception, https://stackoverflow.com/questions/77127/when-to-throw-an-exception still applies.

hudri’s picture

StatusFileSize
new863 bytes
new51.62 KB

Incorporated feedback from #183

bdanin’s picture

The patch in #184 worked well for me.

I had to add some logic to my custom.theme, from https://www.drupal.org/forum/support/module-development-and-code-questio... to get the file URL output into .twig, but this worked well.

adinac’s picture

StatusFileSize
new52.13 KB

I've encountered some issues using the latest patch:

1. In the formElement() method of the LinkitWidget class the default url value for the link element is built like this:
$uri_as_url = !empty($uri) ? Url::fromUri($uri)->toString() : '';
This allows path processing and the current language prefix and other prefixes, if any (like a country/region prefix), are added to the url and these remain the same on the display page, even when the context changes. I've made the following change:
$uri_as_url = !empty($uri) ? Url::fromUri($uri, ['path_processing' => FALSE])->toString() : '';

2. In the getEntityFromUserInput() method of the LinkitHelper class an entity is determined only if the input contains the "entity" scheme. I've made a few changes regarding this as well.

hudri’s picture

-deleted-

idebr’s picture

StatusFileSize
new3.09 KB

Interdiff for 184 -> 186

richardgaunt’s picture

StatusFileSize
new12.73 KB

I was having problems with the link title field being filled, the selector for $linkTitle depending on a certain structure of form.

I am using a sub-theme of Claro (Gin) which was not working, I've added a more direct way of accessing the title field input.

Status: Needs review » Needs work

The last submitted patch, 189: linkit-for-link-field-2712951-189.patch, failed testing. View results

richardgaunt’s picture

Status: Needs work » Needs review
StatusFileSize
new51.86 KB
new562 bytes

Apologies patch in #189 created incorrectly. Attached new patch and interdiff.

See #189 for details on what has changed.

kasey_mk’s picture

The patch in #191 works well for me, once I remembered to set the Linkit profile on each field formatter.

nadavoid’s picture

Status: Needs review » Reviewed & tested by the community

The patch in #191 is working well for me too. This is a great workaround for the core issue of enabling autocomplete of multiple entity types - #2423093: Allow multiple target entity types in the 'entity_autocomplete' Form API element.

godotislate’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new50.18 KB
new4.29 KB

I noticed that in the new field formatter, the cacheable metadata of the substituted URL is not accounted for. It is in the filter \Drupal\linkit\Plugin\Filter\LinkitFilter::proces()

$result
  // - the generated URL (which has undergone path & route processing)
  ->addCacheableDependency($url)
  // - the linked entity (whose URL and title may change)
  ->addCacheableDependency($entity);

I updated the patch to account for this, and also removed the constructor override to follow this: https://www.drupal.org/core/d8-bc-policy#constructors, similar to how Webform did it: https://www.drupal.org/node/3076421

r_h-l’s picture

Great patch but we discovered an issue: encoded characters in the returned autocomplete data.

For instance, a file with a name like "Some Test.file" gets returned from SimpleSuggestion and pasted into the link field as "some/path/Some%20Test.file". When the link field saves, it then further encodes into "some/path/Some%2520Test.file" (to encode the "%"), which then breaks the saved link.

There are two places to alter this, either in SimpleSuggestion (which then makes normal WYSIWYG links out of normal compliance), or someplace in the insertion, which I do not have enough JS experience to tweak and insert a "decodeURI" with a differentiation between when on an entity form vs CKEditor.

nadavoid’s picture

StatusFileSize
new50.87 KB

Updated patch 194 to make the autofill of the link text optional, configurable on form display.

nadavoid’s picture

StatusFileSize
new2.65 KB

Posting an interdiff between 194 and 196.

Status: Needs review » Needs work

The last submitted patch, 196: linkit-for-link-field-2712951-196.patch, failed testing. View results

nadavoid’s picture

Status: Needs work » Needs review
StatusFileSize
new50.99 KB
new3.33 KB
new858 bytes

Added linkit_auto_link_text to the schema to fix the failing test. Posting a couple more interdiffs.

Status: Needs review » Needs work

The last submitted patch, 199: linkit-for-link-field-2712951-199.patch, failed testing. View results

nadavoid’s picture

StatusFileSize
new51.05 KB
new1.99 KB
new1.31 KB

Updated patch to fix tests

nadavoid’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 201: linkit-for-link-field-2712951-201.patch, failed testing. View results

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

dylan donkersgoed’s picture

StatusFileSize
new107.26 KB
new3.58 KB

I've expanded the patch to support route:. Patch and interdiff attached.

I see that a fork has been opened but it does not seem to be up to date with the latest patches. Should we be using that instead?

bdanin’s picture

Even with the latest patch, I'm still getting an error:
TypeError: Argument 1 passed to Drupal\linkit\SuggestionManager::getSuggestions() must implement interface Drupal\linkit\ProfileInterface, null given, called in /app/docroot/modules/contrib/linkit/src/Controller/AutocompleteController.php on line 79 in Drupal\linkit\SuggestionManager->getSuggestions() (line 28 of /app/docroot/modules/contrib/linkit/src/SuggestionManager.php)

This causes linkit to silently fail, and does not provide any suggestions in the field for authors.

And I'm not sure what's causing this yet.

sanduhrs’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
StatusFileSize
new52.48 KB

Status: Needs review » Needs work

The last submitted patch, 207: linkit-for-link-field-2712951-207.patch, failed testing. View results

bdanin’s picture

This new patch in #207 doesn't fix the issue I have in #206.

sanduhrs’s picture

@bdanin I did not say, that it would solve your problem, did I?
I could have spent some time on declaring why i posted it, though:

The patch in #207 removes the unnecessary linkit-for-link-field-2712951-201.patch file from the patch in #205.

sanduhrs’s picture

Issue summary: View changes
Status: Needs work » Needs review
StatusFileSize
new52.55 KB

The attached patch adds a default theme to the field tests to prevent a deprecation notice.

todo: The auto fill title test still fails, because of a missing class in the markup.

1) Drupal\Tests\linkit\FunctionalJavascript\LinkFieldTest::testLinkFieldWidgetAndFormatter
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'Foo'
+''

/srv/http/drupal/linkit/web/modules/contrib/linkit/tests/src/FunctionalJavascript/LinkFieldTest.php:158

Status: Needs review » Needs work

The last submitted patch, 211: linkit-for-link-field-2712951-211.patch, failed testing. View results

peterwegren’s picture

Issue summary: View changes
Related issues: -#2937848: Double encoded special characters

@bdanin, re. #206: You have to explicitly set the Linkit matcher profile in the field display widget settings (including 'Update' and 'Save'). It appears as if the default matcher profile is selected by default, but it isn't saved in those widget settings until you update and save.

If you look in AutocompleteController.php on line 79, you can see that it is expecting the first parameter to be a Linkit profile:
$suggestionCollection = $this->suggestionManager->getSuggestions($this->linkitProfile, mb_strtolower($string));

If it is receiving null, as suggested by your error message, this likely indicates that the widget does not have a matcher profile set.

bdanin’s picture

@petorrr, you are correct. This was confusing because when I go to the form view display page, it looked like the default profile was already selected. I figured out how to export the config and it appears to be working for me now.

jlancaster’s picture

This is great! #211 works for me cleanly on the 6.x branch and performs the functionality I expected/desired.

cainaru’s picture

I re-rolled the patch in #211 to resolve the test failure and to address the feedback from #195 regarding double encoding internal links that contain %20.

When a user would enter a link such as /unencoded%20path%20with%20spaces.pdf into the link field that used the Linkit widget, save the node, and revisit the node's edit form, the value in the widget would be changed to /unencoded%2520path%2520with%2520spaces.pdf. Save the node again, revisit the node's edit form, and then the value would be /unencoded%252520path%252520with%252520spaces.pdf... This patch leverages getUriAsDisplayableString to address that in the Linkit widget.

Disclaimer: There seems to be a bug in core where, in a regular link field, a link with the value of /unencoded%20path%20with%20spaces.pdf is outputted as /unencoded%2520path%2520with%2520spaces.pdf even though it is saved correctly in the database as /unencoded%20path%20with%20spaces.pdf (and doesn't change on subsequent node saves). I was able to reproduce this on https://simplytest.me/. This patch does not address that core bug, and I haven't yet found an existing core issue that does.

glardup’s picture

#216 works like a charm!
This is very useful for a commerce site where you want to link to products. I was a bit flabbergasted to find out that core doesn't autocomplete links to other entities than nodes.
Thank you so much for this!

samlerner’s picture

The patch in #216 works for me using version 6.0.0-beta1, but there's one caveat: you MUST edit and save the configuration options form for the Link field on the Manage form display page. It's the form opened by clicking the gear in the Link field row. Doing this saves the Linkit profile in the field settings. If you don't do this first, and go to add/edit content and use the Link field, you'll get this lovely error:

WARNING: [pool www] child 284 said into stderr: "NOTICE: PHP message: TypeError: Argument 1 passed to Drupal\linkit\SuggestionManager::getSuggestions() must implement interface Drupal\linkit\ProfileInterface, null given, called in /var/www/docroot/modules/contrib/linkit/src/Controller/AutocompleteController.php on line 79 in /var/www/docroot/modules/contrib/linkit/src/SuggestionManager.php on line 28 #0 /var/www/docroot/modules/contrib/linkit/src/Controller/AutocompleteController.php(79): Drupal\linkit\SuggestionManager->getSuggestions(NULL, 'test')"

Looking at the code, it's calling $suggestionCollection = $this->suggestionManager->getSuggestions($this->linkitProfile, mb_strtolower($string)); and if you haven't saved that profile by saving the config, you get the above error.

e5sego’s picture

The patch in #216 works for me using version 6.0.0-beta2 too.

Note: I run into the following composer error during import of configuration (drush config:import). I had to clear caches and run the import again.
The &quot;linkit&quot; plugin does not exist. Valid plugin IDs for Drupal\Core\Field\WidgetPluginManager are: datetime_datelist, datetime_default, dynamic_entity_reference_options_buttons, dynamic_entity_reference_options_select, dynamic_entity_reference_default, entity_reference_revisions_autocomplete, file_generic, image_image, link_default, (...)

I did not run into error mentioned in #218, but did not tested this much.

mstrelan’s picture

@bdanin @SamLerner what are the steps to reproduce the issue in #206 and #218? Does this only happen when you're upgrading from an old patch to a new patch with an existing LinkIt formatter configured? I was unable reproduce it on a clean installation.

bdanin’s picture

@mstrelan as @SamLerner further points out in #218, you have to go to the form display config, and select the formatter, click save, and then export the configs for linkit. If you do not do this, then you get the error we outline in the logs and the linkit auto-fill silently fails on the edit screen.

mstrelan’s picture

@bdanin on a fresh installation I added a Link field, set the formatter to LinkIt and hit save, no extra step required.

bbombachini’s picture

+1 this works on 8.x-5.0-beta12 version of the module.

jeffam’s picture

Status: Needs work » Needs review

Just tested on 6.0.0-beta2 and it's a huge improvement over the link field autocomplete from core.

larowlan’s picture

Status: Needs review » Needs work

Great work here folks, this looks promising. Added a review while I was here

  1. +++ b/src/Plugin/Field/FieldFormatter/LinkitFormatter.php
    @@ -0,0 +1,166 @@
    +    $options = [];
    +    foreach ($linkit_profiles as $linkit_profile) {
    +      $options[$linkit_profile->id()] = $linkit_profile->label();
    +    }
    

    this could use array_map

  2. +++ b/src/Plugin/Field/FieldFormatter/LinkitFormatter.php
    @@ -0,0 +1,166 @@
    +      if ($substituted_url && ($url = \Drupal::pathValidator()->getUrlIfValid($substituted_url->getGeneratedUrl()))) {
    

    We can do dependency injection in formatters, so should be doing so given we're already injecting some services

  3. +++ b/src/Plugin/Field/FieldFormatter/LinkitFormatter.php
    @@ -0,0 +1,166 @@
    +      $profile = Profile::load($this->getSettings()['linkit_profile']);
    

    We inject the entity type manager, but are using the singleton to load? Shouldn't we use the entity type manager?

  4. +++ b/src/Plugin/Field/FieldWidget/LinkitWidget.php
    @@ -0,0 +1,216 @@
    +    $default_allowed = !$item->isEmpty() && (\Drupal::currentUser()->hasPermission('link to any page') || $item->getUrl()->access());
    

    Widgets can do DI, we're doing it in the formatter? Should we do it here too?

  5. +++ b/src/Plugin/Field/FieldWidget/LinkitWidget.php
    @@ -0,0 +1,216 @@
    +      '#default_value' => $default_allowed && isset($entity) ? $entity->getEntityTypeId() == 'file' ? 'file' : 'canonical' : '',
    

    this could use some brackets to aid readability

  6. +++ b/src/Plugin/Field/FieldWidget/LinkitWidget.php
    @@ -0,0 +1,216 @@
    +      $element['title']['#attributes']['class'][] = 'linkit-widget-title--autofill-enabled';
    

    shouldn't we be using data attributes instead of classes for this non-presentational functionality?

  7. +++ b/src/Plugin/Field/FieldWidget/LinkitWidget.php
    @@ -0,0 +1,216 @@
    +      // Otherwise wrap everything in a details element.
    ...
    +          '#type' => 'fieldset',
    

    Fieldset or details? The comment doesn't match the code here

  8. +++ b/src/Plugin/Field/FieldWidget/LinkitWidget.php
    @@ -0,0 +1,216 @@
    +    $linkit_profiles = \Drupal::entityTypeManager()->getStorage('linkit_profile')->loadMultiple();
    ...
    +    $linkit_profile = \Drupal::entityTypeManager()->getStorage('linkit_profile')->load($linkit_profile_id);
    

    Same comment here re DI

  9. +++ b/src/Plugin/Field/FieldWidget/LinkitWidget.php
    @@ -0,0 +1,216 @@
    +    foreach ($linkit_profiles as $linkit_profile) {
    +      $options[$linkit_profile->id()] = $linkit_profile->label();
    +    }
    

    same comment here re array_map

  10. +++ b/src/Plugin/Field/FieldWidget/LinkitWidget.php
    @@ -0,0 +1,216 @@
    +    if ($scheme === 'base') {
    +      $uri_reference = explode(':', $uri, 2)[1];
    +      $uri = 'internal:' . $uri_reference;
    +    }
    +    elseif ($scheme === 'entity') {
    +      $uri_reference = explode(':', $uri, 2)[1];
    

    we could return early here and avoid using elseif

  11. +++ b/src/Plugin/Linkit/Matcher/EmailMatcher.php
    @@ -23,11 +23,14 @@ class EmailMatcher extends MatcherBase {
    +    // Strip the mailto: prefix to match only the e-mail part of the string.
    +    $string = str_replace('mailto:', '', $string);
    ...
    -      $suggestion->setLabel($this->t('E-mail @email', ['@email' => $string]))
    +      $suggestion->setLabel($string)
    

    this seems out of scope

  12. +++ b/src/Plugin/Linkit/Matcher/EntityMatcher.php
    @@ -344,6 +344,12 @@ class EntityMatcher extends ConfigurableMatcherBase {
    +      if ($query = parse_url($string, PHP_URL_QUERY)) {
    +        $suggestion->setPath($suggestion->getPath() . '?' . $query);
    +      }
    +      if ($fragment = parse_url($string, PHP_URL_FRAGMENT)) {
    +        $suggestion->setPath($suggestion->getPath() . '#' . $fragment);
    

    This seems out of scope too

  13. +++ b/src/Plugin/Linkit/Matcher/FrontPageMatcher.php
    @@ -22,12 +22,18 @@ class FrontPageMatcher extends MatcherBase {
    +    $front_path = '/';
    ...
    -        ->setPath(Url::fromRoute('<front>')->toString())
    

    Is replacing the generated URL with a hard-coded / the right approach?

  14. +++ b/src/Plugin/Linkit/Matcher/NolinkMatcher.php
    @@ -0,0 +1,39 @@
    +class NolinkMatcher extends MatcherBase {
    

    This is out of scope here

  15. +++ b/src/Utility/LinkitHelper.php
    @@ -0,0 +1,223 @@
    +      if (count($parts) == 2 && ($entity_type = $parts[0]) && ($entity_id = $parts[1])) {
    +        $entity_manager = \Drupal::entityTypeManager();
    

    why not use list or the new array destructuring syntax here?

  16. +++ b/src/Utility/LinkitHelper.php
    @@ -0,0 +1,223 @@
    +        if ($entity_manager->getDefinition($entity_type, FALSE)) {
    

    this should use hasDefinition because we're not using the returned value

  17. +++ b/src/Utility/LinkitHelper.php
    @@ -0,0 +1,223 @@
    +      ->getViaScheme('public')
    

    what about private files?

  18. +++ b/src/Utility/LinkitHelper.php
    @@ -0,0 +1,223 @@
    +    preg_match('/^([a-z]*?):/', $input, $protocol_matches);
    

    shouldn't this use parse_url with the PHP_URL_SCHEME flag instead of a regex?

  19. +++ b/src/Utility/LinkitHelper.php
    @@ -0,0 +1,223 @@
    +    elseif ((count($protocol_matches) > 1 && in_array($protocol_matches[1], UrlHelper::getAllowedProtocols())) || $is_nolink) {
    

    elseif isn't needed with a return in the previous hunk

    in addition, in_array should use the third argument set to TRUE

  20. +++ b/src/Utility/LinkitHelper.php
    @@ -0,0 +1,223 @@
    +    else {
    

    no need for an else if both previous hunks returned

  21. +++ b/src/Utility/LinkitHelper.php
    @@ -0,0 +1,223 @@
    +      $possibly_an_entity_type = key($params);
    

    the entity type is not necessarily the first route parameter

  22. +++ b/src/Utility/LinkitHelper.php
    @@ -0,0 +1,223 @@
    +      $input_path = parse_url($input, PHP_URL_PATH);
    

    no need to do this every time, can be moved outside the loop

  23. +++ b/src/Utility/LinkitHelper.php
    @@ -0,0 +1,223 @@
    +      if ($prefix = $config->get('url.prefixes.' . $language->getId())) {
    

    what if prefixes isn't the language negotiation method? ie what if it is done by domain

  24. +++ b/tests/src/FunctionalJavascript/LinkitDialogTest.php
    @@ -196,9 +196,6 @@ class LinkitDialogTest extends WebDriverTestBase {
    -    // Make sure the linkit field field is populated with the node url.
    -    $this->assertEquals($entity->toUrl()->toString(), $href_field->getValue(), 'The href field is populated with the node url.');
    

    this feels out of scope, why are we changing dialog tests?

  25. +++ b/tests/src/Kernel/LinkitAutocompleteTest.php
    @@ -110,7 +109,7 @@ class LinkitAutocompleteTest extends LinkitKernelTestBase {
    -    $this->assertSame((string) new FormattableMarkup('E-mail @email', ['@email' => $email]), $data[0]['label'], 'Autocomplete returned email suggestion.');
    +    $this->assertSame($email, $data[0]['label'], 'Autocomplete returned email suggestion.');
    

    This feels out of scope too, possibly even a regression

cluke009’s picture

This patch is working great for me so far but I did encounter an issue with the node access module.

Probably pretty out of scope at moment but wanted to document it. I will take a deeper look when I get a chance.

Error report below

Drupal\Core\Entity\EntityStorageException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'gid' cannot be null: INSERT INTO {node_access} (nid, langcode, fallback, realm, gid, grant_view, grant_update, grant_delete) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7), (:db_insert_placeholder_8, :db_insert_placeholder_9, :db_insert_placeholder_10, :db_insert_placeholder_11, :db_insert_placeholder_12, :db_insert_placeholder_13, :db_insert_placeholder_14, :db_insert_placeholder_15), (:db_insert_placeholder_16, :db_insert_placeholder_17, :db_insert_placeholder_18, :db_insert_placeholder_19, :db_insert_placeholder_20, :db_insert_placeholder_21, :db_insert_placeholder_22, :db_insert_placeholder_23); Array ( [:db_insert_placeholder_0] => 66251 [:db_insert_placeholder_1] => en [:db_insert_placeholder_2] => 1 [:db_insert_placeholder_3] => nodeaccess_rid [:db_insert_placeholder_4] => 1 [:db_insert_placeholder_5] => 1 [:db_insert_placeholder_6] => 0 [:db_insert_placeholder_7] => 0 [:db_insert_placeholder_8] => 66251 [:db_insert_placeholder_9] => en [:db_insert_placeholder_10] => 1 [:db_insert_placeholder_11] => nodeaccess_rid [:db_insert_placeholder_12] => 2 [:db_insert_placeholder_13] => 1 [:db_insert_placeholder_14] => 0 [:db_insert_placeholder_15] => 0 [:db_insert_placeholder_16] => 66251 [:db_insert_placeholder_17] => en [:db_insert_placeholder_18] => 1 [:db_insert_placeholder_19] => nodeaccess_rid [:db_insert_placeholder_20] => [:db_insert_placeholder_21] => 1 [:db_insert_placeholder_22] => 1 [:db_insert_placeholder_23] => 1 ) in Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (line 846 of /app/docroot/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).

cainaru’s picture

For what it's worth, I just noticed that there isn't any validation on the $element['uri'] in formElement in /linkit/src/Plugin/Field/FieldWidget/LinkitWidget.php.

This means someone can accidentally include a leading space in their link (e.g., /my-link-here or https://www.google.com/) and are not warned that Manually entered paths should start with one of the following characters: / ? #.

It looks like validation can be added back by doing something like the following:

  1. Remove '#error_no_message' => TRUE, from line 75 in linkit/src/Plugin/Field/FieldWidget/LinkitWidget.php
  2. Add '#element_validate' => [['\Drupal\link\Plugin\Field\FieldWidget\LinkWidget', 'validateUriElement']], after line 67 in linkit/src/Plugin/Field/FieldWidget/LinkitWidget.php

Note: Caveat with the above is that, if you are also using the contrib module Media Entity Download and have content creators who tend to enter the download path to the media (e.g., /media/1234/download), on node save you'll get an error that The path 'internal:/media/1234/download' is invalid. Somewhere along the way in linkit/src/Utility/LinkitHelper.php that media download path is getting turned into internal:internal:/media/1234/download. I'm hoping I'll have a chance to dig deeper into that soon.

Another note: It looks like early iterations of patches in this issue did in fact have uri validation, but it was removed in #113 because of multi-lingual issues. If re-rolling the latest patch to re-introduce uri validation, it might be a good idea to test against multi-lingual links similar to the ones listed in #113?

cluke009’s picture

That is some quality info. Will give me somewhere to start if you don't get to it first.

jeroent’s picture

Status: Needs work » Needs review
StatusFileSize
new53.28 KB
new9.34 KB

Fixed some of the feedback in #225.

  • 1: fixed
  • 2: fixed
  • 3: fixed
  • 4: fixed
  • 5: fixed
  • 7: fixed
  • 8: fixed
  • 9: fixed
  • 10: fixed
  • 15: fixed
  • 16: fixed
  • 19: fixed
  • 20: fixed

Still left:

  • 6
  • 11
  • 12
  • 13
  • 14
  • 17
  • 18
  • 21
  • 22
  • 23
  • 24
  • 25

Status: Needs review » Needs work

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

cainaru’s picture

Re-rolled #229 in hopes of the tests passing.

In this patch, I also re-added validation to the URI element -- as a first pass.

It was very tricky trying to harmonize the various use cases and the URI validation (particularly with files such as /sites/default/files/2021-07/my-uploaded-document.pdf, internal paths such as /media/1234/download, links such as mailto:name@example.com or tel:1-315-867-5309, <front>, etc.). It could use additional improvement from someone who has more insight in the plethora of link-related use cases, as I'm not sure if I might have missed any.

cainaru’s picture

Status: Needs work » Needs review
philltran’s picture

@cainaru Thank you for your latest patch. I am glad it passed the automated testing.

So far my quick test is working to reference a media entity by manually entering the internal media url. Autocomplete is not searching for the media title. I am not sure if that is intended to work.

jeroent’s picture

Created #3223781: Add Support for <nolink> so the NoLinkMatcher can be removed from this patch.

cainaru’s picture

@philltran autocomplete for media should work as long as you've got Media among your matchers (go to /admin/config/content/linkit/manage/<name of whatever linkit profile you are using>/matchers to check)

philltran’s picture

@cainaru Thank you for your comment. It was an issue on my end.

I re-rolled patch without NoLinkMatcher per @JeroenT's comment and review in comment #225

Do we still need to perform the tasks still left from review in comment #225

  • 6
  • 11
  • 12
  • 13
  • 17
  • 18
  • 21
  • 22
  • 23
  • 24
  • 25
jeroent’s picture

StatusFileSize
new46.9 KB
new11.72 KB

Ok, so I went through the tasks from #2712951-235: Linkit for Link field again:

Still left:

  • 17
  • 18
  • 21
  • 22
  • 23

Status: Needs review » Needs work

The last submitted patch, 237: 2172951-237.patch, failed testing. View results

jeroent’s picture

Status: Needs work » Needs review
StatusFileSize
new46.46 KB
new2.26 KB

Status: Needs review » Needs work

The last submitted patch, 239: 2712951-239.patch, failed testing. View results

jeroent’s picture

Status: Needs work » Needs review
StatusFileSize
new46.52 KB
new749 bytes

Status: Needs review » Needs work

The last submitted patch, 241: 2172951-241.patch, failed testing. View results

jeroent’s picture

Status: Needs work » Needs review
StatusFileSize
new46.61 KB
new1.44 KB
adrian83’s picture

A few days ago I applied patch 231 to Drupal 8.9.14 which gave us autocomplete matching for taxonomy terms and nodes, exactly what we needed.

bernardm28’s picture

It would be great getting this patch to work with 9.2. However, I'm not sure what's up with that error.
PHP Fatal error: Uncaught TypeError: Return value of Drupal\Composer\Composer::ensureComposerVersion() must be an instance of Drupal\Composer\void, none returned in /var/www/html/composer/Composer.php:96
Stack trace:

bernardm28’s picture

This patch worked on ddev with Drupal core 9.2.4. It seems like that error above has to do with
https://www.drupal.org/project/drupal/issues/3126566 which is merged. So idk why that would trigger an error but it does.

betoaveiga’s picture

StatusFileSize
new53.1 KB

Hey @tbsiqueira, I was having the same issue with the patch from #243 applied.

Error: Call to a member function getMatcherByEntityType() on null in Drupal\linkit\Plugin\Field\FieldFormatter\LinkitFormatter->getSubstitutedUrl()

This issue was happening when running tests on CI, while cron was executed, so it is difficult for me to find why it is happening.

I fixed it by returning NULL when no profile was available.

My site looks normal, and all tests are passing.

I updated the mentioned patch.

niles38’s picture

@BetoAveiga Your patch worked well for me. Thank you all for your work on this. I'm looking forward to this functionality being part of Linkit!

Edit: I'm running Drupal 9.2.4.

sachbearbeiter’s picture

@BetoAveiga and @JeroenT
Thanks a lot for the work ...
I'm looking forward ;)

niles38’s picture

This patch does work.

ac’s picture

Status: Needs review » Reviewed & tested by the community

#247 works well

jeroent’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new46.68 KB
new3.67 KB

It seems that the patch in #247 removed some changes that were made in #243.
So I created a new patch, based on #243 and added the same check.

There was also still some feedback left from #235:

  • 17. I tried linking to a private file and this was working correctly. Since private files are served using the system.files route, there is no special handling needed for private files.
  • 18. Fixed.
  • 21. Fixed.
  • 22. I moved the check in a loop. When the first route parameter isn't an entity, the next parameters are checked.
  • 23. When the language negotiation method is done by domain, there is no language prefix. The same logic as a monolingual site will happen.

Status: Needs review » Needs work

The last submitted patch, 252: 2712951-252.patch, failed testing. View results

jeroent’s picture

Status: Needs work » Needs review
StatusFileSize
new46.75 KB
new5.61 KB
tessa bakker’s picture

Status: Needs review » Needs work
StatusFileSize
new104.12 KB

The required title validation of a required link field isn't displayed.

This is because of the following line of code in the title element:

'#error_no_message' => TRUE,

When removed the required message is displayed for title field.

The validateTitleElement callback is only there for an optional link field with a required title if the url is set. Not for validating a required title on a required link field.

The image will explain how the core link widget works with a required title validation Variations of required title validations in a link field

tessa bakker’s picture

Status: Needs work » Needs review
StatusFileSize
new501 bytes
new46.71 KB

Removed the line as suggested in comment #255

laura.gates’s picture

Any way to get this patch for linkit v6.0.0-beta-3?

kevin.pfeifer’s picture

@laura.gates The patch from #256 is applicable to 6.0-beta3 as well!

I just applied it, cleared cache and it works!

choneyse’s picture

I just installed this for 6.0-beta3 and the field is working, but I'm not able to get the "Direct URL to media file entity" to work. Regardless of my profile settings, I'm only able to get a link to the media entity. My hope is to be able to link to a PDF that is in the Media Entity as a File.

natemow’s picture

@choneyse re: #259 -- double-check that your entity's field display settings are using the Linkit format.

spadxiii’s picture

StatusFileSize
new49.56 KB
new5.43 KB

I noticed a strange usage of the ContainerFactoryPluginInterface create method (introduced from #194 onward): here properties were assigned manually to the instance, instead of passing them to the constructor.

Fixed this by re-introducing the constructor again. Also removed the unused EntityTypeManager property in the LinkitFormatter.
Other than that, the patch is the same as in #256.

Status: Needs review » Needs work

The last submitted patch, 261: 2712951-261.patch, failed testing. View results

dieterholvoet’s picture

here properties were assigned manually to the instance, instead of passing them to the constructor

That's intentional, more information here. I suggest changing it back.

spadxiii’s picture

StatusFileSize
new68.34 KB
new23.92 KB

I made a little mistake with the third_party_settings and label arguments. So here's a new patch:

spadxiii’s picture

That's intentional, more information here. I suggest changing it back.

It feels weird to me to refactor something inside a huge patch without refactoring the rest of the project as well. But then again, refactoring the rest of the project inside a huge patch is also not a good thing to do. I would suggest doing the refactor separately and once that is in, refactor the remaining open patches afterwards.

Besides that, doing it the way it was done in the patch, limits the testability quite a bit. It makes it unnecessarily hard to replace/mock the dependencies. As you can see here, using a public setter method would be better as that allows for more easily mocking the dependencies.

jeroent’s picture

I don't have a strong opinion on both options.

Anyway, The patch in #264 still needs work since the tests are failing and contains some interdiff files, which should be removed or patch #256 should be used.

spadxiii’s picture

StatusFileSize
new49.58 KB
new5.44 KB

Oh whoops, forgot to remove those from my patch. Here's the same patch without the interdiffs.

Not sure why the tests are failing; the error I see seems unrelated to the changes made with this patch.

jeroent’s picture

I triggered the tests again for patch in #256 and that patch is still green.
So the error does seem related to the changes.

spadxiii’s picture

I'll have a closer look

spadxiii’s picture

Status: Needs work » Needs review
StatusFileSize
new49.8 KB
new5.67 KB

I found the issue: missed the initialization of the linkitProfileStorage property.
Now the tests should pass again.

andyd328’s picture

Version: 8.x-5.x-dev » 6.0.0-beta3

I've moved the version to 6 as #270 also applies and works well on the latest. Many thanks for the patch SpadXIII!

droath’s picture

I'm currently using the patch in #267, but without switching the field to use the Linkit Widget, the patch already converted the link URL field and provide autocomplete without any configuration changes. Is that what should be expected?

UPDATE: Looks like Drupal core link widget allows searching out of the box, wasn't expecting that. I switched the widget to LinkIt and everything works as expected. Thanks for the patch!

akasake’s picture

StatusFileSize
new885 bytes
new50.29 KB

I ran into some deprecation notices while upgrading my site to PHP 8.1.

  • "Deprecated function: parse_url(): Passing null to parameter #1 ($url) of type string is deprecated in Drupal\linkit\Plugin\Field\FieldWidget\LinkitWidget->formElement()"
  • "Deprecated function: substr(): Passing null to parameter #1 ($string) of type string is deprecated in Drupal\linkit\Plugin\Field\FieldWidget\LinkitWidget->formElement()"

Here is #270 with some changes to prevent that.

clement.ferrier’s picture

StatusFileSize
new49.9 KB
new945 bytes

Fixed an issue where LinkitHelper::getEntityFromUserInput() was not properly identifying the entity from route params.

clement.ferrier’s picture

clement.ferrier’s picture

Issue summary: View changes

The fix from #2981543: Issue when linking to content with ampersands or single quotes in the title is useful if you use the functionality 'Automatically populate link text from entity label'

omnia.ibrahim’s picture

There is an issue when we have multiple link fields, all of them starts the searching in the autocomplete:

omnia.ibrahim’s picture

StatusFileSize
new104.51 KB
MGHollander’s picture

@omnia.ibrahim. That should be solved by #2925828: Multiple Linkit elements breaks.

aslaymoore’s picture

Tested the patch from #274 on Drupal 9.2.13. Patch works as expected without any issues that I can see; Linkit widget becomes available from the Form Display settings page, and clicking on the settings gear allows me to choose which LinkIt profile I want to use.

+1 for RTBTC

jeroent’s picture

@azslay, there’s a status for that 😉

norman.lol’s picture

Issue summary: View changes

Can someone with a little bit more insight please add a proper issue description? Coming from #2423093: Allow multiple target entity types in the 'entity_autocomplete' Form API element I had no clue how all this work done here was supposed to solve which exact problem.

omnia.ibrahim’s picture

@MGHollander they are not working together, when I apply both patches there is error applying both together

norman.lol’s picture

There is error. What error? When applying the patch? When using the form?

daniel korte’s picture

Patch #274 does not apply cleanly with the patch from #2925828: Multiple Linkit elements breaks. Both patches modify js/linkit.autocomplete.js around line 168.

seanb’s picture

StatusFileSize
new1.81 KB
new50.56 KB

Add support for multi value fields in this patch.

Status: Needs review » Needs work

The last submitted patch, 286: 2712951-286.patch, failed testing. View results

seanb’s picture

Not sure how the test fails are related to the JS changes I made?

+++ b/src/Plugin/Field/FieldWidget/LinkitWidget.php
@@ -0,0 +1,288 @@
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
+    $item = $items[$delta];
+    $uri = $item->uri;
+    $uri_scheme = null;
+    $is_nolink = false;
+    if ($uri) {

I also just noticed the formElement method in the widget is not calling the parent method. This means any changes / fixes in the LinkWidget will not work for the Linkit widget. In time the changes between the default link widget and linkit widget will become a problem and harder to maintain. We should probably call the parent, and after that only change/add what we actually need.

seanb’s picture

Status: Needs work » Needs review
StatusFileSize
new8.81 KB
new47.49 KB

Attached patch tries to add only the necessary changes to the LinkWidget, which significantly reduces the complexity. I think we should let the default LinkWidget handle as much as possible.

The test fails in #286 seem to be caused by a change in the editor config schema (in /tests/fixtures). Did not yet look at that. Let's see what the tests think.

Status: Needs review » Needs work

The last submitted patch, 289: 2712951-289.patch, failed testing. View results

seanb’s picture

Status: Needs work » Needs review
StatusFileSize
new781 bytes
new48.25 KB

Let's see if this fixes the tests.

Status: Needs review » Needs work

The last submitted patch, 291: 2712951-291.patch, failed testing. View results

seanb’s picture

Status: Needs work » Needs review
StatusFileSize
new1.17 KB
new48.48 KB

Sorry for the noise...

anprok’s picture

Status: Needs review » Reviewed & tested by the community

This patch works fine on my project based on Drupal 9.4.2, it will be cool to get this feature in released version.

hudri’s picture

I would really appreciate if we could get this patch merged soon.

This issue has 300 comments, a plethora of patches and interdiffs, and adding more and more edge-case-handling won't make it easier to merge it. Improvements can still be made later on, a lot of people are already using this patch in production for years, it is already in a pretty good state.

If we wait until we get a perfect solution, we might never get one at all.

jacobbell84’s picture

I'd love to see this merged in as well. It's making large enough changes that it's interfering with other patches that are trying to touch the same files. Be great to get this in so the other patches can be rerolled

anybody’s picture

RTBC +1! :)

bramvandenbulcke’s picture

This would be a great addition to the link module. I hope it will be added soon.

johns996’s picture

Adding another RTBC to the list.

sharique’s picture

+1 for RTBC.

samlerner’s picture

I've been using this patch on Drupal 9.x sites for 6+ months now, I'm moving this to RTBC.

jedsaet’s picture

RTBC+1. Would be great if this were merged in.

johnpitcairn’s picture

+1 for a merge from me. Edge cases can be followups given a site has to explicitly switch to using the new widget and formatter.

There is also Linkit Field module for those wary of tracking such a large patch, or experiencing patch collisions (ie ckeditor 5 compatibility) - but that needs composer aliasing for linkit 6.x, and patching to fix a missing validate method...

johnpitcairn’s picture

Version: 6.0.0-beta3 » 6.0.x-dev
Status: Reviewed & tested by the community » Needs work

Version was changed to 6.x in #271. The patch at #293 fails to apply to current dev.

jeroent’s picture

Issue tags: +Needs reroll
Ankit.Gupta’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new8.48 KB

Rerolled the patch #293 with 6.0.x

johnpitcairn’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

@Ankit.Gupta: #306 is missing the new files for the field formatter and widget. Note the file size compared to #293...

Ankit.Gupta’s picture

StatusFileSize
new44.68 KB

Interdiff file

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

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

bojan_dev’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll

I rebased 6.0.x on MR 12, also fixed the "LinkFieldTest", it was failing due link selectors that were based on link wrappers that don't exist on a stark theme.

karlshea’s picture

I'll try and dig into it, but the current MR puts internal:/media/x instead of entity:/media/x so direct file URLs don't work again.

karlshea’s picture

My bad, of course right after I post I see further up that "Standalone media URL" MUST be enabled. It is working.

spadxiii’s picture

StatusFileSize
new48.71 KB
new1.02 KB

I ran into a little issue with paragraphs where one of the paragraphs has a linkit-field. When the user types in an invalid uri and then tries to add a new paragraph-item, an exception is preventing the new paragraph to be added.
One part of the problem is that the add-more button in paragraphs has a limit_validation_errors, so no validation is done or error is shown at all. I tried removing this, but that didn't work properly: it would validate the whole form and show error-messages in a way that's confusing for the user. After a bit of digging, I found that the error is an exception thrown when trying to make an Url-object from the invalid uri. So after adding a try/catch, it works fine :)
I based this change on the patch in #293, as we're still using version 5.x of linkit.

Note that this change also requires a patch in core for the link field widget. (Same change basically): 3340154

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

mark_fullmer’s picture

StatusFileSize
new47.78 KB

For folks using this with the 6.0.x branch, the attached patch, which is identical to the Merge Request at hash 3ded22a7, provides LinkIt for the link field for the latest changes (current with the 6.0.0-beta4 release on 5 March 2023, which provides Drupal 10 compatibility and CKEditor5 support).

berdir’s picture

The patch doesn't apply with composer due to the removal of the drupal-8 test file in the merge request, that seems unrelated to this issue and that change was not in patches posted before the merge request was created/updated. You might want to double check that there are no other differences.

Bram Linssen’s picture

The patch works against the dev branch (dev-6.0.x).

You also can get the diff file from the merge request directly, https://git.drupalcode.org/project/linkit/-/merge_requests/12.diff

berdir’s picture

6.0.x and beta4 are currently identical. The patch applies with git apply, but it doesn't properly apply with the patch tool.

$ curl https://www.drupal.org/files/issues/2023-03-05/2712951_316.6.x.diff | patch -p1 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 48922  100 48922    0     0   312k      0 --:--:-- --:--:-- --:--:--  314k
patching file config/schema/linkit.schema.yml
patching file js/linkit.autocomplete.js
patching file src/Entity/Profile.php
patching file src/Plugin/Field/FieldFormatter/LinkitFormatter.php
patching file src/Plugin/Field/FieldWidget/LinkitWidget.php
patching file src/ProfileInterface.php
patching file src/Utility/LinkitHelper.php
patching file tests/fixtures/update/drupal-8.linkit-enabled.standard.php.gz
Not deleting file tests/fixtures/update/drupal-8.linkit-enabled.standard.php.gz as content differs from patch
patching file tests/src/FunctionalJavascript/LinkFieldTest.php
patching file tests/src/Kernel/LinkitEditorLinkDialogTest.php
$ echo $?
1

My point is that the removal of the old database dump doesn't belong in this issue, it is only in the merge request and was not in in the last compete patch in #293. And if that is different, then other things might be different too and that should be verified.

Bram Linssen’s picture

Hi Berdir, I had the same issue as you with my composer update. After replacing the beta release with the dev release in my composer.json the patch did apply with composer.

mark_fullmer’s picture

StatusFileSize
new12.26 KB

The patch doesn't apply with composer due to the removal of the drupal-8 test file in the merge request

In my testing, the patch in #317 cleanly applies via Composer when requiring either 6.0.x or 6.0.0-beta4 (they currently point to the same commit hash).

As Bram said above, if you were previously requiring 6.0.x in your codebase, you would need to run composer update drupal/linkit in order for the composer.lock file to update to the latest hash and then be able to apply the patch.

There are two different syntaxes I've seen for marking the removal of a binary file via diff, but as far as I can tell, that removed .gz file for testing is not the culprit here.

that change was not in patches posted before the merge request was created/updated. You might want to double check that there are no other differences.

Yes, Berdir makes a good clarification: that the patch in #317 incorporates the latest changes from the MR, rather than a previous patchfile for 6.0.x, since based on this issue history, it looks like that's where active work is happening for 6.0.x. There are differences between the latest patch for 8.x-5.x and the 6.0.x, which I've attached as a diff. To me, it looks like the 6.0.x version is better -- it updates the test logic not to use assertEquals which as of Drupal 10 strips out HTML and instead uses LinkByHrefExists, but folks more familiar with this functionality might better be able to weigh in on the change in LinkitWidget.php

mark_fullmer’s picture

My point is that the removal of the old database dump doesn't belong in this issue

I tend to agree that this "cleanup" is not directly related to this issue and should be left out of the changes for this issue specifically; we can create a separate issue for test cleanup.

mark_fullmer’s picture

I added #3346274: Remove old test fixture of site install (gzipped file), which only removes the test fixture. Committing that to 6.0.x would require a new patch / updated MR here, but I don't see any reason not to do that.

schiavone’s picture

StatusFileSize
new8.27 KB

There seems to still be an issue with the #317 patch

Using
ddev composer require 'drupal/linkit:^6.0@beta'

I can apply the patch directly by going to the module directory and using
curl https://www.drupal.org/files/issues/2023-03-05/2712951_316.6.x.diff | patch -p1

but with an entry in composer.json I get

[Exception]                                                                                                                                        
Cannot apply patch Adds linkit formatter and widget option for link fields (https://www.drupal.org/files/issues/2023-03-05/2712951_316.6.x.diff)!

I re-rolled the patch using a diff from the successfully patch module and it worked.

berdir’s picture

#325 is missing the new files.

I'm really trying to not add even more comments to this very very long issue (judging from the d.o response and render times, it's going to explode at some point), but there really is a composer issue here, although only under some circumstances. Per my output in #320, patch -p1 *can* mostly apply the patch, but it skips the removed binary file. As a result, you have a kinda correctly patched module because whether or not the file is removed is not relevant to the functionality. But it sets the exit code to 1, meaning an error. *If* composer-patches is configured to abort if a patch fails to apply (which is IMHO recommended, otherwise you might deploy your project without some patches), it detects that as an error state and aborts. Also, if you switch between dev and a tagged release and already have a git checkout, composer will just switch your existing git checkout around and not reinstall.

Re #324, if the MR is updated now to not include the file, then it doesn't matter if the other issue is done before or after, it won't conflict anymore.

schiavone’s picture

StatusFileSize
new5.52 KB

Correcting the patch.

schiavone’s picture

Yes @Berdir is correct. The patch does not properly apply due to gz file.

hctom’s picture

Unfortunately the patch from #327 misses a lot of code (like the field formatter plugin etc.)

mark_fullmer’s picture

StatusFileSize
new47.43 KB

Per Berdir's good suggestion in #326, I've voided the removal of the .gz test fixture; that can be addressed in #3346274: Remove old test fixture of site install (gzipped file).

The merge request is updated an otherwise unchanged compared to the previous commit. The attached patch is a replica of the MR at commit 314cd74, provided so folks don't directly reference the MR diff in Composer.

schiavone’s picture

StatusFileSize
new47.43 KB

Thank you @markfullmer the diff now successfully patches using composer. Attaching it here for convenience.

proteo’s picture

Status: Needs review » Reviewed & tested by the community

Just confirming that the patch applies cleanly, and the functionality it provides works great. Tested on two different sites with Linkit 6.0.0-beta4 and Drupal 9.5.4.

  • mark_fullmer committed 8aafeae4 on 6.0.x
    Issue #2712951 by marcoscano, arpad.rozsa, blazey, Primsi, JeroenT,...
mark_fullmer’s picture

Status: Reviewed & tested by the community » Fixed

The latest change, reflected in last MR commit, only adds PHP coding syntax fixes; I omitted fixes for the changed JS file since it already had syntax violations and didn't want to increase the scope of this issue; those changes can be dealt with subsequently. I did a final manual functional review and everything checked out with the new Linkit field widget/formatter and there were no regressions to the existing CKEditor integration.

I've merged this into the 6.0.x branch, though I would like to leave it there for some time in order to allow for resolution of other issues with patches that might need to be updated, and for community reports of any as-yet undiscovered issues with this implementation. This will be included in the next release. See #3345480: LinkIt Release Roadmap and Issue Prioritization.

Thanks, everyone, for nearly eight years of work on this!

Created: 25 Apr 2016
Committed: 10 Mar 2023

agoradesign’s picture

that's really huge! thanks everyone!

Status: Fixed » Closed (fixed)

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

inoodle’s picture

StatusFileSize
new8.3 KB

ref to https://www.drupal.org/project/linkit/issues/2712951#comment-14956491
There is an issue when linking to content with ampersands or single quotes in the title
A js html decode function added

inoodle’s picture

StatusFileSize
new8.3 KB

Add in missing new files to 2712951_331_3.6.x.patch

inoodle’s picture

inoodle’s picture

StatusFileSize
new46.88 KB
dpi’s picture

@inoodle, please open a new issue.

The issue has been closed, let's avoid emailing over 200 people over follow ups