1

On my drupal 8 website I have created a view, with list of content. As an output format I have chosen HTML list. So currently it looks like following:

 <form id="views-form">
   <div></div>
   <div class="item-list"></div>
   <div class="item-list"></div>
   <div class="item-list"></div>
   <div class="item-list"></div>
   <div class="item-list"></div>
    ....
   <div></div>
</form>

For formatting I would need to wrap the html list in some other div, is there a way to do it ? Can not find anything in the interface.

Expected:

<form id="views-form">
   <div></div>
   <div class="html_list">
     <div class="item-list"></div>
     <div class="item-list"></div>
     <div class="item-list"></div>
     <div class="item-list"></div>
     <div class="item-list"></div>
   </div> 
   ....
   <div></div>
</form>
1
  • There are good template methods to customize markup. Are you trying to wrap an element in views rows, or views filters?? The only problem I see with the jQuery below is that Drupal May print out that class in other, unwanted instances. Jan 25, 2019 at 20:09

1 Answer 1

1

Another approach would be template files.

The template name depends on the entity you are theming.

For example, with views-view-list.html.twig:

change

<{{ list.type }}{{ list.attributes }}>

  {% for row in rows %}
    <li{{ row.attributes }}>
      {{- row.content -}}
    </li>
  {% endfor %}

</{{ list.type }}>

to

<div class="html_list">
  <{{ list.type }}{{ list.attributes }}>

    {% for row in rows %}
      <li{{ row.attributes }}>
        {{- row.content -}}
      </li>
    {% endfor %}

  </{{ list.type }}>
 </div>

If you go the template route, it can be general so that any view of that type will inherit your custom markup. Or, it can be specific to that view name or ID.


If you want to utilize jQuery, I would recommend being more specific with your class selectors and allow for multiple view instances. For example:

$('.views-class ul').each(function() {
  if ($(this).hasClass('item-list')) {
    $(this).wrap("<div class='html_list'></div>");
  }
});

Here is an example views-view.html.twig, which is one level up really from the above template... which prints the views name as a class... which allows view by view customization to structure and layout by CSS alone:

views-view.html.twig

{%
  set classes = [
    dom_id ? 'js-view-dom-id-' ~ dom_id,
    'views-wrapper',
    'view-' ~ css_name,
  ]
%}

<div {{ attributes.addClass(classes) }}>

  {{ title_prefix }}
  {{ title }}
  {{ title_suffix }}

  {% if header %}
    <header>
      {{ header }}
    </header>
  {% endif %}

  {{ exposed }}

  {% if attachment_before %}
    <div class="views-attachment views-attachment-before">
      {{ attachment_before }}
    </div>
  {% endif %}

  {% if rows.header %}
    <div class="views-header-wrapper">
      {{ rows.header }}
    </div>
  {% endif %}

  {# add custom wrapper here around rows, or in deeper template files. #}
  {{ rows | without('header') }}

  {{ empty }}

  {% if pager %}
    <div class="views-pager">
      {{ pager }}
    </div>
  {% endif %}

  {% if attachment_after %}
    <div class="views-attachment views-attachment-after">
      {{ attachment_after }}
    </div>
  {% endif %}

  {% if more %}
    <div class="views-more">
      {{ more }}
    </div>
  {% endif %}

  {% if footer %}
    <footer>
      {{ footer }}
    </footer>
  {% endif %}

  {{ feed_icons }}

</div>

Plus, this template separates the header and exposed filters making custom templating and individual CSS easier to implement and maintain.

I add this answer because I believe Drupal theming layer should be utilized when possible before jQuery and other front-end technologies.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.