One crazy way to theme a fieldable panels pane to get exactly the markup you want.

In a hurry to get this information up... Sorry for any typos :)

First, prevent modules like Display Suite from taking over by adjusting module weight. Otherwise, you can't offer template suggestions. This method is way better than display suite anyway.
<?php
/**
 * Implements hook_install().
 * 
 * Sets module weight to high number so that it runs after contrib modules.
 */
function examplebannerwithfactbox_install() {
  db_query("UPDATE {system} SET weight = 2000 WHERE type = 'module' AND name = 'examplebannerwithfactbox'");
}
 
?>
Then, create new fieldable_panels_pane bundle:
<?php
/**
 * Implements hook_entity_info_alter().
 * 
 * Adds fieldable panel pane bundles.
 */
function examplebannerwithfactbox_entity_info_alter(&$entity_info) {
  $entity_info['fieldable_panels_pane']['bundles']['bannerwithfactbox'] = array(
    'label' => t('Banner w/ Fact Box'),
    'pane category' => t('Custom'),
    'pane top level' => TRUE,
    //'pane icon' => drupal_get_path('module', 'examplebannerwithfactbox') . '/images/icon-banner.png',
    'admin' => array(
      'path' => 'admin/structure/fieldable-panels-panes/manage/%fieldable_panels_panes_type',
      'bundle argument' => 4,
      'real path' => 'admin/structure/fieldable-panels-panes/manage/bannerwithfactbox',
      'access arguments' => array('administer fieldable panels panes'),
    ),
  );
}
 
?>
Alter the edit form for the new fieldable panel pane to clear up the editor interface. There are two hooks needed, one for the standalone edit form and another for the panels UI edit form. So, I call out a helper function in both hooks, resulting in three functions:
<?php
/**
 * Implements hook_form_FORM_ID_alter().
 * 
 * Alters the Fieldable Panels Panes content edit form.
 */
function examplebannerwithfactbox_form_fieldable_panels_panes_entity_edit_form_alter(&$form, &$form_state, $form_id) {
  _examplebannerwithfactbox_fieldable_panels_panes_entity_edit_form_alter($form);
}
 
/**
 * Implements hook_form_FORM_ID_alter().
 * 
 * Alters the Fieldable Panels Panes content edit form used within the panels UI.
 */
function examplebannerwithfactbox_form_fieldable_panels_panes_fieldable_panels_pane_content_type_edit_form_alter(&$form, &$form_state, $form_id) {
  _examplebannerwithfactbox_fieldable_panels_panes_entity_edit_form_alter($form);
}
 
/**
 * Alters the Fieldable Panels Panes content edit forms.
 */
function _examplebannerwithfactbox_fieldable_panels_panes_entity_edit_form_alter(&$form) {
  switch ($form['#bundle']) {
    case 'banner_with_fact_boxes':
    case 'bannerwithfactbox':
      // Do not render the checkbox that asks whether to make the title a link since
      // the title is not shown on the edit form.
      unset($form['link']);
      // Adds help text to the title field.
      $form['title']['#description'] = t('The title is only used for administrative purposes.');
      // Sets default state of the revision checkbox to disabled.
      $form['revision']['revision']['#default_value'] = 0;
      break;
    case 'quick_facts_row':
      // Sets default state of the revision checkbox to disabled.
      $form['revision']['revision']['#default_value'] = 0;
      break;
  }
}
 
?>
Add a line to the .info file to add a css file:
stylesheets[all][] = css/examplebannerwithfactbox.css
Add a custom template file:
<?php
/**
 * Implements hook_theme();
 */
function examplebannerwithfactbox_theme() {
  return array(
    'examplebannerwithfactbox' => array(
      'template' => 'examplebannerwithfactbox',
      'path' => drupal_get_path('module', 'examplebannerwithfactbox') . '/templates',
    ),
  );
}
 
?>
In the preprocessor, for each field, use render() but render out the individual ['content']['field_name'][0] field entries instead of rendering out the entire field. This is only necessary if you don't want all the field wrapper stuff.
<?php
/**
 * Preprocesses fieldable panels panes.
 */
function examplebannerwithfactbox_preprocess_fieldable_panels_pane(&$variables) {
  switch ($variables['elements']['#bundle']) {
    case 'bannerwithfactbox':
      $variables['theme_hook_suggestions'][] = 'examplemodule';
      $variables['banner'] = isset($variables['content']['field_bannerwithfactbox_banner'][0]) ? render($variables['content']['field_bannerwithfactbox_banner'][0]) : '';
      $variables['heading'] = isset($variables['content']['field_bannerwithfactbox_heading'][0]) ? render($variables['content']['field_bannerwithfactbox_heading'][0]) : '';
      $variables['thumb'] = isset($variables['content']['field_bannerwithfactbox_img'][0]) ? render($variables['content']['field_bannerwithfactbox_img'][0]) : '';
      $variables['link'] = isset($variables['field_bannerwithfactbox_img'][0]['uri']) ? $variables['field_bannerwithfactbox_img'][0]['uri'] : '';
      $variables['teaser'] = isset($variables['content']['field_bannerwithfactbox_teaser'][0]) ? render($variables['content']['field_bannerwithfactbox_teaser'][0]) : '';
      $variables['layout'] = drupal_clean_css_identifier($variables['content']['field_bannerwithfactbox_layout']['#items'][0]['value']);
      $variables['heading_bg'] = drupal_clean_css_identifier($variables['content']['field_bannerwithfactbox_headbg']['#items'][0]['value']);
      break;
  }
}
 
?>
This last step may not be necessary, but I'm not sure right now so I'm adding it here anyway :)
<?php
/**
 * Implements hook_module_implements_alter().
 */
function examplebannerwithfactbox_module_implements_alter(&$implementations, $hook) {
  // Runs our examplebannerwithfactbox theme suggestion after other modules.
  if ($hook == 'examplebannerwithfactbox') {
    unset($implementations['examplebannerwithfactbox']);
    $implementations['examplebannerwithfactbox'] = FALSE;
  }
}
 
?>

Tags

Internal References

Article Type

General