css aggragation breaks urls in theme css file

mariuss - September 4, 2007 - 00:38
Project:Drupal
Version:5.7
Component:base system
Category:bug report
Priority:normal
Assigned:Unassigned
Status:duplicate
Description

If you have URLs that are relative to the server root then CSS aggregation will break these URLs.

For example, in your theme CSS you can reference a background image like this:
background-image: url(/theme/images/Footer.gif);

Since the URL starts with a / it is relative to the server root.

When you enable CSS aggregation this is rewritten and becomes:
background-image: url(/sites/example.com/themes/example//theme/images/Footer.gif);

and results in a 404

URLs that start with / should not be rewritten.

A workaround is to use a relative URL in your CSS. Assumin the above images folder is in the theme folder then you can write:
background-image: url(images/Footer.gif);
and this gets rewritten properly to:
background-image: url(/sites/example.com/themes/example/images/Footer.gif);

Another workaround is to use the full URL, including protocol and server name:
background-image: url(http://example.com/theme/images/Footer.gif);

In this example /theme is a web server alias to /sites/example.com/themes/example, but there could be other cases when you want a URL to start with a /.

#1

mariuss - September 6, 2007 - 00:55

The code that rewrites the URLs in aggregated CSS files is in drupal_build_css_cache, in the includes/common.inc file:

<?php
         
// Fix all paths within this CSS file, ignoring absolute paths.
         
$data .= preg_replace('/url\(([\'"]?)(?![a-z]+:)/i', 'url(\1'. $path . '\2', $contents);
?>

The regular expression avoids URLs starting with a protocol, (?![a-z]+:), but not URLs starting with /.

#2

dvessel - September 8, 2007 - 02:45
Priority:critical» normal

I'd consider this a bug but in what situation would an absolute path be needed?

#3

mariuss - September 8, 2007 - 05:36

Couple of examples:
- your site is installed at http://example.com/drupal/ and you want to use images from http://example.com/images/
- in order to avoid long paths like /sites/example.com/theme/mytheme/images/ in apache you have an alias called /theme that points to /sites/example.com/theme/mytheme/

But this is really besides the point. The fix is trivial:

<?php
         
// Fix all paths within this CSS file, ignoring absolute paths.
         
$data .= preg_replace('/url\(([\'"]?)(?![a-z]+:|\/)/i', 'url(\1'. $path . '\2', $contents);
?>

#4

Jorrit - January 12, 2008 - 19:33

That fix will turn
background: url('/static/bg_menu.gif') repeat-y;
into
background: url(/drupal5/sites/all/themes/travelhome/'/static/bg_menu.gif') repeat-y;

For me this works:
$data .= preg_replace('/url\(([\'"]?)(?![\'"]?(?:[a-z]+:|\/))/i', 'url(\1'. $path . '\2', $contents);

There is some repetition, but apparently preg is not greedy enough, it will not match the first ([\'"]?), even when there is a '.

(Tested with Drupal 5.6, PHP 5.2.5 on Gentoo for both absolute urls with / and http:// in front, and relative urls)

#5

Jorrit - April 12, 2008 - 09:10
Version:5.2» 5.7
Status:active» needs review

Perhaps it will only be fixed when someone provides a patch ...

AttachmentSizeStatusTest resultOperations
css-aggregation.patch823 bytesIgnoredNoneNone

#6

drumm - May 13, 2008 - 04:42
Status:needs review» duplicate

http://drupal.org/node/113607 already more-throughly solved this in Drupal 6.x.

#7

mariuss - May 22, 2008 - 23:29
Status:duplicate» needs review

If it was fixed in Drupal 6 then this cannot be a duplicate. Drupal 5 still has an issue.

#8

Damien Tournoud - May 22, 2008 - 23:33
Status:needs review» duplicate

This will be solved by partially backporting #113607: Import @import commands when building CSS cache.

 
 

Drupal is a registered trademark of Dries Buytaert.