diff --git a/client/galaxy/scripts/mvc/tours.js b/client/galaxy/scripts/mvc/tours.js
index cad6f996d8a..5ce6d3aac25 100644
--- a/client/galaxy/scripts/mvc/tours.js
+++ b/client/galaxy/scripts/mvc/tours.js
@@ -9,16 +9,25 @@ define(["libs/bootstrap-tour"], function(BootstrapTour) {
var tourpage_template = `
Galaxy Tours
This page presents a list of interactive tours available on this Galaxy server.
Select any tour to get started (and remember, you can click 'End Tour' at any time).
+
-<% _.each(tours, function(tour) { %>
+<% _.each(tourgroups, function(tourgroupdata) { %>
-
- >
- <%- tour.attributes.name || tour.id %>
-
- - <%- tour.attributes.description || "No description given." %>
+
+ <%- tourgroupdata.attributes.name %>
+
+
+ <% _.each(tourgroupdata.attributes.tours, function(tour) { %>
+ -
+ >
+ <%- tour.name || tour.id %>
+
+ - <%- tour.description || \"No description given.\" %>
+
+ <% }); %>
+
-<% }); %>
-
`;
+<% }); %>`;
var tour_opts = {
storage: window.sessionStorage,
@@ -112,7 +121,7 @@ Select any tour to get started (and remember, you can click 'End Tour' at any ti
render: function() {
var tpl = _.template(tourpage_template);
this.$el
- .html(tpl({ tours: this.model.models }))
+ .html(tpl({ tourgroups: this.model.models }))
.on("click", ".tourItem", function(e) {
e.preventDefault();
giveTour($(this).data("tour.id"));
diff --git a/config/plugins/tours/core.galaxy_ui.yaml b/config/plugins/tours/core.galaxy_ui.yaml
index 3c1fb7e5f80..dff2ca9f74b 100644
--- a/config/plugins/tours/core.galaxy_ui.yaml
+++ b/config/plugins/tours/core.galaxy_ui.yaml
@@ -2,6 +2,8 @@ id: galaxy_ui
name: Galaxy UI
description: A gentle introduction to the Galaxy User Interface
title_default: "Welcome to Galaxy"
+group: galaxy_default
+group_name: "Galaxy Default Tours"
# A tour is made of several steps, each of them beginning with a dash '-'
steps:
diff --git a/config/plugins/tours/core.history.yaml b/config/plugins/tours/core.history.yaml
index 20b64f07ce0..0c8390d1a73 100644
--- a/config/plugins/tours/core.history.yaml
+++ b/config/plugins/tours/core.history.yaml
@@ -1,6 +1,9 @@
name: History Introduction
description: A detailed introduction to the Galaxy History
title_default: "Galaxy History Introduction"
+group: galaxy_default
+group_name: "Galaxy Default Tours"
+
steps:
- content: "This short tour will guide you through Galaxy's History and datasets."
diff --git a/config/plugins/tours/core.scratchbook.yaml b/config/plugins/tours/core.scratchbook.yaml
index f3662a3452f..e00afdb0cb5 100644
--- a/config/plugins/tours/core.scratchbook.yaml
+++ b/config/plugins/tours/core.scratchbook.yaml
@@ -1,6 +1,9 @@
name: Scratchbook - Introduction
title_default: "Scratchbook Introduction"
description: "An introduction on how to display multiple datasets and visualizations next to each other."
+group: galaxy_default
+group_name: "Galaxy Default Tours"
+
steps:
- content: "This short tour will walk you through Galaxy's Scratchbook feature"
diff --git a/config/plugins/tours/test.yaml b/config/plugins/tours/test.yaml
new file mode 100644
index 00000000000..b2f61d79a00
--- /dev/null
+++ b/config/plugins/tours/test.yaml
@@ -0,0 +1,8 @@
+name: Test Tour
+description: Test Tour for no reason
+title_default: "Test Tour"
+group: test_tours
+group_name: "Test Tours"
+
+steps:
+ - content: "Test tour."
\ No newline at end of file
diff --git a/lib/galaxy/tours/__init__.py b/lib/galaxy/tours/__init__.py
index c35d147759c..44f20c1c2ff 100644
--- a/lib/galaxy/tours/__init__.py
+++ b/lib/galaxy/tours/__init__.py
@@ -33,10 +33,14 @@ class ToursRegistry(object):
self.load_tours()
def tours_by_id_with_description(self):
- return [{'id': k,
- 'description': self.tours[k].get('description', None),
- 'name': self.tours[k].get('name', None)}
- for k in self.tours.keys()]
+ return [{'name': self.tourgroups[i].get('name', None),
+ 'tours': [{'id': k,
+ 'description': self.tours[k].get('description', None),
+ 'name': self.tours[k].get('name', None),
+ 'group': self.tours[k].get('group_name', None)}
+ for k in self.tours.keys()
+ if self.tours[k].get('group', None) == i]}
+ for i in self.tourgroups.keys()]
def load_tour(self, tour_id):
for tour_dir in self.tour_directories:
@@ -52,6 +56,7 @@ class ToursRegistry(object):
def load_tours(self):
self.tours = {}
+ self.tourgroups = {}
for tour_dir in self.tour_directories:
for filename in os.listdir(tour_dir):
if filename.endswith('.yaml') or filename.endswith('.yml'):
@@ -71,6 +76,9 @@ class ToursRegistry(object):
conf = yaml.safe_load(handle)
tour = tour_loader(conf)
self.tours[tour_id] = tour_loader(conf)
+ if tour['group'] not in self.tourgroups.keys():
+ self.tourgroups[tour['group']] = {'name': tour['group_name'], 'tours': []}
+ self.tourgroups[tour['group']]['tours'].append(tour_id)
log.info("Loaded tour '%s'" % tour_id)
return tour
except IOError: