Skip to content

Commit cd741f1

Browse files
Merge pull request #19340 from Yoast/DUPP-826-settings-ui-search-case-sensitive
Lowercase query before searching in new settings UI
2 parents 8cd2340 + 61caf97 commit cd741f1

13 files changed

Lines changed: 83 additions & 41 deletions

File tree

packages/js/src/settings/components/search.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { debounce, first, groupBy, includes, isEmpty, map, max, reduce, split, t
99
import PropTypes from "prop-types";
1010
import { useHotkeys } from "react-hotkeys-hook";
1111
import { useNavigate } from "react-router-dom";
12+
import { safeToLocaleLower } from "../helpers";
1213
import { useParsedUserAgent, useSelectSettings } from "../hooks";
1314

1415
const QUERY_MIN_CHARS = 3;
@@ -37,6 +38,7 @@ const Search = () => {
3738
// eslint-disable-next-line no-unused-vars
3839
const [ isOpen, , , setOpen, setClose ] = useToggleState( false );
3940
const [ query, setQuery ] = useState( "" );
41+
const userLocale = useSelectSettings( "selectPreference", [], "userLocale" );
4042
const queryableSearchIndex = useSelectSettings( "selectQueryableSearchIndex" );
4143
const [ results, setResults ] = useState( [] );
4244
const ariaSvgProps = useSvgAria();
@@ -77,8 +79,8 @@ const Search = () => {
7779
return false;
7880
}
7981

80-
// Split query into words.
81-
const splitQuery = split( trimmedQuery, " " );
82+
// Lowercase and split query into words.
83+
const splitQuery = split( safeToLocaleLower( trimmedQuery, userLocale ), " " );
8284

8385
// Filter search index by split query and store number of hits.
8486
// A hit is registered if a single word from split query in found in a fields keywords.
@@ -115,7 +117,7 @@ const Search = () => {
115117
} );
116118

117119
setResults( sortedGroupedQueryResults );
118-
}, 100 ), [ queryableSearchIndex ] );
120+
}, 100 ), [ queryableSearchIndex, userLocale ] );
119121

120122
const handleQueryChange = useCallback( event => {
121123
setQuery( event.target.value );
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* Lowercase a string in a locale, but with invalid locale safety.
3+
* @param {string} string The string to lowercase.
4+
* @param {string} locale The locale string.
5+
* @returns {string} The lower case string if locale is valid, the string if locale is invalid.
6+
*/
7+
export const safeToLocaleLower = ( string, locale ) => {
8+
try {
9+
return string.toLocaleLowerCase( locale );
10+
} catch ( error ) {
11+
console.error( error.message );
12+
return string;
13+
}
14+
};

packages/js/src/settings/helpers/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export * from "./i18n";
12
export * from "./user-social-profiles";
23
export * from "./search";
34
export * from "./submit";

packages/js/src/settings/helpers/search.js

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22
import { __, sprintf } from "@wordpress/i18n";
33
import { Code } from "@yoast/ui-library";
44
import { createInterpolateElement } from "@wordpress/element";
5-
import { omit, reduce, times, toLower, filter, includes, isEmpty } from "lodash";
5+
import { omit, reduce, times, filter, includes, isEmpty } from "lodash";
6+
import { safeToLocaleLower } from "./i18n";
67

78
/**
89
* @param {Object} postType The post type.
10+
* @param {Object} options The options.
11+
* @param {string} options.userLocale The user locale string.
912
* @returns {Object} The search index for the post type.
1013
*/
11-
export const createPostTypeSearchIndex = ( { name, label, route, hasArchive } ) => ( {
14+
export const createPostTypeSearchIndex = ( { name, label, route, hasArchive }, { userLocale } ) => ( {
1215
[ `title-${ name }` ]: {
1316
route: `/post-type/${ route }`,
1417
routeLabel: label,
@@ -30,7 +33,7 @@ export const createPostTypeSearchIndex = ( { name, label, route, hasArchive } )
3033
fieldLabel: sprintf(
3134
// translators: %1$s expands to the post type plural, e.g. Posts.
3235
__( "Show %1$s in search results", "wordpress-seo" ),
33-
toLower( label )
36+
safeToLocaleLower( label, userLocale )
3437
),
3538
keywords: [],
3639
},
@@ -120,7 +123,7 @@ export const createPostTypeSearchIndex = ( { name, label, route, hasArchive } )
120123
fieldLabel: sprintf(
121124
// translators: %1$s expands to the post type plural, e.g. Posts.
122125
__( "Show the archive for %1$s in search results", "wordpress-seo" ),
123-
toLower( label )
126+
safeToLocaleLower( label, userLocale )
124127
),
125128
keywords: [],
126129
},
@@ -150,9 +153,11 @@ export const createPostTypeSearchIndex = ( { name, label, route, hasArchive } )
150153

151154
/**
152155
* @param {Object} taxonomy The taxonomy.
156+
* @param {Object} options The options.
157+
* @param {string} options.userLocale The user locale string.
153158
* @returns {Object} The search index for the taxonomy.
154159
*/
155-
export const createTaxonomySearchIndex = ( { name, label, route } ) => ( {
160+
export const createTaxonomySearchIndex = ( { name, label, route }, { userLocale } ) => ( {
156161
[ `title-tax-${ name }` ]: {
157162
route: `/taxonomy/${ route }`,
158163
routeLabel: label,
@@ -175,7 +180,7 @@ export const createTaxonomySearchIndex = ( { name, label, route } ) => ( {
175180
/* translators: %1$s expands to "Yoast SEO". %2$s expands to the taxonomy plural, e.g. Categories. */
176181
__( "Enable %1$s for %2$s", "wordpress-seo" ),
177182
"Yoast SEO",
178-
toLower( label )
183+
safeToLocaleLower( label, userLocale )
179184
),
180185
keywords: [],
181186
},
@@ -193,7 +198,7 @@ export const createTaxonomySearchIndex = ( { name, label, route } ) => ( {
193198
fieldLabel: sprintf(
194199
// translators: %1$s expands to the taxonomy plural, e.g. Categories.
195200
__( "Show %1$s in search results", "wordpress-seo" ),
196-
toLower( label )
201+
safeToLocaleLower( label, userLocale )
197202
),
198203
keywords: [],
199204
},
@@ -232,9 +237,11 @@ export const createTaxonomySearchIndex = ( { name, label, route } ) => ( {
232237
/**
233238
* @param {Object} postTypes The post types.
234239
* @param {Object} taxonomies The taxonomies.
240+
* @param {Object} options The options.
241+
* @param {string} options.userLocale The user locale string.
235242
* @returns {Object} The search index.
236243
*/
237-
export const createSearchIndex = ( postTypes, taxonomies ) => ( {
244+
export const createSearchIndex = ( postTypes, taxonomies, { userLocale } = {} ) => ( {
238245
blogdescription: {
239246
route: "/site-basics",
240247
routeLabel: __( "Site basics", "wordpress-seo" ),
@@ -751,7 +758,7 @@ export const createSearchIndex = ( postTypes, taxonomies ) => ( {
751758
fieldId: `input-wpseo_titles-post_types-${ postType.name }-maintax`,
752759
fieldLabel: createInterpolateElement(
753760
// translators: %1$s expands to the post type plural, e.g. posts.
754-
sprintf( __( "Breadcrumbs for %1$s<code />", "wordpress-seo" ), toLower( postType.label ) ),
761+
sprintf( __( "Breadcrumbs for %1$s<code />", "wordpress-seo" ), safeToLocaleLower( postType.label, userLocale ) ),
755762
{
756763
code: <Code className="yst-ml-2 group-hover:yst-bg-primary-200 group-hover:yst-text-primary-800">{ postType.name }</Code>,
757764
}
@@ -768,7 +775,7 @@ export const createSearchIndex = ( postTypes, taxonomies ) => ( {
768775
fieldId: `input-wpseo_titles-taxonomy-${ taxonomy.name }-ptparent`,
769776
fieldLabel: createInterpolateElement(
770777
// translators: %1$s expands to the taxonomy plural, e.g. categories.
771-
sprintf( __( "Breadcrumbs for %1$s<code />", "wordpress-seo" ), toLower( taxonomy.label ) ),
778+
sprintf( __( "Breadcrumbs for %1$s<code />", "wordpress-seo" ), safeToLocaleLower( taxonomy.label, userLocale ) ),
772779
{
773780
code: <Code className="yst-ml-2 group-hover:yst-bg-primary-200 group-hover:yst-text-primary-800">{ taxonomy.name }</Code>,
774781
}
@@ -1056,12 +1063,12 @@ export const createSearchIndex = ( postTypes, taxonomies ) => ( {
10561063
// Post types - Attachments are handled separately above.
10571064
...reduce( omit( postTypes, [ "attachment" ] ), ( acc, postType ) => ( {
10581065
...acc,
1059-
...createPostTypeSearchIndex( postType ),
1066+
...createPostTypeSearchIndex( postType, { userLocale } ),
10601067
} ), {} ),
10611068
// Taxonomies
10621069
...reduce( omit( taxonomies, [ "post_format" ] ), ( acc, taxonomy ) => ( {
10631070
...acc,
1064-
...createTaxonomySearchIndex( taxonomy ),
1071+
...createTaxonomySearchIndex( taxonomy, { userLocale } ),
10651072
} ), {} ),
10661073
},
10671074
wpseo_social: {

packages/js/src/settings/routes/author-archives.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { __, sprintf } from "@wordpress/i18n";
44
import { Badge, Code, Link } from "@yoast/ui-library";
55
import FeatureUpsell from "@yoast/ui-library/src/components/feature-upsell";
66
import { useFormikContext } from "formik";
7-
import { toLower } from "lodash";
87
import {
98
FieldsetLayout,
109
FormikFlippedToggleField,
@@ -14,6 +13,7 @@ import {
1413
OpenGraphDisabledAlert,
1514
RouteLayout,
1615
} from "../components";
16+
import { safeToLocaleLower } from "../helpers";
1717
import { withFormikDummyField } from "../hocs";
1818
import { useSelectSettings } from "../hooks";
1919

@@ -25,8 +25,9 @@ const FormikReplacementVariableEditorFieldWithDummy = withFormikDummyField( Form
2525
const AuthorArchives = () => {
2626
const label = __( "Author archives", "wordpress-seo" );
2727
const singularLabel = __( "Author archive", "wordpress-seo" );
28-
const labelLower = useMemo( () => toLower( label ), [ label ] );
29-
const singularLabelLower = useMemo( () => toLower( singularLabel ), [ singularLabel ] );
28+
const userLocale = useSelectSettings( "selectPreference", [], "userLocale" );
29+
const labelLower = useMemo( () => safeToLocaleLower( label, userLocale ), [ label, userLocale ] );
30+
const singularLabelLower = useMemo( () => safeToLocaleLower( singularLabel, userLocale ), [ singularLabel, userLocale ] );
3031

3132
const premiumUpsellConfig = useSelectSettings( "selectUpsellSettingsAsProps" );
3233
const replacementVariables = useSelectSettings( "selectReplacementVariablesFor", [], "author_archives", "custom-post-type_archive" );

packages/js/src/settings/routes/date-archives.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { createInterpolateElement, useMemo } from "@wordpress/element";
33
import { __, sprintf } from "@wordpress/i18n";
44
import { Badge, Code, FeatureUpsell, Link } from "@yoast/ui-library";
55
import { useFormikContext } from "formik";
6-
import { toLower } from "lodash";
76
import {
87
FieldsetLayout,
98
FormikFlippedToggleField,
@@ -13,6 +12,7 @@ import {
1312
OpenGraphDisabledAlert,
1413
RouteLayout,
1514
} from "../components";
15+
import { safeToLocaleLower } from "../helpers";
1616
import { withFormikDummyField } from "../hocs";
1717
import { useSelectSettings } from "../hooks";
1818

@@ -23,7 +23,8 @@ const FormikReplacementVariableEditorFieldWithDummy = withFormikDummyField( Form
2323
*/
2424
const DateArchives = () => {
2525
const label = __( "Date archives", "wordpress-seo" );
26-
const labelLower = useMemo( () => toLower( label ), [ label ] );
26+
const userLocale = useSelectSettings( "selectPreference", [], "userLocale" );
27+
const labelLower = useMemo( () => safeToLocaleLower( label, userLocale ), [ label, userLocale ] );
2728

2829
const premiumUpsellConfig = useSelectSettings( "selectUpsellSettingsAsProps" );
2930
const replacementVariables = useSelectSettings( "selectReplacementVariablesFor", [], "date_archive", "custom-post-type_archive" );

packages/js/src/settings/routes/format-archives.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { createInterpolateElement, useMemo } from "@wordpress/element";
33
import { __, sprintf } from "@wordpress/i18n";
44
import { Badge, Code, FeatureUpsell, Link } from "@yoast/ui-library";
55
import { useFormikContext } from "formik";
6-
import { toLower } from "lodash";
76
import {
87
FieldsetLayout,
98
FormikFlippedToggleField,
@@ -13,6 +12,7 @@ import {
1312
OpenGraphDisabledAlert,
1413
RouteLayout,
1514
} from "../components";
15+
import { safeToLocaleLower } from "../helpers";
1616
import { withFormikDummyField } from "../hocs";
1717
import { useSelectSettings } from "../hooks";
1818

@@ -29,8 +29,9 @@ const FormikReplacementVariableEditorFieldWithDummy = withFormikDummyField( Form
2929
*/
3030
const FormatArchives = () => {
3131
const { name, label, singularLabel } = useSelectSettings( "selectTaxonomy", [], "post_format" );
32-
const labelLower = useMemo( () => toLower( label ), [ label ] );
33-
const singularLabelLower = useMemo( () => toLower( singularLabel ), [ singularLabel ] );
32+
const userLocale = useSelectSettings( "selectPreference", [], "userLocale" );
33+
const labelLower = useMemo( () => safeToLocaleLower( label, userLocale ), [ label, userLocale ] );
34+
const singularLabelLower = useMemo( () => safeToLocaleLower( singularLabel, userLocale ), [ singularLabel, userLocale ] );
3435

3536
const premiumUpsellConfig = useSelectSettings( "selectUpsellSettingsAsProps" );
3637
const replacementVariables = useSelectSettings( "selectReplacementVariablesFor", [ name ], name, "term-in-custom-taxonomy" );

packages/js/src/settings/routes/media-pages.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { createInterpolateElement, useMemo } from "@wordpress/element";
22
import { __, sprintf } from "@wordpress/i18n";
33
import { Link, SelectField, ToggleField } from "@yoast/ui-library";
44
import { useFormikContext } from "formik";
5-
import { toLower } from "lodash";
65
import {
76
FieldsetLayout,
87
FormikFlippedToggleField,
@@ -11,14 +10,16 @@ import {
1110
FormLayout,
1211
RouteLayout,
1312
} from "../components";
13+
import { safeToLocaleLower } from "../helpers";
1414
import { useSelectSettings } from "../hooks";
1515

1616
/**
1717
* @returns {JSX.Element} The media pages route.
1818
*/
1919
const MediaPages = () => {
2020
const { name, label, hasSchemaArticleType } = useSelectSettings( "selectPostType", [], "attachment" );
21-
const labelLower = useMemo( () => toLower( label ), [ label ] );
21+
const userLocale = useSelectSettings( "selectPreference", [], "userLocale" );
22+
const labelLower = useMemo( () => safeToLocaleLower( label, userLocale ), [ label, userLocale ] );
2223

2324
const replacementVariables = useSelectSettings( "selectReplacementVariablesFor", [ name ], name, "custom_post_type" );
2425
const recommendedReplacementVariables = useSelectSettings( "selectRecommendedReplacementVariablesFor", [ name ], name, "custom_post_type" );

packages/js/src/settings/routes/site-basics.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ const SiteBasics = () => {
190190
__( "%1$s has auto-detected whether it needs to force rewrite the titles for your pages, if you think it's wrong and you know what you're doing, you can change the setting here.", "wordpress-seo" ),
191191
"Yoast SEO"
192192
) }
193+
className="yst-max-w-sm"
193194
/>
194195
) }
195196
<FormikValueChangeField

packages/js/src/settings/routes/templates/post-type.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { createInterpolateElement, useMemo } from "@wordpress/element";
33
import { __, sprintf } from "@wordpress/i18n";
44
import { Badge, FeatureUpsell, Link, SelectField, TextField, Title, ToggleField } from "@yoast/ui-library";
55
import { Field, useFormikContext } from "formik";
6-
import { toLower } from "lodash";
76
import PropTypes from "prop-types";
87
import { addLinkToString } from "../../../helpers/stringHelpers";
98
import {
@@ -17,6 +16,7 @@ import {
1716
OpenGraphDisabledAlert,
1817
RouteLayout,
1918
} from "../../components";
19+
import { safeToLocaleLower } from "../../helpers";
2020
import { withFormikDummyField } from "../../hocs";
2121
import { useSelectSettings } from "../../hooks";
2222

@@ -45,13 +45,14 @@ const PostType = ( { name, label, singularLabel, hasArchive, hasSchemaArticleTyp
4545
const hasWooCommerceShopPage = useSelectSettings( "selectPreference", [], "hasWooCommerceShopPage" );
4646
const editWooCommerceShopPageUrl = useSelectSettings( "selectPreference", [], "editWooCommerceShopPageUrl" );
4747
const wooCommerceShopPageSettingUrl = useSelectSettings( "selectPreference", [], "wooCommerceShopPageSettingUrl" );
48+
const userLocale = useSelectSettings( "selectPreference", [], "userLocale" );
4849
const noIndexInfoLink = useSelectSettings( "selectLink", [], "https://yoa.st/show-x" );
4950
const socialAppearancePremiumLink = useSelectSettings( "selectLink", [], "https://yoa.st/4e0" );
5051
const pageAnalysisPremiumLink = useSelectSettings( "selectLink", [], "https://yoa.st/get-custom-fields" );
5152
const schemaLink = useSelectSettings( "selectLink", [], "https://yoa.st/post-type-schema" );
5253

53-
const labelLower = useMemo( () => toLower( label ), [ label ] );
54-
const singularLabelLower = useMemo( () => toLower( singularLabel ), [ singularLabel ] );
54+
const labelLower = useMemo( () => safeToLocaleLower( label, userLocale ), [ label, userLocale ] );
55+
const singularLabelLower = useMemo( () => safeToLocaleLower( singularLabel, userLocale ), [ singularLabel, userLocale ] );
5556
const recommendedSize = useMemo( () => createInterpolateElement(
5657
sprintf(
5758
/**

0 commit comments

Comments
 (0)