Figured I was overdue to throw something up here on the ol' neglected blog, so here it is.
I generally get called on to projects to do custom module development and internal architecture/engineering, so I have increasingly less frequent contact with the front end tools and site building type modules. But I've been playing with Panels again lately for a project and ran into an issue with block visibility. While Panels will generally give you an option to respect a block's configured visibility settings, for blocks generated via Views, it does not (even if you have specified visibility rules for that block via admin/build/block). I suspect this is because Panels invokes Views generated blocks directly thereby bypassing that extra 'layer'.
The Panel I was building out is for user profiles which, on the site being developed, have a number of regions and blocks for any given profile page. Profiles belonging to the current user and profies belonging to other users have the same general content, but also some differences. For instance, it makes sense to have a block with links to send a user a private message and add them to your contact list when viewing someone else's profile, but it doesn't make much sense to have those links on the page when you are viewing your own profile (who needs to send themselves a message?). For custom defined blocks, this is fine and we set the appropriate visibility conditions (ie. a PHP snippet that returns true only IF this page is NOT my own profile), but for Views defined blocks we can not block specific visibility rules and have them recognized by Panels.
So I made a small little wrapper function to allow this. It might be useful to someone who is Googling around trying to figure this out. I'll start with pasting the code that I am actually using (rather specific to my case) and then I'll generalize it to what I think might be more universally useful to people.
<?php
/**
* A wrapper function that will return the rendered output of a View block, allowing the visibility to be restricted
* based on the context of the current profile page.
* This is necessary as Panels invokes Views blocks directly, so any visibility settings applied to a View block through
* /admin/build/block are not respected.
*
* @param $view_name
* The 'machine readable' name of the View
* @param $realm
* Optional, defaults to 'all'. May be 'all', 'own' (self), or 'other'. All will return the output on any profile page,
* 'own' will return the output only on a user's own profile page, 'other' will return the output only on a profile page belonging
* to a user other than the current user
* @delta
* Optional. This parameter is generally not needed, but is useful if you have a View that defines multiple blocks.
* @return
* The rendered output of the underlying block if the realm matches, otherwise an empty string
*/
function mymodule_profile_view_wrapper($view_name, $realm = 'all', $delta = 1) {
global $user;
$display = FALSE;
$output = '';
switch($realm) {
case 'all':
$display = TRUE;
break;
case 'own':
if (mymodule_is_own_profile_page()) {
$display = TRUE;
}
break;
case 'other':
if (mymodule_is_profile_page() && arg(1) != $user->uid) {
$display = TRUE;
}
}
if ($display) {
$output = module_invoke('views', 'block', 'view', $view_name.'-block_'.$delta);
}
return $output['content'];
}
?>As you can see, this code is rather specific to the problem I was solving. More generally, we could just have the wrapper accept PHP code to eval just like we would normally do when creating block visibility rules through the core block mechanism.
Note that this is untested, but I'd put a ten-spot down on it working.
<?php
function mymodule_view_wrapper($view_name, $eval, $delta = 1) {
$output = '';
if (drupal_eval($eval)) {
$output = module_invoke('views', 'block', 'view', $view_name.'-block_'.$delta);
}
return $output['content'];
}
?>In Panels you would click to add a new block, choose 'Custom PHP Content' and call the wrapper with your visibility conditional code (remember the PHP tags, and remember to return TRUE .. just like when you are creating a visibility condition for any other block).
For example, assuming a View block called 'scorecard' that you wanted to display only after 6pm you could paste this into your 'Custom PHP Content' block
$eval = '<?php if (date('G', time()) > 18) return TRUE; ?>';
$block->content = mymodule_view_wrapper('scorecard', $eval);Hope that is helpful for someone and not too terribly confusing.






The module is very useful. Thanks for sharing.
Thanks for this very useful article.
This module seems to be very helpful for me.
Good to know!
The panel code is bug less.. I guess you have worked on this too much.. The scripts are too clear that any new programmer can understand..! Thanks for sharing this... !Angeline @ Marcus evans scam
very interesting, thanks for the information
Thanks for this very useful article.
This module seems to be very helpful for me.
Good to know!
Great Post. Very helpful. Glad I found it.
Thanks so much for this, you've just saved me from certain death! [note: small exaggeration]
awsome module, thanks for share
This is wonderful I swear you Drupal developers are pure genius. Seems there is always module made for a specific task, is only wordpress developers were as efficient (and as many, and smart)
interesting, thanks for the information
Excellent stuff! i've been having trouble with the whole blocking procedure, and your article kinda helped me realized what i was doing wrong! thanks so much! cheers!
Great article, it has very nicely briefed about the simple steps that need to be taken in order generate block panels and its was quite straight forward! thanks! cheers..
Panels can be difficult to code properly. Thanks for showing us how you do it.
The use of panels for viewing pages/profiles is informative.The way the wrapper function used is excellent.
I guess itwouldn't really be that different in Drupal 5, but the Interface to Views is completely different, so none of the screenshots apply here. You would still use the same code as your default argument, still use the same fields and such.
panels can be difficult to code, so thanks for showing us how to do it properly
Thanks so much for this, you've just saved me from certain death!
The custom defined blocks on user profiles prepared by you is very informative & very useful for Drupal users like me.Thanks for it.
Currently there isn't so much setting here. But I hear you can enable the server mode, so that other sites where remoteblocks are enabled, can pull data from your site. It can be a better solution to refactor this functionality to a different module.
Thanks for the tip! My developer told me it's impossible to get this done but you've proven it otherwise! Thank you!!!! I'll show him this article :)
I am not sure how panels2 handles arguments, but I guess you can always handle it using the argument handling code within the view. It's not so elegant, but I think it would work.
Good Job, this was a great way to block visibility rules.i
Before the release of Panels for Drupal 6, how can one associate a block with the node it's being displayed next to without writing a custom module? It turned out to be simpler than I expected. I actually started going down the path of custom modules, but in the process I noticed that Views still have the ability to load Arguments with PHP Code, and my solution wrote itself.