web-dev-qa-db-fra.com

Vues - Ajouter un DIV wrapper autour d'un groupe

Dans Drupal 7, j'ai créé une vue qui répertorie plusieurs champs. Les champs sont regroupés par un autre champ (l'ID de terme du champ). Le balisage ressemble à ceci:

<h3>[Term 1]</h3>
<div class="views-row views-row-1 views-row-odd views-row-first"> [Field Content] </div>
<div class="views-row views-row-2 views-row-even"> [Field Content] </div>
<div class="views-row views-row-3 views-row-odd views-row-last"> [Field Content] </div>

<h3>[Term 2]</h3>
<div class="views-row views-row-1 views-row-odd views-row-first"> [Field Content] </div>
<div class="views-row views-row-2 views-row-even"> [Field Content] </div>
<div class="views-row views-row-3 views-row-odd views-row-last"> [Field Content] </div>

<h3>[Term 3]</h3>
<div class="views-row views-row-1 views-row-odd views-row-first"> [Field Content] </div>
<div class="views-row views-row-2 views-row-even"> [Field Content] </div>
<div class="views-row views-row-3 views-row-odd views-row-last"> [Field Content] </div>

Cependant, j'ai besoin de la marque pour ressembler à ceci:

<div id="term_1">
     <h3>[Term 1]</h3>
     <div class="views-row views-row-1 views-row-odd views-row-first"> [Field Content] </div>
     <div class="views-row views-row-2 views-row-even"> [Field Content] </div>
     <div class="views-row views-row-3 views-row-odd views-row-last"> [Field Content] </div>
</div>

<div id="term_2">
     <h3>[Term 2]</h3>
     <div class="views-row views-row-1 views-row-odd views-row-first"> [Field Content] </div>
     <div class="views-row views-row-2 views-row-even"> [Field Content] </div>
     <div class="views-row views-row-3 views-row-odd views-row-last"> [Field Content] </div>
</div>

<div id="term_3">
     <h3>[Term 3]</h3>
     <div class="views-row views-row-1 views-row-odd views-row-first"> [Field Content] </div>
     <div class="views-row views-row-2 views-row-even"> [Field Content] </div>
     <div class="views-row views-row-3 views-row-odd views-row-last"> [Field Content] </div>
</div>

Je sais que vous pouvez utiliser views-view-unformatted.tpl.php (Style Output) pour surpasser la vue, puis insérer un DIV pour envelopper le groupe.

Cependant, j'ai besoin que mon wrapper DIV soit comme ça <div id="term_ID_{number of ID}">. L'identifiant numérique correspondra au terme utilisé pour regrouper les champs. Par défaut, si vous utilisez views-view-unformatted.tpl.php, vous ne pouvez pas y insérer de jetons pour les ID de terme.

Toute aide serait appréciée.

42
big_smile

J'ai dû faire la même chose récemment. Vous pouvez créer un fichier modèle:

  • Trouvez le modèle sous /modules/views/themes/views-view-unformatted.tpl.php.
  • Copiez-le dans votre /sites/all/themes/<your-theme> dossier et renommer en views-view-unformatted--<nodetype>.tpl.php.
  • Modifiez le fichier en ajoutant un div autour de l'ensemble du modèle. Le <h3> tag est le nom du groupe.

Voici à quoi pourrait ressembler le fichier de modèle modifié.

<div class="your-class">
<?php if (!empty($title)): ?>
    <h3><?php print $title; ?></h3><!--this is the group name-->
<?php endif; ?>
<?php foreach ($rows as $id => $row): ?>
  <div class="<?php print $classes_array[$id]; ?>">
    <?php print $row; ?>
</div>
<?php endforeach; ?>
</div><!--end your div-->
50
Kristy Gislason

Essayez Format: liste HTML. Cela enveloppera le tout dans une liste d'articles. Pour moi, c'est parfait (une liste d'articles de taxonomie). J'espère que cela t'aides.

15
Dagomar

Avez-vous essayé la fonction Rewrite results? Cliquez sur le champ que vous souhaitez modifier et faites défiler vers le bas jusqu'à ce que vous voyiez Réécrire les résultats. Cochez la case Réécrivez la sortie de ce champ , puis personnalisez le code HTML si nécessaire. Pour les jetons, vous pouvez utiliser les Patterns de remplacement affichés dans la zone sous la zone de saisie de texte.

Concernant le Patterns de remplacement, notez l'avertissement que Views affiche:

Notez qu'en raison de l'ordre de rendu, vous ne pouvez pas utiliser les champs qui viennent après ce champ; si vous avez besoin d'un champ non répertorié ici, réorganisez vos champs.

Si cela ne suffit pas, essayez d'ajouter un nouveau champ, Global: texte personnalisé. Cela vous permettra d'ajouter du HTML arbitraire et les Patterns de remplacement sont également disponibles ici. Vous pouvez utiliser deux champs Global: texte personnalisé distincts pour ajouter le <div> balises de début et de fin.

10
Patrick Kenny

Ces jours-ci, je suis tombé sur le même problème. Et ce dont j'avais besoin à côté de l'encapsuleur de groupe était une classe CSS comme premier/dernier par groupe.

J'ai donc ajouté dans views-view-unformatted.tpl.php le code php suivant:

<?php
  #### defs
  // call a global variable every time the template is called
  global $static;
  // be aware of the key_name for the global variable to keep it 
  // unique for every display
  // I call the same view in one panel several times with 
  // different arguments 
  $key_name = $view->name . '_' . $view->current_display ;
  foreach ($view->args as $value) {
    $key_name .= '_' . $value;
  }
  // init classes array
  $group_classes = array();
  ## groups counter - store in global variable 
  if (!isset($static[$key_name]['gc'])) {
    $static[$key_name]['gc'] = 1;
  }
  else {
    $static[$key_name]['gc']++;
  }
  #### classes
  ## counter
  $group_classes[] = 'group-' . $static[$key_name]['gc'];
  ## first
  if ($static[$key_name]['gc'] == 1) {
    $group_classes[] = 'first';
  }
  ## last
  // get max row "id" per group
  foreach ($rows as $id => $row) {
    $max_id = $id;
  }
  // count results (-1 because $id starts with 0)
  $count_results = count($view->result) - 1;
  //
  if ($max_id == $count_results) {
    $group_classes[] = 'last';
  }
  ## ret
  $group_class = implode(' ', $group_classes);
?>

Voici la partie html avec le wrapper et les classes:

<div class="views-group <?php print $group_class; ?>">
  <?php if (!empty($title)): ?>
    <h3><?php print $title; ?></h3>
  <?php endif; ?>
  <?php foreach ($rows as $id => $row): ?>
    <div <?php if ($classes_array[$id]) { print 'class="' . $classes_array[$id] .'"';  } ?>>
      <?php print $row; ?>
    </div>
  <?php endforeach; ?>
</div>

La sortie sera:

<div class="views-group group-1 first">
  content of first group
</div>
<div class="views-group group-2">
  content of second group
</div>    
<div class="views-group group-3 last">
  content of third group
</div>

Pourrait être utile - profitez-en

4
andres

Je suppose donc que la plus grande énigme est de savoir comment générer la classe en utilisant la valeur du $ title dans les balises h3. J'essaierais le module de translittération et l'extrait de code suivant:

<?php
  $group_class = function_exists('transliteration_get') ? transliteration_get($title) : $title;
  $group_class = trim($group_class);
  $group_class = str_replace(' ', '-', $group_class);
  $group_class = strtolower($group_class);
?>

Cela a fonctionné pour moi lorsque j'ai dû créer des ancres nommées dans une vue.

2
Artur

Je suis tombé sur un problème similaire. Je voulais que mes rangées groupées s'affichent dans un bootstrap accordéon. Je ne pouvais pas le faire fonctionner avec le Views Bootstrap module .
Le commentaire # 4 a résolu mon problème.
Voici ce que mon views-view-unformatted-[my_view_name]-[my_display_name].tpl.php ressemble à

<?php

/**
 * @file
 * YOUR_THEME simple view template to display a list of rows.
 *
 * @ingroup views_templates
 */
?>

    <?php
    #### defs
      // call a global variable every time the template is called
      global $static;
      // be aware of the key_name for the global variable to keep it 
      // unique for every display
      // I call the same view in one panel several times with 
      // different arguments 
      $key_name = $view->name . '_' . $view->current_display ;
      foreach ($view->args as $value) {
        $key_name .= '_' . $value;
      }
      // init classes array
      $group_classes = array();
      ## groups counter - store in global variable 
      if (!isset($static[$key_name]['gc'])) {
        $static[$key_name]['gc'] = 1;
      }
      else {
        $static[$key_name]['gc']++;
      }
      #### classes
      ## counter
      $group_classes[] = 'group-' . $static[$key_name]['gc'];
      ## first
      if ($static[$key_name]['gc'] == 1) {
        $group_classes[] = 'first';
      }
      ## last
      // get max row "id" per group
      foreach ($rows as $id => $row) {
        $max_id = $id;
      }
      // count results (-1 because $id starts with 0)
      $count_results = count($view->result) - 1;
      //
      if ($max_id == $count_results) {
        $group_classes[] = 'last';
      }
      ## ret
      $group_class = implode(' ', $group_classes);
      $group_id = implode($group_classes); // helps me having a id whithout spaces for my accordions panels.
    ?>

    <div class="panel panel-default <?php print $group_class; ?>">
        <?php if (!empty($title)): ?>
          <?php if($group_id == 'group-1first'): ?>
                <!--<h3><?php //print $title; ?></h3>-->
                <div class="panel-heading" role="tab" id="heading<?php print $group_id; ?>">
                    <h3 class="panel-title">
                        <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse<?php print $group_id; ?>" aria-expanded="true" aria-controls="collapse<?php print $group_id; ?>">
                            <?php print $title; ?>
                        </a>
                    </h3>
                </div>
                <div id="collapse<?php print $group_id; ?>" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="heading<?php print $group_id; ?>">

            <?php else: ?>
                <div class="panel-heading" role="tab" id="heading<?php print $group_id; ?>">
                    <h3 class="panel-title">
                        <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse<?php print $group_id; ?>" aria-expanded="false" aria-controls="collapse<?php print $group_id; ?>">
                            <?php print $title; ?>
                        </a>
                    </h3>
                </div>
                <div id="collapse<?php print $group_id; ?>" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading<?php print $group_id; ?>">

            <?php endif; ?>
        <?php endif; ?>                                                 

                    <div class="panel-body">
                        <?php foreach ($rows as $id => $row): ?>
                                    <div<?php if ($classes_array[$id]) { print ' class="' . $classes_array[$id] .'"';  } ?>>
                                        <?php print $row; ?>
                                    </div>
                        <?php endforeach; ?>
                    </div>
            </div>
    </div>

bien sûr, pour que l'accordéon fonctionne, vous devez également éditer views-view- [my_view_name] - [my_display_name] .tpl.php afin d'avoir

<?php if ($rows): ?>
    <!--<div class="view-content">-->
    <div class="view-content panel-group" id="accordion" role="tablist" aria-multiselectable="true">
      <?php print $rows; ?>
    </div>
  <?php elseif ($empty): ?>
    <div class="view-empty">
      <?php print $empty; ?>
    </div>
  <?php endif; ?>

J'ai laissé le code par défaut du module entre les commentaires html.
J'espère que cela aide.

1
Mars

Pour tous ceux qui ne veulent pas plonger dans le code et se moquer des modèles, il existe un moyen facile de le faire en supprimant les classes div par défaut en utilisant Fences et en ajoutant votre propre div dans le préfixe et le suffixe de le champ en utilisant Formateur de champ simple . Si vous avez plusieurs champs, ajoutez simplement le div contenant dans le préfixe du premier champ et le suffixe du dernier champ.

Ainsi, la structure native avec les zones de préfixe et de suffixe non dépouillées ressemblerait à quelque chose comme:

<div class="field field-name-field-test field-type-text field-label-above">
 <div class="field-label">Foobar field:&nbsp;</div>
  <div class="field-items">
   *:prefix posted here*
   <div class="field-item even">Leaner markup means better front-end performance.</div>
   *:suffix posted here*
 </div>
</div>

Si vous deviez ajouter la classe "foo", il deviendrait

   <div class="foo"> *:prefix posted here*
    Leaner markup means better front-end performance.
   </div> *:suffix posted here*
1
Ezra

Très utile - je devais ajouter quelques classes alpha/oméga pour une mise en page basée sur une grille et aussi quelques étranges même pour pouvoir effacer les deux pour chaque ligne. J'ai édité la ligne de:

$group_classes[] = 'group-' . $static[$key_name]['gc'];

pour ça:

$group_classes[] = 'group-' . $static[$key_name]['gc'] . ($static[$key_name]['gc'] % 2 ? ' alpha even' : ' omega odd');

Ce qui donne la sortie requise.

1
soulston

J'ai eu un problème similaire aujourd'hui, mais j'avais besoin d'une classe spécifique sur le wrapper html, dans mon cas, la vue est groupée par termes de taxonomie, et nous avons besoin d'un style spécifique sur chaque terme, donc une classe spécifique par terme. Voici comment nous avons modifié le modèle d'affichage non formaté:

<?php if(is_numeric($title)) { $term = taxonomy_term_load($title); $title = $term->name; } ?>
<div class="term-<?php print $term->tid;?>">
<?php if (!empty($title)): ?>
    <h3><?php print $title; ?></h3><!--this is the group name-->
<?php endif; ?>
<?php foreach ($rows as $id => $row): ?>
  <div class="<?php print $classes_array[$id]; ?>">
    <?php print $row; ?>
</div>
<?php endforeach; ?>
</div><!--end your div-->

Dans la vue, l'affichage du champ de terme de taxonomie est défini sur: "Afficher l'identifiant d'entité". Nous obtenons donc l'id dans le nom de classe, puis charge le titre en fonction du même id.

1
vegardjo

La réponse de chrisjlee ci-dessus l'explique bien, sauf pour nommer le fichier modèle. Si vous souhaitez modifier une seule vue, le nouveau fichier doit inclure le nom d'ordinateur de la vue. Vous pouvez le trouver dans l'url de la page d'édition de la vue. C'est très bien expliqué dans ce commentaire sur un problème similaire: https://www.drupal.org/node/1383696#comment-6729128

J'avais besoin d'une classe autour des lignes en utilisant la valeur de $ title afin de pouvoir les rendre sur 2 colonnes. Voici le code:

<?php if (!empty($title)): ?>
  <h3><?php print $title; ?></h3>
<?php endif; ?>
<div class="<?php print strtolower($title); ?>" > <!--added div with class-->
<?php foreach ($rows as $id => $row): ?>
  <div<?php if ($classes_array[$id]) { print ' class="' . $classes_array[$id] .'"';  } ?>>
    <?php print $row; ?>
  </div>
<?php endforeach; ?>
</div> <!--end of added div-->
1
jn2

Vous n'avez pas besoin du module de translittération. Drupal core a la fonction drupal_html_class pour cela.

1
Baris Wanschers