Skip to content

Commit 3fafd9a

Browse files
authored
Merge pull request #63 from Yoast/stories/refactor-replacevars
Refactor replacevars
2 parents 38d79f9 + 8bf7a59 commit 3fafd9a

File tree

9 files changed

+435
-109
lines changed

9 files changed

+435
-109
lines changed

inc/class-ac-yoast-acf-content-analysis.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ protected function get_blacklist_type() {
200200
'tab',
201201
'repeater',
202202
'flexible_content',
203+
'group',
203204
);
204205

205206
foreach ( $default_blacklist as $type ) {

js/src/app.js

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,49 +13,58 @@ var App = function(){
1313
YoastSEO.app.registerModification('content', collect.append.bind(collect), config.pluginName);
1414

1515
this.bindListeners();
16+
1617
};
1718

1819
App.prototype.bindListeners = function(){
1920

21+
var _self = this;
22+
2023
if(helper.acf_version >= 5){
21-
var _self = this;
24+
2225
acf.add_action('ready', function () {
23-
_self.replaceVars = replaceVars.createReplaceVars(collect);
26+
27+
replaceVars.updateReplaceVars(collect);
28+
2429
acf.add_action('change remove append sortstop', _self.maybeRefresh);
25-
acf.add_action('change remove append sortstop', replaceVars.updateReplaceVars.bind(_self, collect, _self.replaceVars));
30+
acf.add_action('change remove append sortstop', replaceVars.updateReplaceVars.bind(_self, collect));
31+
2632
});
33+
2734
}else{
35+
2836
var fieldSelectors = config.fieldSelectors.slice(0);
37+
var wysiwygSelector = 'textarea[id^=wysiwyg-acf]';
2938

3039
// Ignore Wysiwyg fields because they trigger a refresh in Yoast SEO itself
31-
fieldSelectors = _.without(fieldSelectors, 'textarea[id^=wysiwyg-acf]');
32-
33-
var _self = this;
40+
fieldSelectorsWithoutWysiwyg = _.without(fieldSelectors, wysiwygSelector);
3441

3542
jQuery(document).on('acf/setup_fields', function(){
36-
this.replaceVars = replaceVars.createReplaceVars(collect);
43+
44+
replaceVars.updateReplaceVars(collect);
45+
46+
var fieldsWithoutWysiwyg = jQuery('#post-body, #edittag').find(fieldSelectorsWithoutWysiwyg.join(','));
3747
var fields = jQuery('#post-body, #edittag').find(fieldSelectors.join(','));
38-
//This would cause faster updates while typing
39-
//fields.on('change input', _self.maybeRefresh.bind(_self) );
40-
fields.on('change', _self.maybeRefresh.bind(_self) );
41-
fields.on('change', replaceVars.updateReplaceVars.bind(_self, collect, _self.replaceVars));
4248

49+
fieldsWithoutWysiwyg.on('change', _self.maybeRefresh.bind(_self) );
4350
// Do not ignore Wysiwyg fields for the purpose of Replace Vars.
44-
jQuery('textarea[id^=wysiwyg-acf]').on('change', replaceVars.updateReplaceVars.bind(_self, collect, _self.replaceVars));
51+
fields.on('change', replaceVars.updateReplaceVars.bind(_self, collect));
52+
4553
if (YoastSEO.wp._tinyMCEHelper) {
46-
jQuery('textarea[id^=wysiwyg-acf]').each( function () {
54+
55+
jQuery(wysiwygSelector).each( function () {
4756
YoastSEO.wp._tinyMCEHelper.addEventHandler(this.id, [ 'input', 'change', 'cut', 'paste' ],
48-
replaceVars.updateReplaceVars.bind(_self, collect, _self.replaceVars));
57+
replaceVars.updateReplaceVars.bind(_self, collect));
4958
});
50-
}
5159

60+
}
5261

5362
//Also refresh on media close as attachment data might have changed
5463
wp.media.frame.on('close', _self.maybeRefresh.bind(_self) );
5564
});
56-
}
5765

58-
}
66+
}
67+
};
5968

6069
App.prototype.maybeRefresh = function(){
6170

js/src/collect/collect-v4.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ fields.each(function() {
1010
var $el = jQuery(this).parents('.field').last();
1111

1212
field_data.push({
13-
$el : $el,
14-
key : $el.data('field_key'),
15-
name : $el.data('field_name'),
16-
type : $el.data('field_type')
13+
$el : $el,
14+
key : $el.data('field_key'),
15+
name : $el.data('field_name'),
16+
type : $el.data('field_type'),
17+
post_meta_key : $el.data('field_name')
1718
});
1819

1920
});

js/src/collect/collect-v5.js

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,67 @@
11
module.exports = function(){
2-
return _.map(acf.get_fields(), function(field){
2+
3+
var outerFieldsName = [
4+
'flexible_content',
5+
'repeater',
6+
'group'
7+
];
8+
9+
var innerFields = [];
10+
var outerFields = [];
11+
12+
var fields = _.map(acf.get_fields(), function(field){
313

414
var field_data = jQuery.extend( true, {}, acf.get_data(jQuery(field)) );
515
field_data.$el = jQuery(field);
16+
field_data.post_meta_key = field_data.name;
17+
18+
// Collect nested and parent
19+
if( outerFieldsName.indexOf(field_data.type) === -1 ) {
20+
innerFields.push(field_data);
21+
}else{
22+
outerFields.push(field_data);
23+
}
24+
625
return field_data;
726

827
});
9-
};
28+
29+
if( outerFields.length === 0){
30+
return fields;
31+
}
32+
33+
// Transform field names for nested fields.
34+
_.each(innerFields, function(inner){
35+
36+
_.each(outerFields, function(outer){
37+
38+
if (jQuery.contains(outer.$el[0], inner.$el[0])) {
39+
40+
// Types that hold multiple children.
41+
if (outer.type === 'flexible_content' || outer.type === 'repeater'){
42+
43+
outer.children = outer.children || [];
44+
outer.children.push(inner);
45+
inner.parent = outer;
46+
inner.post_meta_key = outer.name + '_' + (outer.children.length - 1) + '_' + inner.name;
47+
48+
}
49+
50+
// Types that hold single children.
51+
if (outer.type === 'group') {
52+
53+
outer.children = [inner];
54+
inner.parent = outer;
55+
inner.post_meta_key = outer.name + '_' + inner.name;
56+
57+
}
58+
59+
}
60+
61+
});
62+
63+
});
64+
65+
return fields;
66+
67+
};

js/src/collect/collect.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Collect.prototype.getFieldData = function () {
1515

1616
if(config.debug) {
1717

18-
console.log('Used types:')
18+
console.log('Used types:');
1919
console.log(used_types);
2020

2121
}
@@ -44,10 +44,10 @@ Collect.prototype.append = function(data){
4444
});
4545

4646
if(config.debug){
47-
console.log('Field data:')
47+
console.log('Field data:');
4848
console.table(field_data);
4949

50-
console.log('Data:')
50+
console.log('Data:');
5151
console.log(data);
5252
}
5353

js/src/replacevars.js

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,52 +6,51 @@ var ReplaceVar = YoastReplaceVarPlugin.ReplaceVar;
66

77
var supportedTypes = ['email', 'text', 'textarea', 'url', 'wysiwyg'];
88

9-
var createReplaceVars = function (collect) {
9+
var replaceVars = {};
10+
11+
var replaceVarPluginAvailable = function(){
1012
if (ReplaceVar === undefined) {
1113
if (config.debug) {
12-
console.log('Replacing ACF variables in the Snippet Window requires the latest version of wordpress-seo.');
14+
console.log('Replacing ACF variables in the Snippet Window requires Yoast SEO >= 5.3.');
1315
}
16+
return false;
17+
}
18+
return true;
19+
};
20+
21+
var updateReplaceVars = function (collect) {
22+
if (!replaceVarPluginAvailable()) {
1423
return;
1524
}
1625

17-
fieldData = _.filter(collect.getFieldData(), function (field) { return _.contains(supportedTypes, field.type) });
18-
replaceVars = {}
26+
var fieldData = _.filter(collect.getFieldData(), function (field) { return _.contains(supportedTypes, field.type) });
1927

2028
_.each(fieldData, function(field) {
2129
// Remove HTML tags using jQuery in case of a wysiwyg field.
22-
var content = (field.type === 'wysiwyg') ? jQuery( jQuery.parseHTML( field.content) ).text() : field.content;
30+
var content = (field.type === 'wysiwyg') ? jQuery(jQuery.parseHTML(field.content)).text() : field.content;
2331

24-
replaceVars[field.name] = new ReplaceVar( '%%cf_'+field.name+'%%', content, { source: 'direct' } );
25-
YoastSEO.wp.replaceVarsPlugin.addReplacement( replaceVars[field.name] );
26-
if (config.debug) {
27-
console.log("Created ReplaceVar for: ", field.name, " with: ", content, replaceVars[field.name]);
28-
}
29-
});
32+
if(replaceVars[field.post_meta_key]===undefined){
3033

31-
return replaceVars;
32-
};
34+
replaceVars[field.post_meta_key] = new ReplaceVar( '%%cf_'+field.post_meta_key+'%%', content, { source: 'direct' } );
35+
YoastSEO.wp.replaceVarsPlugin.addReplacement( replaceVars[field.post_meta_key] );
3336

34-
var updateReplaceVars = function (collect, replace_vars) {
35-
if (ReplaceVar === undefined) {
36-
if (config.debug) {
37-
console.log('Replacing ACF variables in the Snippet Window requires the latest version of wordpress-seo.');
38-
}
39-
return;
40-
}
37+
if (config.debug) {
38+
console.log("Created ReplaceVar for: ", field.post_meta_key, " with: ", content, replaceVars[field.post_meta_key]);
39+
}
4140

42-
fieldData = _.filter(collect.getFieldData(), function (field) { return _.contains(supportedTypes, field.type) });
43-
_.each(fieldData, function(field) {
44-
// Remove HTML tags using jQuery in case of a wysiwyg field.
45-
var content = (field.type === 'wysiwyg') ? jQuery(jQuery.parseHTML(field.content)).text() : field.content;
41+
}else{
42+
43+
replaceVars[field.post_meta_key].replacement = content;
44+
45+
if (config.debug) {
46+
console.log("Updated ReplaceVar for: ", field.post_meta_key, " with: ", content, replaceVars[field.post_meta_key]);
47+
}
4648

47-
replaceVars[field.name].replacement = content;
48-
if (config.debug) {
49-
console.log("Updated ReplaceVar for: ", field.name, " with: ", content, replaceVars[field.name]);
5049
}
50+
5151
});
5252
};
5353

5454
module.exports = {
55-
createReplaceVars: createReplaceVars,
5655
updateReplaceVars: updateReplaceVars
5756
};

0 commit comments

Comments
 (0)