tags:

views:

97

answers:

3

For example, I want to join a prefix path to resource paths like /js/foo.js.

I want the resulting path to be relative to the root of the server. In the above example if the prefix was "media" I would want the result to be /media/js/foo.js.

os.path.join does this really well, but how it joins paths is OS dependent. In this case I know I am targeting the web, not the local file system.

Is there a best alternative when you are working with paths you know will be used in URLs? Will os.path.join work well enough? Should I just roll my own?

+6  A: 
>>> import urlparse
>>> urlparse.urljoin('/media/', 'js/foo.js')
'/media/js/foo.js'

Note that you will get different results from /js/foo.js and js/foo.js because the former begins with a slash which signifies that it already begins at the website root.

Ben James
So I have the strip off the leading "/" on /js/foo.js, but it seems that would be the case with os.path.join too. Requiring the slash after media means I have to most of the work myself anyway.
amjoconn
Specifically once I have that the prefix has to ends in / and that the target path can't begin in / I might as well just concatenate. In this case I am not sure if urljoin is really helping?
amjoconn
+1  A: 

The basejoin function in the urllib package might be what you're looking for.

basejoin = urljoin(base, url, allow_fragments=True)
    Join a base URL and a possibly relative URL to form an absolute
    interpretation of the latter.

Edit: I didn't notice before, but urllib.basejoin seems to map directly to urlparse.urljoin, making the latter preferred.

mwc
A: 

Since, from the comments the OP posted, it seems he doesn't want to preserve "absolute URLs" in the join (which is one of the key jobs of urlparse.urljoin;-), I'd recommend avoiding that. os.path.join would also be bad, for exactly the same reason.

So, I'd use something like '/'.join(s.strip('/') for s in pieces) (if the leading / must also be ignored -- if the leading piece must be special-cased, that's also feasible of course;-).

Alex Martelli
Thanks. I didn't mind so much requiring that the leading '/' on the second part couldn't be there, but requiring the trailing '/' on the first part make me feel as if in this use case urljoin wasn't doing anything for me. I would like at least join("/media", "js/foo.js") and join("/media/", "js/foo.js") to work. Thanks for what appears to be the right answer: roll your own.
amjoconn