CSS and JS for Cached Blocks (drupal_add_css incompatible with blocks)

IcyAndy - January 27, 2008 - 22:11
Project:Drupal
Version:7.x-dev
Component:block.module
Category:bug report
Priority:normal
Assigned:Unassigned
Status:active
Description

The way event.css is added does not work when block caching is enabled (event.css is missing when the calender block is displayed for anonymous user when block caching is on)

Solution: implement hook_init and add the css files there with drupal_add_css

#1

killes@www.drop.org - February 9, 2008 - 07:49

ugly solution, I need o think of something else.

#2

IcyAndy - February 10, 2008 - 13:36

The drupal api states this about hook_init:

"For example, this hook is a typical place for modules to add CSS or JS that should be present on every page. This hook is not run on cached pages - though CSS or JS added this way will be present on a cached page."

If I understand it right it is not perfect as it is added to every page, even to pages where the block is not displayed. I don't know the caching system very well but I guess for a clean solution a core patch is needed? Something like drupal_add_block_css and drupal_add_block_js (or even better a parameter to drupal_add_css, drupal_add_js so the block specific css and js are then only cached with the block)? The solution definitely should support css aggregation if possible (drupal_build_css_cache)
But I guess it is to late for drupal 6 so this will be only cleanly solvable in 7 (unless I overlooked something, as said I'm not not a core code expert)

#3

Rob Loach - February 19, 2008 - 15:49
Title:Incompatible with block caching because add_css» CSS and JS for Cached Blocks (drupal_add_css incompatible with blocks)
Project:Event» Drupal
Version:6.x-2.x-dev» 7.x-dev
Component:Code» block.module
Priority:normal» critical

Moving this to the Drupal project as a core patch is required to allow cached blocks to have their own CSS and JS files included. Having the CSS and JS files added in hook_init doesn't seem like a clean solution.

Maybe something like this?

<?php
function mymodule_block($op = 'list', $delta = 0, $edit = array()) {
 
$blocks = array();
  if (
$op == 'list') {
   
$blocks[0]['info'] = t("My module's block");
   
$blocks[0]['cache'] = BLOCK_CACHE_PER_PAGE;
   
$blocks[0]['css'] = array(drupal_get_path('module', 'mymodule') .'/mymodule.css');
   
$blocks[0]['js'] = array(drupal_get_path('module', 'mymodule') .'/mymodule.js');
  }
  return
$blocks;
}
?>

$block['css'] provides an array of CSS files to be included when the block is shown. $block['js'] provides an array of JS files to be included when the block is shown.

#4

add1sun - February 19, 2008 - 15:54

subscribing - this nipped me with nice menus upgrade.

#5

jgoldberg - February 19, 2008 - 21:00

Wouldn't this be better with a callback rather than ['css'] or ['js']. For instance:

<?php
function mymodule_block($op = 'list', $delta = 0, $edit = array()) {
 
$blocks = array();
  if (
$op == 'list') {
   
$blocks[0]['info'] = t("My module's block");
   
$blocks[0]['cache'] = BLOCK_CACHE_PER_PAGE;
   
$blocks[0]['init'] = 'mymodule_block_0_init';
  }
  return
$blocks;
}

function
mymodule_block_0_init() {
 
drupal_add_css(drupal_get_path('module', 'mymodule') .'/mymodule.css'));
 
drupal_add_js(drupal_get_path('module', 'mymodule') .'/mymodule.js'));
}
?>

There might be other things people want to do while still using cached blocks.

Good idea though. We've faced a simiiar question over at the Tagadelic module.

#6

Bèr Kessels - February 19, 2008 - 21:04

I'd like top see one more positive test before releasing a 1.0. If no-one finds time to test before end oàf the week, i'll release a beta version by then and a stable after the beta is tested.

#7

dmitrig01 - February 21, 2008 - 04:08

@Bèr - Umm....

#8

moshe weitzman - February 21, 2008 - 20:08

I don't find this necessary at all. A module should just do this in hook_init if the block is at all enabled. The cost is nearly free now that we aggregate css and send the right headers so the css is cached on client. This is overengineering.

#9

Bèr Kessels - February 21, 2008 - 21:11

@dmitry: yea, I was being stupid, commenting in the wrong thread. Sorry 'bout that.

#10

catch - February 22, 2008 - 12:28
Priority:critical» normal

This isn't critical.

#11

Rob Loach - February 28, 2008 - 21:46

moshe at #8: If the block is disabled, and the module is enabled, the CSS and the Javascript will still be included even though it isn't needed. Although the performance hit on the server side is negotiable, it would be better if it didn't even shoot it out to the user at all.

#12

moshe weitzman - February 28, 2008 - 22:51

@robloach - true. yet the the proposed patch is uglier than the buglet it wants to fix.

#13

Rob Loach - February 29, 2008 - 17:38

Which one? $blocks[0]['css'] and $blocks[0]['js'], or $blocks[0]['init']?

#14

Eaton - May 16, 2008 - 17:27

If we're already returning keyed data in the block definition itself, wouldn't it make more sense to jam any CSS/JS data in there so that Drupal can keep the styles/scripts with it?

#15

Crell - May 17, 2008 - 02:25

This is probably related to and better solved at: #257032: Blocks system refactoring

 
 

Drupal is a registered trademark of Dries Buytaert.