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

ESLint: Add rule to prevent usage of the word 'sidebar' in translatable strings #68894

Open
wants to merge 9 commits into
base: trunk
Choose a base branch
from

Conversation

im3dabasia
Copy link
Contributor

@im3dabasia im3dabasia commented Jan 27, 2025

Related comment: #61499 (comment)

What?

This PR introduces a new ESLint rule to prevent the use of the term "sidebar" in user-facing strings throughout the codebase. The rule aims to ensure that more generic and accessible terms like "panel" are used in place of "sidebar."

Why?

The term "sidebar" is problematic for blind and low-vision users, as it relies on spatial concepts that are irrelevant to them. Additionally, the term can be misleading on smaller screens where "sidebars" are often full-width overlays. This change is necessary to align with the accessibility guidelines. It ensures consistency in user-facing language across WordPress projects.

How?

The PR implements an ESLint rule that flags occurrences of the word "sidebar" in translatable strings, helping developers avoid its usage in user-facing content. The rule is added to the .eslintrc.js configuration to prevent new instances of this term from being introduced.

Testing Instructions

  1. Change any word inside any translation ready functions to "sidebar" in any file.
  2. Check if your IDE raises an ESLint error with the message: "Avoid using the word 'sidebar' in translatable strings."

Screencast

Screen.Recording.2025-01-27.at.4.03.49.PM.mov

@t-hamano t-hamano added the Gutenberg Plugin Issues or PRs related to Gutenberg Plugin management related efforts label Jan 28, 2025
@im3dabasia im3dabasia marked this pull request as ready for review January 30, 2025 11:43
Copy link

github-actions bot commented Jan 30, 2025

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: im3dabasia <[email protected]>
Co-authored-by: tyxla <[email protected]>
Co-authored-by: afercia <[email protected]>
Co-authored-by: swissspidy <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@im3dabasia
Copy link
Contributor Author

Hi @swissspidy,

When you have a moment, could you please review my PR.

cc: @afercia

Copy link
Member

@tyxla tyxla left a comment

Choose a reason for hiding this comment

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

Looks good overall 👍

.eslintrc.js Outdated Show resolved Hide resolved
.eslintrc.js Outdated Show resolved Hide resolved
@im3dabasia im3dabasia requested a review from tyxla February 7, 2025 12:12
@im3dabasia
Copy link
Contributor Author

im3dabasia commented Feb 7, 2025

The lint checks are failing, but the ones related to this PR possibly include... I'll put together a comprehensive set of suggestions so we can move forward.

Edit: I see some false positives being raised, especially in URLs, such as /sidebar-panel-is-here. I think a regex update should solve this.

<TextControl
__next40pxDefaultSize
__nextHasNoMarginBottom
label={ __( 'Name' ) }
value={ title }
onChange={ setTitle }
placeholder={ defaultTitle }
disabled={ isBusy }
help={ __(
'Describe the template, e.g. "Post with sidebar". A custom template can be manually applied to any post or page.'
) }
/>

content: (
<>
<h1 className="edit-site-welcome-guide__heading">
{ heading }
</h1>
<p className="edit-site-welcome-guide__text">
{ __(
'It’s now possible to edit page content in the site editor. To customise other parts of the page like the header and footer switch to editing the template using the settings sidebar.'
) }
</p>
</>
),

if ( ! selectedWidgetArea ) {
description = __(
'Widget Areas are global parts in your site’s layout that can accept blocks. These vary by theme, but are typically parts like your Sidebar or Footer.'
);
} else if ( selectedWidgetAreaId === 'wp_inactive_widgets' ) {

<p>
{ createInterpolateElement(
__(
'They also show up as sub-items in the default navigation menu. <a>Learn more.</a>'
),
{
a: (
<ExternalLink
href={ __(
'https://wordpress.org/documentation/article/page-post-settings-sidebar/#page-attributes'
) }
/>
),
}
) }
</p>

help={
! shouldUseDescriptionLabel ? (
<ExternalLink
href={ __(
'https://wordpress.org/documentation/article/page-post-settings-sidebar/#excerpt'
) }
>
{ __( 'Learn more about manual excerpts' ) }
</ExternalLink>
) : (
__( 'Write a description' )
)
}

<TextControl
__next40pxDefaultSize
__nextHasNoMarginBottom
label={ __( 'Name' ) }
value={ title }
onChange={ setTitle }
placeholder={ DEFAULT_TITLE }
disabled={ isBusy }
help={ __(
'Describe the template, e.g. "Post with sidebar". A custom template can be manually applied to any post or page.'
) }
/>

<p className="editor-post-url__intro">
{ createInterpolateElement(
__(
'<span>Customize the last part of the Permalink.</span> <a>Learn more.</a>'
),
{
span: <span id={ postUrlSlugDescriptionId } />,
a: (
<ExternalLink
href={ __(
'https://wordpress.org/documentation/article/page-post-settings-sidebar/#permalink'
) }
/>
),
}
) }
</p>

<PreferenceToggleControl
scope="core"
featureName="showListViewByDefault"
help={ __(
'Opens the List View sidebar by default.'
) }
label={ __( 'Always open List View' ) }
/>

const { documentLabel } = useSelect( ( select ) => {
const { getPostTypeLabel } = select( editorStore );
return {
documentLabel:
// translators: Default label for the Document sidebar tab, not selected.
getPostTypeLabel() || _x( 'Document', 'noun, sidebar' ),
};
}, [] );

title={
/* translators: button label text should, if possible, be under 16 characters. */
_x( 'Settings', 'sidebar button label' )
}

{ createInterpolateElement(
__(
'They also show up as sub-items in the default navigation menu. <a>Learn more.</a>'
),
{
a: (
<ExternalLink
href={ __(
'https://wordpress.org/documentation/article/page-post-settings-sidebar/#page-attributes'
) }
children={ undefined }
/>
),
}
) }

@im3dabasia
Copy link
Contributor Author

Hi @afercia , @swissspidy , @tyxla ,

I’d appreciate your input once again in suggesting alternative strings for the following:

For now, I have replaced "sidebar" with "panel," but if you have any alternative suggestions for any of these, I’d be happy to update them.

  1. 'Describe the template, e.g. "Post with sidebar". A custom template can be manually applied to any post or page.'
  2. 'It’s now possible to edit page content in the site editor. To customise other parts of the page like the header and footer switch to editing the template using the settings sidebar.'
  3. 'Widget Areas are global parts in your site’s layout that can accept blocks. These vary by theme, but are typically parts like your Sidebar or Footer.'
  4. 'Describe the template, e.g. "Post with sidebar". A custom template can be manually applied to any post or page.'
  5. 'Opens the List View sidebar by default.'
  6. _x( 'Document', 'noun, sidebar' )
  7. _x( 'Settings', 'sidebar button label' )

Additionally, we have URLs inside translation functions( 4 instances ), such as:

__('https://wordpress.org/documentation/article/page-post-settings-sidebar/#page-attributes')

We could add an ESLint ignore here, but I don’t think that’s the best solution. A better approach would be to update the regex.

The previous regex worked well, but it caused false positives for URLs because \b only checks for alphanumeric characters, and a hyphen (-) is not considered alphanumeric. This led to unintended matches.

I have updated the regex to ensure that "sidebar" is only flagged when it is a standalone word and not part of another word (e.g., "no-sidebar").

Updated regex:

{
	selector:
		'CallExpression[callee.name=/^(__|_x|_n|_nx)$/] > Literal[value=/(?<![-\\w])sidebar(?![-\\w])/i]',
	message:
		"Avoid using the word 'sidebar' in translatable strings. Consider using 'panel' instead.",
}

I have updated the PR with this new regex. Let me know your thoughts! @swissspidy

@swissspidy
Copy link
Member

New regex looks good at first glance, seems to nicely prevent false positives.

I don't think we should change the instances where sidebar refers to a theme template part ("post with sidebar", "sidebar or footer", ...), as in that context the sidebar is a pretty common term.

Curious what others say though.

@afercia
Copy link
Contributor

afercia commented Feb 11, 2025

I'd agree with @swissspidy that the only occurrences to change should be the ones in the editor UI.

@swissspidy
Copy link
Member

Then I'd say for the other instances let's ignore the eslint errors & add an explanatory comment why it's disabled

@im3dabasia
Copy link
Contributor Author

Hi @afercia and @swissspidy,
I believe the changes have been made, and the PR is now ready. When you have a moment, I’d appreciate it if you could check the latest changes.

Hopefully, it can be merged into trunk soon. Thanks!

@im3dabasia
Copy link
Contributor Author

Hi @afercia and @swissspidy,
Since the PR has been approved, I believe we can proceed with merging it now. Let me know if anything else is needed. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Gutenberg Plugin Issues or PRs related to Gutenberg Plugin management related efforts
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants