I know this module is called block_class, but I wanted to be able to set the block's CSS id in very much the same way.
Unlike classes, there should be only one id, so the code is actually even simpler.

I hacked through the block_class.module and made a working block_id.module, but if there is interest, I could write a patch to merge the two.
Or it could be included as a submodule.

#4 block_class-863554-4.patch4.34 KBtim.plunkett
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch block_class-863554-4.patch. Unable to apply patch. See the log in the details link for more information.
[ View ]
#2 block_class-863554-2.patch4.39 KBtim.plunkett
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch block_class-863554-2.patch. Unable to apply patch. See the log in the details link for more information.
[ View ]
block_id.tgz.gz1.77 KBtim.plunkett


grendzy’s picture

+1. This would be a useful improvement, though I think a patch makes the most sense. No need for a submodule.

Since Drupal core derives the id from the block's delta, this value can change when a block is moved between databases, being able to manually force it to a stable id would be awesome.

tim.plunkett’s picture

Version:6.x-2.x-dev» 6.x-1.x-dev
Status:Active» Needs review
new4.39 KB
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch block_class-863554-2.patch. Unable to apply patch. See the log in the details link for more information.
[ View ]

My original post was against 6.x-1.x-dev, and I've had a lot of issues with the 2.x branch, so this patch is against 1.x as well.

Added block_class.css_id field to the schema, with an accompanying hook_update_N().
Changed block_class() to take an additional "type" parameter, set default to "css_class" for backwards compatibility.
Added relevant code to block_class_form_alter().
Added block_class.css_id field to all db_query()'s.

tim.plunkett’s picture

Oh, in block_class_preprocess_block() I specifically used $variables['block_html_id'], since there should only be one ID, and that's the variable name used in Drupal 7 (and D6 Zen). This probably needs a description similar to the "Add a call to print $block_classes", but that can be ironed out later.

tim.plunkett’s picture

new4.34 KB
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch block_class-863554-4.patch. Unable to apply patch. See the log in the details link for more information.
[ View ]

Fixed an if statement.

Todd Nienkerk’s picture

I'm hesitant to add the ability to set an ID for each block, as blocks already have unique CSS IDs (#block-modulename-delta).

What's a use case for this that can't be achieved by using a CSS class? I understand grendzy's point about custom blocks changing IDs as they move from dev to production, but it seems this could be done using unique CSS classes rather than IDs.

Todd Nienkerk’s picture

Title:Set block's CSS id» Set block's CSS ID
Status:Needs review» Postponed (maintainer needs more info)
grendzy’s picture

Status:Postponed (maintainer needs more info)» Needs review

From a strictly technical perspective, you are correct that there's nothing ids can do that can't be done with classes. Here are some reasons to support ids:

  • Completeness. Even though they are often interchangeable, id and class are both equally important parts of HTML and CSS. Other Drupal modules (for example Panels) support both.
  • Semantics. "id" means something different than "class". Designers and themers care about this, and by supporting both you'll be helping to remedy the common designer complaint that Drupal generates bloated and inflexible markup.
  • Javascript. Some js techniques rely on getElementById. I've had to work around this with jQuery (for example $('.myblock').attr('id', 'myblock')) - this works but is kind of messy.
Todd Nienkerk’s picture

@grendzy: Thanks for supplying some reasoning and use cases.

Is the proposal to allow the addition of CSS IDs, or are we talking about the replacement of the existing CSS ID? I'd prefer the first approach. (And just out of curiosity, I double-checked the CSS specs, and CSS 2.1 and 3 do allow multiple IDs per element.)

Todd Nienkerk’s picture

Title:Set block's CSS ID» Add ability to set a block's CSS ID
Assigned:Unassigned» Todd Nienkerk
Status:Needs review» Postponed (maintainer needs more info)
tim.plunkett’s picture

"What makes attributes of type ID special is that no two such attributes can have the same value in a conformant document, regardless of the type of the elements that carry them; whatever the document language, an ID typed attribute can be used to uniquely identify its element."

What you're referring to is actually this: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/full/tng/cs...

Meaning that #pass#pass { background-color: green; } is still valid.

If we're not talking about replacing IDs, this issue should be marked "won't fix". It's not a huge deal.

tim.plunkett’s picture

Oh. "If an element has multiple ID attributes, all of them must be treated as IDs for that element for the purposes of the ID selector."

I'm really confusing myself. Still leaving postponed.

klonos’s picture

...coming from #340145: Block ID.

A couple of more reasons to add in Dylan's list over in #7:

- "id=my-easy-to-remember-block-id" instead of "id=block-block-24" is way more efficient when theming. So being able to define/alter block IDs to custom, more descriptive ones is a life/time-saver.
- While using multiple classes is supported by the majority of browsers, really old browsers don't support them or misbehave (only recognize the first one).

It so happens that in drupal the first class added to blocks is not always the one with the most specific information for an element. I have found myself in this situation many times and adding/using an id (in addition to the classes) provided an easy(ier) way for me to be able to select some specific elements while theming. I used to use the solution provided by provinciadicuneo in #340145: Block ID plus some tips from these articles:

Create block id attributes based on block title
Give your Drupal blocks a more descriptive HTML ID attribute
Core Block CSS IDs

The last linked article lists how core block IDs have changed in D7 compared to the ones in D6. I use it as a manual blacklist so I don't accidentally re-use a reserved id. Perhaps this could be implemented in this feature as a check of not-accepted values for the 'css_id' textfield (either ajax-style à la password strength indicator or message thrown after save/submit).

klonos’s picture

PS: I would love it if I had some patch for 7.x to test this against my latest D7 setups. #4 still works just fine in D6 though. Thanx Tim ;)

tim.plunkett’s picture

Version:6.x-1.x-dev» 7.x-1.x-dev
Assigned:Todd Nienkerk» tim.plunkett
Status:Postponed (maintainer needs more info)» Needs work

Ah, what the hell. I might as well make this happen if I can, and then we can decide if it's worthwhile :)

klonos’s picture


Todd Nienkerk’s picture

Supplying a new variable in template_preprocess_block() that can be optionally printed in block.tpl.php is, I think, a good solution. (This is basically what tim.plunkett suggested in #4.) This would allow each user to replace the ID or add a second ID at their discretion.

Todd Nienkerk’s picture

(Accidental double post removed.)

berenddeboer’s picture

You can't have a second id. I don't think this is a useful feature to give in the hands of users.

klonos’s picture

Yeah, I somehow missed your post Todd. IDs are meant to be unique and single per item AFAIK. If there is need for more identifiers, one can use class(es) along with the ID. I am pretty sure you already know that, so may I ask what exactly you meant by mentioning one can add a second ID?

klonos’s picture

I'd like to bring your attention to the Block 2.0 module and my proposal. If Dave decides to implement this in this module of his, we'll have great chances to get what we need in D8 ;)

PS: ...there's a core issue available for D8: #334759: Add machine names for custom blocks

lpalgarvio’s picture

suggestion: provide a second form field for the ID, where you can specify an optional block ID for the block.

* when set, this block ID would override the block ID provided by block.tpl (>=3 characters), as an HTML element can only have one ID.

* when not set, use the block ID provided by block.tpl, no changes.

Todd Nienkerk’s picture

@berenddeboer, @klonos: While I agree that elements should only have one ID, the CSS 2.1 and 3 specs state it's possible for elements to have more than one ID. Of course, it's not allowed for multiple elements on a page to share the same ID.

In other words, this is allowed:

<div id="#id1 #id2"></div>

...And this is not:

<div id="#id1"></div>
<div id="#id1"></div>

Can anyone thing of any core functionality or contrib module that would break if we replaced the block ID? I'm concerned that some JavaScript code might be looking for the #block-module_name-delta pattern on a page and not find it because a user has overridden it.

klonos’s picture

...the CSS 2.1 and 3 specs state it's possible for elements to have more than one ID.

...ok, I honestly wasn't aware of that. I'm sure a lot of others out there aren't either. Perhaps because of a lot misleading documentation/tutorials/books all over the place (they actually suggest using IDs whenever an element is used/present once per page, but it is phrased in such a way that we are lead to believe this is a css standard restriction).

I'm concerned that some JavaScript code might be looking for the #block-module_name-delta pattern on a page and not find it because a user has overridden it.

Good catch Todd! It never crossed my mind.

Anyways, it seems it is legit for a single element to have multiple IDs as long as they are unique among other elements in the same page. On the other hand people might be concerned of the fact that there might be issues when using multiple IDs (like lack of browser support for example). So, I propose the following changes:

- Add a "Default block ID:" info field displaying the current/drupal-default ID. A help text that explains that this is an ID that is auto-generated by drupal would be nice so that people don't wonder.
- Add an "Override block's default id" checkbox ("override" could also be "replace").
- Set it to be checked/on by default. If people report that things break due to missing default IDs, then consider changing the default setting to be unchecked/off.
- Add a help text explaining why this feature/checkbox is there for. Something like this perhaps: "By default, drupal assigns its own machine-generated ID to each block. When disabled, this setting allows you to add your custom ID(s) and also keep the one that drupal adds instead of replacing it."

Still, we do need to check if the custom IDs entered by users are unique though IMO.

PS: I have read someplace some time ago that there are issues where only the first class is actually recognized by some browsers. I cannot say if the same is valid for IDs too though.

klonos’s picture

klonos’s picture

Perhaps a set of two radio boxes is better than a single checkbox now that I think of it. One option being "Replace the block's default ID with my custom ID(s)" and the second "Add my custom ID(s) and also keep the block's default one".

The "Replace the block's default ID..." option might be risky due to what Todd mentions back in #22. So, there should be a warning text: "This might break core functionality or other modules that may require the block's auto-generated ID in order to work.".

Since using multiple IDs is (or might) be risky when it comes to browser support, the "Add my custom ID(s) and also keep..." option should also have a warning text: "Some really old browsers might not support/detect multiple IDs for a single element. In such cases, it is recommenced to use classes instead of IDs.". The same warning should be shown when one chooses to replace the default ID with multiple custom ones instead of only one.

PS: The warning is not frustrating for the user at all, since the recommended solution is a feature provided by this very same module.

yareckon’s picture

I would avoid citing CSS docs to justify what kind of HTML we are generating. As far as I know id -> element is expected to be a 1 -> 1 relationship in HTML. HTML validators will choke on documents with more than one element with the same id. Not sure how they will react for a single element with more than one id. How CSS syntax works is secondary to this classes discussion.

Still the ability to set the id is a good one. I would just have it definitely override the system one.

berenddeboer’s picture

Status:Needs work» Closed (won't fix)
tim.plunkett’s picture

Status:Closed (won't fix)» Needs work
berenddeboer’s picture

Tim, I closed this as I think giving the typical user the ability to create duplicate ids to a site is not a good idea.

klonos’s picture

That ability won't be there for the typical user. It's meant to help site themers. Besides, we can always implement a permission and the site admins can then decide which users will be granted that.

berenddeboer’s picture

You don't even want it at the themer level.

I really see very very little use for this. It just introduces extremely obscure bugs.

RaF7’s picture

Which obscure bugs are we talking about?

berenddeboer’s picture

If a user uses a duplicate id, what element will $("#id") return?

grendzy’s picture

Panels has supported user-defined ids for a long time, and I haven't heard any complaints.

If a user uses a duplicate id, what element will $("#id") return?

It's certainly a mistake on the user's part - but nothing terrible happens. The return value is the same as $("#unique-id"): A jQuery collection containing all matched elements. This is true whether the selector matched 0, 1 or many elements.

mindfullsilence’s picture

Tim, I closed this as I think giving the typical user the ability to create duplicate ids to a site is not a good idea.

I don't think this is an issue considering this module is targeted towards people who know their way around html and css. Following this type of logic, the entire devel themer module wouldn't exist because someone might use it in production. The removal of features because of how a person might abuse said features will always result in you pulling your hair out.

Here's a couple examples:
Gotta get rid of the comment module because users might not know how to install mollom or captcha. Same goes for the forum module.
Have to get rid of PHP blocks because a user could crash their site.
Can't use views because it's too confusing for the end user to grasp.
Heck, let's get rid of modules entirely because the user might install them to the wrong directory.

Just a matter of letting the user know not to use the same id more than once really.

lpalgarvio’s picture

given this and other core and context blockers, i've opted to replace with a panels/panels_everywhere solution long, long ago.
zen theme goes along very well.

nithinkolekar’s picture

Issue summary:View changes

another nice discussion thread without any update?
Was looking for same think for theming purpose only. Thats why this modules exists right?

+1 for #21 but it would be nice if it extend by providing options like

(1)Wrapper element

<div id='my-custom-block-id'>
<div id='block-block-24'>...</div>

(2)Replace id
<div id='my-replaced-block-id'>

(3)Child element
<div id='block-block-24'>
<div id='my-custom-block-id'>
....content goes here..

I think Menu attribute is also provides this function to menu item and other menu based modules like superfish, nice menu plays well without any problem.

kthull’s picture

Yeah, I would love this feature. Having a js smooth scroll menu link point to foo.com/#block-views-clients-block-1 instead of foo.com/#clients is just not ok.

tim.plunkett’s picture

Assigned:tim.plunkett» Unassigned

I still think this is important, but someone else will have to tackle it.

DYdave’s picture

Status:Needs work» Needs review

Hi guys,

Thanks a lot for all your comments and ideas.

It seems this discussion has been going on for ages...

Following up with #2211703: Block attributes?, I spent some time thinking about the idea of working with a Block Attributes module and unfortunately I was unable to find any existing module that would allow users to modify block attributes through the back-end, other than block classes (Block Class was the closest I could find).
So I went ahead and contributed the Block Attributes module, based on the Block Class and Menu Attributes modules.

The Block Attributes module allows users to specify additional HTML attributes for blocks, through the block's configuration interface, such as class, id, style, title and more.

Since the HTML ID could be considered as a HTML attribute, it is also supported by the Block Attributes module, among other HTML attributes, such as class, style, align, and more (see a screenshot of the block configuration page and module page's section named Features).

Feel free to take a closer look at suggested module and follow up in the issue queue if you have any questions, comments, ideas or encounter any problems while testing, your feedback and comments would be greatly appreciated.

If there is enough feedback and it reaches the level of expectations of the participants in this discussion, I assume we could perhaps consider moving this issue forward towards closure and potentially moving the discussions over to Block Attributes issue tracker.
Lastly, I allowed myself to modify Block Class' project page to let users know of the Block Attributes module, which is a bit similar (see under the section/paragraph "Similar modules").

Block Attributes: For users looking for more theming flexibility, capabilities or with more advanced requirements, the Block Attributes module allows to specify additional HTML attributes for blocks, through the block's configuration interface, such as HTML id, style, title, align, class and more.

I would greatly appreciate to have your comments, feedback, questions, issues, objections, reviews, testing/reporting, suggestions or concerns on this new module.

I hope this new module could help more site builders, themers and developers fulfill their projects' requirements related with blocks.
Thanks in advance to everyone for your testing, reviews, feedback and comments on this issue.

The last submitted patch, 2: block_class-863554-2.patch, failed testing.

Status:Needs review» Needs work

The last submitted patch, 4: block_class-863554-4.patch, failed testing.