PDA

View Full Version : Relative File Paths


jurgmay
April 4th, 2010, 07:32 AM
Hi there,

I'm wondering if FusionPro allows the use of relative file paths so that I don't have to hard-code them.

At the moment all my resources have to be placed inside the same folder as my template file which I'd like to avoid. What I'd like to do is have a folder within my template's parent folder titled 'Resources'. In my code I would reference it something like '~/Resources/' where the ~ will be the path to the parent folder of my template file.

Ideally my folder structure would be something like...

TEMPLATE FOLDER (Parent Folder)
INPUT (Child of TEMPLATE FOLDER)
OUTPUT (Child of TEMPLATE FOLDER)
RESOURCES (Child of TEMPLATE FOLDER)

All my resources would be places in the RESOURCES folder and all output files would appear in the OUTPUT folder.

It seems though that I have to either set the Search Path (through Compose > Advanced) or hard code the FULL file path. Both of these options mean I have to determine a static path rather than a dynamic one.

Essentially I'd like to replace "C:\\Folder 1\\Folder 2\\Template Folder\\" with something like PathToMe which would return the path to the FusionPro template file.

I hope it's clear what I'm trying to achieve.

Many thanks,

Juergen

esmith
April 5th, 2010, 05:28 AM
I typically keep my FP template in the parent folder and have a child folder for my resources. I create a relative path in that scenario as a JavaScript Global variable that I can reference in my various rules.

Regardless of where you choose to put your template file, relative paths should work for you as well (i.e. "..\\RESOURCES\\").

jurgmay
April 5th, 2010, 06:20 AM
Hi Eric,

Thanks for the reply.

I've just tried adding a relative folder path to JavaScript Globals
gOutputFolder = "..\\OUTPUT\\";

and in the OnNewOutputFile Callback rule I have the following code...


if (!FusionPro.Composition.isPreview)
{
fileName = (FormatDate(Today(), "ddMM ") + productNames[ProductID]);
FusionPro.Composition.outputFileFullPathName = gOutputFolder + fileName;
}


(Ignore the 'productNames[ProductID]' part - it's simply referencing an array to construct the filename)

If I compose, the file is saved at the root level of the hard drive?! I've checked to make sure that a folder titled OUTPUT exists in the template's parent folder so don't understand why the file is being saved where it is.

This is the sort of behaviour that prompted me to post on the forum as I'd exhausted all the possibilities I could think of!

Any clues?

Thanks,

Juerg

jurgmay
April 5th, 2010, 06:28 AM
Just a thought - do you think it matters that I'm testing this on a Mac? The template will ultimately be used on a PC but I often do the programming at home on a Mac...

jurgmay
April 5th, 2010, 07:06 AM
Very weird! Just noticed that the file is being saved in the FusionPro application folder!!! I've attached a screenshot...

Juerg

esmith
April 5th, 2010, 08:18 AM
The mac does use a different separator for path names. I didn't realize you were on a Mac based on your signature. In my globals, the rule I use is:
var gOutputFolder = (FusionPro.isMac) ? "..::OUTPUT:" : "..\\OUTPUT\\";

jurgmay
April 5th, 2010, 08:31 AM
I assumed that FP used standard delimiters in file paths. Curious why it doesn't?!

Anyway, I'm now getting the attached error!

Seems I'm destined to be chasing my tail on this one! :confused:

esmith
April 5th, 2010, 09:04 AM
Your latest JPEG only shows one colon preceding the OUTPUT folder although I don't know if that alone is the issue. What happens if you place the template in the parent folder and change the output path to "::OUTPUT:"?

jurgmay
April 5th, 2010, 09:37 AM
Hi Eric,

I get the same error message, it just shows to colons instead of one. I changed it because I assumed it was incorrect when it first threw the error.

At the moment I have a folder called FIC. Within this folder is my template file along with all associated files .cfg, .def, .dif etc. as well as all the graphic resources. Finally I have a folder titled OUTPUT which I'm trying to put my output file in.

Does this sound like the correct structure?

Thanks for your help so far - much appreciated!

Juerg

esmith
April 5th, 2010, 09:53 AM
I see nothing wrong with your file structure. Will the structure (or the relative location) change once the template is being used on the PC?

Here is where I posted my own solution for a similar problem (http://forums.printable.com/showthread.php?t=1254&highlight=relative+path) which is why I'm somewhat baffled that your scenario is proving harder to solve.

Of course, I have never used this information in conjunction with an output file name; only for pulling in resources. I wonder of an absolute path is required by the outputFileFullPathName object?

Dan Korn
April 5th, 2010, 11:10 AM
Let me try to clear up a few things.

First, you can use "regular" DOS- or UNIX/POSIX-style path specifications to denote paths in FusionPro, on any platform. So "../OUTPUT/" will work fine, as will "..\OUTPUT\"; however, in the latter case, if you're defining that as a string literal in JavaScript, you need to escape the backslashes, i.e. "..\\OUTPUT\\" since those have a special meaning in JavaScript code. The HFS-style paths with colons will work too, but relative paths with multiple colons get complicated and confusing. So I would just stick with POSIX-style forward slashes ala "../OUTPUT/" and your life will be simpler.

Next, you can definitely use relative paths in FusionPro, to access just about anything. Relative paths will be resolved in this order at composition time:


The current working directory (mainly for FP Server jobs)
The input file location
The format file location (the template PDF for FP Desktop or the .DIF file for FP Server)
The user-defined Search Path (set on the "Advanced" tab of the Composition Settings dialog in FP Desktop)


Finally, while relative paths can be used and will be resolved as above, this only applies to files that already exist. For a file doesn't already exist on disk, FusionPro will only resolve a relative path based on the current working directory, which is really only relevant in certain FP Server workflows. So you can't really create your output file in a relative location like this in FP Desktop, at least not directly. However, you can use a workaround like so:
FusionPro.Composition.outputFileFullPathName = FusionPro.ResolveFile(".") + "/" + gOutputFolder + fileName;Note that the folder must already exist.

esmith
April 5th, 2010, 11:25 AM
Thanks for chiming in Dan. I just wish you could be available 24/7.
Next, you can definitely use relative paths in FusionPro, to access just about anything. Relative paths will be resolved in this order at composition time:


The current working directory (mainly for FP Server jobs)
The input file location
The format file location (the template PDF for FP Desktop or the .DIF file for FP Server)
The user-defined Search Path (set on the "Advanced" tab of the Composition Settings dialog in FP Desktop)

In the case of FP Server, how would it work for the .dif file to be somewhere other than the template file itself? Do you just manually move it, or does something internal to the template need to point to an alternate location?

Dan Korn
April 5th, 2010, 11:34 AM
In the case of FP Server, how would it work for the .dif file to be somewhere other than the template file itself? Do you just manually move it, or does something internal to the template need to point to an alternate location?
Well, if you're using FP Server, the files can be anywhere you like, and you can specify either relative or absolute paths in the command-line parameters or CFG file settings. For instance, the .DIF file may have been generated by the DIF API in a network location which you could reference via a UNC path. But things will still work if everything is in the same folder too. It all depends on how you design your custom application which uses FP Server.

If you have FP Server-specific questions, feel free to post them in the FusionPro Server forum (http://forums.printable.com/forumdisplay.php?f=8).

jurgmay
April 5th, 2010, 12:52 PM
Guys - thanks for your input. I felt that this should be an easier problem to solve that it's proved!

Dan - just one thing if I may...

So you can't really create your output file in a relative location like this in FP Desktop, at least not directly. However, you can use a workaround like so:
FusionPro.Composition.outputFileFullPathName = FusionPro.ResolveFile(".") + "/" + gOutputFolder + fileName;Note that the folder must already exist.


Can you explain how this works please? It's just that if I set gOutputFolder to "../OUTPUT/" a folder named OUTPUT is created in the parent folder of the parent folder of the template?! For example: I have a folder on the Desktop called FIC. Inside this is my template and resources and a folder called OUTPUT. When I run the composition, rather than the output file appearing in FIC > OUTPUT it actually creates a new folder on the Desktop and puts the file in there! If I only put one . in front of /OUTPUT/ it works fine. I'm just not sure why!

Out of interest, is there a reason why FP supports so many different conventions? If POSIX is the easiest cross-platform format then why not support just that one format?

Thanks so much to you and Eric for your help on this.

Regards,

Juerg

Dan Korn
April 5th, 2010, 04:53 PM
Can you explain how this works please? It's just that if I set gOutputFolder to "../OUTPUT/" a folder named OUTPUT is created in the parent folder of the parent folder of the template?!
Okay, some of the subtleties here depend on your exact operating system version. It's not clear to me which OS you're running. Your signature says, "FusionPro Desktop 6.1P1e Windows," and your original post mentioned "C:", which indicates Windows as well, but the screen-shot you attached is obviously from a Mac.

On Windows, a folder that doesn't already exist is generally not created, but on Mac it may be (depending on the version of OS X, the folder permissions, and some other things.) (The reasons for this different Windows and Mac functionality are complicated and have to do with low-level Carbon file handling routines on Mac which have been patched to work with POSIX paths; I'll just say that it would be more difficult to make it NOT work on Mac to match Windows than to just recommend that the folder already exist on both platforms.)

At any rate, I would recommend making sure that the folder exists first.
For example: I have a folder on the Desktop called FIC. Inside this is my template and resources and a folder called OUTPUT. When I run the composition, rather than the output file appearing in FIC > OUTPUT it actually creates a new folder on the Desktop and puts the file in there! If I only put one . in front of /OUTPUT/ it works fine. I'm just not sure why!
I'm not understanding exactly what you're doing in the case that doesn't work.
Out of interest, is there a reason why FP supports so many different conventions? If POSIX is the easiest cross-platform format then why not support just that one format?
Well, we run on both Windows and Mac, and both platforms support multiple path formats, so limiting to a subset of those formats would not only be more complicated for us to program, but would also, arguably, be more confusing to users who are used to dealing in various path formats.

It's also a historical/backwards-compatibility thing: when FusionPro (actually its predecessor DL Formatter) started out, it only ran on Windows, which used DOS paths, and then we ported to Mac OS 9, which used HFS paths (with colons), and then OS X came along with POSIX paths, and meanwhile newer versions of Windows came along which added support for using POSIX-style forward slashes as well as DOS-style backward slashes. And we don't want older jobs with the older path specifications to just stop working and break existing customers' jobs. So as in many other areas, we have to keep one foot in "legacy" specifications while at the same time supporting the newest fancy thing that Microsoft or Apple or Adobe decides that everyone should port to.

That said, at this point in time, for new jobs, I would recommend using POSIX-style paths (with forward slashes) on both Windows and Mac.

tsghost
April 6th, 2010, 05:38 AM
I run on a Mac, no server.
I put my template in one folder and then create another folder which I put my DATA file and all my resources.
I do not have any problems or have to create any paths to my resources.
Seems as if FusionPro assumes the resources have the same path as the DATA file.

Not sure if this will help but thought I would throw it out there.

esmith
April 6th, 2010, 06:11 AM
Can you explain how this works please? It's just that if I set gOutputFolder to "../OUTPUT/" a folder named OUTPUT is created in the parent folder of the parent folder of the template?! For example: I have a folder on the Desktop called FIC. Inside this is my template and resources and a folder called OUTPUT. When I run the composition, rather than the output file appearing in FIC > OUTPUT it actually creates a new folder on the Desktop and puts the file in there! If I only put one . in front of /OUTPUT/ it works fine. I'm just not sure why
One dot (.) indicates current directory so ./OUTPUT indicates you are looking for the OUTPUT folder within the directory your template is located.

Two dots (..) indicates to go up one level from the current directory so ../OUPUT indicates you are going to the parent folder of your current directory (the Desktop in your case) and looking for OUTPUT at the same level as the folder your template is in.

So if you had a directory structure like so:
DESKTOP
-- FIC
---- INPUT
---- DATA
-- ABC
---- OUTPUT
-- XYZ

and you were in the FIC/INPUT folder, you could navigate to ABC/OUTPUT via a relative path, "../../ABC/OUTPUT". Confusing enough? ;)

jurgmay
April 6th, 2010, 07:36 AM
One dot (.) indicates current directory so ./OUTPUT indicates you are looking for the OUTPUT folder within the directory your template is located.

Two dots (..) indicates to go up one level from the current directory so ../OUPUT indicates you are going to the parent folder of your current directory (the Desktop in your case) and looking for OUTPUT at the same level as the folder your template is in.

So if you had a directory structure like so:
DESKTOP
-- FIC
---- INPUT
---- DATA
-- ABC
---- OUTPUT
-- XYZ

and you were in the FIC/INPUT folder, you could navigate to ABC/OUTPUT via a relative path, "../../ABC/OUTPUT". Confusing enough? ;)

Actually Eric this makes perfect sense and I really appreciate the time you've taken to help me out with this. I am now 100% clear on how I need to handle paths to suit my needs. I may be wrong but I just don't see this in the documentation anywhere - would be a very useful addition for a future release (Dan - you reading this? ;))

Thanks again,

Juerg

esmith
April 6th, 2010, 07:46 AM
I may be wrong but I just don't see this in the documentation anywhere - would be a very useful addition for a future release
I think it's not in the FP documentation because it's a generic (albeit advanced) concept for computing. Including all the general computing and JavaScript coding examples would make for a daunting challenge. Plus, between the internet and these forums, most of the questions you might have are covered. One area that I think Dan already knows needs better documentation is for scripting objects/properties which are unique to FP (like ResolveFile) which we have no way of knowing about unless they pop up on the forums in a thread like this.

(Dan - you reading this? ;))

jurgmay
April 6th, 2010, 07:46 AM
Okay, some of the subtleties here depend on your exact operating system version. It's not clear to me which OS you're running. Your signature says, "FusionPro Desktop 6.1P1e Windows," and your original post mentioned "C:", which indicates Windows as well, but the screen-shot you attached is obviously from a Mac.

I am now using both and will update my signature accordingly.

On Windows, a folder that doesn't already exist is generally not created, but on Mac it may be (depending on the version of OS X, the folder permissions, and some other things.) (The reasons for this different Windows and Mac functionality are complicated and have to do with low-level Carbon file handling routines on Mac which have been patched to work with POSIX paths; I'll just say that it would be more difficult to make it NOT work on Mac to match Windows than to just recommend that the folder already exist on both platforms.)

OK, got that. Thanks for the explanation.

I'm not understanding exactly what you're doing in the case that doesn't work.

No worries. I thought it was clear enough but Eric has offered an explanation to this query and I now understand exactly how things work.

Just out of interest - is there anything about file paths in the documentation? I looked and looked and couldn't see anything there that really explained it fully. I'm sure the answers I've got from yourself and Eric could be of real benefit to all FP users.

Anyway, thanks for your patience and your clear explanations. I've learnt so much already from this forum especially from people like yourself and Eric and just wanted to say 'Thanks!' :)

Regards,

Juerg

Dan Korn
April 6th, 2010, 03:55 PM
I am now using both and will update my signature accordingly.
It still just says Windows, but feel free to go ahead and change it. Although my suggestion to put the version information in your signature is mainly targeted to users who are only on one platform, which is the most common scenario. In any case, when you're reporting an issue or asking a question, you should still specify the specific OS and FusionPro versions related to what you're posting, especially if your signature is going to list more than one version.
Just out of interest - is there anything about file paths in the documentation? I looked and looked and couldn't see anything there that really explained it fully. I'm sure the answers I've got from yourself and Eric could be of real benefit to all FP users.
Well, I'm not sure about all users. This specific functionality of renaming your output file in JavaScript is an advanced feature which I would be surprised if a lot of people were using. And I'm also not sure that basic knowledge of how path specifications work, i.e. how many dots you need to denote a relative path, is something that needs to go in the product documentation.

In fact, you don't even need to specify a path at all (relative or absolute) to accomplish what you're doing here. Instead of specifying a path and file name with FusionPro.Composition.outputFileFullPathName, you can simply set the file name with FusionPro.Composition.outputFileName, and the output will go into the same folder as the output file specified in your composition settings. For instance:
FusionPro.Composition.outputFileName = fileName;Now, going back to your original post, which was not really about changing the output file name in a rule as much as it was about just generally working with relative paths for things like resources, yes, there could be more clarification in the documentation about what kinds of relative path formats to use, if necessary. However, in a case like the example in your first post, you don't need any relative path specification there either. Let's go back to your original question:
At the moment all my resources have to be placed inside the same folder as my template file which I'd like to avoid. What I'd like to do is have a folder within my template's parent folder titled 'Resources'. In my code I would reference it something like '~/Resources/' where the ~ will be the path to the parent folder of my template file.

Ideally my folder structure would be something like...

TEMPLATE FOLDER (Parent Folder)
INPUT (Child of TEMPLATE FOLDER)
OUTPUT (Child of TEMPLATE FOLDER)
RESOURCES (Child of TEMPLATE FOLDER)

All my resources would be places in the RESOURCES folder and all output files would appear in the OUTPUT folder.

It seems though that I have to either set the Search Path (through Compose > Advanced) or hard code the FULL file path. Both of these options mean I have to determine a static path rather than a dynamic one.
That's not entirely true. If you merely want to reference resources in a subfolder of your template folder, all you need to do is type that folder's name in the "Search Path" box on the Advanced tab of the Composition Settings dialog. Not a relative path with dots and slashes and such, just the folder name, i.e. "RESOURCES". That's all you need. Then any calls to file names in functions like CreateResource will automatically search that folder. The key here is that "RESOURCES" is a relative path; it's the same as "./RESOURCES" (or ".\RESOURCES", or even ":RESOURCES" in the old HFS-style specification on Mac).

You can also type other relative path specifications in the "Search Path" box. For instance, typing "../RESOURCES" there will reference a folder that's a sibling of your template folder. And ".." will reference the parent folder of your template folder.

Note also that you can enter multiple paths in the "Search Path" box, using semicolons to delimit them. So you can type something like "Graphics;../Graphics;../data" and all of those folders will be searched, in order (after the input and format/template file folders, which are always searched first, as I noted in my previous post).

We designed FusionPro to make it easy to locate resources and things without having to write any code or type path specifications, while still providing hooks for users who need more advanced functionality. (And for users with highly advanced requirements, we recommend FusionPro Server, which allows even more control over every aspect of the job through CFG file settings and other parameters than FusionPro Desktop.)

So again, to access resources from a subfolder of your main template folder, all you need to do is type that folder's name in the "Search Path" box. You don't need any dots or slashes or colons. For the output file, that's a little more complicated because you do need some JavaScript, but as noted previously, if that's also going into a subfolder of your template folder, you still don't need to type any dots or colons for that. So the whole thing about how many dots or colons or slashes goes away, and there's no need to document any specific path formats.

jurgmay
April 7th, 2010, 03:02 AM
Dan - thanks once again for such a clear explanation.

I now feel completely informed about how FP handles paths and the way it references files. Very interesting to learn that I don't even need to use relative paths in the way I had assumed.

Please forgive me for banging on about the documentation - and I promise this is the last time I mention it - but I really think a brief explanation could be included.

Let me give some examples...

At the bottom of page 101 of the Rules System Guide it shows the following code -

FusionPro.Composition.outputFileFullPathName = "C:\\path\\"
+ Field("name") + ".pdf"

The code and accompanying text imply that you need to hard-code the file path. I just think that an extra few lines condensing your last post would be really beneficial here.

Also in the section 'Help! The name of my graphics folder changed' on page 107 it mentions adding paths to the Composition Settings as you suggest but again it implies that you must hard-code the FULL path.

Do you see why I made the assumptions that I did? I'm just trying to point out to you how and why I thought I had to hard-code the paths. Whether you guys change the documentation or not makes no difference to me now but it could have saved a lot of time for myself, you and Eric if it was explained a bit more clearly. Also note that the two references above are in the 'Tips and Tricks' section which I think it's fair to say is what many would consider a more 'Advanced' section.

Anyway, look, I'm not after a debate - I'm sure we both have better things to do! In fact I'll make this my last post on the subject of documentation but I just wanted you to understand where I'm coming from and hopefully you'll see that I'm not just being deliberately awkward about this.

Thanks once again for all your input and clarifications.

Best wishes,

Juerg

Dan Korn
April 7th, 2010, 10:20 AM
Thanks Juerg. I have entered case FP-11390 requesting that the documentation be updated to address the issues you've brought up. Sorry if I seemed argumentative; your concerns are completely valid. Thanks especially for those specific examples. Your continued feedback is appreciated and will help us to improve the product. Hopefully this forum will help to fill in some of the documentation gaps as well, so keep asking questions!

jurgmay
April 7th, 2010, 12:10 PM
Thanks Juerg. I have entered case FP-11390 requesting that the documentation be updated to address the issues you've brought up. Sorry if I seemed argumentative; your concerns are completely valid. Thanks especially for those specific examples. Your continued feedback is appreciated and will help us to improve the product. Hopefully this forum will help to fill in some of the documentation gaps as well, so keep asking questions!

Dan - really no need to apologise. I'm glad the examples helped explained why I came to those conclusions and if it helps improve the documentation for other users then that's great.

Anyway, I've got the answers I was looking for thanks to yourself and Eric - and yes, I will certainly be asking more questions! (I have a few lined up already!)

Cheers for now,

Juerg

jshobar
July 13th, 2011, 04:06 PM
Does anyone know if relative paths will work with paths to external data files?


matrix = new ExternalDataFileEx("/Users/UserA/Jobs/L142/Data/L142_matrix.txt", "\t")

matrix = new ExternalDataFileEx("../Data/L142_matrix.txt", "\t")

The former works, the latter does not.

I'm running 7.2 on OS X and my folder structure is:

-Jobs
--L142
---L142_Job.pdf
--Data
---datafile.txt
---L142_matrix.txt

Dan Korn
July 14th, 2011, 11:14 AM
Does anyone know if relative paths will work with paths to external data files?
Yes, the Frodo Travel Tutorial uses a relative path with ExternalDataFileEx.
matrix = new ExternalDataFileEx("/Users/UserA/Jobs/L142/Data/L142_matrix.txt", "\t")

matrix = new ExternalDataFileEx("../Data/L142_matrix.txt", "\t")

The former works, the latter does not.

I'm running 7.2 on OS X and my folder structure is:

-Jobs
--L142
---L142_Job.pdf
--Data
---datafile.txt
---L142_matrix.txt
The path should be relative to the input data file. If the external file is in the same folder as the main input data file, then you don't need any path at all, just the file name.

jshobar
July 15th, 2011, 11:13 AM
Thanks Dan! I wrongly thought it was relative to the PDF file, not the input file. Thanks for the clarification.