I am using a field theme function in my template.php file to override a field.

Everything works fine, but the function only seems to run if my field has content. If my field is empty, it does not run. How can I get the function to run all the time?

Here is the code I am using. The function checks a value in theme_settings.php and then alters the output of the field accordingly.

function THEMENAME_field__field_call_to_action_button(&$variables) {
 // kpr($variables);

    //Load the value of CTA to determin which text to use
    $field_cta_option = field_get_items('node', $variables['element']['#object'], 'field_call_to_action_setting');
        $cta_option = $field_cta_option[0]['value'];

    //Assign theme/node settings to variables for easy access   
    $cta_link_main      = theme_get_setting('cta_main_node');
    $cta_link_secondary = theme_get_setting('cta_secondary_node');
    $cta_link_custom    = theme_get_setting('cta_main_node');
    $cta_text_main      = theme_get_setting('cta_main_button_text');
    $cta_text_secondary = theme_get_setting('cta_secondary_button_text');
    $cta_text_custom    = $variables['#items'][0]['value'];
    switch ($cta_option) {
        case 'cta_main':
            return ctabutton($cta_link_main, $cta_text_main);
        case 'cta_secondary':
            return ctabutton($cta_link_secondary, $cta_text_secondary);
        case 'cta_custom':
            return ctabutton($cta_link_custom, $cta_text_custom);
        case 'cta_none':
            return "";

You may want to change the way you are theming the information, for example by overriding node.tpl.php, but if you really want the field function to be run even when the field is empty, you can do it by modifying the node before it gets displayed:

function THEMENAME_preprocess_node(&$variables) {
  if($variables['type'] == 'mynodetype' && !isset($variables['content']['FIELD'])) {
      $variables['content']['body'] = array(
      '#theme' => 'field', 
      '#field_type' => 'FIELDTYPE', 
      '#field_name' => 'FIELDNAME', 
      '#items' => array(), 
      '#bundle' => 'mynodetype', 
      '#label_display' => 'hidden', 
      '#entity_type' => 'node');

This will make sure the field is passed to your theme field function, even if it is empty.

To get the values to use for FIELDNAME and FIELDTYPE you can print out the contents of $variables['content'] on a page where the field is not empty.

Again, it might be better to override the theme of the entire node in this situation.

  • This works, however, when I display my page with Panels, it stops working. Is there a way to get it to work with Panels. – big_smile Jan 29 '13 at 18:28
  • I experimented with a panel page containing a node with build mode set to 'Full content', and the theme_field hook is still being called. Could you give me more details about your panel? – penten Jan 30 '13 at 1:43
  • I think it something with my set up, so I will have to investigate further. However, the bounty is about to expire and I don't want you to miss out after all your hardwork, so I will award it to you. – big_smile Jan 30 '13 at 18:50

You appear to have no return if $cta_option is NULL or empty, may this be the problem? If you have the devel module installed ( if not install it, it will help with debugging no end ), try adding this somewhere in the function:

dpm('THEMENAME_field__field_call_to_action_button has run');

If you get a notification on those pages then the function is running but just isn't doing what you think it is ( probably not returning when $cta_option is NULL or empty ). If no notification appears then you may need to look at where that function is run.

if you do get the notification then change the line to


to see what the variable actually contains ( if anything ) on those pages and modify your switch accordingly.

  • If I run kpr($variables) from my function (in template.php) then the Devel message will appear, but only if the field has content (If there is no content, then nothing happens). dpm('THEMENAME_field__field_call_to_action_button has run') and dpm($cta_option); do nothing, regardless if the field has any content. – big_smile Jan 24 '13 at 21:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.