Copy link to clipboard
Copied
Hello fellows,
I am writing a small xtendscript that saves a file to a network folder upon hitting Save.
For some reason, the tilde (~) doesn't get resolved as C:\Users\<username>\ in a file path I define (Win10, FM13).
For example:
var FilePath = "~\\AppData\\Roaming\\Adobe\\FrameMaker\\SharePoint\\TestFolder\\Latest Collaterals\\UG\\Sources\\";
if I run alert(FilePath), I get "~\AppData\..."
Any ideas why it doesn't get resolved?
Thanks,
Roman
Hi Rombanks,
indexOf Returns 0 in this case, as the string starts with the string provided as parameter. Strings starts at the first position, and the first position in an JavaScript array is 0 (not 1). This is by Definition.
this is what "ObjectModel Viewer" (F1 in ESTK) tells for File.copy
File.copy (target: string 😞 Boolean Core JavaScript Classes Copies this object’s referenced file to the specified target location. Resolves any aliases to find the source file. If a file exists at the target
...
Copy link to clipboard
Copied
Hi Rombanks,
try this
var filePath = new File("~\\AppData\\Roaming\\Adobe\\FrameMaker\\SharePoint\\TestFolder\\Latest Collaterals\\UG\\Sources\\")
Hope this helps
Markus
Copy link to clipboard
Copied
Hi Markus,
I appreciate your response!
new File doesn't resolve it either.
What I actually do is check the path of the open file. If it is C:\Users\<username>\..., then save the file to a network folder (in my case, a SharePoint folder).
Thanks,
Roman
Copy link to clipboard
Copied
Hi,
when I do this in FM 2019 (ESTK CC 4.0.0.1 ES 4.5.5)
var filePath = new File("~\\AppData\\Roaming\\Adobe\\FrameMaker\\SharePoint\\TestFolder\\Latest Collaterals\\UG\\Sources\\")
I get this in console, when I put "filePath" variable in there
C:\Users\Markus\AppData\Roaming\Adobe\FrameMaker\SharePoint\TestFolder\Latest Collaterals\UG\Sources
Maybe, it's me, and i don't understand the problem.
Perhaps, it's also an idea to use FM's Directory properties like:
app.UserHomeDir
app.UserSettingsDir
app.TmpDir
etc.
Markus
Copy link to clipboard
Copied
Hi,
Just saw, behavior is different in FM 2015.
Path isn't resolved like it is done above.
(one more reason to upgrade ;-))
But you can do it like this:
$.getenv('appdata') + "\\Adobe\\FrameMaker\\SharePoint\\TestFolder\\Latest Collaterals\\UG\\Sources\\"
or better
var filePath = new Folder($.getenv('appdata') + "\\Adobe\\FrameMaker\\SharePoint\\TestFolder\\Latest Collaterals\\UG\\Sources\\");
Hope this works now for you
Markus
Copy link to clipboard
Copied
All you are doing with this code is creating a string and printing it, so there is nothing special going on here.
What you want to do is create a new Folder object and then use its properties and methods to do what you want.
Here are some examples of accepted syntax:
var folder = new Folder('~/Desktop');
var folder2 = new Folder(Folder.desktop + '/NewFolder');
var folder3 = new Folder('//servername/sharename');
var folder4 = new Folder(Folder.userData);
alert(folder.fullName);
alert(folder.fsName);
Full details can be found in the "JavaScript Tools Guide CC" PDF (do a google for it or I think its in the ESTK help menu)
Copy link to clipboard
Copied
Hi,
Thanks for your response!
I am using FM13 and the ESTK that comes with it.
What I do is:
1. Extract the file's path and assign it to the FilePath variable:
...
var FilePath = doc.Name.substr (0, (doc.Name.indexOf(FileName)));
...
Then, I'd like to test whether the FilePath value is C:\Users\<username>\...
If yes, save to a SharePoint folder. Here is another catch: if the file is checked out,
Copy link to clipboard
Copied
var FilePath = doc.Name.substr (0, (doc.Name.indexOf(FileName)));
if (FilePath.indexOf($.genenv('appdata'))==0)
{
//starts with %appdata%
//so copy suff to network
}
and this has the same effect
if (doc.Name.indexOf($.genenv('appdata'))==0)
{
//starts with %appdata%
//so copy suff to Network
}
Hope this helps now.
markus
Copy link to clipboard
Copied
Here is another interesting catch: if the file is checked out in SharePoint, the script overwrites the file that is on SharePoint, cancels checkout, and checks out the .backup file. If I do the same operation with a batch file, the file is overwritten but checkout is not cancelled.
Copy link to clipboard
Copied
Thanks a lot, Markus!
I see that even if the script works, FrameMaker creates a mess on SharePoint when trying to overwrite the file that sits on SharePoint with a snapshot that sits locally under Appdata. So, I'll have to look for other solutions.
Copy link to clipboard
Copied
Hi rombanks,
I think ,you should save file locally, and copy file with "File.copy" to the server.
Don't use FrameMaker to work on that server directory directly.
Open File From Server:
- copy to file to local dir
- let the user work on this file
- copy file to server dir
(of course there are some issues (like file references to solve)
Markus
Copy link to clipboard
Copied
BTW, (FilePath.indexOf($.getenv('appdata'))==0) doesn't work either.
Why is it equal to 0?
Regards,
Roman
Copy link to clipboard
Copied
You have this string:
filepath = "c:\users\markus\myfile.txt"
indexOf provides the position where parameter string starts
filePath.indexOf("C:\users\") returns Position 0 (starting of the string)
filePath.indexOf("users") returns position 3 (4th Position in string)
string array index starts always with 0 (not with 1)
filePath.indexOf("rombanks") returns -1
-1 (negative value) indicates that string is not found.
this Code works with my FM 2015 installation
var filePath = "C:\\Users\\Markus\\AppData\\Roaming\\Adobe\\FrameMaker\\SharePoint\\TestFolder\\Latest Collaterals\\UG\\Sources\\" ;
if (filePath.indexOf($.getenv('appdata'))==0)
{
//starts with %appdata%
//so copy suff to network
$.writeln("hallo")
}
But I had a typo: must be $.getenv and not $genenv.
Markus
Copy link to clipboard
Copied
Hi Markus,
Thanks for your explanations!
It's not quite clear to me why filePath.indexOf("C:\users\") returns Position 0.
Line if (filePath.indexOf($.getenv('AppData'))==0) started working only after I defined a system variable called AppData.
I'd like to test your suggestion to use File.copy() instead of saving the file.
Interestingly enough, I didn't see the File.copy() method in the Scripting Guide, nor in the Javascript Tools Guide.
So, assuming the open file is defined as:
var doc = app.ActiveDoc;
and the target folder to copy the file to is defined as:
var docLib = "T:\\My_UG\\Sources\\";
I've created a new file object:
var oFile = new File(doc.Name);
To copy the file over to the network folder, I tried:
oFile.copy(docLib);
For some reason, it doesn't work. Any idea why?
Thank you!!
Copy link to clipboard
Copied
Hi Rombanks,
indexOf Returns 0 in this case, as the string starts with the string provided as parameter. Strings starts at the first position, and the first position in an JavaScript array is 0 (not 1). This is by Definition.
this is what "ObjectModel Viewer" (F1 in ESTK) tells for File.copy
File.copy (target: string 😞 Boolean Core JavaScript Classes Copies this object’s referenced file to the specified target location. Resolves any aliases to find the source file. If a file exists at the target location, it is overwritten. Returns true if the copy was successful. target: Data Type: string or File A string with the URI path to the target location, or a File object that references the target location. Example: aFile.copy(target)
File.copy expects and URI or a File object, so do this
var oFile = new File(doc.Name);
oFile.copy(new File(docLib));
or
oFile.copy(new File(docLib).toString());
Make sure, docLib is a file path not not a path to a Folder. docLib sounds like a Folder path. this doesn't work. a file Name is expected here.
File.copy works with an URI not with a Windows file path. An URI starts with file://c:/somepath or ~AppData\Users.... etc.
So this should also work with Network paths, but I haven't testet it yet.
$.getenv reads environment variables from the system. %appdata% is defined by default. not sure why this doesn't work in your environment. Put the string in JavaScript console and see what the result is.
Copy link to clipboard
Copied
Hi Markus,
Thank you for your detailed explanations! You are a great mentor!
The interesting thing is that the file path didn't work with the URI notation (file://c:/somepath) but it did with the regular Win notation (T:\\My_UG\\Sources\\...).
The File.copy syntax you suggested really surprised me as the Object Model doc provided a fuzzy example: File.copy(target). Without your help I wouldn't have guessed that in order for File.copy to work, you need to add "new File(target)" as its argument. The ES documentation is very laconic, to say the least...
It seems that the FM feature I am dealing with is something that remained unexplored even by the experienced FM scripters. In my previous post, I've asked if anyone knows how to access the CMSObject properties, and disable the dependent files option in the CMS checkout window.
In the Object Model viewer, I see the following:
CMSObject.CMSCheckout (rootWithDescendants: Boolean ):int
Adobe FrameMaker-2015 Object Model
rootWithDescendants: Data Type: Boolean
But 3 things are unclear:
1. Is this a global setting (per FM session) or per file to be checked out?
2. How to access the the CMS object? What is its parent?
3. If this is a per-file setting, is there a dedicated CMS checkout constant to be caught using the event notifier? I didn't see any in the Scripting Reference Guide.
Many thanks for your insightful input!
Best Regards,
Roman
Copy link to clipboard
Copied
Hi,
fortunately, I haven't done anything with CMS connectors, yet :-),
But it should work like this:
//get the CMS connection
var cmsConnection = new CMSSession();
//don't know how to Login... sorry
//get the CMS object
var cmsObject = cmsConnection.GetCMSObjectFromPath("libs/source.fm")
var result = cmsObject.CheckOut(true); //true if references should be checkout otherwise false
///TODO anything and then check in again
var checkInParameters = null; //TODO: instance a list of key value pairs, instance of CMSCheckinParam
cmsObject.CheckIn(checkInParameters)
Unfortunately, I can't tell you more. There are some Basic samples in FDK reference https://help.adobe.com/en_US/framemaker/pdfs/fdkreference.pdf but I think they won't help much
Markus
Copy link to clipboard
Copied
Hi Markus,
Thank you for your sample code! I see it's based on an interpretation of the FDK example.
The example provided in the FDK guide cannot be applied to a real-life use case as it seems to show how to check out a file that is hard coded in a script.
At least it shows that the "checkout dependent files" is a per-file option and not a session-level option. But it's not clear how to catch the Checkout event.
new CMSSession() is not accepted. The error I get is "CMSSession() is not a function".
Once the CMS connection is established, I don't think we need to log in.
It is not clear how to retrieve the session ID and object ID, which are required by the CMSCheckout function.
The Adobe documentation is so cryptic that it makes it virtually unusable.
Thanks again,
Roman
Copy link to clipboard
Copied
Hi,
> The Adobe documentation is so cryptic that it makes it virtually unusable.
It's not crypted. it's just not really there for these usecases.
There is a global function "CMSLogin". This Returns the session
//sample how to create Login data (not sure if this is correct)
var loginData = new IdValuePairs();
var idCommand = new IdValuePair(Constants.FV_CMSCommandNameId, 1);
loginData.push(idCommand);
//add anything else
var session = CMSLogin(loginData);
If you set the loginData correctly, you shout get a valid CMSSession, and from there you could get the CMS object as described above.
But I'm not sure what to set to login data, I think you have to figure this out by your self, as Long as noone else has a solution.
Constants for loginData are described in ES reference, but I'm not sure what values should be provided
Markus
Copy link to clipboard
Copied
Hi Marcus,
Thank you for your response!
What I meant is that I have manually established the CMS connection to the SharePoint directory where the FM files are stored. So, I am not sure why I have to go through the login process in the script.
The question is how to retrieve the session ID and object ID from the already established connection.
This is not described anywhere. So many years have passed since ES was introduced and the documentation remained really bad.
Copy link to clipboard
Copied
Hi Roman,
May be I'm wrong, but I think it won't work that way.
The script has to Login, as it's seems to be the only way to get the session.
Maybe "GetCmsIdFromName" could help. This provides a CMSRegistration, but this can only prompt an UI for login.
Maybe you can check your data browser, if there is any object available, which provides this Information. But I haven't found one.
Sorry, I reached the end. Maybe someone else knows how to get this stuff to work.
Perhaps it would be a good idea to open a new thread for this.
Good luck
Markus
Copy link to clipboard
Copied
Hi Markus,
Thank you for your great input! I know you did your best to help.
I actually did open a separate thread but no one has responded.
I guess only Adobe can shed light on how all this works. But Adobe has been silent so far.
Best wishes,
Roman
Copy link to clipboard
Copied
Hi Roman,
could you add a link to that thread here.
I try to involve Adobe to this issue.
Good luck
Markus
Copy link to clipboard
Copied
Hi Markus,
I posted this question here:
FM 13 - Catching CMSCheckout event
Thank you so much for your help! A friend in need is a friend indeed.
Best wishes,
Roman
Copy link to clipboard
Copied
Hi Roman,
I have sent a private message to you. Please check and share the requested information so that we can connect and look into it.
Looking forward to your response.
Regards,
Ajit