Skip to content

Instantly share code, notes, and snippets.

@erikyo
Last active July 23, 2024 22:03
Show Gist options
  • Save erikyo/53ec6a1b2264135dae95e866194a0a8a to your computer and use it in GitHub Desktop.
Save erikyo/53ec6a1b2264135dae95e866194a0a8a to your computer and use it in GitHub Desktop.
Adds to Yoast an additional replacement variable both in frontend and snippet preview (backend)
/* inspired from https://github.com/Yoast/wpseo-woocommerce/blob/trunk/js/src/yoastseo-woo-replacevars.js */
/* global jQuery, YoastSEO, app, globals YoastACFAnalysisConfig */
var pluginName = "additionalVariablePlugin";
var ReplaceVar = window.YoastReplaceVarPlugin && window.YoastReplaceVarPlugin.ReplaceVar;
var placeholders = {};
var modifiableFields = [
"content",
"title",
"snippet_title",
"snippet_meta",
"primary_category",
"data_page_title",
"data_meta_desc",
];
var replaceVarPluginAvailable = function() {
if ( typeof ReplaceVar === "undefined" ) {
if ( config.debug ) {
console.log( "Additional replace variables in the Snippet Window requires Yoast SEO >= 5.3." );
}
return false;
}
return true;
};
/**
* Gets yomama
*
* @returns {string} Yo Mama!
*/
var i = 0;
function getMama() {
return 'Yo Mama! ' + jQuery( "#inspector-text-control-1" ).val() + ' n' + i++ ;
}
/**
* Variable replacement plugin for WordPress.
*
* @returns {void}
*/
var YoastReplaceVarPlugin = function () {
if ( ! replaceVarPluginAvailable() ) {
return;
}
this._app = YoastSEO.app;
this._app.registerPlugin(pluginName, {status: "ready"});
this._store = YoastSEO.store;
this.registerReplacements();
this.registerModifications( this._app );
this.registerEvents();
};
/**
* Register the events that might have influence for the replace vars.
*
* @returns {void}
*/
YoastReplaceVarPlugin.prototype.registerEvents = function() {
jQuery( document ).on( "change", "#inspector-text-control-1", this.declareReloaded.bind( this ) );
};
/**
* Registers all the placeholders and their replacements.
*
* @returns {void}
*/
YoastReplaceVarPlugin.prototype.registerReplacements = function () {
this.addReplacement(new ReplaceVar("%%yomama%%", "yomama"));
};
/**
* Registers the modifications for the plugin on initial load.
*
* @param {app} app The app object.
*
* @returns {void}
*/
YoastReplaceVarPlugin.prototype.registerModifications = function (app) {
var callback = this.replaceVariables.bind(this);
for (var i = 0; i < modifiableFields.length; i++) {
app.registerModification(modifiableFields[i], callback, pluginName, 10);
}
};
/**
* Runs the different replacements on the data-string.
*
* @param {string} data The data that needs its placeholders replaced.
*
* @returns {string} The data with all its placeholders replaced by actual values.
*/
YoastReplaceVarPlugin.prototype.replaceVariables = function (data) {
if (typeof data !== "undefined") {
data = data.replace(/%%yomama%%/g, getMama());
data = this.replacePlaceholders( data );
}
return data;
};
/**
* Adds a replacement object to be used when replacing placeholders.
*
* @param {ReplaceVar} replacement The replacement to add to the placeholders.
*
* @returns {void}
*/
YoastReplaceVarPlugin.prototype.addReplacement = function (replacement) {
placeholders[replacement.placeholder] = replacement;
this._store.dispatch({
type: "SNIPPET_EDITOR_UPDATE_REPLACEMENT_VARIABLE",
name: replacement.placeholder.replace(/^%%|%%$/g, ""),
value: replacement.placeholder,
});
};
/**
* Reloads the app to apply possibly made changes in the content.
*
* @returns {void}
*/
YoastReplaceVarPlugin.prototype.declareReloaded = function() {
this._app.pluginReloaded( pluginName );
this._store.dispatch( { type: "SNIPPET_EDITOR_REFRESH" } );
};
/**
* Replaces placeholder variables with their replacement value.
*
* @param {string} text The text to have its placeholders replaced.
*
* @returns {string} The text in which the placeholders have been replaced.
*/
YoastReplaceVarPlugin.prototype.replacePlaceholders = function (text) {
for (var i = 0; i < placeholders.length; i++) {
var replaceVar = placeholders[i];
text = text.replace(
new RegExp(replaceVar.getPlaceholder(true), "g"), replaceVar.replacement
);
}
return text;
};
/**
* Initializes the Additional ReplaceVars plugin.
*
* @returns {void}
*/
function initializeReplacevarPlugin() {
// When YoastSEO is available, just instantiate the plugin.
if (typeof YoastSEO !== "undefined" && typeof YoastSEO.app !== "undefined") {
new YoastReplaceVarPlugin(); // eslint-disable-line no-new
return;
}
// Otherwise, add an event that will be executed when YoastSEO will be available.
jQuery(window).on(
"YoastSEO:ready",
function () {
console.log('ready');
new YoastReplaceVarPlugin(); // eslint-disable-line no-new
}
);
}
initializeReplacevarPlugin();
<?php
// while developing with yoast this will be your best friend https://developer.yoast.com/
// additiona replace var example
// https://github.com/Yoast/wordpress-seo/blob/fc56f550de4581013f1b90ada32de526844e3a39/inc/wpseo-functions.php#L106
/**
* @return string YO MAMA
*/
function myprefix_yomama_callback() {
return "Yo Mama!";
}
/**
* the action that register a replacement of the variable in the snippet
*/
function myprefix_Yoast_additional_replacement_variables() {
wpseo_register_var_replacement( 'yomama', 'myprefix_yomama_callback', 'basic', 'this is a help text for yomama' );
}
add_action('wpseo_register_extra_replacements', 'myprefix_Yoast_additional_replacement_variables');
/**
* Loads plugin to replace variable into YOAST SEO snippet
*/
function myprefix_Yoast_additional_replacement_variables_scripts() {
wp_enqueue_script( 'myprefix-seo-scripts', get_template_directory_uri() . "/assets/dist/admin/js/replacevar-script.js", array('jquery') );
}
add_action( 'admin_footer', 'myprefix_Yoast_additional_replacement_variables_scripts' );
@phamquangbaoplus
Copy link

Can you add auto update preview with js please?

@erikyo
Copy link
Author

erikyo commented Aug 11, 2021

Can you add auto update preview with js please?

@phamquangbaoplus Let me know if has worked! I suppose this is the simplest way to replace variables into backend 😬. You need to get data that are already in page with jQuery( "#datacontainer" ).val() or something like.

@phamquangbaoplus
Copy link

Hello, there is a small problem that the preview does not update automatically when I change the value of input.

@erikyo
Copy link
Author

erikyo commented Aug 12, 2021

yes, in fact the value of the variable is not updated if you change it... it would be necessary to update the replacement value that was set on init. will update the script

@erikyo
Copy link
Author

erikyo commented Aug 12, 2021

@phamquangbaoplus this will update the fields on the fly but you need to register the event that init the replace vars (actually near line 66).

@phamquangbaoplus
Copy link

Thank you <3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment