在你的drupal主题中对css进行聚合

Drupal内置的CSS聚合工作原理是,在"files/css"文件夹下,创建一个聚合文件,可以创建多个这样的聚合文件,比如当一个css文件在特定页面不需要时,而在另一个页面则用得到,这时就会新建一个聚合文件,通过$styles变量将其输出到page.tpl.php中。然而,这种方式对于部分人是行不通的,例如,将drupal运行在多台前台终端服务器上,但是却没有共享的"files"文件夹(它们可以与主服务器进行同步,而编辑则向主服务器添加内容),并且启用了缓存。在这种情况下,在部分前台终端服务器上css就显示不出来了,这是由于返回的是缓存页面,而没有检查css文件是否存在。

 

  • 用户访问服务器1,生成一个缓存页面和聚合了的css
  • 缓存页面提供给访问者,不过这次是从服务器2上提供的。
  • 而缓存页面引用的css文件在服务器2上并不存在。

 

这个问题的解决方案是,由template.php来负责css的聚合,并将css文件缓存在主题目录下(在服务器间同步时,通常将这个目录排除在外,即使你包含了这个目录,它仍然管用)。

每当用户访问一个前台终端服务器时,将会对文件名和最近修改时间应用md5函数从而创建一个字符串。如果存在了一个以该字符串为名的文件的话,将会使用这个文件,否则,将会创建一个这样的文件,并将其保存到'cache'目录下。

 

所以,首先在你的drupal主题下面创建一个名为'cache'的子目录,修改相应的权限,这样当代码执行时可以向该子目录写入文件。

 

如果你使用了Zen主题,那可可以向你子主题的template.php添加下面的代码(首先需要检查一下,这个函数是否已经存在,如果存在的话,你需要把函数声明去掉,将代码添加到函数的最底部),将STARTERKIT改为你主题的名字。

 

function STARTERKIT_preprocess_page(&$vars) {
$css = drupal_add_css();
$css_arr = array();
$modifiedDates = '';
$fileString = '';
foreach($css['all']['module'] as $css_module => $css_module_on) {
if(file_exists($_SERVER['DOCUMENT_ROOT'] . base_path() . $css_module)) {
$modifiedDates .= filemtime($_SERVER['DOCUMENT_ROOT'] . base_path() . $css_module);
$css_arr[] = $_SERVER['DOCUMENT_ROOT'] . base_path() . $css_module;
$fileString .= $css_module . ',';
}

}
foreach($css['all']['theme'] as $css_theme => $css_theme_on) {
if(file_exists($_SERVER['DOCUMENT_ROOT'] . base_path() . $css_theme)) {
$modifiedDates .= filemtime($_SERVER['DOCUMENT_ROOT'] . base_path() . $css_theme);
$css_arr[] = $_SERVER['DOCUMENT_ROOT'] . base_path() . $css_theme;
$fileString .= $css_theme . ',';
}
}
$combinedContent = '';
$fileName = base_path() . path_to_subtheme() . '/cache/' . md5($fileString . $modifiedDates) . '.css';
$file = $_SERVER['DOCUMENT_ROOT'] . $fileName;
if(!file_exists($file)) {
foreach($css_arr as $css_file) {
$combinedContent .= PHP_EOL.PHP_EOL.file_get_contents($css_file);
}
$fh = fopen($file, 'w');
fwrite($fh, $combinedContent);
fclose($fh);
}
$vars['styles_aggregated'] = '<style type="text/css" media="all">@import "' . $fileName . '";</style>';
}

 

如果你用的是一个普通的主题的话,你需要向你的template.php文件中添加以下代码(同样,存在函数已经存在的情况):

 

function  _phptemplate_variables($hook, $vars) {
   switch($hook) {
     case 'page' :
$css = drupal_add_css();
$css_arr = array();
$modifiedDates = '';
$fileString = '';
foreach($css['all']['module'] as $css_module => $css_module_on) {
if(file_exists($_SERVER['DOCUMENT_ROOT'] . base_path() . $css_module)) {
$modifiedDates .= filemtime($_SERVER['DOCUMENT_ROOT'] . base_path() . $css_module);
$css_arr[] = $_SERVER['DOCUMENT_ROOT'] . base_path() . $css_module;
$fileString .= $css_module . ',';
}
}
foreach($css['all']['theme'] as $css_theme => $css_theme_on) {
if(file_exists($_SERVER['DOCUMENT_ROOT'] . base_path() . $css_theme)) {
$modifiedDates .= filemtime($_SERVER['DOCUMENT_ROOT'] . base_path() . $css_theme);
$css_arr[] = $_SERVER['DOCUMENT_ROOT'] . base_path() . $css_theme;
$fileString .= $css_theme . ',';
}
}
$combinedContent = '';
$fileName = base_path() . path_to_theme() . '/cache/' . md5($fileString . $modifiedDates) . '.css';
$file = $_SERVER['DOCUMENT_ROOT'] . $fileName;
if(!file_exists($file)) {
foreach($css_arr as $css_file) {
$combinedContent .= PHP_EOL.PHP_EOL.file_get_contents($css_file);
}
$fh = fopen($file, 'w');
fwrite($fh, $combinedContent);
fclose($fh);
}
$vars['styles_aggregated'] = '<style type="text/css" media="all">@import "' . $fileName . '";</style>';
        break;
   }
   return $vars;
}

 

最后,在你的page.tpl.php中,注意将$styles替换为$styles_aggregated

 相关链接: http://drupal.org/node/254780 , Think in Drupal

 

Drupal版本: