(I mistakenly posted this in the Block Region issue tracker but it belongs to the core Drupal project block module. I would appreciate it if someone can delete the original post.)

There's currently no way to assign an ID to a block to be used in your CSS stylesheet to format different blocks in different ways, in order to for example change background, add icons or change block colors. Now the only option is to use a combination of the block's title and its module to create an id, which is rather ugly and is dependent on what the block's title happens to be. The delta cannot be used either as the site admin may want to change a block's weight.

I therefore suggest the blocks module includes an ID field for every block. The ID can either be specified by the site administrator in the block configuration (admin/block) or be auto-generated. A fresh Drupal install should include default IDs for the basic blocks so that themes can take advantage of this feature.

Comments

Crell’s picture

Status: Active » Closed (won't fix)

Actually you can do that now in the theme layer. Example from Bluemarine's block.tpl.php:

<div class="block block-<?php print $block->module; ?>" id="block-<?php print $block->module; ?>-<?php print $block->delta; ?>">
    <h2 class="title"><?php print $block->subject; ?></h2>
    <div class="content"><?php print $block->content; ?></div>
 </div>

Note that first line. The div gets an id that consists of "block", the module the block is coming from, and the delta within that block. That creates a completely unique key for the block. The delta is often numeric, but that's just convention from what modules are using. Modules are free to use non-numeric deltas if they wish (and I do, myself).

Setting won't fix, since there's nothing to "fix". :-)

dman’s picture

True.
I also do it in theme, but generate an id by scrunching the block title.

Block weight has nothing to do with the delta. I use non-numeric ids for my own blocks, also.

solipsist’s picture

Status: Closed (won't fix) » Active

You're missing the point, unless I am totally mistaken as to how the system works, deltas do change depending on the weight you assign to blocks.

This is the method I use now but it is bulky and ugly, and just a workaround for a proper fix that would introduce some kind of consistent and reliable way of doing it so that the free themes could take advantage of it.

dman’s picture

Yup, I think you're mistaken.

Try editing your block.tpl.php to include a dump of the entire block:

  <div class="block block-{?php print $block->module; ?}" 
    id="block-{?php print $block->module; ?}-{?php print $block->delta; ?}">
    <h2 class="title">{?php print $block->subject; ?}</h2>
    <div class="content">{?php print $block->content; print_r($block); ?}</div>
 </div>

(slightly munged code to get through the formatter)

I get:

  <div class="block block-block" id="block-block-2">
    <h2 class="title">delta?</h2>
    <div class="content">stuff:
stdClass Object
(
    [module] => block
    [delta] => 2
    [theme] => coders
    [status] => 1
    [weight] => 6
    [region] => right
    [custom] => 0
    [throttle] => 0
    [visibility] => 0
    [pages] => 
    [subject] => delta?
    [content] => stuff:

)
</div>

The delta is 2 (the second block-block I've made today) and the weight is 6.
My ID always says block-block-2, independant of the block position/weight, and I key the CSS on that.
Other module-suppled blocks (like menu) work the same. Delta is not weight. Delta (annoying name) is a module-relative block id.

solipsist’s picture

Ok. But what if I remove several blocks that belong to the same block module, wouldn't that change the assignment of delta to the remaining blocks as delta is relative to the blocks available and it isn't unique and independent?

dman’s picture

Nope.
It is unique, and static - within the context of that module.

There's two ways delta happens.

Normally, a module like image provides a cople of hard-coded blocks:
block delta-0 : latest image
block delta-1 : random image

Whether you use 'latest' or not, 'random image' is always image.modules block number '1'
Most modules do this, providing one or two non-mutable blocks.

Advanced block modules, including menu and block.module, allow new user-defined blocks to be added, and it just happens to give them numerical IDs.
These are IDs - not ordinal positions.
Delta is a misleading, stupid name for this, if that's what's confusing you.

You can make block #1, block #2, and block #3.
Going back later and deleting or disabling block #2 will not renumber the blocks any more than deleting node 7 will cause node 8 (and the rest) to slip down a slot.
Module-block ids are just the same as term ids, vocab ids, and the rest.

In fact, if you try a lot of trial and error (as I did once) you may find yourself editing block#16 when there are no other user blocks at all.

Have you tried testing any of this? Look at the URLs and you'll see what's happening pretty quick.

solipsist’s picture

Okay, then I'll present one final argument why this is a good idea, the need for reasonable, descriptive and totally customizable IDs for blocks - IDs that make sense. Well-written IDs and classes make for better and more readable CSS. There's no good reason to use technical addressing for block IDs, it's as impractical and down-right stupid as not using clean and easy-to-remember URLs for websites! :) We all love clean urls, don't we??? :) Clean IDs should be a given!

michelle’s picture

+1 from me. While it's not strictly needed since you can just use the number, a friendly class name for it would make the css file read better. I just customized to of my blocks and had to write a comment in the css so I could remember what -9 and -10 were. Self commenting is always nicer, I think.

Michelle

solipsist’s picture

Thanks for the vote Michelle!

I'd prefer to see this in core hoping someone with time and skills is prepared to code it, but failing that I might just write a module for it though god knows when I'll have the time for that...

dman’s picture

I AGREE that it would be nice if blocks have string ids, not numeric ones. The ones I create do, so I can invoke them by name, and find them in the css. That's good.

I was mostly explaining some clear misunderstandings you had on the system as it works now.

It is probably possible to patch block.module dto do this - without breaking anything. It just requires that you expose the 'delta' (which is already varchar(32) in the DB) for editing in the form.

However, as above, it's also possible to get an almost-identical result by changing your theme slightly
Instead of

id="block-{?php print $block->module; ?}-{?php print $block->delta; ?}"

I use

id="block-{?php print preg_replace('|[^a-zA-Z0-9_]+|','-',$block->subject) ?}"

and so my block titles become exposed as the block id. Great for css.
Forget 'delta', it's an internal ID, and not semantically significant, you are right. The code above, however, is.
1/2 a line in your theme.

I would like to get_block_by_name() programatically sometimes however, and have had to write my own tools to do so.

Crell’s picture

I'm not sure about user-created blocks off hand, but for pre-existing blocks, it's easy. In the code for hook_block of the module in question, change the deltas from numeric to strings. :-) That's something you'd submit as a patch against the module in question. If you did core, contrib modules would probably follow suit in time.

There's been talk of this before. In fact, I thought it already happened for some reason. :-) I doubt such a patch would get in right now, so close to feature freeze, but it probably wouldn't be a huge challenge in the next release.

Crell’s picture

I'm not sure about user-created blocks off hand, but for pre-existing blocks, it's easy. In the code for hook_block of the module in question, change the deltas from numeric to strings. :-) That's something you'd submit as a patch against the module in question. If you did core, contrib modules would probably follow suit in time.

There's been talk of this before. In fact, I thought it already happened for some reason. :-) I doubt such a patch would get in right now, so close to feature freeze, but it probably wouldn't be a huge challenge in the next release.

solipsist’s picture

dman: Thanks for explaining it but your code above will just result in IDs based on block title which means the CSS rules will depend on the actual content itself, not its classification nor semantics nor application. It just puts us back on square one I'm afraid.

dman’s picture

I don't rename my blocks too often after they are made, so I don't really consider a blocks label to be a mutable part of the content.
If I create a user block, labelled 'Contact Details' and that can be found and styled via CSS as the id #block-contact-details ... well I'd call that semantic enough.
.. although I've also met designers who created style sheets that were nothing BUT a series of content-id-anchored special cases :( . If your title reflects the purpose of the block, I don't mind that approach.

Classification is (appropriately enough) done via class. The class is 'block' and 'block-block' (block-module supplied user block) so those are good CSS hooks to work with.

What is it that you are doing that you have a large number of user-defined blocks that you change the titles for a lot?
To get any more fine-tuned on this, and sub-classify user-defined boxes into groups - a layer of detail between what it is (.block-block) and what it does (#block-contact-details) would seem to suggest you may want a taxonomy classification going on here.

Whatever, look into editing the block delta. It is quite possible, and even shows up correctly in URLs when in the admin/block/* area

solipsist’s picture

Okay, splitting hairs over semantics and what class actually implies, it's beside the point so I'm not pursuing it. :) But I digress and disagree.

There needs to be a layer of sorts to get readable, semantic CSS that makes sense, and I suggest a solution to edit and control that layer thru the blocks admin page. Alternately editing the delta but how can you possibly do that now without modifying the block-generating modules themselves? I think it's better to keep the delta as what it is and instead add a layer which exists for this purpose and this purpose alone.

dman’s picture

Status: Active » Closed (works as designed)

Unless there's a patch, or an entirely new layer of block administration module methods forthcoming, I think this issue has reached a bit of a dead end.
Something to keep in mind for forthcoming Admin UI developments possibly. As above, I'd vote for just making the id itself (the mis-named 'delta') directly editable by admins.
Closing

gpk’s picture

Version: x.y.z » 5.x-dev

This module probably provides something like the required functionality - essentially it lets you add an additional "tag" to a block which you can then pick up in your CSS in various ways, or use a different block template. http://drupal.org/project/blocktheme

I agree something like this should be in core really since for user defined blocks, picking up the ID in the CSS is pretty inflexible. It's doable for an admin with FTP access, but for a content creator it's hopeless. We can do this sort of thing with nodes and node/page template - why not for blocks too?

gpk’s picture