' . t('About Portfolio') . ''; $output .= '

' . t('Portfolio module provide a Drupal integration with the jquery library Shuffle. This module provide :') . '

'; $output .= ''; $output .= '

' . t("For more information, see README.txt") . '

'; return $output; } } /** * Implements hook_theme(). */ function portfolio_theme() { return array( 'field_portfolio' => array( 'variables' => array( 'items' => NULL, 'settings' => NULL, 'filter_options' => NULL, 'view_mode' => NULL, 'entity' => NULL, 'wrapper_class' => NULL, 'field_name' => NULL, ), ), ); } /** * Implements hook_theme_suggestions_HOOK_alter(). */ function portfolio_theme_suggestions_views_view_portfolio_alter(array &$suggestions, array $variables, $hook) { $view = $variables['view']; $id = $view->storage->id(); $display = $view->current_display; $suggestions[] = 'views_view_portfolio__' . $id; $suggestions[] = 'views_view_portfolio__' . $display; $suggestions[] = 'views_view_portfolio__' . $id . '__' . $display; } /** * Prepares variables for views portfolio style templates. * * Default template: views-view-portfolio.html.twig. */ function template_preprocess_views_view_portfolio(array &$variables) { /** @var \Drupal\views\ViewExecutable $view */ $view = $variables['view']; $rows = $variables['rows']; $style = $view->style_plugin; $options = $style->options; $portfolio_id = Html::cleanCssIdentifier('views-portfolio-' . $view->storage->id() . '-' . $view->current_display); $default_row_class = isset($options['default_row_class']) ? $options['default_row_class'] : FALSE; $langcode = \Drupal::config('system.site')->get('langcode'); $trans = new PhpTransliteration(); // If filters are set, use the field label to render it // as title of selector list. $filter = $options['filter']; if (isset($view->field[$filter])) { if ($view->field[$filter]->options['label']) { $variables['filter_label'] = $view->field[$filter]->options['label']; } } // The filters found in each row. $filters = ''; // The list of all filter found in all rows. $filters_list = []; // A temporay array for keeping original filter value. $tmp = []; $count = 0; $max = count($rows); foreach ($rows as $id => $row) { // Prepare filter if enable. if ($filter != 'none') { if (isset($view->field[$filter])) { // get entities id from field $filters_values = $style->getFieldValue($id, $filter); // Process filters_name only if there is some data. if (!empty($filters_values)) { foreach ($filters_values as $key => $term_id) { // Transliterate value for serialize them in a Json object. $filters_values[$key] = $filter . '-' . $term_id; // Keep original value for display them in the select list. $tmp[$key] = trim($term_id); } // Merge the filters for use them in the selector list. $filters_list = array_unique(array_merge($filters_list, $tmp)); // Encode the field's values to set it as a row attribute. $filters = Json::encode($filters_values); } } } $variables['grid_classes'] = portfolio_build_classes($options); $variables['nogutter'] = $options['nogutter']; // Defining classes. $classes = array(); $count++; $classes[] = 'shuffle-item'; if ($options['nogutter']) { $classes[] = 'no-gutter'; } if ($default_row_class) { $classes[] = 'views-row'; $classes[] = 'views-row-' . $count; $classes[] = 'views-row-' . ($count % 2 ? 'odd' : 'even'); if ($count == 1) { $classes[] = 'views-row-first'; } if ($count == $max) { $classes[] = 'views-row-last'; } } if ($row_class = $view->style_plugin->getRowClass($id)) { $classes[] = $row_class; } $variables['rows'][$id] = array(); $variables['rows'][$id]['content'] = $row; /** @var \Drupal\Core\Template\Attribute $attributes */ $attributes = new Attribute(); $attributes->addClass($classes); if ($filters) { $attributes->setAttribute('data-groups', $filters); } $variables['rows'][$id]['attributes'] = $attributes; } // Prepare the list of options filter. $filters_options = []; $variables['filter_options'] = []; if ($filters_list && count($filters_list) > 1) { foreach ($filters_list as $key => $value) { // render the term to get the label $term = Term::load($value); $name = $term->getName(); $filters_options[$key]['#markup'] = $name; $filters_options[$key]['#wrapper_attributes'] = array( 'class' => array('shuffle-filters-item'), 'data-group' => array($filter . '-' . $value), ); } $variables['filter_options'] = array( '#theme' => 'item_list', '#items' => $filters_options, '#attributes' => array( 'class' => array( 'shuffle-filters', 'filter-options', ), ), ); } // The wrapper class is used for initializing each shuffle grid in shuffle.js. $wrapper_class = new Attribute(); $wrapper_class->addClass($portfolio_id); $variables['wrapper_class'] = $wrapper_class; $wrapper_class->addClass('portfolio-wrapper'); if ($options['nogutter']) { $wrapper_class->addClass('no-gutter-wrapper'); } } function portfolio_build_classes($options) { $css = array(); $devices = array( 'sm', 'md', 'lg' ); foreach ($devices as $device) { if ($options[$device]) { $css[] = 'col-' . $device . '-' . $options[$device]; } } return $css; }