css linking order different between 5.x and 6.x

fax8 - December 28, 2008 - 10:44
Project:CSS
Version:6.x-1.0-rc1
Component:Code
Category:bug report
Priority:normal
Assigned:Unassigned
Status:active
Description

CSS module version 6.x uses drupal_set_html_head() to link to css module defined rules while css module version 5.x uses drupal_add_css with type set to 'module'.

This difference implies that css rules defined trough css module will be the first one parsed in drupal 6.x while the last one in drupal 5.x.

A consequence is that in drupal 6.x users will not be able to override theme css rules while drupal 5.x users will be able to do that.

Side problem will be on upgrades from drupal 5.x to 6.x: the change of behavior will probably break some of the rules which worked correctly in drupal 5.x.

We should have a common approach in linking css module files. Any suggestion?

#1

Aaron Hawkins - December 28, 2008 - 13:40

I agree that this change in sequence presents a problem as it will prevent overrides from working on the page by page level. Is there any reason the function couldn't be switched back for 6x? As I see it drupal_add_css() is still perfectly suited for the task.

#2

fax8 - December 28, 2008 - 14:44

Unfortunately not. drupal_add_css() will only work on real files available on the file system.
(See drupal_get_css calls to file_exists($file) )

As CSS module's CSS files are dynamically generated it will not pass the file_exists check and will not be included.

#3

jchan - December 28, 2008 - 17:12

The order of the HTML header elements is determined by the theme's page.tpl.php. Mostly, it is--

    <?php print $head ?>
    <?php print $styles ?>
    <?php print $scripts ?>

So perhaps one way is for users to manually edit page.tpl.php and rearrange $head to come after $styles.

Another possibility is to add our CSS into the $scripts area. This would be a hack using drupal_add_js. We would need to add our own closing tag like in an injection attack. For example--

<?php
    $css
= "etc. etc.";
   
$css = "\n<!--//--><![CDATA[//><!--\n".'</script>'.
          
'<style type="text/css">'.$css.'</style>'.
          
'<script type="text/javascript">'."\n//--><!]]>\n";
   
drupal_add_js($css, 'inline', 'header', FALSE, FALSE, FALSE);
?>

#4

jchan - December 28, 2008 - 17:19

Sorry, there was a mistake in my last post. The code should be--

<?php
    $css
= "etc. etc.";
   
$css = "\n//--><!]]>\n".'</script>'.
          
'<style type="text/css">'.$css.'</style>'.
          
'<script type="text/javascript">'."\n<!--//--><![CDATA[//><!--\n";
   
drupal_add_js($css, 'inline', 'header', FALSE, FALSE, FALSE);
?>

#5

fax8 - December 29, 2008 - 10:09

We can't ask users to rearrange the head variable order as other modules could possibly rely on the order to implement some of them features. We should think at it like a sort of standard.

What we can do is ask the user to put some code just before the html head closing tag: it might be a call to a css module defined function which should print it's link to the css.

The drupal_add_js solution even if kind of "hacky" ... it doesn't require the user to make changes to the theme code which is a good advantage.

Anyother suggestions?

#6

Aaron Hawkins - December 31, 2008 - 12:02

If drupal_add_css requires a real css file, then why don't we actually create the file and store it in a folder in the file system? It's not that hard to actually write information to a document in php. We could use hook_nodeapi to remove the files when the nodes are deleted and to write new information to them when edited. It may be very different than the old approach, but I think it could be workable.

#7

jchan - January 1, 2009 - 21:32

Creating actual .css files in the filesystem would likely improve performance as well, since these can be fetched without accessing the database. A minor drawback is that we would lose the ability to log page views within Drupal for the virtual CSS files. Overall I think this would be a good option, although it is a big change to make at the RC stage.

Another hacky idea I had is to use drupal_add_js() to add dynamic html code to the header with Javascript. Like so--

<?php
    $css
= '<link rel="stylesheet" media="all" href="css/get/123" />';
   
drupal_add_js("document.write('$css');", 'inline', 'header', FALSE, FALSE, FALSE);
?>

But this will not work if users have disabled Javascript.

#8

tdskate - September 10, 2009 - 11:27

Why not just write the css directly into page.tpl.php at the end of the tag?

Like this:

<?php if (isset($node->css_css)) : ?>
<style type="text/css"><?php print $node->css_css ?></style>
<?php endif; ?>

#9

fax8 - September 11, 2009 - 12:38

@tdskate sure. That would fix that. But unfortunately I would like to do not require theme modifications for the end user.

The solution proposed in #4 is so far the best one. I'm going to implement that asap.

 
 

Drupal is a registered trademark of Dries Buytaert.