diff --git a/cloud/routes.py b/cloud/routes.py
index 1a37ab3..458d7b7 100644
--- a/cloud/routes.py
+++ b/cloud/routes.py
@@ -6,6 +6,7 @@ from pillarsdk.exceptions import ResourceNotFound
from flask_login import current_user
from flask import Blueprint, current_app, render_template, redirect, url_for
from pillar.web.utils import system_util, get_file, current_user_is_authenticated
+from pillar.web.utils import attach_project_pictures
blueprint = Blueprint('cloud', __name__)
log = logging.getLogger(__name__)
@@ -110,6 +111,64 @@ def join():
return redirect('https://store.blender.org/product/membership/')
+def get_projects(category):
+ """Utility to get projects based on category. Should be moved on the API
+ and improved with more extensive filtering capabilities.
+ """
+ api = system_util.pillar_api()
+ projects = Project.all({
+ 'where': {
+ 'category': category,
+ 'is_private': False},
+ 'sort': '-_created',
+ }, api=api)
+ for project in projects._items:
+ attach_project_pictures(project, api)
+ return projects
+
+
+@blueprint.route('/courses')
+def courses():
+ @current_app.cache.cached(timeout=3600, unless=current_user_is_authenticated)
+ def render_page():
+ projects = get_projects('course')
+ return render_template(
+ 'projects_index_collection.html',
+ title='courses',
+ projects=projects._items,
+ api=system_util.pillar_api())
+
+ return render_page()
+
+
+@blueprint.route('/open-projects')
+def open_projects():
+ @current_app.cache.cached(timeout=3600, unless=current_user_is_authenticated)
+ def render_page():
+ projects = get_projects('film')
+ return render_template(
+ 'projects_index_collection.html',
+ title='open-projects',
+ projects=projects._items,
+ api=system_util.pillar_api())
+
+ return render_page()
+
+
+@blueprint.route('/workshops')
+def workshops():
+ @current_app.cache.cached(timeout=3600, unless=current_user_is_authenticated)
+ def render_page():
+ projects = get_projects('workshop')
+ return render_template(
+ 'projects_index_collection.html',
+ title='workshops',
+ projects=projects._items,
+ api=system_util.pillar_api())
+
+ return render_page()
+
+
def get_random_featured_nodes():
import random
diff --git a/src/templates/layout.pug b/src/templates/layout.pug
index 82290d1..0a29454 100644
--- a/src/templates/layout.pug
+++ b/src/templates/layout.pug
@@ -159,26 +159,45 @@ html(lang="en")
data-placement="left")
i.pi-character
| Characters
+
+
+ li(class="dropdown libraries")
+ a.navbar-item.dropdown-toggle(
+ href="",
+ data-toggle="dropdown",
+ title="Training")
+ span Training
+ i.pi-angle-down
+
+ ul.dropdown-menu
li
a.navbar-item(
- href="{{ url_for('projects.view', project_url='gallery') }}",
- title="Curated artwork collection",
- data-toggle="tooltip",
- data-placement="left")
+ href="{{ url_for('cloud.courses') }}",
+ title="Courses",
+ data-toggle="tooltip",
+ data-placement="left")
+ i.pi-graduation-cap
+ | Courses
+ li
+ a.navbar-item(
+ href="{{ url_for('cloud.workshops') }}",
+ title="Workshops",
+ data-toggle="tooltip",
+ data-placement="left")
+ i.pi-lightbulb
+ | Workshops
+ li
+ a.navbar-item(
+ href="{{ url_for('projects.view', project_url='gallery') }}",
+ title="Curated artwork collection",
+ data-toggle="tooltip",
+ data-placement="left")
i.pi-image
| Art Gallery
li
a.navbar-item(
- href="{{ url_for('main.training') }}",
- title="Training & Tutorials",
- data-toggle="tooltip",
- data-placement="bottom",
- class="{% if category == 'training' %}active{% endif %}")
- span Training
- li
- a.navbar-item(
- href="{{ url_for('main.open_projects') }}",
+ href="{{ url_for('cloud.open_projects') }}",
title="Browse all the Open Projects",
data-toggle="tooltip",
data-placement="bottom",
diff --git a/src/templates/projects_index_collection.pug b/src/templates/projects_index_collection.pug
index cca0a0e..d8a829c 100644
--- a/src/templates/projects_index_collection.pug
+++ b/src/templates/projects_index_collection.pug
@@ -1,21 +1,41 @@
| {% extends 'layout.html' %}
+| {# Default case is Open Projects #}
+| {% set page_title = 'Open Projects' %}
+| {% set page_description = 'Full production data and tutorials from all open movies, for you to use freely' %}
+| {% set page_header_image = url_for('static', filename='assets/img/backgrounds/background_agent327_01.jpg') %}
+| {% set page_header_text = 'The iconic Blender Institute Open Movies. Featuring all the production files, assets, artwork, and never-seen-before content.' %}
+
+| {% if title == 'courses' %}
+| {% set page_title = 'Courses' %}
+| {% set page_description = 'Production quality training by 3D professionals' %}
+| {% set page_header_image = url_for('static', filename='assets/img/backgrounds/background_caminandes_3_03.jpg') %}
+| {% set page_header_text = 'Character modeling, 3D printing, VFX, rigging and more.' %}
+
+| {% elif title == 'workshops' %}
+| {% set page_title = 'Workshops' %}
+| {% set page_description = 'Production quality training by 3D professionals' %}
+| {% set page_header_image = url_for('static', filename='assets/img/backgrounds/background_caminandes_3_03.jpg') %}
+| {% set page_header_text = 'Enter the artist workshop and learn by example.' %}
+
+| {% endif %}
+
| {% block og %}
meta(property="og:type", content="website")
meta(property="og:url", content="https://cloud.blender.org")
-meta(property="og:title", content="{% if title == 'open-projects' %}Open Projects{% elif title == 'training' %}Training{% endif %}")
-meta(name="twitter:title", content="{% if title == 'open-projects' %}Open Projects{% elif title == 'training' %}Training{% endif %} on Blender Cloud")
+meta(property="og:title", content="{{ page_title }} on Blender Cloud")
+meta(name="twitter:title", content="{{ page_title }} on Blender Cloud")
-meta(property="og:description", content="{% if title == 'open-projects' %}Full production data and tutorials from all open movies, for you to use freely{% elif title == 'training' %}Production quality training by 3D professionals{% endif %}")
-meta(name="twitter:description", content="{% if title == 'open-projects' %}Full production data and tutorials from all open movies, for you to use freely{% elif title == 'training' %}Production quality training by 3D professionals{% endif %}")
+meta(property="og:description", content="{{ page_description }}")
+meta(name="twitter:description", content="{{ page_description }}")
-meta(property="og:image", content="{% if title == 'training' %}{{ url_for('static', filename='assets/img/backgrounds/background_caminandes_3_03.jpg')}}{% else %}{{ url_for('static', filename='assets/img/backgrounds/background_agent327_01.jpg')}}{% endif %}")
-meta(name="twitter:image", content="{% if title == 'training' %}{{ url_for('static', filename='assets/img/backgrounds/background_caminandes_3_03.jpg')}}{% else %}{{ url_for('static', filename='assets/img/backgrounds/background_agent327_01.jpg')}}{% endif %}")
+meta(property="og:image", content="{{ page_header_image }}")
+meta(name="twitter:image", content="{{ page_header_image }}")
| {% endblock %}
| {% block page_title %}
-| {% if title == 'open-projects' %}Open Projects{% elif title == 'training' %}Training{% else %}Projects{% endif %}
+| {{ page_title }}
| {% endblock %}
| {% block body %}
@@ -24,22 +44,13 @@ meta(name="twitter:image", content="{% if title == 'training' %}{{ url_for('stat
#node_index-container
#node_index-header.collection
- img.background-header(src="{% if title == 'training' %}{{ url_for('static', filename='assets/img/backgrounds/background_caminandes_3_03.jpg')}}{% else %}{{ url_for('static', filename='assets/img/backgrounds/background_agent327_01.jpg')}}{% endif %}")
+ img.background-header(src="{{ page_header_image }}")
#node_index-collection-info
- | {% if title == 'open-projects' %}
.node_index-collection-name
- span Open Projects
+ span {{ page_title }}
.node_index-collection-description
span.
- The iconic Blender Institute Open Movies.
- Featuring all the production files, assets, artwork, and never-seen-before content.
- | {% elif title == 'training' %}
- .node_index-collection-name
- span Training
- .node_index-collection-description
- span.
- Character modeling, 3D printing, VFX, rigging and more.
- | {% endif %}
+ {{ page_header_text }}
.node_index-collection
diff --git a/src/templates/welcome.pug b/src/templates/welcome.pug
index b7797f2..ee0312e 100644
--- a/src/templates/welcome.pug
+++ b/src/templates/welcome.pug
@@ -51,7 +51,7 @@ meta(property="og:image", content="{{ url_for('static', filename='assets/img/bac
#page-content
section.page-card-header
h2
- a(href="{{ url_for('main.training') }}") Training & Tutorials
+ a(href="{{ url_for('main.courses') }}") Training & Tutorials
.page-triplet-container.homepage
.row
@@ -112,14 +112,14 @@ meta(property="og:image", content="{{ url_for('static', filename='assets/img/bac
Advanced
Digital Painting
and
- much more!
+ much more!
.page-triplet-container-fluid.dark(
style="background-image: url({{ url_for('static', filename='assets/img/backgrounds/pattern_01.jpg')}})")
section.page-card-header
h2
- a(href="{{ url_for('main.open_projects') }}") Browse all the Open Movies
+ a(href="{{ url_for('cloud.open_projects') }}") Browse all the Open Movies
.page-triplet-container.homepage
.row
@@ -166,7 +166,7 @@ meta(property="og:image", content="{{ url_for('static', filename='assets/img/bac
Tears of Steel,
Glass Half,
and
- more.
+ more.
section.page-card-header