Simple problem: menu block deltas are "menu-xxxx", they use hyphens instead of underscores but the block module fails to change the hyphens to underscores when calling drupal_alter with "block_view_MODULE_DELTA".
Eclipse+Git doesn't let me create patches (grrrrr) so here's my fix:
// Allow modules to modify the block before it is viewed, via either
// hook_block_view_alter() or hook_block_view_MODULE_DELTA_alter().
$delta = str_replace('-', '_', $block->delta);
drupal_alter(array('block_view', "block_view_{$block->module}_{$delta}"), $array, $block);
Hope that helps.
Comments
Comment #1
dcrocks commentedRelated:
http://drupal.org/node/1129972
http://drupal.org/node/1021270
http://drupal.org/node/992376
Comment #2
wojtha commentedDuplicate of #1021270: Blocks for custom menus are impossible to theme
Comment #3
tstoecklerActually, this is not at all duplicate.
That one was about the template suggestions not working this one is about hook implementations. The root of the problem is the same (hyphens in block deltas), but they need to be handled separately.
I'll see if I can roll a patch.
Comment #4
tstoecklerHere we go.
Comment #5
tstoecklerI tested this patch, and it works as advertised.
In theory, we could write tests for this, but this is pretty specific, and it's very unlikely that we'll ever break this again, so I would vote against it.
Comment #6
dozymoe commented0.0
Comment #7
tstoecklerThinking about this, I think we should swap the approach, at least for D8.
We don't replace hypens with underscores elsewhere, for form IDs, node types, etc.
We should standardize on hyphen-less block deltas instead, I think.
For D7, though, this patch fixes a bug, so is definitely valid.
Comment #8
selltrends commentedNot to fix, but switch the hook_block_view_alter() can work correct.
Comment #9
barrapontoLooking at the bright side, this will fix it for any module that uses hyphens in module deltas. Since hook_block_view_MODULE_DELTA_alter was broken for them, this won't do any harm, just bring lots of joy.
Comment #10
xjmThanks for your work on this. Regarding #7, we shouldn't fix this in D7 until it is fixed in D8 one way or another, because otherwise we'll have a regression. I'd suggest committing this fix to D8 and D7, and then opening a followup for the better approach in D8.
Also, this seems like something that could use an automated test.
Comment #11
tstoecklerI suspect that I'm going to be overruled, but I think this is one of those things where it doesn't really make sense to write a test. When you think about it, menu.module is misusing the block API, it just took us a couple versions to figure that out. In D8, as I said, we should fix this proper (in menu.module), so those tests would be superfluous anyway. We would be testing for an obscure edge-case bug which we only support for BC, not because it's actually a feature.
Comment #12
xjmWell, if we're going to support it for BC and it's an extreme edge case, all the more reason to have a test to make sure we don't break it again in D7, IMO. Edit: We can remove/repurpose the test in D8 as needed if/when we do the refactor.
Comment #13
star-szrClosed #1399364: hook_block_view_MODULE_DELTA_alter() doesn't always translate to a valid function as a duplicate of this issue.
Comment #14
danillonunes commentedMaybe is better if we enforce that block deltas must have underscores instead of hyphens (just like hook_node_info() do with machine names). Otherwise, things can be broken if some module do something like:
Comment #15
barraponto@danillonunes I can see how modules that let the user inform a block delta might fall into that case. However, from reading http://api.drupal.org/api/drupal/modules%21node%21node.api.php/function/... I didn't see any enforcing of that rule. There's only a suggestion in the documentation.
Comment #16
coolestdude1 commented#14 has a valid point. Now with implementing this change I agree that we can support more robust code and more edge cases, however I don't believe that we can support a valid change/fix if we go and create a new problem(s). We, as a community, start to become more like spaghetti in this fashion. A more complete fix would be to enforce the no hyphen rule, rebuild the menu module and have an upgrade path that includes fixing any remaining db instances of deltas with hyphens (which in core does not seem like there is many).
Yes the above entails involving more people but I think it is warranted. Thoughts? Open to discussion
Comment #17
barrapontoIf we are to implement danillonunes suggestion in #14, we better open a new issue and fix d8 (if it needs fixing). I don't think it's worth backporting to d7, since we can only provide upgrade paths to core.
Comment #18
coolestdude1 commentedIn D8 it does appear as though menu_name is now fixed with no hyphen in the default configs (account, admin, footer, main, tools). The only thing that needs to be made sure of is that end users don't enter in a menu (machine) name that has hyphens, probably best accomplished using form validation as well as api validation.
In D7 however a few passes with the ctrl-f and find and replace ought to do the trick within just the menu module itself (menu.inc, menu.module, menu.admin.inc). Good practice here as well would be to upgrade current menu_custom db entries that have hyphens and do the same validation as above.
Both will need slight documentation tweaks, and some warning to admins when upgrading drupal.
Comment #19
barrapontoI believe it should only be changed for D8 (machine name validation) and added to Drupal core upgrade path. As mentioned before, I don't think we should enforce this change for D7 since it might break contributed modules.
Comment #20
coolestdude1 commentedThanks barraponto, I agree we ought to update the documentation about this known issue and let others know that in D8 this will no longer an issue.
Url for that page in the api is http://api.drupal.org/api/drupal/modules!block!block.api.php/function/ho...
Something along the lines of
"PLEASE NOTE: When using hook_block_view_MODULE_DELTA_alter for menus that you would like to alter, please keep in mind that in drupal 7 the block module will convert hyphens (-) into underscores (_) and that function names with hyphens will trigger a php fatal error. You can either go back and make your menu machine name without hyphens OR change your hook definition to account for this."
Comment #21
barraponto@coolestdude1 it's not as easy as it is in github, but I'm pretty sure you can patch that. Give it a try!
Comment #22
coolestdude1 commentedI will be leaving the version alone as the upstream changes matter more for right now. So this patch will probably fail tests because of that but here is the patch file against D7 Core for that documentation update.
Comment #23
coolestdude1 commentedMy git bash glitched here is the correct file
Comment #24
fizk commentedMy experience with D8 is very limited, and so much code has changed. I was able to track down the relavant part to
core/modules/block/lib/Drupal/block/BlockRenderController.php, which looks like this:You can see that some string replacement is already being applied.
My concern right now is that, while this issue sits in the queue, a real bug is going unfixed for a long time. If we can't get someone who knows D8 well enough to know that no more string replacements are needed, then we should switch the focus to D7 before it's too late.
#4 is exactly what we need to fix this bug. The patch has already been tested by several people, including me. I think the only thing missing is a test case.
I'm closing my own duplicate, #1821004: Alter delta before executing hook_block_view_MODULE_DELTA_alter.
Comment #25
fizk commentedHere is a patch with tests.
Comment #26
star-szr@fizk - Thanks for the patch, we do need to fix this in D8 first though, see #10.
Comment #27
fizk commentedTests only patch didn't contain the actual test.
Comment #28
fizk commented@Cottser, thanks, but no one has established that this is a bug in D8. If someone can show this, then we can set this back to 8.x.
Comment #30
star-szr@fizk - If you could forward port your test to 8.x that would likely show us whether the bug still exists in 8.x or not. Thanks for your continued work on this issue!
Comment #31
xjmFixing version again. Thanks! Our backport policy indicates that we need to confirm whether this exists in D8 or not, and add coverage for it and fix it if appropriate, before we add the change to D7.
Comment #32
fizk commentedForgot to update, it does look like D8 is affected by this -
hook_block_view_ID_alter()andhook_block_view_NAME_alter()are not called when a hyphen is present.hook_block_view_NAME_alter()is actually broken in another way as well:As far as I can tell,
$entity->id()never returns an array, just a string. That probably should be changed to:I'll try to post D8 tests.
Comment #33
fizk commentedHere is a D8 fix and test.
Comment #35
star-szr@fizk - Thank you, that's great! Next time, if you upload your test-only patch first (red then green), we won't get the automatic "needs work" (#34).
Comment #36
xjmThanks @fizk; that's an excellent test, and I'm glad you caught the bug in D8 too. In fact, this sort of thing is exactly why we have the backport policy--we broke it again in D8, differently, without realizing it. :) Overall I think this patch looks good; I just have a few polishes to add to the test so that it's easier for people to understand what it's doing in the future.
So the standard for this changed last summer. It should be:
I'd move this to the beginning of the test method itself. At first I was really confused as to how the test method was providing coverage for the bug.
The docblock should be a single line of 80 characters or less. Also, note that "ID" should always be capitalized.
Let's remove the assertion messages here -- they provide less information than the default assertion message will in this case.
Also, an inline comment referencing block_test_block_view_test_id_hyphen_alter() would help here, so that folks in the future know what this is actually testing (that the alter hooks are actually invoked). Edit: actually, instead of an inline comment, see the next point.
Hook and function names should always have parens when used in text. Also, let's make it a little clearer what the purpose is here, i.e.:
hook_block_view_ID_alter() invoked.With those simple cleanups I think this patch will be ready. Also tagging as a block plugins followup because we apparently introduced this bug in a brand new way with that conversion...
Comment #37
fizk commented@Cottser, Thanks for the tip!
@xjm, Here's the patch with your suggested improvements.
Comment #38
fizk commentedFixing tags.
needs backport to D7- this needs to be fixed in D8 first.Needs tests- we have tests.Novice- no longer novice IMHO :)Comment #39
star-szr@fizk, thanks for the revised patch! Interdiffs are also very helpful for reviewers and therefore moving issues along quicker :)
If you'd like to get this fix into D7, it's in your best interest to keep the backport tag intact. When a core committer sees the backport tag, after a commit they will set the issue to "patch (to be ported)" and change the issue version back to the relevant version (in this case 7.x-dev). At that point you or someone else can post a 7.x patch to be reviewed. Without the tag, usually the status will go to "fixed" and the issue is automatically closed after 2 weeks of inactivity. I'm fine with the other two tag removals for the time being, although the backport itself is still probably a novice task.
As @xjm mentioned, this needs to be "Contains \Drupal…", just missing the leading slash.
Also, for point #3 in #36, ID was capitalized but the description should be shortened to fit on a line of less than 80 characters. Ref: http://drupal.org/node/1354#drupal - "All summaries (first lines of docblocks)…"
Comment #40
xjmNW and novice for those last couple minor cleanups (per #39). Thanks!
Comment #41
friesk commentedfriesk via core.drupalofficehours and #drupal ksf
Comment #42
fizk commented@friesk, I don't understand your changes, and what "friesk via core.drupalofficehours and #drupal ksf" means?
Comment #43
xjm@fizk, @friesk is currently working on the cleanups suggested in #39, as a part of core mentoring. @friesk's username in IRC is ksf.
Please don't unassign issues from other people so quickly without asking first, since d.o does not allow reassigning to arbitrary users. :)
Comment #44
xjmAssigning to myself until friesk can take it back.
Comment #45
fizk commentedAh, ok, sorry about that. I don't think this should have been marked as task, though, nor made active instead of needs work.
Comment #46
xjmAye, agreed. :)
Comment #47
friesk commentedmy bad, still learning the vocab
Comment #48
friesk commentedEndless mentoring props to xjm.
Comment #49
friesk commentedinterdiff
Comment #51
friesk commentednew patch
Comment #52
fizk commentedThis looks good to me!
@xjm, can you set this to RTBC?
Comment #53
fizk commentedComment #54
xjmThanks @fizk and @friesk!
Comment #55
tim.plunkettThis clashes with the direction taken in #1927608: Remove the tight coupling between Block Plugins and Block Entities. Not unRTBCing yet because this seems to have been a pre-existing bug, but I'd be grateful if this was postponed.
Comment #56
alexpottThis is postponed on #1927608: Remove the tight coupling between Block Plugins and Block Entities...
Also I think the patch can be improved... see interdiff attached
Comment #57
fizk commentedComment #58
tim.plunkettThis is moot in D8, hook_block_view_MODULE_DELTA_alter() was removed.
Comment #59
fizk commentedThanks Tim, for people trying to port their modules with
hook_block_view_MODULE_DELTA_alter(), how would you accomplish this in D8?Setting to RTBC from #54.
Comment #61
adaddinsaneIn D8 blocks are entities so respond to all the entity hooks and specifically you have:
hook_block_view_alter(array &$build, \Drupal\block\Plugin\Core\Entity\Block $block)
and even
hook_block_view_ID_alter(array &$build, \Drupal\block\Plugin\Core\Entity\Block $block)
hook_block_view_NAME_alter(array &$build, \Drupal\block\Plugin\Core\Entity\Block $block)
Comment #62
bleen commentedThe patch in #54 was for D8 ... the last patch for D7 was #25
Comment #63
bleen commented#25: 1076132-hook_block_view_MODULE_DELTA_alter-1.patch queued for re-testing.
Comment #64
fizk commented@adaddinsane Looks like there's only
hook_block_view_alter()andhook_block_view_BASE_BLOCK_ID_alter()in D8 now.http://drupalcode.org/project/drupal.git/blob/refs/heads/8.x:/core/modul...
http://drupalcode.org/project/drupal.git/blob/refs/heads/8.x:/core/modul...
The
BASE_BLOCK_IDcomes fromBlockBase::getPluginId(). I'm not 100% sure if that function always returns strings that can be used directly in a callable function name (i.e. only letters, numbers, and underscores).Comment #65
tim.plunkettA block plugin ID must be machine_name safe, so a-zA-Z0-9_
Comment #66
fizk commentedThanks for confirming Tim.
Setting to RTBC from #54.
Comment #67
tim.plunkettThis is not actually a unit test, it's a web test.
Missing a blank line after beginning and before the end of the class.
These should be marked public
These are indented 2 spaces too many
Comment #68
tim.plunkettQuick fixes though! Almsot done.
Comment #69
Sethie commentedI'll fix these small things.
Comment #70
foxtrotcharlie commented@Sethie - @Cottser suggested I take a shot at these fixes as part of core mentoring. If you're busy with it and want to complete it just let me know and I'll find something else :-)
Comment #71
foxtrotcharlie commentedNot 100% sure I got all the suggested changes but here's a first attempt. My interdiff doesn't look right though - I thought it was supposed to just reflect the changes I made after the previous patch...
I also wasn't quite sure what the difference between the 2 files: hook_block_view_MODULE_DELTA_alter-64.patch and hook_block_view_MODULE_DELTA_alter-64-tests-only.patch that were attached to comment 64. Was I supposed to work on both? I only worked on the file: hook_block_view_MODULE_DELTA_alter-64.patch
Comment #72
foxtrotcharlie commentedComment #73
star-szrThanks @foxtrotcharlie!
We got some extra trailing whitespace here that needs to be removed per http://drupal.org/coding-standards#indenting.
Comment #74
foxtrotcharlie commentedThank you @Cottser. I have now set up my IDE to remove trailing whitespace. Patch with whitespace removed, attached.
Comment #75
fizk commentedMarking RTBC.
Comment #76
skwashd commentedThis formatting change is unrelated to the fix. As per the coding standards, this needs to be in a separate issue.
Comment #77
skwashd commentedHere is the rerolled version.
Comment #78
fizk commentedI think we're getting a little bit too picky with our changes now. Can we RTBC this, commit it to HEAD, and then make further improvements if needed?
Comment #79
David_Rothstein commentedtim.plunkett's review in #67 wasn't fully addressed, plus calling array_pop() directly on a function result produces E_STRICT errors...
Fixed those in the attached, plus a small code style issue (function summary should be on one line).
These are small fixes, so I will commit it as long as it passes tests.
Comment #80
David_Rothstein commentedCommitted to 7.x - thanks! http://drupalcode.org/project/drupal.git/commit/226fe69