get_post_type_label( get_post_type( $post_id ) );
/* translators: %1$s expands to the translated name of the post type. */
- $first_sentence = sprintf( __( 'You just trashed a %1$s.', 'wordpress-seo' ), $post_label );
- $message = $this->get_message( $first_sentence, 'trashed', $post_label );
+ $first_sentence = sprintf( __( 'You just trashed a %1$s.', 'wordpress-seo' ), $post_label );
+ $second_sentence = __( 'Search engines and other websites can still send traffic to your trashed content.', 'wordpress-seo' );
+ $message = $this->get_message( $first_sentence, $second_sentence );
$this->add_notification( $message );
}
@@ -85,8 +86,9 @@ public function detect_post_delete( $post_id ) {
$post_label = $this->get_post_type_label( get_post_type( $post_id ) );
/* translators: %1$s expands to the translated name of the post type. */
- $first_sentence = sprintf( __( 'You just deleted a %1$s.', 'wordpress-seo' ), $post_label );
- $message = $this->get_message( $first_sentence, 'deleted', $post_label );
+ $first_sentence = sprintf( __( 'You just deleted a %1$s.', 'wordpress-seo' ), $post_label );
+ $second_sentence = __( 'Search engines and other websites can still send traffic to your deleted content.', 'wordpress-seo' );
+ $message = $this->get_message( $first_sentence, $second_sentence );
$this->add_notification( $message );
}
@@ -107,8 +109,9 @@ public function detect_term_delete( $term_taxonomy_id ) {
$term_label = $this->get_taxonomy_label_for_term( $term->term_id );
/* translators: %1$s expands to the translated name of the term. */
- $first_sentence = sprintf( __( 'You just deleted a %1$s.', 'wordpress-seo' ), $term_label );
- $message = $this->get_message( $first_sentence, 'deleted', $term_label );
+ $first_sentence = sprintf( __( 'You just deleted a %1$s.', 'wordpress-seo' ), $term_label );
+ $second_sentence = __( 'Search engines and other websites can still send traffic to your deleted content.', 'wordpress-seo' );
+ $message = $this->get_message( $first_sentence, $second_sentence );
$this->add_notification( $message );
}
@@ -209,17 +212,15 @@ protected function check_visible_post_status( $post_status ) {
* Returns the message around changed URLs.
*
* @param string $first_sentence The first sentence of the notification.
- * @param string $action The action performed, either "deleted" or "trashed".
- * @param string $object_label The label of the object that was deleted or trashed.
+ * @param string $second_sentence The second sentence of the notification.
*
* @return string The full notification.
*/
- protected function get_message( $first_sentence, $action, $object_label ) {
+ protected function get_message( $first_sentence, $second_sentence ) {
return '' . __( 'Make sure you don\'t miss out on traffic!', 'wordpress-seo' ) . '
'
. ''
. $first_sentence
- /* translators: %1$s expands to either "deleted" or "trashed". %2$s expands to the name of the post or term. */
- . ' ' . sprintf( __( 'Search engines and other websites can still send traffic to your %1$s %2$s.', 'wordpress-seo' ), $action, $object_label )
+ . ' ' . $second_sentence
. ' ' . __( 'You should create a redirect to ensure your visitors do not get a 404 error when they click on the no longer working URL.', 'wordpress-seo' )
/* translators: %s expands to Yoast SEO Premium */
. ' ' . sprintf( __( 'With %s, you can easily create such redirects.', 'wordpress-seo' ), 'Yoast SEO Premium' )
diff --git a/config/dependency-injection/deprecated-classes.php b/config/dependency-injection/deprecated-classes.php
index 0a20094b0f6..f731d54932b 100644
--- a/config/dependency-injection/deprecated-classes.php
+++ b/config/dependency-injection/deprecated-classes.php
@@ -35,6 +35,8 @@
use Yoast\WP\SEO\Integrations\Schema_Blocks;
use Yoast\WP\SEO\Integrations\Third_Party\CoAuthors_Plus;
use Yoast\WP\SEO\Integrations\Third_Party\The_Events_Calendar;
+use Yoast\WP\SEO\Integrations\Third_Party\Wincher;
+use Yoast\WP\SEO\Integrations\Third_Party\Wordproof_Integration_Toggle;
use Yoast\WP\SEO\Routes\Indexables_Page_Route;
use Yoast\WP\SEO\Schema_Templates\Assets\Icons;
@@ -56,6 +58,8 @@
Schema_Blocks::class => '20.5',
Icons::class => '20.5',
Old_Premium_Integration::class => '20.10',
+ Wincher::class => '21.6',
+ Wordproof_Integration_Toggle::class => '21.6',
];
foreach ( $deprecated_classes as $original_class => $version ) {
diff --git a/config/jenkins/Jenkinsfile_artifact b/config/jenkins/Jenkinsfile_artifact
deleted file mode 100644
index e4d13330bc7..00000000000
--- a/config/jenkins/Jenkinsfile_artifact
+++ /dev/null
@@ -1,25 +0,0 @@
-node( 'docker-agent' ) {
- checkout scm
- env.GIT_COMMIT = sh(returnStdout: true, script: "git log -n 1 --pretty=format:'%h'")
- docker.withServer( 'tcp://172.17.0.1:2375' ) {
- def ubuntu = docker.image( 'yoastseo/docker-php-composer-node' )
- ubuntu.pull()
- ubuntu.inside() {
- stage( 'Set Version'){
- // sed using '#' as separators. overwriting php files with the new plugin name.
- sh "SEARCH_STRING=\"[Pp]lugin [Nn]ame.*\" && REPLACE_STRING=\'* Plugin Name: Yoast SEO (beta) | ${env.BRANCH_NAME} | ${env.GIT_COMMIT}\' && sed -i \"s#\$SEARCH_STRING#\$REPLACE_STRING#\" wp-seo.php"
- }
- stage( 'Build' ){
- sh 'composer install'
- sh 'yarn'
- sh 'grunt build'
- sh 'grunt artifact'
- }
- stage( 'Expose Artifact' ) {
- def BRANCH_NAME = sh(returnStdout: true, script: "echo ${env.BRANCH_NAME} | sed -e s#/#-# | tr --delete '\n'")
- sh "mv artifact.zip wordpress-seo-${BRANCH_NAME}.zip"
- archiveArtifacts artifacts: "wordpress-seo-${BRANCH_NAME}.zip", fingerprint: true
- }
- }
- }
-}
\ No newline at end of file
diff --git a/config/webpack/externals.js b/config/webpack/externals.js
index 03f564ae81e..2a26a0926d2 100644
--- a/config/webpack/externals.js
+++ b/config/webpack/externals.js
@@ -1,11 +1,13 @@
-const { camelCaseDash } = require( "@wordpress/dependency-extraction-webpack-plugin/lib/util" );
+const {
+ camelCaseDash,
+} = require("@wordpress/dependency-extraction-webpack-plugin/lib/util");
/**
* Yoast dependencies, declared as such in the package.json.
*/
-const { dependencies } = require( "../../packages/js/package" );
-const legacyYoastPackages = [ "yoast-components", "yoastseo" ];
-const additionalPackages = [
+const { dependencies } = require("../../packages/js/package");
+const legacyYoastPackages = ["yoast-components", "yoastseo"];
+const additionalPackages = [
"draft-js",
"styled-components",
"jed",
@@ -13,26 +15,26 @@ const additionalPackages = [
"redux",
"@reduxjs/toolkit",
"react-helmet",
+ "chart.js",
];
const YOAST_PACKAGE_NAMESPACE = "@yoast/";
// Fetch all packages from the dependencies list.
-const yoastPackages = Object.keys( dependencies )
- .filter(
- ( packageName ) =>
- packageName.startsWith( YOAST_PACKAGE_NAMESPACE ) ||
- legacyYoastPackages.includes( packageName ) ||
- additionalPackages.includes( packageName )
- );
+const yoastPackages = Object.keys(dependencies).filter(
+ (packageName) =>
+ packageName.startsWith(YOAST_PACKAGE_NAMESPACE) ||
+ legacyYoastPackages.includes(packageName) ||
+ additionalPackages.includes(packageName)
+);
/**
* Convert Yoast packages to externals configuration.
*/
-const yoastExternals = yoastPackages.reduce( ( memo, packageName ) => {
- let useablePackageName = packageName.replace( YOAST_PACKAGE_NAMESPACE, "" );
+const yoastExternals = yoastPackages.reduce((memo, packageName) => {
+ let useablePackageName = packageName.replace(YOAST_PACKAGE_NAMESPACE, "");
- switch ( useablePackageName ) {
+ switch (useablePackageName) {
case "components":
useablePackageName = "components-new";
break;
@@ -47,9 +49,9 @@ const yoastExternals = yoastPackages.reduce( ( memo, packageName ) => {
break;
}
- memo[ packageName ] = camelCaseDash( useablePackageName );
+ memo[packageName] = camelCaseDash(useablePackageName);
return memo;
-}, {} );
+}, {});
module.exports = {
YOAST_PACKAGE_NAMESPACE,
diff --git a/config/webpack/webpack.config.base.js b/config/webpack/webpack.config.base.js
index 64ca5a24e32..84b40e3c172 100644
--- a/config/webpack/webpack.config.base.js
+++ b/config/webpack/webpack.config.base.js
@@ -10,7 +10,7 @@ const { yoastExternals } = require( "./externals" );
let analyzerPort = 8888;
module.exports = function( { entry, output, combinedOutputFile, cssExtractFileName } ) {
- const exclude = /node_modules[/\\](?!(yoast-components|gutenberg|yoastseo|@wordpress|@yoast|parse5)[/\\]).*/;
+ const exclude = /node_modules[/\\](?!(yoast-components|gutenberg|yoastseo|@wordpress|@yoast|parse5|chart.js)[/\\]).*/;
// The index of the babel-loader rule.
let ruleIndex = 0;
if ( process.env.NODE_ENV !== "production" ) {
diff --git a/css/src/introductions.css b/css/src/introductions.css
index a047f9f9d91..aa72b205234 100644
--- a/css/src/introductions.css
+++ b/css/src/introductions.css
@@ -6,4 +6,11 @@
focus:yst-outline-none
focus:yst-ring-offset-0;
}
+ .yst-introduction-modal-panel {
+ background-image: linear-gradient(180deg, rgba(166, 30, 105, 0.25) 10%, rgba(255, 255, 255, 0.25) 50%);
+ }
+ .yst-introduction-modal-uppercase{
+ letter-spacing: 0.8px;
+ @apply yst-uppercase yst-text-slate-500;
+ }
}
diff --git a/css/src/modal.css b/css/src/modal.css
index 714ac12d7ec..e3484058d3e 100644
--- a/css/src/modal.css
+++ b/css/src/modal.css
@@ -64,6 +64,7 @@
@media (min-width: 600px) {
border-radius: 8px;
+ max-height: calc( 100% - 48px );
}
}
@@ -80,6 +81,10 @@
margin: 0;
}
+.yoast-gutenberg-modal .components-modal__content .components-modal__header {
+ border-bottom: 1px solid #e2e8f0 !important;
+}
+
.yoast-gutenberg-modal .components-modal__icon-container {
display: inline-flex;
}
diff --git a/package.json b/package.json
index e9ac12c7200..4ec7ed46108 100644
--- a/package.json
+++ b/package.json
@@ -83,7 +83,7 @@
"typescript": "^4.2.4"
},
"yoast": {
- "pluginVersion": "21.5-RC1"
+ "pluginVersion": "21.5-RC4"
},
"version": "0.0.0"
}
diff --git a/packages/babel-preset/index.js b/packages/babel-preset/index.js
index b9b6601be29..51798047fda 100644
--- a/packages/babel-preset/index.js
+++ b/packages/babel-preset/index.js
@@ -3,7 +3,11 @@ module.exports = ( api ) => {
return {
presets: [ "@wordpress/babel-preset-default" ],
- plugins: [ "@babel/plugin-proposal-optional-chaining", "@babel/plugin-transform-runtime" ],
+ plugins: [
+ "@babel/plugin-proposal-optional-chaining",
+ "@babel/plugin-transform-runtime",
+ "@babel/plugin-transform-class-properties",
+ ],
sourceType: "unambiguous",
};
};
diff --git a/packages/babel-preset/package.json b/packages/babel-preset/package.json
index cf427199114..df81cbc8084 100644
--- a/packages/babel-preset/package.json
+++ b/packages/babel-preset/package.json
@@ -13,6 +13,7 @@
"private": false,
"dependencies": {
"@babel/plugin-proposal-optional-chaining": "^7.17.12",
+ "@babel/plugin-transform-class-properties": "^7.22.5",
"@babel/plugin-transform-runtime": "^7.17.12",
"@wordpress/babel-preset-default": "^6.13.0"
},
diff --git a/packages/js/package.json b/packages/js/package.json
index ea70d872a91..f130756f2d6 100644
--- a/packages/js/package.json
+++ b/packages/js/package.json
@@ -11,8 +11,9 @@
"@draft-js-plugins/mention": "^5.0.0",
"@headlessui/react": "^1.7.8",
"@heroicons/react": "^1.0.6",
- "@wordpress/api-fetch": "^6.13.0",
+ "@reduxjs/toolkit": "^1.8.3",
"@wordpress/a11y": "^2.15.1",
+ "@wordpress/api-fetch": "^6.13.0",
"@wordpress/block-editor": "^5.3.1",
"@wordpress/blocks": "^11.1.2",
"@wordpress/components": "^13.0.3",
@@ -40,9 +41,13 @@
"@yoast/ui-library": "^3.2.1",
"a11y-speak": "git+https://github.com/Yoast/a11y-speak.git#master",
"babel-polyfill": "^6.26.0",
+ "bowser": "^2.11.0",
+ "chart.js": "^4.2.1",
+ "chartjs-adapter-moment": "^1.0.1",
"classnames": "^2.3.2",
"draft-js": "^0.11.7",
"find-with-regex": "~1.0.2",
+ "formik": "^2.2.9",
"interpolate-components": "^1.1.0",
"jed": "^1.1.1",
"lodash": "^4.17.21",
@@ -51,22 +56,20 @@
"moment-duration-format": "^2.2.2",
"prop-types": "^15.5.10",
"react-animate-height": "^2.0.23",
+ "react-aria-live": "^2.0.5",
+ "react-chartjs-2": "^5.2.0",
"react-helmet": "^6.1.0",
+ "react-hotkeys-hook": "^4.0.5",
"react-intl": "^2.4.0",
"react-redux": "^5.0.6",
+ "react-router-dom": "^6.3.0",
"react-select": "^3.1.0",
"redux": "^3.7.2",
"redux-thunk": "^2.2.0",
"styled-components": "^5.3.6",
"yoast-components": "^5.24.0",
"yoastseo": "^1.91.1",
- "formik": "^2.2.9",
- "@reduxjs/toolkit": "^1.8.3",
- "react-router-dom": "^6.3.0",
- "yup": "^0.32.11",
- "bowser": "^2.11.0",
- "react-hotkeys-hook": "^4.0.5",
- "react-aria-live": "^2.0.5"
+ "yup": "^0.32.11"
},
"devDependencies": {
"@babel/core": "^7.17.9",
diff --git a/packages/js/src/ai-generator/initialize.js b/packages/js/src/ai-generator/initialize.js
index 974645e9661..e048379933e 100644
--- a/packages/js/src/ai-generator/initialize.js
+++ b/packages/js/src/ai-generator/initialize.js
@@ -32,7 +32,7 @@ const AiGeneratorUpsell = ( { fieldId } ) => {
{ __( "Use AI", "wordpress-seo" ) }
-
+
diff --git a/packages/js/src/components/AdvancedSettings.js b/packages/js/src/components/AdvancedSettings.js
index 07d37428a9f..710dde707fc 100644
--- a/packages/js/src/components/AdvancedSettings.js
+++ b/packages/js/src/components/AdvancedSettings.js
@@ -31,7 +31,7 @@ const getNoIndexOptions = ( editorContext ) => {
return [
{
name: sprintf(
- /* Translators: %s translates to "yes" or "no", %s translates to the Post Label in plural form */
+ /* translators: the first %s translates to "yes" or "no", the second %s translates to the content type label in plural form */
__( "%s (current default for %s)", "wordpress-seo" ),
noIndex,
editorContext.postTypeNamePlural
@@ -45,7 +45,7 @@ const getNoIndexOptions = ( editorContext ) => {
return [
{
name: sprintf(
- /* Translators: %s translates to the "yes" or "no" ,%s translates to the Post Label in plural form */
+ /* translators: the first %s translates to "yes" or "no", the second %s translates to the content type label in plural form */
__( "%s (current default for %s)", "wordpress-seo" ),
noIndex,
editorContext.postTypeNamePlural
@@ -81,12 +81,7 @@ const MetaRobotsNoIndex = ( { noIndex, onNoIndexChange, editorContext, isPrivate
}