Show Drupal 8 Content in Tabs, Using Views

Show Drupal Content in Tabs, Using Views

One of our OSTraining members asked how best to make a tabbed view of content in Drupal 8. We already have a whole class on tabs in Drupal 7, but D8 works differently.

For this tutorial, I used 2 content types: “Article” and “News”. We are going to show the Articles in one tab, and the News in a second tab.

In Drupal 8, you can make tabs without using any extra modules at all.

As a tip, I used the Devel module to create some dummy content for this exercise. You don’t have to do this, but Devel always make it easy to test content-heavy tasks.

Once we have our content, we can go ahead and make our view.

  • Go to Structure > Views > Add a new view. and set the view settings.

Logically you would be tempted here to select “Create a page or Create a block”, but I found doing so created an issue. So skip these and we will explain how to make these from the view.

  • Enter a “View name” and click “Save and edit”.

Creating a new view

Now we need to add a page display. When we do this the default Master will become hidden.

  • Click “Add” and choose “Page”.

2

  • Update the display name. This is going to display our Article entries, so I am going to rename it to “Articles”.
  • Update the Menu from ‘No menu’ to  ‘Default menu tab’. Be sure to add a ‘Menu link title’ and save. On the next page ‘Already exists’ should be selected by default. Select “apply”.
  • We also need to set a Path as doing it this way does not generate a path to start with. The path will bring up this first page, which for us will be using Articles.

I’ve updated the fields and tweaked the display. See below if you want your view to look exactly the same.

3

  • Now we need to duplicate the page display. This will create the second tab.

4

Update the following settings

  • Display Name
  • Path
  • Menu

5

  • Now update the “Filter Criteria” so that it only displays the News content. Be sure to set that it only applies to this display:

6

Now if you click on articles and news you should see that the content changes.

Save the view and go to the path we designated for the primary view – in my case drupal/example – and you should see the same as I have below.

7

Now that works, but I want the Title to display above the body. To achieve this, we need to take a couple of steps. First, I’m going to hide the ‘Body’ and ‘Title’ fields.

8

Next, I’m going to display the Body and Title fields, but in the way I want. I’m going to add a “Global: Custom text” field, with a rewrite rule that places the ‘Title’ above the ‘Body’ content for display.

9

And that should give you a final display like this:

10

Author

0 0 votes
Article Rating
Subscribe
Notify of
guest

30 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
frank kelly
frank kelly
7 years ago

So, you have one view that contains two page displays: article and news. I’d assume that the “example” view could be shown on any top level menu on your site and that’s how you let users access it?
Perhaps a little explanation about how you left align image and get title and body to sit next to the image in a second “column”. And what the meaning of the {{ and }} characters surrounding the title and body “fields” in the layout are.
Thanks for the helpful article. I’m off to read about how rewrite rules work.

Fareed Agbaje
Fareed Agbaje
7 years ago

Thank you for the post on tabs. I was able to create the pages for blog and events with their paths, however I did not get the path to display the view as a page or in a block. Can you provide more help please?

Anonymous
Anonymous
5 years ago

Hi, if i add a block view, it doesn’t output the result exactly as how it was viewed as a Page.As you have 2 pages with different filtering criteria, how to output the result with 2 tabs in a block region, instead of as a page? Pls help.

MissPlease
MissPlease
7 years ago

Thank you for this tutorial. I have been trying forever to create this.

steve
steve
7 years ago
Reply to  MissPlease

You’re welcome, Sandra

pepperstreet
7 years ago

Neat! Tricky one, but nice to have it in core, although somewhat “hidden” 😉

steve
steve
7 years ago
Reply to  pepperstreet

Yeah, I had zero idea this was in the core, even after working with Drupal 8 for a year, and writing a book on it 🙂

pepperstreet
7 years ago
Reply to  steve

I am reassured to hear that 😉 Thought it was just me.

Charlie
Charlie
7 years ago

There a way to integrate this view output into a panel?

Charlie
Charlie
7 years ago

I guess I’m just referring to having your view generated tab display output as a block instead of a page, so the tabbed block can be used as a pane. (tried blocktabs module, failed miserably when trying to leverage view arguments)

Bullseye
Bullseye
7 years ago
Reply to  Charlie

Saw your comment after posting mine. I need to display these tabs in a block on the homepage. Have you figured that one out yet?

Bullseye
Bullseye
7 years ago

Is there a way to get a nice layout using DIVs instead of HMTL tables? Seems pretty dated. Also, how did you figure this out?!? Because it only works this EXACT way..
More importantly, how can i display this tabs view INSIDE a block? I tried to add a block to this view but only one table displays with no tabs. Thank you.

steve
steve
7 years ago
Reply to  Bullseye

Hi Bullseye,
I am not sure you can put it in DIVs Drupal 7 was overflowed with DIVs so they waged a bit of a war against the use of DIVs. We figured it out because a client asked for it and we aim to help our clients.
Once you have made a saved it you should be able to go to the Display Add and add a block option for it.

Moreira
Moreira
6 years ago

Hello I think you forgot to say that… the second page display should have a path similar to “drupal/example/tab2”

Steve Brown
Steve Brown
6 years ago

Thanks for this tutorial Daniel. I don’t seem to be able to get a 3rd tab to work. I’m using Drupal 8 in Windows 7. In Chrome, if I go directly to the third tab, it looks fine — I see three tabs and the current third tab has lists the correct items, but when I click on one of the other tabs, the third tab disappears. In IE, if I go directly to the third tab, it doesn’t look like a tab — it looks like a regular page. Paths are /bizflow-tab, /bizflow-budg and /bizflow-exp. I also tried making the sub-tabs subfolders of /bizflow-tab but that didn’t change anything. I don’t think this is the first time I attempted this — I was having a problem with just 2 tabs, but then I found your tutorial and was able to get that working. Your assistance is appreciated.

Steve Brown
Steve Brown
6 years ago
Reply to  Steve Brown

This morning, I was not able to see tabs at all. I changed from my default Mayo theme to Bartik and then I could see the tabs. Back to Mayo and I could still see the tabs. Problem solved!

Lydie B
Lydie B
4 years ago
Reply to  Steve Brown

Thank you,Steve Brown. The idea of switching themes rang a bell when I saw your post as this has solved other pesky issues in Drupal before. I now see tabs in Bartik.

Steve
Steve
4 years ago

I am sorry but I am just missing something here and I am not getting this to work. I see there is a [i]Tabs[/i] block in the blocks for Drupal 8. I tried enabling this and still nothing but I am wondering if newer versions of Drupal 8 (8.7.1) are working differently.  

Lydie B
Lydie B
4 years ago

Thank you for your showing this. I was looking for a way to show a group of pages as tabs. And thanks to Steve Brown, posting below, for the tip on switching themes temporarily. That rang a bell as it has fixed pesky Drupal issues in the past. After switching to Bartik and clearing caches, I instantly saw the tabs. Unfortunately my theme won’t display them, but that’s another hurdle.

Lulu
Lulu
4 years ago

Hi, thank you for the tutorial.

I can’t see any tabs at all even if i have my pages displays ok when I enter their paths directly. I tried to switch themes and cleared caches without result. I made two differences with that tuto :
– I display paragraphs instead of contents
– I gave my two pages those paths : /node/%/images and /node/%/files because i need a contextual filter on node id.
(I didn’t configure that contextual filter yet, only set paths).

I would be grateful for any idea that could help. 

Lulu
Lulu
4 years ago
Reply to  Lulu

And a second question : how can i display this render (tabs and related content) in a block ? 
Structure> block layout does not allow to place this view as it is not a block yet but pages.
And when i just create a display block in the view, as suggested, it does not display the tabs but some brut and unfiltered content. How can I create a block that contains the tabs and related view pages that I created before ?
Thank you in advance

Paul Rijke
Paul Rijke
4 years ago

I did exacty in simplytest.me what you said, but the tabs are not showing. Here’s the export of the view:

[code]
uuid: ad8d04f9-35c2-41b9-a84f-f9c7901d517a
langcode: en
status: true
dependencies:
config:
– field.storage.node.body
– field.storage.node.field_image
– node.type.article
– node.type.news
module:
– image
– node
– text
– user
id: example_of_tabbed_view
label: ‘example of tabbed view’
module: views
description: ”
tag: ”
base_table: node_field_data
base_field: nid
display:
default:
display_plugin: default
id: default
display_title: Master
position: 0
display_options:
access:
type: perm
options:
perm: ‘access content’
cache:
type: tag
options: { }
query:
type: views_query
options:
disable_sql_rewrite: false
distinct: false
replica: false
query_comment: ”
query_tags: { }
exposed_form:
type: basic
options:
submit_button: Apply
reset_button: false
reset_button_label: Reset
exposed_sorts_label: ‘Sort by’
expose_sort_order: true
sort_asc_label: Asc
sort_desc_label: Desc
pager:
type: mini
options:
items_per_page: 10
offset: 0
id: 0
total_pages: null
expose:
items_per_page: false
items_per_page_label: ‘Items per page’
items_per_page_options: ‘5, 10, 25, 50’
items_per_page_options_all: false
items_per_page_options_all_label: ‘- All -‘
offset: false
offset_label: Offset
tags:
previous: ‹‹
next: ››
style:
type: table
options:
grouping: { }
row_class: ”
default_row_class: true
override: true
sticky: false
caption: ”
summary: ”
description: ”
columns:
title: title
info:
title:
sortable: false
default_sort_order: asc
align: ”
separator: ”
empty_column: false
responsive: ”
default: ‘-1’
empty_table: false
row:
type: fields
options:
inline: { }
separator: ”
hide_empty: false
default_field_elements: true
fields:
title:
id: title
table: node_field_data
field: title
entity_type: node
entity_field: title
label: ”
alter:
alter_text: false
make_link: false
absolute: false
trim: false
word_boundary: false
ellipsis: false
strip_tags: false
html: false
hide_empty: false
empty_zero: false
settings:
link_to_entity: true
plugin_id: field
relationship: none
group_type: group
admin_label: ”
exclude: false
element_type: ”
element_class: ”
element_label_type: ”
element_label_class: ”
element_label_colon: true
element_wrapper_type: ”
element_wrapper_class: ”
element_default_classes: true
empty: ”
hide_alter_empty: true
click_sort_column: value
type: string
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ‘, ‘
field_api_classes: false
field_image:
id: field_image
table: node__field_image
field: field_image
relationship: none
group_type: group
admin_label: ”
label: Image
exclude: false
alter:
alter_text: false
text: ”
make_link: false
path: ”
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ”
rel: ”
link_class: ”
prefix: ”
suffix: ”
target: ”
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ”
more_link_path: ”
strip_tags: false
trim: false
preserve_tags: ”
html: false
element_type: ”
element_class: ”
element_label_type: ”
element_label_class: ”
element_label_colon: true
element_wrapper_type: ”
element_wrapper_class: ”
element_default_classes: true
empty: ”
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: target_id
type: image
settings:
image_style: ”
image_link: ”
group_column: ”
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ‘, ‘
field_api_classes: false
plugin_id: field
body:
id: body
table: node__body
field: body
relationship: none
group_type: group
admin_label: ”
label: Body
exclude: false
alter:
alter_text: false
text: ”
make_link: false
path: ”
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ”
rel: ”
link_class: ”
prefix: ”
suffix: ”
target: ”
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ”
more_link_path: ”
strip_tags: false
trim: false
preserve_tags: ”
html: false
element_type: ”
element_class: ”
element_label_type: ”
element_label_class: ”
element_label_colon: true
element_wrapper_type: ”
element_wrapper_class: ”
element_default_classes: true
empty: ”
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: text_default
settings: { }
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ‘, ‘
field_api_classes: false
plugin_id: field
filters:
status:
value: ‘1’
table: node_field_data
field: status
plugin_id: boolean
entity_type: node
entity_field: status
id: status
expose:
operator: ”
operator_limit_selection: false
operator_list: { }
group: 1
type:
id: type
table: node_field_data
field: type
relationship: none
group_type: group
admin_label: ”
operator: in
value:
news: news
group: 1
exposed: false
expose:
operator_id: ”
label: ”
description: ”
use_operator: false
operator: ”
operator_limit_selection: false
operator_list: { }
identifier: ”
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
reduce: false
is_grouped: false
group_info:
label: ”
description: ”
identifier: ”
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
entity_type: node
entity_field: type
plugin_id: bundle
sorts:
created:
id: created
table: node_field_data
field: created
order: DESC
entity_type: node
entity_field: created
plugin_id: date
relationship: none
group_type: group
admin_label: ”
exposed: false
expose:
label: ”
granularity: second
header: { }
footer: { }
empty: { }
relationships: { }
arguments: { }
display_extenders: { }
cache_metadata:
max-age: -1
contexts:
– ‘languages:language_content’
– ‘languages:language_interface’
– url.query_args
– ‘user.node_grants:view’
– user.permissions
tags:
– ‘config:field.storage.node.body’
– ‘config:field.storage.node.field_image’
page_1:
display_plugin: page
id: page_1
display_title: Articles
position: 1
display_options:
display_extenders: { }
display_description: ”
menu:
type: ‘default tab’
title: Articles
description: ”
expanded: false
parent: ”
weight: 0
context: ‘0’
menu_name: main
tab_options:
type: none
title: ”
description: ”
weight: 0
path: articles
filters:
status:
value: ‘1’
table: node_field_data
field: status
plugin_id: boolean
entity_type: node
entity_field: status
id: status
expose:
operator: ”
operator_limit_selection: false
operator_list: { }
group: 1
type:
id: type
table: node_field_data
field: type
relationship: none
group_type: group
admin_label: ”
operator: in
value:
article: article
group: 1
exposed: false
expose:
operator_id: ”
label: ”
description: ”
use_operator: false
operator: ”
operator_limit_selection: false
operator_list: { }
identifier: ”
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
reduce: false
is_grouped: false
group_info:
label: ”
description: ”
identifier: ”
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
entity_type: node
entity_field: type
plugin_id: bundle
defaults:
filters: false
filter_groups: false
filter_groups:
operator: AND
groups:
1: AND
cache_metadata:
max-age: -1
contexts:
– ‘languages:language_content’
– ‘languages:language_interface’
– url.query_args
– ‘user.node_grants:view’
– user.permissions
tags:
– ‘config:field.storage.node.body’
– ‘config:field.storage.node.field_image’
page_2:
display_plugin: page
id: page_2
display_title: News
position: 1
display_options:
display_extenders: { }
display_description: ”
menu:
type: tab
title: News
description: ”
expanded: false
parent: ”
weight: 0
context: ‘0’
menu_name: main
tab_options:
type: none
title: ”
description: ”
weight: 0
path: news
filters:
status:
value: ‘1’
table: node_field_data
field: status
plugin_id: boolean
entity_type: node
entity_field: status
id: status
expose:
operator: ”
operator_limit_selection: false
operator_list: { }
group: 1
type:
id: type
table: node_field_data
field: type
relationship: none
group_type: group
admin_label: ”
operator: in
value:
news: news
group: 1
exposed: false
expose:
operator_id: ”
label: ”
description: ”
use_operator: false
operator: ”
operator_limit_selection: false
operator_list: { }
identifier: ”
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
reduce: false
is_grouped: false
group_info:
label: ”
description: ”
identifier: ”
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
entity_type: node
entity_field: type
plugin_id: bundle
defaults:
filters: false
filter_groups: false
filter_groups:
operator: AND
groups:
1: AND
cache_metadata:
max-age: -1
contexts:
– ‘languages:language_content’
– ‘languages:language_interface’
– url.query_args
– ‘user.node_grants:view’
– user.permissions
tags:
– ‘config:field.storage.node.body’
– ‘config:field.storage.node.field_image’

[/code]

Anonymous Joe
Anonymous Joe
3 years ago

[quote=steve]Hi Bullseye,
I am not sure you can put it in DIVs Drupal 7 was overflowed with DIVs so they waged a bit of a war against the use of DIVs. We figured it out because a client asked for it and we aim to help our clients.
Once you have made a saved it you should be able to go to the Display Add and add a block option for it.[/quote]
Hi Steve,

Apologies if I might be missing something from previous explanations about how to add a block for displaying the whole two-tabbed view (not just the default search results from the first tab). Could you please kindly elaborate a bit on the actual settings for adding such a block? Many thanks in advance

osmirnova
3 years ago

Thank you Daniel  – very useful tutorial,
I have one problem- the page got pulled up Every time you click on tabs, what is the best way to preventDefault behavior.
Thank you again!

Umair
Umair
2 years ago

How to show a link/page within tabs?. Like what quicktab does

imrodmartin
2 years ago
Reply to  Umair

Hi Umair, I’m not sure I totally get what you’re asking – but you could create a view specifically for that by following the above tutorial only adding all the fields.  

Since you brought up Quicktabs – what exactly are you trying to accomplish that Quicktabs can’t?

Happy to see if we can help here 🙂

30
0
Would love your thoughts, please comment.x
()
x