Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add No Follow toggle to Link Control #48722

Open
wants to merge 1 commit into
base: trunk
Choose a base branch
from

Conversation

tomdevisser
Copy link
Member

@tomdevisser tomdevisser commented Mar 3, 2023

What, why and how?

After almost three years and a lot of fruitful discussion, it's finally here. The ability to add a nofollow rel to a link.

Everything works in the backend as shown on the screengrab. The only thing I couldn't figure out in the time I had now was how to save this to the markup so it also renders correctly on the frontend. Hope someone can help with this or point me in the right direction.

Testing Instructions

  1. Add a paragraph block
  2. Insert a link
  3. Check the rel attribute

A few important notes

  • My linter gave a lot of warnings on the useEffect dependency arrays. Someone should look into that, but probably for a separate issue. I didn't want to autocorrect them all, as that could mess up the tests.
  • I don't really like the fact the popup closes automatically after toggling. This was already the case with the new tab option, but especially when there's more options you don't want to open the toggle for every single setting. Also worth creating another issue for.
  • There's a few other refactors possible, like reusing the titles for the settings in the constants file, on the BottomSheet.SwitchCell components (link-settings-screen.native.js:213). These do however have lower priority and I will assign those to myself after this PR gets merged.

Don't see this as finished yet, but I think we now have a very good starting point to start adding this feature!

Fixes #23011

nofollow.mov

After almost three years and a lot of fruitful discussion, it's finally here. The ability to add a nofollow rel to a link.

Everything works in the backend as shown on the screengrab. The only thing I couldn't figure out in the time I had was how to save this to the markup so it also renders correctly on the frontend. Hope someone can help with this or point me in the right direction.

Fixes WordPress#23011
@tomdevisser tomdevisser self-assigned this Mar 3, 2023
@tomdevisser tomdevisser added [Type] Enhancement A suggestion for improvement. [Block] Paragraph Affects the Paragraph Block [Feature] Link Editing Link components (LinkControl, URLInput) and integrations (RichText link formatting) labels Mar 3, 2023
@tomdevisser
Copy link
Member Author

One more thing: I've never written a test in a big project like this, so if someone can help me with updating any tests where necessary, that would also be greatly appreciated. 🙂

@getdave
Copy link
Contributor

getdave commented Mar 3, 2023

Thank you. This is on my radar to review. As explained we are in the WP 6.2 release cycle so I may not be able to get to this straight away.

Also tagging in @jameskoster as he's been working on the Design here.

@tomdevisser
Copy link
Member Author

@getdave Good luck with the release!

@getdave
Copy link
Contributor

getdave commented Mar 3, 2023

A good place to add tests is in packages/block-editor/src/components/link-control/test/index.js. That's the base component.

That said I think the tests are suitale generic as to not need anything additional for this new control. You'll see there's already a test should display a setting control with correct default state for each of the custom settings provided.

The other option is an e2e test in packages/e2e-tests/specs/editor/various/links.test.js.

@getdave getdave requested a review from jameskoster March 3, 2023 12:34
@getdave
Copy link
Contributor

getdave commented Mar 3, 2023

I don't really like the fact the popup closes automatically after toggling. This was already the case with the new tab option, but especially when there's more options you don't want to open the toggle for every single setting. Also worth creating another issue for.

Agreed. That's definitely one for another Issue. In fact I think we already have one 🤔

@jameskoster
Copy link
Contributor

Nice, thanks for working on this :)

I don't really like the fact the popup closes automatically after toggling.

+1.

The label looks a little long but I appreciate the context. Maybe we can use some helper text instead?

Screenshot 2023-03-03 at 14 39 11

@getdave
Copy link
Contributor

getdave commented Mar 7, 2023

I think the test failures here are legit. We'll need to look into those.

@tomdevisser
Copy link
Member Author

I think the test failures here are legit. We'll need to look into those.

Do you know anyone that can help with this? :)

@getdave getdave requested a review from SaxonF March 9, 2023 08:17
@getdave
Copy link
Contributor

getdave commented Mar 9, 2023

I am happy to try and support that. Likely post-WP 6.2 release.

@getdave
Copy link
Contributor

getdave commented Mar 15, 2023

I haven't forgotten about this. I've been super busy with 6.2. It's still on my list.

@getdave
Copy link
Contributor

getdave commented Mar 31, 2023

Let me take a look at this today.

@getdave getdave added the Mobile App - i.e. Android or iOS Native mobile impl of the block editor. (Note: used in scripts, ping mobile folks to change) label Mar 31, 2023
Copy link
Contributor

@getdave getdave left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's try and get a @WordPress/gutenberg-design review on this one.

We should also add some e2e test coverage. I'm going to take a look at how we can extend what we have.

Apologies for the delay here but it's been an extremely busy period with the 6.2 release.

@@ -42,6 +42,9 @@ const LinkSettingsScreen = ( {
const [ opensInNewWindow, setOpensInNewWindows ] = useState(
activeAttributes.target === '_blank'
);
const [ markedAsNoFollow, setMarkedAsNoFollow ] = useState(
( activeAttributes.rel = 'nofollow' )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
( activeAttributes.rel = 'nofollow' )
( activeAttributes.rel?.includes( 'nofollow' ) )

Are there other options for this we need to consider?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say let's keep the PR's simple and small, we can always add more later but that prevents them from getting to complex or going stale

Copy link
Contributor

@getdave getdave Mar 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No sorry I was thinking if the attributes have other settings on rel. For example noopener like this PR accounts for elsewhere (e.g. packages/format-library/src/link/inline.js).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to what @getdave asks as it is now it doesn't work because it expects a boolean value for markedAsNoFollow

@jasmussen
Copy link
Contributor

jasmussen commented Mar 31, 2023

Just following up on this comment:

Screenshot 2023-03-03 at 14 39 11

We should show the help text below both control and toggle to match the other instances where this is used:

Screenshot 2023-03-31 at 11 40 43

As for the PR itself, it seems clear enough that nofollow is a property you should be able to set on a link. It's also a somewhat advanced control, so to me this is an argument for keeping the "Advanced" toggle. This one:

Screenshot 2023-03-31 at 11 43 52

@getdave

This comment was marked as outdated.

@@ -16,7 +16,7 @@ export default function useInternalInputValue( value ) {
if ( value && value !== internalInputValue ) {
setInternalInputValue( value );
}
}, [ value ] );
}, [ internalInputValue, value ] );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}, [ internalInputValue, value ] );
}, [ value ] );

Please can we revert this change and use the eslint syntax to disable the warning?

The original code is clearly faulty (that is my fault) but we should avoid overcomplicating this PR by adding the dep here.

I will raise a separate Issue to fix this problem.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once we revert this change we might see tests passing again 🤞

Comment on lines +29 to +31
title: __(
'Search engines should ignore this link (mark as nofollow)'
),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
title: __(
'Search engines should ignore this link (mark as nofollow)'
),
title: __(
'No follow'
),
help: __(
'Search engines should ignore this link'
),

Let's extend this and then make changes within settings.js to optionally include the help prop on the ToggleControl.

@getdave
Copy link
Contributor

getdave commented Mar 31, 2023

We also need to make the new setting optional in the UI and handling code.

For an example of what I mean try adding a link to a Navigation block and try toggling the No follow setting. It doesn't work because the Nav block doesn't handle it yet.

We can patch the Nav block code, but there will be other (3rd party) consumers of this code who may not know about this change and won't have time to adjust their code to account for it.

One idea was that we could filter out any settings that are no included in the value object. We can do this in settings.js:

// filter out any settings not in the value
const filteredSettings = settings.filter( ( setting ) =>
	Object.keys( value ).includes( setting.id )
);

We would need to add a test for this type of scenario in packages/block-editor/src/components/link-control/test/index.js.

The only thing I couldn't figure out in the time I had now was how to save this to the markup so it also renders correctly on the frontend. Hope someone can help with this or point me in the right direction.

Could you elaborate on this a little? I tried with a paragraph block and it rendered on the front of the site.

@geriux geriux self-requested a review March 31, 2023 14:20
@geriux
Copy link
Member

geriux commented Mar 31, 2023

I've just assigned myself to check the native file changes. I'll report back once I've tested these new changes 👍

@getdave getdave changed the title Link Control: Add more controls Add No Follow toggle to Link Control Mar 31, 2023
<BottomSheet.SwitchCell
icon={ external }
label={ __(
'Search engines should ignore this link (mark as nofollow)'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit long for mobile so maybe we could use just the part "No follow" as suggested in this comment.

label={ __(
'Search engines should ignore this link (mark as nofollow)'
) }
value={ markedAsNoFollow }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are using the markedAsNoFollow value here and it's within a useMemo we should include it in the dependencies so it gets the updated value.

@@ -99,6 +102,7 @@ const LinkSettingsScreen = ( {
const format = createLinkFormat( {
url,
opensInNewWindow,
markedAsNoFollow,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
markedAsNoFollow,
markAsNoFollow: markedAsNoFollow,

Since the names are different we should update it so the right value gets to createLinkFormat

@geriux
Copy link
Member

geriux commented Apr 3, 2023

Hey @tomdevisser 👋 thank you for working on including these changes for the mobile editor as well, I've shared some comments/suggestions, let me know what you think. Thanks!

@jonoalderson
Copy link

jonoalderson commented Apr 11, 2023

Weighing in from an SEO perspective; a few things to watch out for:

  • It's nofollow, not no follow.
  • It doesn't mean that search engines won't follow a link; it's a hint which asks them not to pass value to the destination URL. Google et al will still follow/crawl links with a nofollow attribute for discovery purposes.
  • This will need to anticipate interacting gracefully with links with a sponsored rel attribute, in the same way that we handle in Yoast SEO.

Given the above, I'd be keen to make sure that this can be disabled, otherwise, it'll end up duplicating and degrading the functionality we offer in Yoast SEO.

@getdave
Copy link
Contributor

getdave commented Apr 18, 2023

@jonoalderson Thanks for this useful feedback.

Given the above, I'd be keen to make sure that this can be disabled, otherwise, it'll end up duplicating and degrading the functionality we offer in Yoast SEO.

I'm curious about this. My previous review suggested that by way of backwards compatibility, this PR must be updatedd to not include any setting which is not provided in the settings object.

Would this be sufficient to cater for 3rd party extenders (Yoast is one of these) who have an existing implementation which should be extending whatever is provided by Core Gutenberg.

It sounds like we are thinking along the same lines, but I want to check we're not making any exceptions for any specific extenders 🙇‍♂️


@tomdevisser No pressure at all, but do you anticipate being able to continue working on this PR?

@tomdevisser
Copy link
Member Author

tomdevisser commented Apr 20, 2023

@getdave I'm afraid some other higher priority issues are taking up all of my time at the moment. If you'd want to, feel free to move this forward!

@getdave
Copy link
Contributor

getdave commented Apr 20, 2023

@getdave I'm afraid some other higher priority issues are taking up all of my time at the moment. If you'd want to, feel free to move this forward!

Same here. No rush 👍

@getdave
Copy link
Contributor

getdave commented Aug 31, 2023

A PR for this has been merged to Gutenberg trunk in #53945 this can be safely closed.

Thank you for the agency in pushing this forward 🙇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Link Editing Link components (LinkControl, URLInput) and integrations (RichText link formatting) Mobile App - i.e. Android or iOS Native mobile impl of the block editor. (Note: used in scripts, ping mobile folks to change) [Type] Enhancement A suggestion for improvement.
Projects
Status: 💻 Needs development
Development

Successfully merging this pull request may close these issues.

Link Control: Add more controls.
8 participants