Download & Extend

More theme candidates

Project:Bean
Version:7.x-1.x-dev
Component:Code
Category:feature request
Priority:normal
Assigned:Unassigned
Status:active

Issue Summary

I'm looking at the best way to theme certain types (in the entity sense) of bean blocks. I was hoping I'd just be able to create separate .tpl files for each but it doesn't seem like the Bean's entity type gets factored into the candidate names. Right now I only see:

  • block__REGION-NAME
  • block__bean
  • block__bean__BLOCK-LABEL

Is this just due to the underlying block system? Could Bean do an alter and offer more choices?

Update: I'd looked at the possibility of extending bean_plugin and implementing a view() function that called a wrapper theme function but since the bean's I'm using are exported using hook_bean_admin_ui_types() they get the default handler. I guess I could move them over to hook_bean_types() but this seems like a common usage that should be better supported.

Comments

#1

Since bean is an entity you should theme the bean, not the block.

So you can use hook_preprocess_bean()

function template_preprocess_bean(&$vars) {
$vars['theme_hook_suggestions'][] = 'bean__' . $vars['type'];
}

might work. One of my team mates is going to respond also.

#2

I'm very open to suggestions also. I write the low level APIs on our projects :)

#3

This might be a kind of noob question but where is bean's theme function called? Does the Entity API handle that? I see it registered but I'm wondering where we'd add a candidate other than in the template. I'd rather have the templates work across themes if possible.

#4

The Entity module adds the template suggestions.

<?php
function template_preprocess_entity() {
.
.
 
// Add suggestions.
 
$variables['theme_hook_suggestions'][] = $entity_type;
 
$variables['theme_hook_suggestions'][] = $entity_type . '__' . $bundle;
 
$variables['theme_hook_suggestions'][] = $entity_type . '__' . $bundle . '__' . $variables['view_mode'];
  if (
$id = entity_id($entity_type, $entity)) {
   
$variables['theme_hook_suggestions'][] = $entity_type . '__' . $id;
  }
.
.
}
?>

?>

#5

Hummm I was looking at the list of calls inside devel_themer and not seeing entity called. I'll give that a try. We're doing it inside context so I wonder if that has an effect.

#6

Thanks. I'd love some insite to some better theming for bean if you have any suggestions.

#7

So it looks like the theme suggestions are made but the it's not registering the preprocess. I'm not sure why.

https://skitch.com/indytechcook/gphj5/welcome-to-beans.dev-beans.dev

#8

Ah okay so putting the bean.tpl.php in the theme got the call showing up… not sure why it wasn't there before. I'm going to play around with this a bit more I might change it to a support request and close it.

#9

Oh I think this might have something to do with the preprocess: #939462-6: Specific preprocess functions for theme hook suggestions are not invoked

#10

When using Display Suite there is a need for the original issue that started this thread, i.e. a need to theme:

  • block__bean__BEAN-TYPE

While (as mentioned in the thread above) it is best to theme plain vanilla beans with bean.tpl rather than block.tpl, using Display Suite will result in bean.tpl being completely overridden and block.tpl being used. Themers will then want to style block.tpl to be in harmony with the bean type (and the DS style applied to it).

I am having a go at adding to the theme_hook_suggestions for block:

<?php

function themename_preprocess_block(&$variables) {
  if (!empty(
$variables['block']->module)) {
    if (isset(
$variables['elements']['bean'])) {

       
$variables['theme_hook_suggestions'][] = 'block__' . $variables['block']->module . '__' . $variables['elements']['bean'][4]['#bundle'];

       
// kpr($variables);   
   
}
  }
}

?>

This works, but only for one particular bean. Within $variables['elements']['bean'] the data that is needed to get the bean-type is nested within a number which is different for each bean. In this example the number is [4]:

$variables['elements']['bean'][4]

Obviously this code will not work if there is more than one bean, or the bean has a different number. It’s a start, but not much use in practice.

So my questions are:

  • How to discover what that number is for each bean (from within template_preprocess_block), or
  • How to discover the bean-type / #bundle without needing to know the bean number?

I will be overjoyed if I can get this working because Beans with DS are an incredible combination! FWIW I’m a designer & themer, not a module developer, so I apologize if I have missed something obvious.

#11

The following code enables block__bean__BEAN-TYPE as a block.tpl theme suggestion (when pasted into a theme’s template.php file).

However, I would love to have comments:

  • is it okay to do it like this?
  • is there a better way?
  • is the code fragile, breaking all known drupal best practices and about to explode when the Bean module is next updated???

many thanks
Paul

<?php

/*
* Implements template_preprocess_block
*
* enable bean blocks to be themed by bean-type:
* i.e. block__bean__BEAN-TYPE.tpl
*/
function themename_preprocess_block(&$variables) {

 
// select Bean Blocks and ignore other Blocks
 
if (!empty($variables['block']->module) && isset($variables['elements']['bean'])) {

   
$bean_array = $variables['elements']['bean'];
    foreach(
$bean_array as $value) {
   
// if you want to debug the $key you can use: foreach($bean_array as $key=>$value)

     
if (is_array($value)) {
        if (!empty(
$value['#bundle'])) {

         
// kpr($key);
          // kpr($value['#bundle']);

         
$variables['theme_hook_suggestions'][] = 'block__' . $variables['block']->module . '__' . $value['#bundle'];
          break;
        }
      }
    }
  }
}

?>

#12

@paul, that's really interesting. I'd be willing to add this to bean if other people agree. Also, please update http://drupal.org/node/1434622 with findings.

#13

@indytechcook thanks! I have refined the code slightly and added a comment at: http://drupal.org/node/1434622#comment-6761032 I hope others agree, it would be really great if this was added to the bean module.

#14

For reference, this is what I have been using (seems like some of the variable validation in the previous examples are not really needed IMO but maybe mine is too assuming?):

Adds bean type class & template suggestion:

<?php
/**
* Override or insert variables into the block templates.
*/
function YOURTHEME_preprocess_block(&$variables) {
 
// For bean blocks.
 
if ($variables['block']->module == 'bean') {
   
// Get the bean elements.
   
$beans = $variables['elements']['bean'];
   
// There is only 1 bean per block.
   
$bean = $beans[reset(element_children($beans))];
   
// Add bean type classes to the block.
   
$variables['classes_array'][] = drupal_html_class('block-bean-' . $bean['#bundle']);
   
// Add template suggestions for bean types.
   
$variables['theme_hook_suggestions'][] = 'block__bean__' . $bean['#bundle'];
  }
}
?>

#15

Has anyone had any luck with getting MYTHEME_preprocess_bean() to fire?

Even when I have bean.tpl.php in my theme I can't get the preprocess to fire.

Or are we doomed by #939462: Specific preprocess functions for theme hook suggestions are not invoked?

#16

Here is less pretty workaround:

<?php
function MYTHEME_preprocess_entity(&$variables) {
 
// This is a hack to work around drupal.org/node/939462, which means
  // the bean preprocess function isn't called.
 
if ($variables['entity_type'] == 'bean') {
   
MYTHEME_preprocess_bean($variables);
  }
}
?>

Alternatively you could just use template_preprocess_entity for now and be done with it.

[EDIT] Edited to lessen the alarmist wording :)

#17

@rooby why is that dodgy?

#18

Well it isn't really. I use it in a few sites and I'm not worried about it.

But it's not as nice a solution as we could have #939462: Specific preprocess functions for theme hook suggestions are not invoked