• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

tilde doesn't get resolved as user home dir

Participant ,
Jun 11, 2019 Jun 11, 2019

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

TOPICS
Scripting

Views

1.2K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Engaged , Jun 11, 2019 Jun 11, 2019

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
...

Votes

Translate

Translate
Engaged ,
Jun 11, 2019 Jun 11, 2019

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jun 11, 2019 Jun 11, 2019

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jun 11, 2019 Jun 11, 2019

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jun 11, 2019 Jun 11, 2019

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jun 11, 2019 Jun 11, 2019

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)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jun 11, 2019 Jun 11, 2019

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,

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jun 11, 2019 Jun 11, 2019

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jun 11, 2019 Jun 11, 2019

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jun 11, 2019 Jun 11, 2019

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jun 11, 2019 Jun 11, 2019

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jun 11, 2019 Jun 11, 2019

Copy link to clipboard

Copied

BTW, (FilePath.indexOf($.getenv('appdata'))==0) doesn't work either.

Why is it equal to 0?

Regards,

Roman

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jun 11, 2019 Jun 11, 2019

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jun 11, 2019 Jun 11, 2019

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!!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jun 11, 2019 Jun 11, 2019

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jun 12, 2019 Jun 12, 2019

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jun 12, 2019 Jun 12, 2019

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jun 13, 2019 Jun 13, 2019

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jun 13, 2019 Jun 13, 2019

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jun 13, 2019 Jun 13, 2019

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jun 13, 2019 Jun 13, 2019

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jun 13, 2019 Jun 13, 2019

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jun 13, 2019 Jun 13, 2019

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jun 13, 2019 Jun 13, 2019

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Employee ,
Jun 13, 2019 Jun 13, 2019

Copy link to clipboard

Copied

LATEST

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines