Exibições - Adicione um DIV de invólucro ao redor de um grupo

43

No Drupal 7, criei uma exibição que lista vários campos. Os campos são agrupados por outro campo (o termo ID do campo). A marcação aparece assim:

<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>

No entanto, eu preciso da marcação para ficar assim:

<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>

Eu sei que você pode usar views-view-unformatted.tpl.php (Saída de estilo) para exceder a exibição e inserir um DIV para agrupar o grupo.

No entanto, eu preciso que meu DIV do invólucro seja assim <div id="term_ID_{number of ID}">. O ID do número corresponderá ao termo que foi usado para agrupar os campos. Por padrão, se você usar views-view-unformatted.tpl.php, não poderá inserir tokens para IDs de termo nele.

Qualquer ajuda seria apreciada.

grande sorriso
fonte

Respostas:

50

Eu precisava fazer a mesma coisa recentemente. Você pode criar um arquivo de modelo:

  • Encontre o modelo em /modules/views/themes/views-view-unformatted.tpl.php.
  • Copie-o para sua /sites/all/themes/<your-theme>pasta e renomeie para views-view-unformatted--<nodetype>.tpl.php.
  • Edite o arquivo adicionando um divao redor do modelo inteiro. A <h3>tag é o nome do grupo.

Aqui está a aparência do arquivo de modelo modificado.

<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-->
Kristy Gislason
fonte
4
Isso só funcionou para mim também, ta muito :) :)
Clive
Você salvou meu tempo amigo!
DropDragon
1
Para quem estiver lendo esta resposta, imaginando como descobrir o nome de seu tplarquivo, consulte a resposta aqui drupal.stackexchange.com/questions/11468/… tldr; em sua página de edição vista, sob avançado, clique tema: informações
user56reinstatemonica8
Embora o Q e A são Drupal 7, as mesmas obras para Drupal 8.
Duncanmoo
16

Tente Formato: lista HTML. Isso envolverá a coisa toda em uma lista de itens. Para mim, é perfeito (uma lista de itens de taxonomia). Espero que isto ajude.

Dagomar
fonte
Isso é bom. Eu queria adicionar o campo de grupo como uma classe no wrapper para poder estilizar adequadamente, mas não consigo fazer isso na própria interface do usuário das visualizações. Em vez disso, o que fiz se ajudar alguém é: ORDENAR por esse campo também primeiro e depois usar o primeiro seletor de css.
klidifia
11

Você já experimentou o recurso Reescrever resultados ? Clique no campo que deseja editar e role para baixo até ver Reescrever resultados . Marque a caixa Reescrever a saída desse campo e personalize o HTML conforme necessário. Para os tokens, você pode usar os Padrões de substituição mostrados na caixa abaixo da área de entrada de texto.

Em relação aos padrões de substituição , observe o aviso exibido pelo Views:

Observe que, devido à ordem de renderização, você não pode usar campos que vêm depois desse campo; se você precisar de um campo não listado aqui, reorganize-os.

Se isso não for suficiente, tente adicionar um novo campo, Global: Texto personalizado . Isso permitirá que você adicione um pouco de HTML arbitrário e os padrões de substituição também estão disponíveis aqui. Você pode usar dois campos de texto Global: Custom separados para adicionar as <div>tags de início e fim.

Patrick Kenny
fonte
Oi, obrigado pela sua ajuda. Estou tentando alterar o campo de agrupamento (em Página: Opções de estilo> Campo de agrupamento nº 1) Não parece haver nenhuma opção para alterar a saída desse campo de agrupamento. Usando Global: Custom textefeitos a linha dentro do grupo, mas não fora do grupo,
big_smile
Quando você seleciona o campo Agrupamento Nr.1 , há opções para Usar saída renderizada para agrupar linhas e classe Linha . Nenhum deles faz o que você quer?
Patrick Kenny
1
Oi, obrigado pela sua ajuda. Essas opções apenas adicionam DIvs de invólucro ao redor dos campos individuais, em oposição a todo o grupo (criado pelo campo Nr.1 ​​do agrupamento).
Big_smile
@PatrickKenny Você sabe se esse método tem um impacto ruim no tempo de renderização da exibição?
user5950
@ user5950 Uso reescrever resultados o tempo todo, mas nunca notei um impacto no desempenho. Penso que outras tarefas comuns de visualização, como adicionar relacionamentos, têm mais probabilidade de prejudicar o desempenho antes da reescrita de resultados.
22813 Patrick Kenny
5

Esses dias eu me deparei com o mesmo problema. E o que eu precisava ao lado do wrapper do grupo era uma classe de CSS como a primeira / a última por grupo.

Então eu adicionei no views-view-unformatted.tpl.php o seguinte código php:

<?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);
?>

Aqui a parte html com o wrapper e as 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>

A saída será:

<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>

Pode ser útil - aproveite

andres
fonte
3

Então, acho que o maior enigma é como gerar a classe usando o valor do $ title nas tags h3. Eu tentaria o módulo Transliteração e o seguinte trecho:

<?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);
?>

Isso funcionou para mim quando tive que criar âncoras nomeadas em uma exibição.

Artur
fonte
2

Muito útil - eu precisava adicionar algumas classes alfa / ômega para um layout baseado em grade e também algumas ímpares para poder limpar as duas para cada linha. Eu editei a linha de:

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

para isso:

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

O que fornece a saída necessária.

Soulston
fonte
2

Você não precisa do módulo de transliteração. O núcleo do Drupal tem a função drupal_html_class para isso.

Baris Wanschers
fonte
2

Eu tive um problema semelhante hoje, mas precisava de uma classe específica no html do wrapper; no meu caso, a exibição é agrupada por termos de taxonomia e precisamos de um estilo específico para cada termo, portanto, uma classe específica por termo. Veja como alteramos o modelo não formatado da visualização:

<?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-->

Na exibição, a exibição do campo de termo de taxonomia é configurada para: "Mostrar ID da entidade". Portanto, obtemos o ID como parte do nome da classe e carregamos o título com base no mesmo ID.

vegardjo
fonte
2

Para quem não quer se aprofundar no código e mexer nos modelos, há uma maneira fácil de fazer isso, removendo as classes div padrão usando o Fences e adicionando sua própria div no prefixo e sufixo do campo usando o formatador de campo simples . Se você tiver vários campos, adicione a div que contém no prefixo do primeiro campo e no sufixo do último campo.

Portanto, a estrutura nativa com as áreas de prefixo e sufixo desmarcadas seria algo como:

<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>

Se você fosse adicionar a classe "foo", isso se tornaria

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

A resposta de chrisjlee acima explica bem, exceto pelo nome do arquivo de modelo. Se você deseja alterar apenas uma visão, o novo arquivo deve incluir o nome da máquina. Você pode encontrar isso no URL da página de edição da visualização. É explicado muito bem neste comentário sobre um problema semelhante: https://www.drupal.org/node/1383696#comment-6729128

Eu precisava de uma classe em torno das linhas usando o valor de $ title para que eu pudesse renderizá-las em 2 colunas. Aqui está o código:

<?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-->
jn2
fonte
2

Me deparei com um problema semelhante. Eu queria que minhas linhas agrupadas fossem exibidas dentro de um acordeão de inicialização. Eu não poderia trabalhar com o módulo Views Bootstrap .
O comentário nº 4 resolveu meu problema.
Aqui está a minha views-view-unformatted-[my_view_name]-[my_display_name].tpl.phpaparência

<?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>

é claro, para que o acordeão funcione, você também precisa editar views-view- [my_view_name] - [my_display_name] .tpl.php para ter

<?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; ?>

Deixei o código padrão do módulo entre comentários html.
Espero que ajude.

Marte
fonte