Copy link to clipboard
Copied
Hi,
I'm doing a huge leaflet with multiple (around 4000) text strings that need translation. I have each of those strings split into variables and imported from CSV via data merge. The problem is - to input the variable into a text field I have to find this variable on a huge data merge list, and click it. What I would like to do is just input the variable by hand, write it's name in the text field, instead of looking for it. Is there any way to do it?
Example:
I have two text fields in my doc, one for the name, and the second one for description.
I have the content for those fields in data merge, under variables "name" and "desc"
What I want to do is to just write in <<name>> and <<desc>> into those fields, instead of having to find those variables on the data merge list.
If that's not possible - than is there any way to search this data merge list somehow? Or anything else that will speed up adding those variables?
Thanks!
1 Correct answer
Ok, a completely different approach here. Problem originated from insertionPoints references getting wrong once texts got replaced by datamerge fields.
Now I use temp hyperlinks to strongly reference texts. It seems fully functional now :
...var main = function() {
var doc = app.properties.activeDocument, db = {}, props,
found, n, dm, tagName, ip, st, df, cs, ps, foundText, hks = {}, hk,dests = [], srcs = [], d, s, hkdb = {};
if (!doc ) return;
app.findGrepPreferences = null;
app.findGr
Copy link to clipboard
Copied
Sorry, but I don't follow you. Can you explain further? Thanks.
Copy link to clipboard
Copied
Sure.
So I have a leaflet with hundreds of products. Each product has a name, description, and couple others. Now I need to translate it to 10 different languages.
So what I did is created a list with all the translated content in the CSV doc, like this:
prod1_name, prod1_desc...
"Name in EN", "Description in EN"...
"Name in DE", "Description in DE"...
...
What I need to do is just add those variables into right places, and than I can easily switch between the languages.
The problem is - to add a variable you need to open a data merge pane, browse through a list of 4000 variables with your mouse, find the one you're looking for, and click it. Which takes A LOT of time, and is very error prone.
The result of this action is that this variable appears in this text field, looking like this "<<prod1_name>>". So I was trying to just write "<<prod1_name>>" in this text field, but it doesn't work this way. You have to add it from the list so that Indesign recognized it's a variable.
So I'm looking for a workaround. Is there any fast way of adding a variable not using this list?
Hope that helps.
Copy link to clipboard
Copied
Wouldn't it be simpler to create 10 different documents, one for each language? From there you'd create 10 different CSV data files, again, one for each language. Open the English document and merge it with the English CSV data file. Then do the same with all the remaining 9 language layouts and their corresponding data files.
Would this work? Seems easier than trying to do this all in one InDesign document, no?
Copy link to clipboard
Copied
I'm sorry but I'm not sure how this changes anything? Switching between the languages is super easy in data merge, so that's not a problem at all. For each specified variable you have multiple translated contents, and you can switch all the variables in the doc to a specified language with one click, so that's not a problem.
The problem is basically how much time you lose on putting the variables in the document. You have to click the text field, then find the variable on the huge list in data merge pane, and then click it. I know exactly which variable goes where, because their names have a clear structure - prod1_name, prod1_desc, prod2_name, prod2_desc, and so on. So it would be 10x faster to just type the name of the variable, instead of looking for it on the list. But if I do this - Indesign doesn't recognize this string as a variable...
I wonder is there maybe a way to write a script that will use regex to search the text fields for all strings between << and >> , and automatically turn them into the variables from data merge that match their names (so for example if the variable is "desc" and the text is "<<desc>>" - it turns it into variable). That would be beautiful, I'd just write the names of the variables into the text fields by hand, which is much quicker, and then turn them all into actual variables with the script.
Copy link to clipboard
Copied
Hi
have a look here: https://indesignsecrets.com/topic/assign-data-merge-tag-automatically-using-a-script
Be careful, Indesignsecrets forum doesn't handle code nicely, so replace “ and ” by ", and en-dashes by - - (without the space)
Copy link to clipboard
Copied
OMG! This sounds EXACTLY as what I need! Thanks, will test it today!
Copy link to clipboard
Copied
I think I did everything as you said, but the script seems to hang my Indesign. http://prntscr.com/jrbnzn Any ideas? Maybe the amount of tags in data merge is too big?
Copy link to clipboard
Copied
Hard to tell from your screenshot, but have you replaced the curly quotes by straight ones on line 40?
Now, maybe the author himself could share his thoughts... Loic.Aigon
Copy link to clipboard
Copied
vinny38 wrote
Hard to tell from your screenshot, but have you replaced the curly quotes by straight ones on line 40?
…
Hi,
not only in line 40. If I copy/paste the posted code to the ESTK (ExtendScript Toolkit) all quotes come over as curly ones and you must change them to straight ones to run the script successfully: Lines 8, 14 and 40.
Read also into the last post of this thread. Don't know exactly what went wrong there, but maybe you can make sense out of it:
https://indesignsecrets.com/topic/assign-data-merge-tag-automatically-using-a-script#post-88643
Regards,
Uwe
Copy link to clipboard
Copied
Hi everyone,
Seems like copy/pasting snippet from IDS creates a lot of typos. I am posting the code here:
var main = function() {
var doc = app.properties.activeDocument,
found, n, dm, tagName, ip, st, df;
if (!doc ) return;
app.findGrepPreferences = null;
app.findGrepPreferences.findWhat = '<<[^>]+>>';
found = doc.findGrep();
n = found.length;
while ( n-- ) {
tagName = String(found
.contents.replace(/(<<|>>)/g, '')); st = found
.parentStory; ix = found
.index-1; df = getField (doc, tagName );
if ( df!=null ) {
found
.remove(); doc.dataMergeTextPlaceholders.add( st, ix, df );
}
}
}
function getField ( doc, tagName ) {
var dfs = doc.dataMergeProperties.dataMergeFields,
n = dfs.length, df;
while ( n-- ) {
df = dfs
; if ( df.fieldName==tagName) return df;
}
return null;
}
var u;
app.doScript ( 'main()', u,u, UndoModes.ENTIRE_SCRIPT, 'Place tags' );
tested whatever the panel is active or not, visible or closed and always got to make it work, whatever the doc has a datamerge source file or not and it's all working fine.
Copy link to clipboard
Copied
IT WORKS! Thanks a lot!!!
Copy link to clipboard
Copied
Ok so as you contacted me reporting an issue, I thought I would share some improvements here:
First of all, the fact InDesign hangs is due to the quantity of fields you are using in the datasource as the script loops through them over and over explaining the delays. To make thinks better, I store them now once and for all before looping through text results.
Apart from that in the files you sent me, there are lowercase and uppercase mismatches between doc and source. So I chose to make everyone lowercase at the comparison stage. But i can't say if it's a good thing or not.
var main = function() {
var doc = app.properties.activeDocument, db = {}, props,
found, n, dm, tagName, ip, st, df;
if (!doc ) return;
app.findGrepPreferences = null;
app.findGrepPreferences.findWhat = '<<[^>]+?>>';
db = getDatamergeFields(doc);
found = doc.findGrep();
n = found.length;
while ( n-- ) {
$.writeln ( n );
tagName = String(found
.contents.replace(/(<<|>>)/g, '')); st = found
.parentStory; props = found
.properties; ix = found
.index-1; df = db[tagName.toLowerCase()];
if ( !df ) {
continue;
}
if ( df!=null ) {
found
.remove(); try {
doc.dataMergeTextPlaceholders.add( st, ix, df );
}
catch(err){}
}
}
}
function getDatamergeFields ( doc ) {
var dfs = doc.dataMergeProperties.dataMergeFields,
n = dfs.length, df, o = {};
while ( n-- ) {
df = dfs
; o[df.fieldName.toLowerCase()] = df;
}
return o;
}
function getField ( doc, tagName ) {
var dfs = doc.dataMergeProperties.dataMergeFields,
n = dfs.length, df;
while ( n-- ) {
df = dfs
; if ( df.fieldName==tagName) return df;
}
return null;
}
var u;
app.doScript ( 'main()', u,u, UndoModes.ENTIRE_SCRIPT, 'Place tags' );
Copy link to clipboard
Copied
Thanks Loic, I'll check it as soon as I'll get to work!
Copy link to clipboard
Copied
Hi Loic,
It works better and doesn't hang now - thanks!
But, I still have some issues.
1. The letter thing is problematic. It seems that if the variable name in data merge is "PROD01", and I write it like this: <<PROD01>>, your script will change the letters to <<prod01>> in the text itself, and also won't tag it as a variable (I guess because it doesn't match now - the data merge var is with big letters, and the text with small).
EDIT: I did some more testing. It seems that it actually works ok! Sorry!
2. If I have a text field with content like "Price: <<var>>", and I have different formatting styles (e.g. "Price" is bold), after using your script the formatting of the first part overtakes the formatting of the entire text field (so in this case the whole thing becomes bold).
EDIT: Did some more testing on that too. And discovered sth else. If I have sth like that "<<var1>>: <<var2>>" than your script will change it into "<<var1>><<var2>>" (deleting the middle part), reset the formatting as described previously, and also it'll just tag the var2.
Anyway, thanks for all your help!
D.
Copy link to clipboard
Copied
john_problem wrote
… 2. If I have a text field with content like "Price: <<var>>", and I have different formatting styles (e.g. "Price" is bold), after using your script the formatting of the first part overtakes the formatting of the entire text field (so in this case the whole thing becomes bold).
Hi,
it should work as expected, if the blank between : and < has the right formatting. E.g. not bold.
Regards,
Uwe
Copy link to clipboard
Copied
Ok, a completely different approach here. Problem originated from insertionPoints references getting wrong once texts got replaced by datamerge fields.
Now I use temp hyperlinks to strongly reference texts. It seems fully functional now :
var main = function() {
var doc = app.properties.activeDocument, db = {}, props,
found, n, dm, tagName, ip, st, df, cs, ps, foundText, hks = {}, hk,dests = [], srcs = [], d, s, hkdb = {};
if (!doc ) return;
app.findGrepPreferences = null;
app.findGrepPreferences.findWhat = '<<[^>]+?>>';
db = getDatamergeFields(doc);
found = doc.findGrep();
n = found.length;
hks = doc.hyperlinks.everyItem().getElements();
while ( hk = hks.pop() ) hkdb[hk.id] = hk;
hks = {};
while ( n-- ) {
foundText = found
; st = foundText.parentStory;
tagName = String(foundText.contents.replace(/(<<|>>)/g, ''));
df = db[tagName.toLowerCase()];
if ( !df ) {
continue;
}
try {
s = doc.hyperlinkTextSources.add ( foundText );
d = doc.hyperlinkURLDestinations.add ( "/http://www.yahoo.fr/"+foundText.contents );
dests.push( d );
srcs.push( s );
hk = doc.hyperlinks.add (
s,
d
);
hks[hk.id] = {hk:hk, tag:tagName, st : st, df : df, id:hk.id};
}
catch(err){}
}
var p, o;
for ( prop in hks ) {
foundText = hks[prop].hk.source.sourceText;
ix = foundText.index;
p = prop;
o = hks[prop];
hks[prop].hk.remove();
foundText.remove();
doc.dataMergeTextPlaceholders.add( hks[prop].st, ix, hks[prop].df );
}
}
function getDatamergeFields ( doc ) {
var dfs = doc.dataMergeProperties.dataMergeFields.everyItem().getElements(),
n = dfs.length, df, o = {};
while ( n-- ) {
df = dfs
; o[df.fieldName.toLowerCase()] = df;
}
return o;
}
function getField ( doc, tagName ) {
var dfs = doc.dataMergeProperties.dataMergeFields,
n = dfs.length, df;
while ( n-- ) {
df = dfs
; if ( df.fieldName==tagName) return df;
}
return null;
}
var u;
app.doScript ( 'main()', u,u, UndoModes.ENTIRE_SCRIPT, 'Place tags' );
Et voilà
HTH
Loic
Copy link to clipboard
Copied
This looks awesome. I'll try it tomorrow and let you know o it works. Thanks!!!
Copy link to clipboard
Copied
Tested it and... IT WORKS!!! So ar I tested it on a smaller doc, but in a week or two I'll have this huge leaflet coming it and will test it further.
THANKS!
Copy link to clipboard
Copied
Unfortunately I still encounter some problems. Basically the script works for most cases, but it breaks on a table with multiple data, that looks like this: http://prntscr.com/k258qn . The error msg says "the object you have chosen is already in use by another hyperlink".
Do you have any idea how I could fix that? I have hundreds of tables like this...:(
Copy link to clipboard
Copied
I did some more testing, and it seems that the actual problem is this:
1. If the table has more than 1 variables in one cell, like this: http://prntscr.com/k26gff , than this won't work, and the error like described above will appear.
2. If there is one variable in one cell, like this: http://prntscr.com/k26gpx , then it will work, BUT another problem appears, that after using your script the variables are removed from the tables and put under (or in some cases above) the table, like this: http://prntscr.com/k26h7w , which obviously is not a desired outcome.
Do you think it's possible to do sth about it?
Copy link to clipboard
Copied
If that'll help here's a package with example table: Folder test.zip - Google Drive
Copy link to clipboard
Copied
I'm also having this problem with the one variable per cell. Does anyone know if there is a workaround?

