I've included this <img> tag, which as can be seen uses a relative path to the image, in a blog entry.

<img src="./files/blog/2006/11/20061122-005.jpg" alt="Fawkner Park (Where I start my runs)" title="" width="450" align="bottom" />

When viewing this entry on the front page, the image appears http://superjacent.net/cms/node?page=2 (scroll down a bit, it's the only image on the page).

When viewing the particular post (http://superjacent.net/cms/node/425) only the 'alt' text is shown.

Am I doing something wrong. Do I have to use an absolute path to display the image in both views.

Any advice appreciated.

Steven Taylor
Melbourne Australia

Comments

Aristide’s picture

Hi Steven,
Just had the same issue this morning when I was adding a few pictures to a post. Of course it works with the absolute url, but I wanted something relative, which is cleaner.
My site is in a directory "/mydrupal" under httpdocs.
My pictures are in /mydrupal/files/pix.
Here's a copy/paste of the relative path I use to 'mypicture.jpg' :
img src="/mydrupal/files/pix/mypicture.jpg"
(add the necessary attributes for alt etc...)
and that seems to works fine.
I hope this is of some help.
A.

NikLP’s picture

The above will break if you move your Drupal installation up or down in the directory hierachy! Fixing hard coded urls isn't too much fun over hundreds of pages...!

Basically you should be adding pics to your posts using the image module, I think. This will look after your paths for you. I reckon you should only be using paths manually if you're editing CSS. This can easily be maintained using relative urls, as the relation between the template files and the images within the theme directory will not change.

superjacent’s picture

I've actually imported across from two blogging systems 460 odd posts. I manually (search and replace) edited all the image links, stripping out the domain name bit and leaving what I thought was a correct relative path starting with "./files/.......". The use of the image module (haven't installed it yet) wasn't an option at that point.

For what it's worth, initially I had my Drupal set up in the root of the domain and everything appeared to be correct as I could see images on the front page. I've since moved Drupal to a sub-folder "/cms".

My sub-folder "/cms" is actaully a 'link' folder pointing to 'drupal-5'. Surely this wouldn't or shouldn't be a problem.

Any clues.

___________________________

Steven Taylor
Melbourne, Australia.

Chill35’s picture

This should be documented clearly, and underlined, for anyone installing Drupal. To prevent considerable amount of energy wasted.

You cannot use relative paths in your nodes' content and have clean URL turned on in Drupal at the same time.

There are a few ways to get around the problem, but no ideal way :

  • Use a contributed module and write a marco, some sort of placeholder, that only drupal will be able to read, for the absolute path "part" of links...
  • Write (as admin) your content in php, and use the Drupal function base_path()... Again a solution that makes content only readable by Drupal.

With these "solutions" you will be able to move your web site around. I understand now that you are testing locally, hence you cannot make a domain point to a subdirectory... For cases where you move you web site from domain to domain, the absolute path would remain the same : /files/... for example.

Here is a thread that may interest you :

http://drupal.org/node/106608

Caroline

superjacent’s picture

Thanks Caroline.

I've just turned off Clean URL's and now my relative paths work, in both views.

Thanks for the reference to http://drupal.org/node/106608.

__________________________

Steven Taylor
Melbourne, Australia.

Chill35’s picture

This will look after your paths for you. I reckon you should only be using paths manually if you're editing CSS. This can easily be maintained using relative urls, as the relation between the template files and the images within the theme directory will not change.

That's an important point you're making here. In CSS files, relative path are relative to the .css file, always. Links are not relative to the file that's linking in the stylesheet.

sepeck’s picture

Image module paths can be found here: http://drupal.org/node/47357

I think the path to the /files directory is relative to your Drupal install root.

-Steven Peck
---------
Test site, always start with a test site.
Drupal Best Practices Guide -|- Black Mountain

-Steven Peck
---------
Test site, always start with a test site.
Drupal Best Practices Guide

Chill35’s picture

<img src="./files...

How does a link starting with a dot function exactly ? I know about the two dots .. meaning "go up to the parent folder" but I am ignorant about the single dot notation.

Caroline

VM’s picture

What are relative URLs?
Put simply, it's an URL which needs some processing before it is valid. It is a local URL, from which certain information is left out. Often this means some directory names have been left off, or the special sequence ../ is being used.

The "relative" comes from the fact that the URL is only valid relative to the URL of the current resource.

Resolving relative URLs
As said, a relative URL needs the URL of the current resource to be interpreted correctly. With some simple manipulations, the relative URL is transformed into an absolute URL, which is then fetched as usual.

A relative URL is always a local URL. The first part is therefore always the same as that of the current URL. The relative URL is then turned into an absolute local URL with the following simple steps:

Omit the filename of the current absolute local URL, if it's not a directory URL.
For every ../ at the beginning of the relative URL, chop off one directory name from the current directory URL.
Append the local URL to the current one.
A few simple examples
In these examples, we assume that the full URL of the current document is

http://www.foo.com/users/galactus/index.html

Relative URL: myessay.html
The full URL for this relative URL is http://www.foo.com/users/galactus/myessay.html

Relative URL: pics/background.gif
The full URL for this relative URL is http://www.foo.com/users/galactus/pics/background.gif

Relative URL: ../cgi-bin/myscript.pl.
The full URL for this relative URL is http://www.foo.com/users/cgi-bin/myscript.pl

Note that it is not necessarily true that the ../ bit in a relative URL refers to going "up" one directory on the server. It may often be the case, since that's the most simple and common way to do it, but the ../ applies to the URL, not the actual directory tree on the server.

As you can see in the last example, it is quite possible that ../ ends you in a totally different directory on the server

How does a link starting with a dot function exactly ?

In most cases, figuring the absolute URL from a relative URL is just a matter of concatenating the base URL and the relative URL, as in the example above. There are, however, a few special cases:

A directory called .. (two periods) in a relative URL indicates the parent directory, essentially stripping off everything up to the previous slash in the the Base URI. Note that this only has meaning inside the pathname, so you cannot use this notation to go up higher than the root directory.

A directory called . (one period) refers to the current directory.

A relative URL that begins with / (a slash) always replaces the entire pathname of the base URL.

A relative URL that begins with // (two slashes) always replaces everything from the hostname onwards.

Chill35’s picture

Thanks a lot Misunderstood!

Note that it is not necessarily true that the ../ bit in a relative URL refers to going "up" one directory on the server. It may often be the case, since that's the most simple and common way to do it, but the ../ applies to the URL, not the actual directory tree on the server... [...] Note that this only has meaning inside the pathname, so you cannot use this notation to go up higher than the root directory.

That's good to know, even for Drupal...

For example, if I am relative to the clean url http://www.mywebsite/node/6/edit, the link ../../node/7 certainly does not mean that I am to move up actual folders.

A directory called . (one period) refers to the current directory.

I guess I had never seen the lonely dot before because these two are equivalent :

src="./files/blog/2006/11/20061122-005.jpg"
src="files/blog/2006/11/20061122-005.jpg"

Please correct me if I am wrong.

VM’s picture

to see ./ in action you would have to look at Drupal core files. index.php and includes/bootstrap.inc are examples where ./ is being referenced.

I hesitate to claim they are exactly the same. I've come across servers and other software where ./ was being stored, which forced everything relative to the index.php of the program. Drupal may be doing this as well. I haven't dug far enough into the code, but I do not recall setting ./ at installation time. I suppose it could be assumed by drupal as well, to make users lives a little easier with paths.

Maybe someone else can jump in here and confirm/deny this.

shunting’s picture

In D6, Drupal would turn this in post content:

href="blah/foo"

into

href="http://www.example.com/node/blah/foo" (with clean URLs on, I'm assuming because that's the "front page" setting).

which would break because there's nothing at that resource.

However:

href="../blah/foo"

chops off the "node/" and now my relative paths work in post content!

NOTE My use case is documenting a Drupal module in Drupal posts, so it was important to me that this work; I couldn't use the drupal l() function.

http://www.universalpantograph.com

Tandaemonium’s picture

After implementing Clean URLs, I had this exact problem.

I like to use a subdirectory for all my css files and images and whatever else so as soon as I uncommented RewriteBase, only the front page could reference the needed files correctly and any other pages within the sites had their relative paths all aldksjf;lasdkjf;...

So anyways, previously I used <? php print $directory ?> before any paths to any of my theme files.

Now I've added <? php print $base_path ?> in front of that token.

For example:

  <link rel="stylesheet" href="<?php print $base_path ?><?php print $directory ?>/css/global.css" />

or

  <img id="logo" src="<?php print $base_path ?><?php print $directory ?>/images/site_logo.png" alt="Site Logo" />

I'm not 100% satisfied with this method but it's fine and requires nothing else more than just the uncommenting of RewriteBase as far as Clean URLs are concerned.

I DID NOT want to do anything with ./, ../, etc. That's not right...especially the deeper into your site you'd go.

This reply is totally like 2 years later but hopefully it is of some help to someone.

resolv_25’s picture

Unfortunately, Drupal handles relative path on different way.
I added a php code to find out what is the absolute path, and I added code like this in the page:

echo realpath(dirname(__FILE__));

And path was: /var/www/drupalsite/includes
So, I added a relative path for a picture as:

<img src="../sites/default/files/pic1.jpg" />

This is a way around.

rahul_sankrit’s picture

Convert full Image URLs to relative URLs.

/**
 * Implements hook_file_url_alter().
 */
function mymodule_file_url_alter(&$uri) {
    global $base_path;

    $scheme = file_uri_scheme($uri);

    // If the file uses the public scheme,
    if ($scheme == 'public') {
        $wrapper = file_stream_wrapper_get_instance_by_scheme($scheme);
        // Get the file's path
        $path = $wrapper->getDirectoryPath() . '/' . file_uri_target($uri);
        // Set the URL to the (relative) base path plus the file's path
        $uri = $base_path . $path;
    }
}