Вы здесь

Как использовать theme функцию для определенного блока?

0

Добрый день! Ломаю голову, сказывается недостаток понимания работы системы темизации в целом - есть модуль, Own carousel, есть файлик темизации в нем с таким содержимым:

/**
 * @file
 * owlcarousel.theme.inc
 *
 * Implements theme functions for Owl Carousel.
 */

/**
 * Template process carousel theme.
 */
function template_process_owlcarousel(&$vars) {
  $instance_id = $vars['settings']['instance'];
  $vars['settings']['attributes']['class'][] = $vars['settings']['id'];
}

/**
 * Theme declaration for Owl Carousel wrapper.
 */
function theme_owlcarousel_wrapper($variables) {
  $attributes = $variables['output']['#settings']['attributes'];
  return '<div' . drupal_attributes($attributes) . '>' . drupal_render($variables['output']) . '</div>';
}

/**
 * Theme declaration for Owl Carousel.
 */
function theme_owlcarousel($variables) {
  $instance = $variables['settings']['id'];
  $settings = $variables['settings'];
  $items = $variables['items'];

  $output = array(
    '#output' => array(
      'settings' => $settings,
      'items' => $items
    ),
    '#pre_render' => array('owlcarousel_pre_render_cache'),
  );

  return drupal_render($output);
}

/**
 * Construct element for render.
 */
function owlcarousel_pre_render_cache($element) {
  $settings = $element['#output']['settings']['instance'];
  $instance = $element['#output']['settings']['id'];

  $output = array(
    '#theme' => 'owlcarousel_list',
    '#items' => $element['#output']['items'],
    '#settings' => $element['#output']['settings']
  );

  // Load carousel settings from the instance id.
  $instance_settings = _owlcarousel_return_carousel_instance_settings($settings);

  // Provide legacy settings alter.
  drupal_alter('owlcarousel_settings', $instance_settings, $instance);

  // Element output /w attached.
  $element['#markup'] = owlcarousel_build($output);
  $element['#children'] = drupal_render($element['#markup']);
  $element['#attached'] = array(
    'js' => array(
      array(
        'data' => drupal_get_path('module', 'owlcarousel') . '/includes/js/owlcarousel.settings.js',
        'type' => 'file',
        'scope' => 'footer'
      ),
      array(
        'data' => array('owlcarousel' => array(
          $instance => array(
            'settings' => $instance_settings,
            'views' => array(
              'ajax_pagination' => variable_get('owlcarousel_override_ajax_pagination_' . $settings)
            ),
          ),
        ),),
        'type' => 'setting'
      )
    ),
    'library' => array(
      array(
        'owlcarousel',
        'owl-carousel'
      )
    ),
  );

  // Provide alter before carousel is rendered.
  drupal_alter('owlcarousel_pre_render', $element);

  return $element;
}

/**
 * Build final output array.
 */
function owlcarousel_build($output) {
  return array(
    '#output' => $output,
    '#theme_wrappers' => array('owlcarousel_wrapper'),
  );
}

/**
 * Default theme implementation for lists
 */
function theme_owlcarousel_list(&$vars) {
  $items = &$vars['items'];
  $output = '';

  if (!empty($items)) {
    foreach ($items as $i => $item) {
      $output .= theme('owlcarousel_list_item', array(
        'item' => $item['row'],
        'class' => drupal_html_class('item-' . $i),
      ));
    }
  }

  return $output;
}

/**
 * Default theme implementation for carousel items
 */
function theme_owlcarousel_list_item(&$vars) {
  return '<div class="' . $vars['class'] . '">' . $vars['item'] . "</div>";
}

Я переопределил функцию function theme_owlcarousel_list(&$vars) в template.php, изменил под свои нужды, и она работает так как нужно, но мне она нужна, только для определенных блоков Views, а не для всех, куда мне копать? Правка tpl views, не подходит, вывод строится этой функцией...

Версия Drupal: 
7.x
Категория: 
Theming
Связанные проекты: 
Owl Carousel
Вопрос задан 06.07.2015 - 17:59
Аватар пользователя Sora
Sora
91

А что содержится в

$settings = $element['#output']['settings']['instance'];
$instance = $element['#output']['settings']['id'];

?

Комментарий оставлен 06.07.2015 - 18:26

settings - owlcarousel_settings_top-selled
instance - owl-carousel-block_18

Я пробовал по instance другой theme_owlcarousel_list(&$vars) пихать, но ничего не вышло, видно фигню написал....

Комментарий оставлен 06.07.2015 - 18:36

Ответы

2
function MYTHEME_owlcarousel_list($vars) {
  if ($instance == 'owl-carousel-block_18') {
    $output = '';
    // тут формируем output
    return $output;
  }
  // иначе стандартный вывод
  return theme_owlcarousel_list($vars);
}

ну и то же самое по аналогии для других функций темизации

Ответ дан 06.07.2015 - 18:45
Аватар пользователя drupby
drupby
456

Спасибо, но не помогло - мой template.php

/**
 * Default theme implementation for lists
 */

function bootstrap_store_owlcarousel_list(&$vars) {
  $items = &$vars['items'];
  dpm($vars);
  $output = '';

  if ($instance == 'owl-carousel-block_18') {
    if (!empty($items)) {
      $array_for_print = array('item' => array(), 'class' => drupal_html_class('item'));
      foreach ($items as $i => $item) {
        $array_for_print['item'][] = $item['row'];
        if($i == 3){
          $output .= theme('owlcarousel_list_item', $array_for_print);
        } else{
          continue;
        }      
      }
    }

  } else {
    if (!empty($items)) {
      foreach ($items as $i => $item) {
        $output .= theme('owlcarousel_list_item', array(
          'item' => $item['row'],
          'class' => drupal_html_class('item'),
          ));
      }
    }

  }
  return $output;
}

function bootstrap_store_owlcarousel_list_item(&$vars) {

  if ($instance == 'owl-carousel-block_18') {

    $output = '';
    $output .= '<div class="my-test ' . $vars['class'] . '">';

    foreach ($vars['item'] as $i => $row){    
      $output .= $row;
    }
    $output .= "</div>";
    return $output;

  }else{
    return '<div class="' . $vars['class'] . '">' . $vars['item'] . "</div>";
  }    
}

Не работает - Notice: Undefined variable: instance in bootstrap_store_owlcarousel_list() (line 94 of /vagrant/drivercom/sites/all/themes/bootstrap_store/template.php).

Комментарий оставлен 06.07.2015 - 19:09

во-первых, нужно определить переменную $instance
во-вторых, я в примере совсем не такой код давал
код своего примера дополнил, чтобы было понятнее

Комментарий оставлен 06.07.2015 - 19:21

Переписал, добавил даже блок где переменная есть $instance, но ничего не меняется, я не понимаю, как определить мне $instance, если как я понимаю, у меня нет доступа к $variables внутри bootstrap_store_owlcarousel_list.


function bootstrap_owlcarousel($variables) { $instance = $variables['settings']['id']; $settings = $variables['settings']; $items = $variables['items']; $output = array( '#output' => array( 'settings' => $settings, 'items' => $items ), '#pre_render' => array('owlcarousel_pre_render_cache'), ); return drupal_render($output); } /** * Default theme implementation for lists */ function bootstrap_store_owlcarousel_list(&$vars) { $items = &$vars['items']; dpm($vars); $output = ''; if ($instance == 'owl-carousel-block_18') { if (!empty($items)) { $array_for_print = array('item' => array(), 'class' => drupal_html_class('item')); foreach ($items as $i => $item) { $array_for_print['item'][] = $item['row']; if($i == 3){ $output .= theme('owlcarousel_list_item', $array_for_print); } else{ continue; } } } return $output; } else { return theme_owlcarousel_list($vars); } } function bootstrap_store_owlcarousel_list_item(&$vars) { if ($instance == 'owl-carousel-block_18') { $output = ''; $output .= '<div class="my-test ' . $vars['class'] . '">'; foreach ($vars['item'] as $i => $row){ $output .= $row; } $output .= "</div>"; return $output; } else { return theme_owlcarousel_list_item($vars); } }
Комментарий оставлен 06.07.2015 - 19:33

если как я понимаю, у меня нет доступа к $variables внутри bootstrap_store_owlcarousel_list.

да у тебя же в функцию передается переменная $vars (по ссылке ее передавать кстати не нужно)
вот в $vars и ищи instance

Комментарий оставлен 06.07.2015 - 19:54

С самого начала так и хотел, но там нету этого, только -

items (Array, 6 elements)
context (Array, 0 elements)
theme_hook_suggestions (Array, 0 elements)

Комментарий оставлен 06.07.2015 - 19:56

должен еще быть элемент $vars['settings']
либо же тогда переопределять owlcarousel_pre_render_cache, для этого нужно в owlcarousel_pre_render_cache() изменить #pre_render на свою функцию и там изменить

$output = array(
    '#theme' => 'owlcarousel_list',
    '#items' => $element['#output']['items'],
    '#settings' => $element['#output']['settings']
);

в зависимости от инстанса

Комментарий оставлен 06.07.2015 - 20:35

Я честно говоря не понял, можно ли переопределять функции модуля, которые не theme_. Если можно, то где?

Комментарий оставлен 06.07.2015 - 20:44
function ИМЯТЕМЫ_owlcarousel($variables) {
  $instance = $variables['settings']['id'];
  $settings = $variables['settings'];
  $items = $variables['items'];

  $output = array(
    '#output' => array(
      'settings' => $settings,
      'items' => $items
    ),
    // задаем свой pre_render
    '#pre_render' => array('ИМЯТЕМЫ_owlcarousel_pre_render_cache'),
  );

  return drupal_render($output);
}
function ИМЯТЕМЫ_owlcarousel_pre_render_cache($element) {
  $settings = $element['#output']['settings']['instance'];
  $instance = $element['#output']['settings']['id'];

  $output = array(
    '#theme' => 'owlcarousel_list',
    '#items' => $element['#output']['items'],
    '#settings' => $element['#output']['settings']
  );
  // добавляем suggestion в виде id инстанса
  $output['#theme'] = 'owlcarousel_list__' .  str_replace('-', '_', $instance);

  // Load carousel settings from the instance id.
  $instance_settings = _owlcarousel_return_carousel_instance_settings($settings);

  //...всю функцию целиком не копировал
}

и потом можно для темизации использовать ИМЯТЕМЫ_owlcarousel_list__owl_carousel_block_13 вообщем смотри потом $vars['theme_hook_original'] в ИМЯТЕМЫ_owlcarousel_list

ну и как вариант добавить код в theme_owlcarousel

function ИМЯТЕМЫ_owlcarousel($variables) {
  $instance = $variables['settings']['id'];
  $settings = $variables['settings'];
  $items = $variables['items'];

  $instance_static = &drupal_static('instance_static');
  $instance_static = $instance;

  $output = array(
    '#output' => array(
      'settings' => $settings,
      'items' => $items
    ),
    '#pre_render' => array('owlcarousel_pre_render_cache'),
  );

  return drupal_render($output);
}

и потом в theme_owlcarousel_list и theme_owlcarousel_list_item получать значение инстанса
$instance_static = drupal_static('instance_static');

Комментарий оставлен 06.07.2015 - 21:04

Спасибо огромное, все получилось!

Комментарий оставлен 06.07.2015 - 22:10