Merge branch 'wip-redesign'

# Conflicts:
#	src/templates/homepage.pug
#	src/templates/services.pug
This commit is contained in:
2018-09-06 14:13:22 +02:00
38 changed files with 2836 additions and 1404 deletions

3
.gitignore vendored
View File

@@ -3,9 +3,12 @@
.coverage .coverage
*.pyc *.pyc
__pycache__ __pycache__
*.js.map
*.css.map
/cloud/templates/ /cloud/templates/
/cloud/static/assets/css/ /cloud/static/assets/css/
/cloud/static/assets/js/bootstrap.min.js
node_modules/ node_modules/
/config_local.py /config_local.py

View File

@@ -1,5 +1,6 @@
var argv = require('minimist')(process.argv.slice(2)); var argv = require('minimist')(process.argv.slice(2));
var autoprefixer = require('gulp-autoprefixer'); var autoprefixer = require('gulp-autoprefixer');
var cache = require('gulp-cached');
var chmod = require('gulp-chmod'); var chmod = require('gulp-chmod');
var concat = require('gulp-concat'); var concat = require('gulp-concat');
var git = require('gulp-git'); var git = require('gulp-git');
@@ -11,16 +12,16 @@ var plumber = require('gulp-plumber');
var rename = require('gulp-rename'); var rename = require('gulp-rename');
var sass = require('gulp-sass'); var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps'); var sourcemaps = require('gulp-sourcemaps');
var uglify = require('gulp-uglify'); var uglify = require('gulp-uglify-es').default;
var cache = require('gulp-cached');
var enabled = { var enabled = {
uglify: argv.production, uglify: argv.production,
maps: argv.production, maps: !argv.production,
failCheck: !argv.production, failCheck: !argv.production,
prettyPug: !argv.production, prettyPug: !argv.production,
cachify: !argv.production, cachify: !argv.production,
cleanup: argv.production, cleanup: argv.production,
chmod: argv.production,
}; };
var destination = { var destination = {
@@ -29,6 +30,12 @@ var destination = {
js: 'cloud/static/assets/js', js: 'cloud/static/assets/js',
} }
var source = {
pillar: '../pillar/',
bootstrap: 'node_modules/bootstrap/',
popper: 'node_modules/popper.js/'
}
/* CSS */ /* CSS */
gulp.task('styles', function() { gulp.task('styles', function() {
@@ -73,7 +80,7 @@ gulp.task('scripts', function() {
.pipe(gulpif(enabled.uglify, uglify())) .pipe(gulpif(enabled.uglify, uglify()))
.pipe(rename({suffix: '.min'})) .pipe(rename({suffix: '.min'}))
.pipe(gulpif(enabled.maps, sourcemaps.write("."))) .pipe(gulpif(enabled.maps, sourcemaps.write(".")))
.pipe(chmod(644)) .pipe(gulpif(enabled.chmod, chmod(644)))
.pipe(gulp.dest(destination.js)) .pipe(gulp.dest(destination.js))
.pipe(gulpif(argv.livereload, livereload())); .pipe(gulpif(argv.livereload, livereload()));
}); });
@@ -88,12 +95,34 @@ gulp.task('scripts_concat_tutti', function() {
.pipe(concat("tutti.min.js")) .pipe(concat("tutti.min.js"))
.pipe(gulpif(enabled.uglify, uglify())) .pipe(gulpif(enabled.uglify, uglify()))
.pipe(gulpif(enabled.maps, sourcemaps.write("."))) .pipe(gulpif(enabled.maps, sourcemaps.write(".")))
.pipe(chmod(644)) .pipe(gulpif(enabled.chmod, chmod(644)))
.pipe(gulp.dest(destination.js)) .pipe(gulp.dest(destination.js))
.pipe(gulpif(argv.livereload, livereload())); .pipe(gulpif(argv.livereload, livereload()));
}); });
// Combine all needed Bootstrap JavaScript into a single file.
gulp.task('scripts_concat_bootstrap', function() {
toUglify = [
source.popper + 'dist/umd/popper.min.js',
source.bootstrap + 'js/dist/index.js',
source.bootstrap + 'js/dist/util.js',
source.bootstrap + 'js/dist/tooltip.js',
source.bootstrap + 'js/dist/dropdown.js',
];
gulp.src(toUglify)
.pipe(gulpif(enabled.failCheck, plumber()))
.pipe(gulpif(enabled.maps, sourcemaps.init()))
.pipe(concat("bootstrap.min.js"))
.pipe(gulpif(enabled.uglify, uglify()))
.pipe(gulpif(enabled.maps, sourcemaps.write(".")))
.pipe(gulpif(enabled.chmod, chmod(644)))
.pipe(gulp.dest(destination.js))
.pipe(gulpif(argv.livereload, livereload()));
});
// While developing, run 'gulp watch' // While developing, run 'gulp watch'
gulp.task('watch',function() { gulp.task('watch',function() {
@@ -103,6 +132,8 @@ gulp.task('watch',function() {
} }
gulp.watch('src/styles/**/*.sass',['styles']); gulp.watch('src/styles/**/*.sass',['styles']);
gulp.watch(source.pillar + 'src/styles/**/*.sass',['styles']);
gulp.watch('src/templates/**/*.pug',['templates']); gulp.watch('src/templates/**/*.pug',['templates']);
gulp.watch('src/scripts/*.js',['scripts']); gulp.watch('src/scripts/*.js',['scripts']);
gulp.watch('src/scripts/tutti/**/*.js',['scripts_concat_tutti']); gulp.watch('src/scripts/tutti/**/*.js',['scripts_concat_tutti']);
@@ -125,4 +156,5 @@ gulp.task('cleanup', function() {
// Run 'gulp' to build everything at once // Run 'gulp' to build everything at once
var tasks = []; var tasks = [];
if (enabled.cleanup) tasks.push('cleanup'); if (enabled.cleanup) tasks.push('cleanup');
gulp.task('default', tasks.concat(['styles', 'templates', 'scripts', 'scripts_concat_tutti']));
gulp.task('default', tasks.concat(['styles', 'templates', 'scripts', 'scripts_concat_tutti', 'scripts_concat_bootstrap']));

View File

@@ -8,20 +8,24 @@
}, },
"devDependencies": { "devDependencies": {
"gulp": "~3.9.1", "gulp": "~3.9.1",
"gulp-autoprefixer": "~2.3.1", "gulp-autoprefixer": "~6.0.0",
"gulp-cached": "~1.1.0", "gulp-cached": "~1.1.1",
"gulp-chmod": "~1.3.0", "gulp-chmod": "~2.0.0",
"gulp-concat": "~2.6.0", "gulp-concat": "~2.6.1",
"gulp-if": "^2.0.1", "gulp-if": "^2.0.2",
"gulp-git": "~2.4.2", "gulp-git": "~2.8.0",
"gulp-pug": "~3.2.0", "gulp-livereload": "~4.0.0",
"gulp-jade": "~1.1.0", "gulp-plumber": "~1.2.0",
"gulp-livereload": "~3.8.1", "gulp-pug": "~4.0.1",
"gulp-plumber": "~1.1.0", "gulp-rename": "~1.4.0",
"gulp-rename": "~1.2.2", "gulp-sass": "~4.0.1",
"gulp-sass": "~2.3.1", "gulp-sourcemaps": "~2.6.4",
"gulp-sourcemaps": "~1.6.0", "gulp-uglify-es": "^1.0.4",
"gulp-uglify": "~1.5.3",
"minimist": "^1.2.0" "minimist": "^1.2.0"
},
"dependencies": {
"bootstrap": "^4.1.3",
"jquery": "^3.3.1",
"popper.js": "^1.14.4"
} }
} }

View File

@@ -1,58 +1,19 @@
.dashboard-container
+container-behavior
+media-xs
flex-direction: column
align-content: center
align-items: flex-start
display: flex
justify-content: space-around
word-break: break-word
section.dashboard-main,
section.dashboard-secondary
+media-xs
width: 100%
margin: 20px auto
img .title-underline
max-width: 100%
section.dashboard-main
+container-box
width: 52%
section.dashboard-secondary
width: 46%
flex-direction: column
margin-right: auto
span.section-lead
display: block
padding: 10px 0
color: $color-text-dark-secondary
section.dashboard-main,
section.dashboard-secondary
h4
padding-bottom: 5px padding-bottom: 5px
margin-bottom: 20px
position: relative position: relative
margin-bottom: 20px
&:before &:before
position: absolute background-color: $primary
width: 50px
height: 2px
top: 125%
content: ' ' content: ' '
display: block display: block
background-color: $color-primary height: 2px
top: 125%
position: absolute
width: 50px
a
color: $color-text
&:hover
color: $color-primary
cursor: pointer
nav#nav-tabs, nav#nav-tabs,
nav#sub-nav-tabs nav#sub-nav-tabs
@@ -113,37 +74,13 @@
border-color: $color-background-light border-color: $color-background-light
pointer-events: none pointer-events: none
li.create .dashboard-container
cursor: pointer word-break: break-word
display: inline-block
float: right
font:
size: 1.2em
weight: 400
padding: 5px 10px
margin-top: 3px
a
color: $color-success
text-decoration: none
&.disabled
cursor: wait
border-color: $color-success
opacity: .8
a
cursor: wait
section.stream section.stream
background-color: white
border-bottom: thin solid $color-background-dark
ul.activity-stream__list ul.activity-stream__list
list-style: none
margin: 0
padding: 0
$activity-stream-thumbnail-size: 110px $activity-stream-thumbnail-size: 110px
> li > li
position: relative position: relative
display: flex display: flex
@@ -180,17 +117,6 @@
transition: font-size 100ms ease-in-out transition: font-size 100ms ease-in-out
&.comment &.comment
.activity-stream__list-thumbnail
background: transparent
color: $node-type-comment
font-size: 1.2em
box-shadow: none
i
+position-center-translate
left: 22px
top: 19px
.activity-stream__list-details .activity-stream__list-details
padding: 0 padding: 0
.title .title
@@ -200,6 +126,8 @@
margin: 0 margin: 0
ul.meta ul.meta
+list-meta
font-size: .9em
padding: 0 10px 7px 10px padding: 0 10px 7px 10px
li li
@@ -300,7 +228,6 @@
overflow: hidden overflow: hidden
position: relative position: relative
max-width: 100% max-width: 100%
margin-right: auto
padding: 10px 0 padding: 10px 0
+media-xs +media-xs
@@ -310,18 +237,14 @@
+ribbon +ribbon
right: -47px right: -47px
top: 5px top: 5px
font: font-size: 12px
size: 12px
weight: 500
span span
padding: 1px 50px padding: 1px 50px
.title .title
display: inline-block
padding: 0 10px padding: 0 10px
color: $color-text-dark color: $color-text-dark
font-size: 1.1em
span span
@include badge(hsl(hue($color-success), 60%, 45%), 3px) @include badge(hsl(hue($color-success), 60%, 45%), 3px)
@@ -329,24 +252,6 @@
padding: 1px 5px padding: 1px 5px
margin-right: 5px margin-right: 5px
ul.meta
+list-meta
padding: 5px 10px 0 10px
font-size: .85em
color: $color-text-dark-secondary
display: flex
white-space: nowrap
&.extra
margin-top: auto
li
padding-left: 10px
&:before
left: -5px
&.where-project
+text-overflow-ellipsis
section.comments section.comments
padding: 0 15px 5px padding: 0 15px 5px
@@ -371,118 +276,6 @@
display: block display: block
padding-bottom: 5px padding-bottom: 5px
section.blog-stream
+media-md
padding-left: 10px
+media-sm
padding-left: 10px
position: relative
.feed
position: absolute
top: 10px
right: 10px
font-size: 1.4em
color: lighten($color-text-dark-hint, 10%)
&:hover
color: $color-primary
> ul
margin: 0
padding: 0
list-style: none
border-top: thin solid $color-background
.blog_index-item
+container-box
display: flex
flex-direction: column
margin-bottom: 50px
&:before
height: 1px
background-color: $color-background-dark
position: absolute
bottom: -26px
left: 25px
right: 25px
content: ' '
&:last-child
margin-bottom: 0
&:before
display: none
video
max-width: 100%
a.item-title
font-size: 1.6em
padding: 5px 15px
display: block
color: $color-text
&:hover
color: $color-primary
ul.meta
+list-meta
font-size: .9em
padding: 15px 15px 5px
&.blog-non-featured
border-radius: 0
margin: 0
.item-content
+node-details-description
padding: 10px 15px
.blog-stream__list-details
.title
color: $color-text-dark-primary
display: block
font-size: 1.3em
&:hover
color: $color-primary
ul.meta
+list-meta
padding-top: 5px
font-size: .9em
color: $color-text-dark-secondary
li
padding-left: 10px
&:before
left: -5px
.blog_index-header
display: block
position: relative
img
border-top-left-radius: 3px
border-top-right-radius: 3px
width: 100%
.more
text-align: center
a
color: $color-text
display: block
padding: 25px 0
text-decoration: underline
width: 100%
&:hover
color: $color-primary
section.random-asset section.random-asset
border-bottom: thin solid $color-background-dark border-bottom: thin solid $color-background-dark
@@ -653,10 +446,6 @@ section.announcement
.title .title
padding-bottom: 10px padding-bottom: 10px
font:
family: $font-body
size: 1.4em
weight: 300
+media-xs +media-xs
font-size: 1.4em font-size: 1.4em
@@ -693,60 +482,21 @@ section.announcement
justify-content: space-around justify-content: space-around
flex-wrap: wrap flex-wrap: wrap
a
+button($color-text-light, 3px)
padding: 5px 0
margin:
bottom: 5px
right: auto
left: auto
font-size: .9em
opacity: 1
flex: 1
+media-xs
margin: 10px auto
width: 100%
&:first-child
margin-right: 15px
&.blue
+button(hsl(hue($color-info), 60%, 45%), 3px)
&.orange
+button(hsl(hue($color-secondary), 50%, 50%), 3px)
padding: 5px 15px
&.green
+button(hsl(hue($color-success), 60%, 40%), 3px, true)
section.dashboard-in-production
.in-production-project
border-bottom: thin solid $color-background-dark
color: $color-text-dark-primary
display: block
font-size: 1.1em
margin-bottom: 15px
> img
margin-bottom: 15px
body.homepage body.homepage
.dashboard-container .blog
.dashboard-main // Custom tweak to Bootstrap grid for the only case when
+media-xs // the post is inside a column (it's usually centered in the page).
width: 100% .col-md-9
background-color: transparent flex: 1
box-shadow: none max-width: 100%
width: 60%
.dashboard-secondary .jumbotron
+container-box padding-top: 6em
+media-xs padding-bottom: 6em
width: 100%
width: 38%
> section *
padding: 15px font-size: $h1-font-size
.lead
font-size: $font-size-base

View File

@@ -10,9 +10,6 @@
li a.navbar-item li a.navbar-item
color: $color-text color: $color-text
.navbar-container
+container-behavior
.navbar-toggle .navbar-toggle
border: 2px solid $color-text-dark-primary border: 2px solid $color-text-dark-primary
color: $color-text color: $color-text
@@ -267,22 +264,6 @@
+media-xs +media-xs
margin-top: 20px margin-top: 20px
.navbar
.nav-item-sign-in
a.navbar-item
background-color: $color-primary
border: none
border-radius: 3px
color: white
height: auto
font-weight: bold
margin-top: 5px
margin-left: 10px
padding: 10px 20px
&:hover
background-color: lighten($color-primary, 10%)
box-shadow: none
.container.wide-on-sm .container.wide-on-sm
+media-sm +media-sm
@@ -334,9 +315,7 @@ section.pricing
+button($color-primary, 3px, true) +button($color-primary, 3px, true)
h3 h3
font: font-size: 1.8em
size: 1.8em
family: $font-body
padding-bottom: 0 padding-bottom: 0
margin: 25px 0 0 10px margin: 25px 0 0 10px

View File

@@ -1,26 +1,99 @@
@import ../../../pillar/src/styles/_normalize // Bootstrap variables and utilities.
@import ../../../pillar/src/styles/_config @import "../../node_modules/bootstrap/scss/functions"
@import ../../../pillar/src/styles/_utils @import "../../node_modules/bootstrap/scss/variables"
@import "../../node_modules/bootstrap/scss/mixins"
/* Generic styles (comments, notifications, etc) come from base.css */ // Pillar variables and utilities.
@import "../../../pillar/src/styles/config"
@import "../../../pillar/src/styles/utils"
// Bootstrap components.
@import "../../node_modules/bootstrap/scss/root"
@import "../../node_modules/bootstrap/scss/reboot"
@import "../../node_modules/bootstrap/scss/type"
@import "../../node_modules/bootstrap/scss/images"
@import "../../node_modules/bootstrap/scss/code"
@import "../../node_modules/bootstrap/scss/grid"
@import "../../node_modules/bootstrap/scss/tables"
@import "../../node_modules/bootstrap/scss/forms"
@import "../../node_modules/bootstrap/scss/buttons"
@import "../../node_modules/bootstrap/scss/transitions"
@import "../../node_modules/bootstrap/scss/dropdown"
@import "../../node_modules/bootstrap/scss/button-group"
@import "../../node_modules/bootstrap/scss/input-group"
@import "../../node_modules/bootstrap/scss/custom-forms"
@import "../../node_modules/bootstrap/scss/nav"
@import "../../node_modules/bootstrap/scss/navbar"
@import "../../node_modules/bootstrap/scss/card"
@import "../../node_modules/bootstrap/scss/breadcrumb"
@import "../../node_modules/bootstrap/scss/pagination"
@import "../../node_modules/bootstrap/scss/badge"
@import "../../node_modules/bootstrap/scss/jumbotron"
@import "../../node_modules/bootstrap/scss/alert"
@import "../../node_modules/bootstrap/scss/progress"
@import "../../node_modules/bootstrap/scss/media"
@import "../../node_modules/bootstrap/scss/list-group"
@import "../../node_modules/bootstrap/scss/close"
@import "../../node_modules/bootstrap/scss/modal"
@import "../../node_modules/bootstrap/scss/tooltip"
@import "../../node_modules/bootstrap/scss/popover"
@import "../../node_modules/bootstrap/scss/carousel"
@import "../../node_modules/bootstrap/scss/utilities"
@import "../../node_modules/bootstrap/scss/print"
// Pillar components.
@import "../../../pillar/src/styles/apps_base"
@import "../../../pillar/src/styles/error"
@import "../../../pillar/src/styles/components/base"
@import "../../../pillar/src/styles/components/jumbotron"
@import "../../../pillar/src/styles/components/alerts"
@import "../../../pillar/src/styles/components/navbar"
@import "../../../pillar/src/styles/components/dropdown"
@import "../../../pillar/src/styles/components/footer"
@import "../../../pillar/src/styles/components/shortcode"
@import "../../../pillar/src/styles/components/statusbar"
@import "../../../pillar/src/styles/components/search"
@import "../../../pillar/src/styles/components/flyout"
@import "../../../pillar/src/styles/components/forms"
@import "../../../pillar/src/styles/components/inputs"
@import "../../../pillar/src/styles/components/buttons"
@import "../../../pillar/src/styles/components/popover"
@import "../../../pillar/src/styles/components/tooltip"
@import "../../../pillar/src/styles/components/checkbox"
@import "../../../pillar/src/styles/components/overlay"
@import "../../../pillar/src/styles/components/card"
@import "../../../pillar/src/styles/comments"
@import "../../../pillar/src/styles/notifications"
/* Blender Cloud specific styles */ /* Blender Cloud specific styles */
@import ../../../pillar/src/styles/_project @import "../../../pillar/src/styles/_project"
@import ../../../pillar/src/styles/_project-sharing @import "../../../pillar/src/styles/_project-sharing"
@import ../../../pillar/src/styles/_project-dashboard @import "../../../pillar/src/styles/_project-dashboard"
@import ../../../pillar/src/styles/_user @import "../../../pillar/src/styles/_user"
@import _welcome @import _welcome
@import _homepage @import _homepage
@import _services @import _services
@import _about @import _about
@import ../../../pillar/src/styles/_search @import "../../../pillar/src/styles/_search"
@import ../../../pillar/src/styles/_organizations @import "../../../pillar/src/styles/_organizations"
/* services, about, etc */ /* services, about, etc */
@import ../../../pillar/src/styles/_pages @import "../../../pillar/src/styles/_pages"
/* plugins are included here, don't include in base unless needed by other pillar apps */ /* plugins are included here, don't include in base unless needed by other pillar apps */
@import ../../../pillar/src/styles/plugins/_jstree @import "../../../pillar/src/styles/plugins/_jstree"
@import ../../../pillar/src/styles/plugins/_js_select2 @import "../../../pillar/src/styles/plugins/_js_select2"
/* CSS for pillar-font comes from fontello.com using static/assets/font/config.json */ /* CSS for pillar-font comes from fontello.com using static/assets/font/config.json */

View File

@@ -1,47 +1,88 @@
@import ../../../pillar/src/styles/_config // Bootstrap variables and utilities.
@import ../../../pillar/src/styles/_utils @import "../../node_modules/bootstrap/scss/functions"
@import "../../node_modules/bootstrap/scss/variables"
@import "../../node_modules/bootstrap/scss/mixins"
// Pillar variables and utilities.
@import "../../../pillar/src/styles/config"
@import "../../../pillar/src/styles/utils"
// Bootstrap components.
@import "../../node_modules/bootstrap/scss/root"
@import "../../node_modules/bootstrap/scss/reboot"
@import "../../node_modules/bootstrap/scss/type"
@import "../../node_modules/bootstrap/scss/images"
@import "../../node_modules/bootstrap/scss/code"
@import "../../node_modules/bootstrap/scss/grid"
@import "../../node_modules/bootstrap/scss/tables"
@import "../../node_modules/bootstrap/scss/forms"
@import "../../node_modules/bootstrap/scss/buttons"
@import "../../node_modules/bootstrap/scss/transitions"
@import "../../node_modules/bootstrap/scss/dropdown"
@import "../../node_modules/bootstrap/scss/button-group"
@import "../../node_modules/bootstrap/scss/input-group"
@import "../../node_modules/bootstrap/scss/custom-forms"
@import "../../node_modules/bootstrap/scss/nav"
@import "../../node_modules/bootstrap/scss/navbar"
@import "../../node_modules/bootstrap/scss/card"
@import "../../node_modules/bootstrap/scss/breadcrumb"
@import "../../node_modules/bootstrap/scss/pagination"
@import "../../node_modules/bootstrap/scss/badge"
@import "../../node_modules/bootstrap/scss/jumbotron"
@import "../../node_modules/bootstrap/scss/alert"
@import "../../node_modules/bootstrap/scss/progress"
@import "../../node_modules/bootstrap/scss/media"
@import "../../node_modules/bootstrap/scss/list-group"
@import "../../node_modules/bootstrap/scss/close"
@import "../../node_modules/bootstrap/scss/modal"
@import "../../node_modules/bootstrap/scss/tooltip"
@import "../../node_modules/bootstrap/scss/popover"
@import "../../node_modules/bootstrap/scss/carousel"
@import "../../node_modules/bootstrap/scss/utilities"
@import "../../node_modules/bootstrap/scss/print"
// Pillar components.
@import "../../../pillar/src/styles/apps_base"
@import "../../../pillar/src/styles/error"
@import "../../../pillar/src/styles/components/base"
@import "../../../pillar/src/styles/components/jumbotron"
@import "../../../pillar/src/styles/components/alerts"
@import "../../../pillar/src/styles/components/navbar"
@import "../../../pillar/src/styles/components/dropdown"
@import "../../../pillar/src/styles/components/footer"
@import "../../../pillar/src/styles/components/shortcode"
@import "../../../pillar/src/styles/components/statusbar"
@import "../../../pillar/src/styles/components/search"
@import "../../../pillar/src/styles/components/flyout"
@import "../../../pillar/src/styles/components/inputs"
@import "../../../pillar/src/styles/components/buttons"
@import "../../../pillar/src/styles/components/popover"
@import "../../../pillar/src/styles/components/tooltip"
@import "../../../pillar/src/styles/components/checkbox"
@import "../../../pillar/src/styles/components/overlay"
@import "../../../pillar/src/styles/components/card"
@import "../../../pillar/src/styles/notifications"
@import "../../../pillar/src/styles/_search"
$node-latest-thumbnail-size: 160px $node-latest-thumbnail-size: 160px
$node-latest-gallery-thumbnail-size: 200px $node-latest-gallery-thumbnail-size: 200px
body
background-color: white
.page-body
background-color: white
nav.navbar nav.navbar
background-color: white
.navbar-header .navbar-header
+media-xs +media-xs
width: 100% width: 100%
.navbar-brand
color: $color-text
li a.navbar-item
color: $color-text
&:hover
color: black
&:focus
color: black
&.active
color: black
.dropdown.open
a
background-color: white
.dropdown.libraries
&:hover
background: none
ul.dropdown-menu
background-color: white
li
a
color: $color-text
&:hover
color: black
background-color: white
.navbar-container
+container-behavior
.navbar-toggle .navbar-toggle
border: none border: none
color: $color-text color: $color-text
@@ -57,11 +98,11 @@ nav.navbar
.node-details-container .node-details-container
max-width: 620px max-width: 620px
font-family: $font-body
font-size: 1.3em font-size: 1.3em
line-height: 1.5em line-height: 1.5em
margin: 0 auto 40px auto margin: 0 auto 40px auto
padding-bottom: 40px padding-bottom: 40px
+media-xs +media-xs
padding-left: 10px padding-left: 10px
padding-right: 10px padding-right: 10px
@@ -106,20 +147,10 @@ section
border-top: thin solid $color-background border-top: thin solid $color-background
margin: 0 auto margin: 0 auto
a.btn
margin: 20px auto
font-size: 1.3em
padding: 9px 18px
border-radius: 8px
color: $color-text-dark
.navbar-secondary .navbar-secondary
max-width: 620px max-width: 620px
margin: 0 auto margin: 0 auto
.navbar-container
border-bottom: 1px solid #dddddd
.navbar-collapse .navbar-collapse
padding-left: 0 padding-left: 0

View File

@@ -0,0 +1,26 @@
include ../mixins/components
| {% macro navigation_tabs(title) %}
+nav-secondary()
+nav-secondary-link(
class="{% if title == 'homepage' %}active{% endif %}",
href="{{ url_for('main.homepage') }}")
| Activity
+nav-secondary-link(
class="{% if title == 'home' %}active{% endif %}",
href="{{ url_for('projects.home_project') }}")
| Home
+nav-secondary-link(
class="{% if title == 'dashboard' %}active{% endif %}",
href="{{ url_for('projects.index') }}")
| My Projects
| {% if current_user.has_organizations() %}
+nav-secondary-link(
class="{% if title == 'organizations' %}active{% endif %}",
href="{{ url_for('pillar.web.organizations.index') }}")
| My Organizations
| {% endif %}
| {% endmacro %}

View File

@@ -18,59 +18,51 @@ meta(property="og:image", content="{% if main_project.picture_header %}{{ main_p
meta(name="twitter:image", content="{% if main_project.picture_header %}{{ main_project.picture_header.thumbnail('l', api=api) }}{% else %}{{ url_for('static', filename='assets/img/backgrounds/background_agent327_04.jpg')}}{% endif %}") meta(name="twitter:image", content="{% if main_project.picture_header %}{{ main_project.picture_header.thumbnail('l', api=api) }}{% else %}{{ url_for('static', filename='assets/img/backgrounds/background_agent327_04.jpg')}}{% endif %}")
| {% endblock %} | {% endblock %}
| {% block body %} | {% block navigation_tabs %}
.dashboard-container | {{ navigation_tabs(title) }}
section.dashboard-main | {% endblock navigation_tabs %}
section.blog-stream | {% block body %}
ul.blog-stream__list .container-fluid.dashboard-container.imgs-fluid
.row
.col-md-8
section.blog
ul.list-unstyled
| {% if latest_posts %} | {% if latest_posts %}
| {% for node in latest_posts %} | {% for node in latest_posts %}
| {{ render_blog_post(node) }} | {{ render_blog_post(node) }}
| {% endfor %} | {% endfor %}
| {% else %} | {% else %}
li li
.blog-stream__list-details | No blog entries... yet!
ul.meta
li.when No blog entries... yet!
| {% endif %} | {% endif %}
.more .d-block.text-center
a(href="{{ url_for('main.main_blog') }}") a.d-inline-block.p-3.text-muted(href="{{ url_for('main.main_blog') }}")
| See All Blog Posts | See All Blog Posts
a.feed( a.d-inline-block.p-3.text-muted(
href="{{ url_for('main.feeds_blogs') }}", href="{{ url_for('main.feeds_blogs') }}",
title="Blogs Feed", title="Blogs Feed",
data-toggle="tooltip", data-toggle="tooltip",
data-placement="left") data-placement="left")
i.pi-rss i.pi-rss
| RSS Feed
.col-md-4
section.dashboard-secondary .dashboard-sidebar
| {{ navigation_tabs(title) }} section.pt-3
h6.title-underline In Production
section.dashboard-in-production a(href="/p/spring/")
h4 In Production
span.section-lead.
Check out these projects currently in production!
a.in-production-project(href="/p/spring/")
img(src="{{ url_for('static', filename='assets/img/projects/spring_450x150.jpg')}}") img(src="{{ url_for('static', filename='assets/img/projects/spring_450x150.jpg')}}")
p.
#[strong Spring] - A poetic short film about a mountain spirit and her wise little dog.
a.in-production-project(href="/p/hero/") p.text-muted.pt-2.
img(src="{{ url_for('static', filename='assets/img/projects/hero_450x150.jpg')}}") A poetic short film about a mountain spirit and her wise little dog. #[a(href="/p/spring/") Check it out].
p.
#[strong Hero] - A '2D' trailer-style movie focused on getting grease pencil
production ready for Blender 2.8.
section.stream section.stream.py-3
h6.title-underline Latest Assets
h4 Latest Assets ul.activity-stream__list.list-unstyled
ul.activity-stream__list
| {% for n in activity_stream %} | {% for n in activity_stream %}
li( li(
class="{{ n.node_type }} {{ n.properties.content_type }} {% if n.picture %}with-picture{% endif %}", class="{{ n.node_type }} {{ n.properties.content_type }} {% if n.picture %}with-picture{% endif %}",
@@ -104,7 +96,7 @@ meta(name="twitter:image", content="{% if main_project.picture_header %}{{ main_
.ribbon .ribbon
span free span free
| {% endif %} | {% endif %}
ul.meta ul.list-unstyled.d-flex.text-muted
| {% if not n.picture %} | {% if not n.picture %}
li.when li.when
a(href="{{ n.url }}", title="{{ n._created }}") {{ n._created | pretty_date_time }} a(href="{{ n.url }}", title="{{ n._created }}") {{ n._created | pretty_date_time }}
@@ -123,7 +115,7 @@ meta(name="twitter:image", content="{% if main_project.picture_header %}{{ main_
| {% endif %} | {% endif %}
| {% if n.picture %} | {% if n.picture %}
ul.meta.extra ul.list-unstyled.d-flex.text-muted.extra
li.when li.when
a(href="{{ n.url }}", title="{{ n._created }}") {{ n._created | pretty_date_time }} a(href="{{ n.url }}", title="{{ n._created }}") {{ n._created | pretty_date_time }}
li.who {{ n.user.full_name }} li.who {{ n.user.full_name }}
@@ -134,12 +126,12 @@ meta(name="twitter:image", content="{% if main_project.picture_header %}{{ main_
| No items to list. | No items to list.
section.random-asset section.random-asset.py-3
h4 h6.title-underline
a(href="/search") Explore the Cloud a(href="/search") Explore the Cloud
span.section-lead Random selection of the best assets & tutorials .pb-3.text-muted Random selection of the best assets & tutorials
ul.random-asset__list ul.random-asset__list.list-unstyled
| {% for n in random_featured %} | {% for n in random_featured %}
| {% if n.picture and loop.first %} | {% if n.picture and loop.first %}
li.random-asset__list-item.project li.random-asset__list-item.project
@@ -151,7 +143,7 @@ meta(name="twitter:image", content="{% if main_project.picture_header %}{{ main_
.random-asset__list-details .random-asset__list-details
a.title(href="{{ n.project.url }}") {{ n.project.name }} a.title(href="{{ n.project.url }}") {{ n.project.name }}
| {% if n.project.summary %} | {% if n.project.summary %}
ul.meta ul.list-unstyled.d-flex.text-muted
li.what li.what
a(href="{{ n.project.url }}") {{ n.project.summary }} a(href="{{ n.project.url }}") {{ n.project.summary }}
| {% endif %} | {% endif %}
@@ -175,7 +167,7 @@ meta(name="twitter:image", content="{% if main_project.picture_header %}{{ main_
a.title(href="{{ n.url }}") a.title(href="{{ n.url }}")
| {{ n.name }} | {{ n.name }}
ul.meta ul.list-unstyled.d-flex.text-muted
li.what li.what
a(href="{{ n.url }}") a(href="{{ n.url }}")
| {% if n.properties.content_type %}{{ n.properties.content_type | undertitle }}{% else %}Folder{% endif %} | {% if n.properties.content_type %}{{ n.properties.content_type | undertitle }}{% else %}Folder{% endif %}
@@ -207,7 +199,7 @@ meta(name="twitter:image", content="{% if main_project.picture_header %}{{ main_
| {% endif %} | {% endif %}
.random-asset__list-details .random-asset__list-details
a.title(href="{{ n.url }}") {{ n.name }} a.title(href="{{ n.url }}") {{ n.name }}
ul.meta ul.list-unstyled.d-flex.text-muted
li.what li.what
a(href="{{ n.url }}") a(href="{{ n.url }}")
| {% if n.properties.content_type %}{{ n.properties.content_type }}{% else %}Folder{% endif %} | {% if n.properties.content_type %}{{ n.properties.content_type }}{% else %}Folder{% endif %}
@@ -218,11 +210,10 @@ meta(name="twitter:image", content="{% if main_project.picture_header %}{{ main_
| {% endfor %} | {% endfor %}
section.comments section.comments.py-3
h6.title-underline Latest Comments
h4 Latest Comments ul.list-unstyled
ul
| {% if latest_comments %} | {% if latest_comments %}
| {% for n in latest_comments %} | {% for n in latest_comments %}
li( li(
@@ -232,7 +223,7 @@ meta(name="twitter:image", content="{% if main_project.picture_header %}{{ main_
a.comment-content(href="{{ n.url }}") a.comment-content(href="{{ n.url }}")
| {{ n.properties.content | striptags | truncate(200) }} | {{ n.properties.content | striptags | truncate(200) }}
ul.meta ul.list-unstyled.d-flex.text-muted
li.who {{ n.user.full_name }} li.who {{ n.user.full_name }}
| {% if n.attached_to %} | {% if n.attached_to %}

View File

@@ -3,7 +3,7 @@ html(lang="en")
head head
meta(charset="utf-8") meta(charset="utf-8")
title {% if self.page_title() %}{% block page_title %}{% endblock %} — {% endif %}Blender Cloud title {% if self.page_title() %}{% block page_title %}{% endblock %} — {% endif %}Blender Cloud
meta(name="viewport", content="width=device-width, initial-scale=1.0") meta(name="viewport", content="width=device-width, initial-scale=1, shrink-to-fit=no")
meta(name="description", content="Blender Cloud is a web based service developed by Blender Institute that allows people to access the training videos and all the data from the open projects.") meta(name="description", content="Blender Cloud is a web based service developed by Blender Institute that allows people to access the training videos and all the data from the open projects.")
meta(name="author", content="Blender Institute") meta(name="author", content="Blender Institute")
meta(name="theme-color", content="#3e92aa") meta(name="theme-color", content="#3e92aa")
@@ -46,14 +46,10 @@ html(lang="en")
link(href="{{ url_for('static', filename='assets/img/favicon.png') }}", rel="shortcut icon") link(href="{{ url_for('static', filename='assets/img/favicon.png') }}", rel="shortcut icon")
link(href="{{ url_for('static', filename='assets/img/apple-touch-icon-precomposed.png') }}", rel="icon apple-touch-icon-precomposed", sizes="192x192") link(href="{{ url_for('static', filename='assets/img/apple-touch-icon-precomposed.png') }}", rel="icon apple-touch-icon-precomposed", sizes="192x192")
link(href="{{ url_for('static_pillar', filename='assets/css/vendor/bootstrap.min.css') }}", rel="stylesheet")
link(href="{{ url_for('static', filename='assets/google-font-roboto/roboto.css') }}", rel="stylesheet")
| {% block head %}{% endblock %} | {% block head %}{% endblock %}
| {% block css %} | {% block css %}
link(href="{{ url_for('static_pillar', filename='assets/css/font-pillar.css') }}", rel="stylesheet") link(href="{{ url_for('static_pillar', filename='assets/css/font-pillar.css') }}", rel="stylesheet")
link(href="{{ url_for('static_pillar', filename='assets/css/base.css') }}", rel="stylesheet")
| {% if title == 'blog' %} | {% if title == 'blog' %}
link(href="{{ url_for('static_pillar', filename='assets/css/blog.css') }}", rel="stylesheet") link(href="{{ url_for('static_pillar', filename='assets/css/blog.css') }}", rel="stylesheet")
| {% else %} | {% else %}
@@ -61,14 +57,10 @@ html(lang="en")
| {% endif %} | {% endif %}
| {% endblock css %} | {% endblock css %}
| {% if not title %}{% set title="default" %}{% endif %} | {% if not title %}{% set title="default" %}{% endif %}
body(class="{{ title }}") body(class="{{ title }}")
.container-page
| {% with messages = get_flashed_messages(with_categories=True) %} | {% with messages = get_flashed_messages(with_categories=True) %}
| {% if messages %} | {% if messages %}
| {% for (category, message) in messages %} | {% for (category, message) in messages %}
.alert(role="alert", class="alert-{{ category }}") .alert(role="alert", class="alert-{{ category }}")
i.alert-icon(class="{{ category }}") i.alert-icon(class="{{ category }}")
@@ -76,23 +68,29 @@ html(lang="en")
button.close(type="button", data-dismiss="alert") button.close(type="button", data-dismiss="alert")
i.pi-cancel i.pi-cancel
| {% endfor %} | {% endfor %}
| {% endif %} | {% endif %}
| {% endwith %} | {% endwith %}
nav.navbar nav.navbar.navbar-expand-md.fixed-top.bg-white
.navbar-container
header.navbar-header
button.navbar-toggle(data-target=".navbar-collapse", data-toggle="collapse", type="button")
span.sr-only Toggle navigation
i.pi-menu
a.navbar-brand( a.navbar-brand(
href="{{ url_for('main.homepage') }}", href="{{ url_for('main.homepage') }}",
title="Blender Cloud") title="Blender Cloud")
span.app-logo span.app-logo
i.pi-blender-cloud i.pi-blender-cloud
button.navbar-toggler.text-light(
data-target=".navbar-collapse",
data-toggle="collapse",
type="button")
span.sr-only Toggle navigation
span.navbar-toggler-icon.d-flex.align-items-center
i.pi-menu
| {% block navigation_tabs %}
| {% endblock navigation_tabs %}
| {% block navigation_search %} | {% block navigation_search %}
// TODO (pablo) - bring it back asap
.search-input .search-input
input#cloud-search( input#cloud-search(
type="text", type="text",
@@ -100,8 +98,8 @@ html(lang="en")
i.search-icon.pi-search i.search-icon.pi-search
| {% endblock navigation_search %} | {% endblock navigation_search %}
nav.collapse.navbar-collapse .collapse.navbar-collapse
ul.nav.navbar-nav.navbar-right ul.navbar-nav.ml-auto
| {% if node and node.properties and node.properties.category %} | {% if node and node.properties and node.properties.category %}
| {% set category = node.properties.category %} | {% set category = node.properties.category %}
| {% else %} | {% else %}
@@ -118,7 +116,7 @@ html(lang="en")
class="{% if category == 'blog' %}active{% endif %}") class="{% if category == 'blog' %}active{% endif %}")
span Blog span Blog
li(class="dropdown libraries") li.dropdown
a.navbar-item.dropdown-toggle( a.navbar-item.dropdown-toggle(
href="", href="",
data-toggle="dropdown", data-toggle="dropdown",
@@ -126,7 +124,7 @@ html(lang="en")
span Libraries span Libraries
i.pi-angle-down i.pi-angle-down
ul.dropdown-menu ul.dropdown-menu.p-0
li li
a.navbar-item( a.navbar-item(
href="{{ url_for('projects.view', project_url='hdri') }}", href="{{ url_for('projects.view', project_url='hdri') }}",
@@ -153,9 +151,9 @@ html(lang="en")
| Characters | Characters
li(class="dropdown libraries") li(class="dropdown")
a.navbar-item.dropdown-toggle( a.navbar-item.dropdown-toggle(
href="", href="{{ url_for('cloud.workshops') }}"
data-toggle="dropdown", data-toggle="dropdown",
title="Training") title="Training")
span Training span Training
@@ -187,41 +185,99 @@ html(lang="en")
i.pi-image i.pi-image
| Art Gallery | Art Gallery
li li(class="dropdown")
a.navbar-item( a.navbar-item.dropdown-toggle(
href="{{ url_for('cloud.open_projects') }}", href="{{ url_for('cloud.open_projects') }}",
title="Browse all the Open Projects", title="Browse all the Open Projects",
data-toggle="tooltip", data-toggle="dropdown",
data-placement="bottom",
class="{% if category in ['open-projects', 'film'] %}active{% endif %}") class="{% if category in ['open-projects', 'film'] %}active{% endif %}")
span Open Projects span Open Projects
i.pi-angle-down
ul.dropdown-menu
li
a.navbar-item(href="/p/spring")
span.px-2 Spring
li
a.navbar-item(href="/p/hero")
span.px-2 Hero
li
a.navbar-item(href="/p/dailydweebs")
span.px-2 The Daily Dweebs
li
a.navbar-item(href="/p/agent-327")
span.px-2 Agent 327
li
a.navbar-item(href="/p/caminandes-3")
span.px-2 Caminandes: Llamigos
li.dropdown-divider
li
a.navbar-item(href="{{ url_for('cloud.open_projects') }}")
span.pl-2 All Open Projects
li(class="dropdown")
a.navbar-item.dropdown-toggle(
href="{{ url_for('cloud.services') }}",
title="Blender Cloud Services",
data-toggle="dropdown",
class="{% if category == 'services' %}active{% endif %}")
span Services
i.pi-angle-down
ul.dropdown-menu
li
a.navbar-item(
href="/attract",
title="Production Management",
data-toggle="tooltip",
data-placement="left")
i.pi-attract
| Attract
li
a.navbar-item(
href="/flamenco",
title="Render Management",
data-toggle="tooltip",
data-placement="left")
i.pi-flamenco
| Flamenco
li
a.navbar-item(
href="/services#blender-cloud-add-on",
title="Blender Sync, Texture Browser and more",
data-toggle="tooltip",
data-placement="left")
i.pi-blender
| Blender Cloud Add-on
li.dropdown-divider
li li
a.navbar-item( a.navbar-item(
href="{{ url_for('cloud.services') }}", href="{{ url_for('cloud.services') }}",
title="Blender Cloud Services", title="All Blender Cloud services",
data-toggle="tooltip", data-toggle="tooltip",
data-placement="bottom", data-placement="left")
class="{% if category == 'services' %}active{% endif %}") i.pi-list
span Services | All Services
| {% endblock navigation_sections %} | {% endblock navigation_sections %}
| {% block navigation_user %}
| {% include 'menus/notifications.html' %}
| {% include 'menus/user.html' %}
| {% endblock navigation_user %}
| {% if current_user.is_anonymous %} | {% if current_user.is_anonymous %}
li li.pt-1
a.navbar-item( a.btn.btn-sm.btn-primary.px-3.mx-1(
href="https://store.blender.org/product/membership/", href="https://store.blender.org/product/membership/",
title="Sign up") Sign up title="Sign up") Sign up
| {% endif %} | {% endif %}
| {% block navigation_user %}
| {% include 'menus/notifications.html' %}
| {% include 'menus/user.html' %}
| {% endblock navigation_user %}
.page-content .page-content
#search-overlay #search-overlay
| {% block page_overlay %} | {% block page_overlay %}
@@ -231,46 +287,101 @@ html(lang="en")
| {% block body %}{% endblock %} | {% block body %}{% endblock %}
| {% block footer_container %} | {% block footer_container %}
#footer-container .footer-wrapper
| {% block footer_navigation %} | {% block footer_navigation %}
#footer-navigation .footer-navigation
.container .container
.row .row
.col-md-4.col-xs-6 .col-md-4.col-xs-6
.footer-support h4
h4 Support & Feedback a(href="{{ url_for('main.homepage') }}")
p. i.pi-blender-cloud-logo
Let us know what you think or if you have any issues
just write to cloudsupport at blender dot org
.col-md-2.col-xs-6 p.pl-2.
ul.footer-social Blender Cloud is the creative hub for your projects,
li powered by Free and Open Source Software.
a(href="https://www.facebook.com/BlenderCloudOfficial/",
title="Follow us on Facebook") h5.d-flex
i.pi-social-facebook a.px-2(href="https://twitter.com/Blender_Cloud",
li title="Follow us on Twitter")
a(href="https://twitter.com/Blender_Cloud", i.pi-social-youtube
a.px-2(href="https://twitter.com/Blender_Cloud",
title="Follow us on Twitter") title="Follow us on Twitter")
i.pi-social-twitter i.pi-social-twitter
a.px-2(href="https://www.facebook.com/BlenderCloudOfficial/",
title="Follow us on Facebook")
i.pi-social-facebook
.col-md-2.col-xs-6 .col-md-2.col-xs-6
h4 h7.font-weight-bold
a(href="{{ url_for('main.homepage') }}") | TRAINING
| Blender Cloud
ul.footer-links ul.list-unstyled
li
a(href="{{ url_for('cloud.courses') }}")
| Courses
li
a(href="{{ url_for('cloud.workshops') }}")
| Workshops
li
a(href="{{ url_for('projects.view', project_url='gallery') }}")
| Art Gallery
.col-md-2.col-xs-6
h7.font-weight-bold
| LIBRARIES
ul.list-unstyled
li li
a(href="{{ url_for('main.main_blog') }}", a(href="{{ url_for('main.main_blog') }}",
title="Blender Cloud Blog") title="Blender Cloud Blog")
| Blog | HDRIs
li li
a(href="{{ url_for('cloud.services') }}", a(href="{{ url_for('cloud.services') }}",
title="Blender Cloud Services") title="Blender Cloud Services")
| Services | Textures
li li
a(href="{{ url_for('cloud.about') }}", a(href="{{ url_for('cloud.about') }}",
title="About Blender Cloud") title="About Blender Cloud")
| About | Characters
.col-md-2.col-xs-6
h7.font-weight-bold
a(href="{{ url_for('cloud.services') }}")
| SERVICES
ul.list-unstyled
li
a(href="{{ url_for('main.main_blog') }}",
title="Blender Cloud Blog")
| Add-on
li
a(href="{{ url_for('main.main_blog') }}",
title="Blender Cloud Blog")
| Blender Sync
li
a(href="{{ url_for('cloud.services') }}",
title="Blender Cloud Services")
| Attract
li
a(href="{{ url_for('cloud.about') }}",
title="About Blender Cloud")
| Flamenco
li
a(href="{{ url_for('cloud.about') }}",
title="About Blender Cloud")
| Image Sharing
.col-md-2.col-xs-6
h7.font-weight-bold
| BLENDER
ul.list-unstyled
li
a(href="{{ url_for('main.main_blog') }}",
title="Blender Cloud Blog")
| blender.org
li li
a(href="{{ url_for('cloud.terms_and_conditions') }}", a(href="{{ url_for('cloud.terms_and_conditions') }}",
title="Terms and Conditions") title="Terms and Conditions")
@@ -279,33 +390,11 @@ html(lang="en")
a(href="{{ url_for('cloud.privacy') }}", a(href="{{ url_for('cloud.privacy') }}",
title="Privacy") title="Privacy")
| Privacy | Privacy
.col-md-2.col-xs-6
h4
a(href="https://www.blender.org",
title="Blender official Website")
| Blender
ul.footer-links
li
a(href="https://www.blender.org",
title="Blender official Website")
| Blender.org
li
a(href="https://store.blender.org/",
title="The official Blender Store")
| Blender Store
.col-md-2.col-xs-6.special
| With the support of the <br/> MEDIA Programme of the European Union<br/><br/>
img(alt="MEDIA Programme of the European Union",
src="https://gooseberry.blender.org/wp-content/uploads/2014/01/media_programme.png")
| {% endblock footer_navigation %} | {% endblock footer_navigation %}
| {% block footer %}
footer.container
#hop(title="Be awesome in space") #hop(title="Be awesome in space")
i.pi-angle-up i.pi-angle-up
| {% endblock footer %}
| {% endblock footer_container %} | {% endblock footer_container %}
#notification-pop(data-url="", data-read-toggle="") #notification-pop(data-url="", data-read-toggle="")
@@ -318,10 +407,7 @@ html(lang="en")
span.nc-date span.nc-date
a(href="") a(href="")
noscript script(src="{{ url_for('static_cloud', filename='assets/js/bootstrap.min.js') }}")
link(href='//fonts.googleapis.com/css?family=Roboto:300,400', rel='stylesheet', type='text/css')
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/jquery.bootstrap-3.3.7.min.js') }}")
| {% if current_user.is_authenticated %} | {% if current_user.is_authenticated %}
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/jquery.typewatch-3.0.0.min.js') }}") script(src="{{ url_for('static_pillar', filename='assets/js/vendor/jquery.typewatch-3.0.0.min.js') }}")

View File

@@ -0,0 +1,69 @@
// {#
// Header of landing pages. title or text can be skipped:
// +jumbotron("{{ page_title }}", null, "{{ page_header_image }}")
// Any extra attributes added (in a separate group) will be passed as is:
// +jumbotron("{{ page_title }}", null, "{{ page_header_image }}")(data-node-id='{{ node._id }}')
// #}
mixin jumbotron(title, text, image, url)
if url
a.jumbotron.jumbotron-overlay.text-white(
style='background-image: url(' + image + ');',
href=url)&attributes(attributes)
.container
.row
.col-md-9
if title
.display-4.text-uppercase.font-weight-bold
=title
if text
.lead
=text
else
.jumbotron.jumbotron-overlay.text-white(style='background-image: url(' + image + ');')&attributes(attributes)
.container
.row
.col-md-9
if title
.display-4.text-uppercase.font-weight-bold
=title
if text
.lead
=text
// {# Secondary navigation.
// e.g. Workshops, Courses. #}
mixin nav-secondary(title)
ul.nav.nav-secondary&attributes(attributes)
if title
li.font-weight-bold.px-2
=title
if block
block
else
p No items defined.
mixin nav-secondary-link()
li.nav-item
a.nav-link&attributes(attributes)
block
// {# Takes as argument the number of columns to use in this deck. 1-6 #}
mixin card-deck(columns)
.card-deck.card-padless(class='card-' + columns + '-columns')
if block
block
else
p No cards defined.
// {#
// Passes all attributes to the card.
// You can do fun stuff in a loop even like:
// +card(data-url="{{ url_for('projects.view', project_url=project.url) }}", tabindex='{{ loop.index }}')
// #}
mixin card()
.card.card-fade.cursor-pointer.mb-4.js-project-go&attributes(attributes)
if block
block
else
p No card content defined.

View File

@@ -0,0 +1,164 @@
include ../../../mixins/components
| {% import 'projects/_macros.html' as projectmacros %}
| {% macro render_blog_post(node, project=None, pages=None) %}
.expand-image-links.imgs-fluid
| {% if node.picture %}
+jumbotron(
"{{ node.name }}",
"{{ node._created | pretty_date }}",
"{{ node.picture.thumbnail('h', api=api) }}",
"{{ node.url }}")(class="row")
| {% else %}
.pt-3.text-center.text-muted
h2
a.text-muted(href="{{ node.url }}")
| {{ node.name }}
ul.d-flex.list-unstyled.justify-content-center
| {% if node.project.name %}
li.pr-2 {{ node.project.name }}
| {% endif %}
| {% if node.user.full_name %}
li.pr-2
| {{ node.user.full_name }}
| {% endif %}
li
a.px-2.text-muted(href="{{ node.url }}",
title="Updated {{ node._updated | pretty_date }}")
| {{ node._created | pretty_date }}
li
a.px-2(href="{{ node.url }}#comments")
| Leave a comment
| {% if node.has_method('PUT') %}
li
a.px-2(href="{{url_for('nodes.edit', node_id=node._id)}}")
i.pi-edit
| Edit Post
| {% endif %}
| {% endif %}
| {% if project and project._id != config.MAIN_PROJECT_ID %}
| {{ projectmacros.render_secondary_navigation(project, pages=pages) }}
| {% endif %}
.row
.col-md-9.mx-auto
.item-content.pt-4
| {{ node.properties | markdowned('content') }}
hr.my-4
| {% endmacro %}
//- ******************************************************* -//
| {% macro render_blog_list_item(node) %}
.row.position-relative.py-2
.col-md-1
| {% if node.picture %}
a.imgs-fluid(href="{{ node.url }}")
img(src="{{ node.picture.thumbnail('s', api=api) }}")
| {% else %}
.bg-primary.rounded.h-100
a.d-flex.align-items-center.justify-content-center.h-100.text-white(href="{{ node.url }}")
i.pi-document-text
| {% endif %}
.col-md-11
h5
a.text-muted(href="{{ node.url }}") {{node.name}}
.text-muted.
#[span(title="{{node._created}}") {{node._created | pretty_date }}]
{% if node._created != node._updated %}
#[span(title="{{node._updated}}") (updated {{node._updated | pretty_date }})]
{% endif %}
{% if node.properties.category %} · {{node.properties.category}}{% endif %}
· {{node.user.full_name}}
{% if node.properties.status != 'published' %} · {{ node.properties.status}} {% endif %}
| {% endmacro %}
//- ******************************************************* -//
| {% macro render_blog_index(project, posts, can_create_blog_posts, api, more_posts_available, posts_meta, pages=None) %}
| {% if can_create_blog_posts %}
+nav-secondary
+nav-secondary-link(href="{{url_for('nodes.posts_create', project_id=project._id)}}")
span.text-success
i.pi-plus
| Create New Blog Post
| {% endif %}
| {% if posts %}
| {{ render_blog_post(posts[0], project=project, pages=pages) }}
.container
.row
.col-md-9.mx-auto
| {% for node in posts[1:] %}
| {% if loop.first %}
h5.text-muted.text-center Blasts from the past
| {% endif %}
| {{ render_blog_list_item(node) }}
| {% endfor %}
| {% if more_posts_available %}
.blog-archive-navigation
a(href="{{ project.blog_archive_url }}")
| {{posts_meta.total - posts|length}} more blog posts over here
i.pi-angle-right
| {% endif %}
| {% else %}
.text-center
p No posts... yet!
| {% endif %} {# posts #}
| {% endmacro %}
//- Macro for rendering the navigation buttons for prev/next pages -//
| {% macro render_archive_pagination(project) %}
.blog-archive-navigation
| {% if project.blog_archive_prev %}
a.archive-nav-button(
href="{{ project.blog_archive_prev }}", rel="prev")
i.pi-angle-left
| Previous page
| {% else %}
span.archive-nav-button
i.pi-angle-left
| Previous page
| {% endif %}
a.archive-nav-button(
href="{{ url_for('main.project_blog', project_url=project.url) }}")
| Blog Index
| {% if project.blog_archive_next %}
a.archive-nav-button(
href="{{ project.blog_archive_next }}", rel="next")
| Next page
i.pi-angle-right
| {% else %}
span.archive-nav-button
| Next page
i.pi-angle-right
| {% endif %}
| {% endmacro %}
| {% macro render_archive(project, posts, posts_meta) %}
| {{ render_archive_pagination(project) }}
| {% for node in posts %}
| {{ render_blog_list_item(node) }}
| {% endfor %}
| {{ render_archive_pagination(project) }}
| {% endmacro %}

View File

@@ -0,0 +1,213 @@
| {% extends 'layout.html' %}
| {% from '_macros/_navigation.html' import navigation_tabs %}
include ../mixins/components
| {% set title = 'organizations' %}
| {% block page_title %}Organizations{% endblock %}
| {% block og %}
meta(property="og:title", content="Dashboard")
meta(name="twitter:title", content="Blender Cloud")
meta(property="og:url", content="https://cloud.blender.org/{{ request.path }}")
meta(property="og:type", content="website")
meta(property="og:image", content="{{ url_for('static', filename='assets/img/backgrounds/cloud_services_oti.jpg')}}")
meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/backgrounds/cloud_services_oti.jpg')}}")
| {% endblock %}
| {% block navigation_tabs %}
| {{ navigation_tabs(title) }}
| {% endblock navigation_tabs %}
| {% block body %}
+nav-secondary
| {% if can_create_organization %}
+nav-secondary-link(
class="create",
onclick='createNewOrganization(this)')
span.text-success
i.pi-plus
| Create Organization
| {% endif %}
li#create_organization_result_panel.result
.container-fluid.dashboard-container
.row
.col-md-6
ul.projects__list
| {% if organizations %}
| {% for organization in organizations['_items'] %}
| {% set link_url = url_for('pillar.web.organizations.view_embed', organization_id=organization._id) %}
li.projects__list-item(
data-url="{{ link_url }}",
id="organization-{{ organization._id }}")
a.projects__list-thumbnail(
href="{{ link_url }}")
i.pi-users
.projects__list-details
a.title(href="{{ link_url }}")
| {{ organization.name }}
ul.meta
li(title="Members")
| {{ organization.members|hide_none|count }} Member{{ organization.members|hide_none|count|pluralize }}
| {% if (organization.unknown_members|count) != 0 %}
| ({{ organization.unknown_members|hide_none|count }} pending)
| {% endif %}
li(title="Seats")
| {{ organization.seat_count }} Seat{{ organization.seat_count|pluralize }}
| {% endfor %}
| {% else %}
li.projects__list-item
a.projects__list-thumbnail
i.pi-blender-cloud
.projects__list-details
span Create an Organization to get started!
| {% endif %}
.col-md-6.py-1.pb-3
#item-details
| {% endblock %}
| {% block footer_scripts %}
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/jquery.typeahead-0.11.1.min.js')}}")
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/jquery.autocomplete-0.22.0.min.js') }}", async=true)
script.
/* Returns a more-or-less reasonable message given an error response object. */
function xhrErrorResponseMessage(err) {
if (typeof err.responseJSON == 'undefined')
return err.statusText;
if (typeof err.responseJSON._error != 'undefined' && typeof err.responseJSON._error.message != 'undefined')
return err.responseJSON._error.message;
if (typeof err.responseJSON._message != 'undefined')
return err.responseJSON._message
return err.statusText;
}
/**
* Open an organization in the #item-details div.
*/
function item_open(item_id, pushState)
{
if (item_id === undefined ) {
throw new ReferenceError("item_open(" + item_id + ") called.");
}
// Style elements starting with item_type and dash, e.g. "#job-uuid"
var clean_classes = 'active processing';
var current_item = $('#organization-' + item_id);
$('[id^="organization-"]').removeClass(clean_classes);
current_item
.removeClass(clean_classes)
.addClass('processing');
var item_url = '/o/' + item_id;
$.get(item_url, function(item_data) {
$('#item-details').html(item_data);
current_item
.removeClass(clean_classes)
.addClass('active');
}).fail(function(xhr) {
if (console) {
console.log('Error fetching organization', item_id, 'from', item_url);
console.log('XHR:', xhr);
}
current_item.removeClass(clean_classes);
toastr.error('Failed to open organization');
if (xhr.status) {
$('#item-details').html(xhr.responseText);
} else {
$('#item-details').html('<p class="text-danger">Opening ' + item_type + ' failed. There possibly was ' +
'an error connecting to the server. Please check your network connection and ' +
'try again.</p>');
}
});
// Determine whether we should push the new state or not.
pushState = (typeof pushState !== 'undefined') ? pushState : true;
if (!pushState) return;
// Push the correct URL onto the history.
var push_state = {itemId: item_id};
window.history.pushState(
push_state,
'Organization: ' + item_id,
item_url
);
}
$('li.projects__list-item').click(function(e){
url = $(this).data('url');
if (typeof url === 'undefined') return;
window.location.href = url;
if (console) console.log(url);
$(this).addClass('active');
$(this).find('.projects__list-thumbnail i')
.removeAttr('class')
.addClass('pi-spin spin');
});
{% if open_organization_id %}
$(function() { item_open('{{ open_organization_id }}', false); });
{% endif %}
{% if can_create_organization %}
function createNewOrganization(button) {
$(button)
.attr('disabled', 'disabled')
.fadeTo(200, 0.1);
$('#create_organization_result_panel').html('');
// TODO: create a form to get the initial info from the user.
$.post(
'{{ url_for('pillar.web.organizations.create_new') }}',
{
name: 'New Organization',
seat_count: 1,
}
)
.done(function(result) {
var $p = $('<p>').text('organization created, reloading list.')
$('#create_organization_result_panel').html($p);
window.location.href = result.location;
})
.fail(function(err) {
var msg = xhrErrorResponseMessage(err);
$('#create_organization_result_panel').html('Error creating organization: ' + msg);
$(button)
.fadeTo(1000, 1.0)
.queue(function() {
$(this)
.removeAttr('disabled')
.dequeue()
;
})
})
;
return false;
}
{% endif %}
| {% endblock %}

View File

@@ -0,0 +1,59 @@
| {% extends 'projects/home_layout.html' %}
| {% set subtab = 'blender_sync' %}
| {% set learn_more_btn_url = '/blog/introducing-blender-sync' %}
| {% block currenttab %}
.container-fluid
section.nav-tabs__tab.active#tab-blender_sync
.tab_header-container
.tab_header-intro(
style="background-image: url({{ url_for('static', filename='assets/img/backgrounds/pattern_01.jpg')}})")
.tab_header-intro_text
h2 Connect Blender with the Cloud
p
| Save your Blender preferences and keymaps once, load them anywhere.
<br/>
| Use the
=' '
a(href='https://cloud.blender.org/r/downloads/blender_cloud-latest-bundle.zip') Blender Cloud add-on
=' '
| to synchronise your settings from within Blender.
| {% if show_addon_download_buttons %}
.row
.col-md-6
a.btn.btn-block.btn-outline-success(
href="https://cloud.blender.org/r/downloads/blender_cloud-latest-bundle.zip")
i.pi-download
| Download <small>v</small>{{ config.BLENDER_CLOUD_ADDON_VERSION }}
.col-md-6
a.btn.btn-link(
href="{{ learn_more_btn_url }}")
| Learn More
i.pi-angle-right
| {% endif %}
.tab_header-intro_icons
i.pi-blender
i.pi-heart-filled
i.pi-blender-cloud
| {% for version in synced_versions %}
.blender_sync-main
.blender_sync-main-header
h5.blender_sync-main-title
i.pi-blender
| Blender {{ version.version }}
.blender_sync-main-last
| Last synced on: {{ version.date|pretty_date }}
| {% else %}
.blender_sync-main.empty
.blender_sync-main-header
span.blender_sync-main-title
| No settings synced yet
<hr/>
a.download(
href='https://cloud.blender.org/r/downloads/blender_cloud-latest-bundle.zip')
| Download add-on
| {% endfor %}
| {% endblock %}

View File

@@ -0,0 +1,51 @@
| {% extends 'layout.html' %}
| {% from '_macros/_navigation.html' import navigation_tabs %}
include ../mixins/components
| {% set title = 'home' %}
| {% block og %}
meta(property="og:type", content="website")
meta(property="og:url", content="https://cloud.blender.org{{ request.path }}")
meta(property="og:title", content="Blender Cloud - Home")
meta(name="twitter:title", content="Blender Cloud")
meta(property="og:image", content="{{ url_for('static', filename='assets/img/backgrounds/cloud_services_oti.jpg')}}")
meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/backgrounds/cloud_services_oti.jpg')}}")
| {% endblock %}
| {% block page_title %}
| {{current_user.full_name}}
| {% endblock %}
| {% block navigation_tabs %}
| {{ navigation_tabs(title) }}
| {% endblock navigation_tabs %}
| {% block body %}
.dashboard-container
section#projects.bg-white
+nav-secondary()(id='sub-nav-tabs__list')
+nav-secondary-link(id="subtab-blender_sync", data-tab-url="{{ url_for('projects.home_project')}}")
| Blender Sync
+nav-secondary-link(id="subtab-images", data-tab-url="{{ url_for('projects.home_project_shared_images')}}")
| Images
| {% block currenttab %}{% endblock %}
| {% endblock %}
| {% block footer_scripts %}
script.
$(document).ready(function () {
$('#subtab-{{ subtab }}').addClass('active');
var $nav_tabs = $('#sub-nav-tabs__list').find('a.nav-link');
$nav_tabs.on('click', function (e) {
console.log($(this));
window.location = $(this).attr('data-tab-url');
});
});
| {% endblock %}

View File

@@ -0,0 +1,300 @@
| {% extends 'layout.html' %}
| {% from '_macros/_navigation.html' import navigation_tabs %}
include ../mixins/components
| {% set title = 'dashboard' %}
| {% block og %}
meta(property="og:title", content="Dashboard")
meta(name="twitter:title", content="Blender Cloud")
meta(property="og:url", content="https://cloud.blender.org/{{ request.path }}")
meta(property="og:type", content="website")
meta(property="og:image", content="{{ url_for('static', filename='assets/img/backgrounds/cloud_services_oti.jpg')}}")
meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/backgrounds/cloud_services_oti.jpg')}}")
| {% endblock %}
| {% block page_title %}
| {{current_user.full_name}}
| {% endblock %}
| {% block css %}
| {{ super() }}
style.
.deleted-projects-toggle {
z-index: 10;
position: absolute;
right: 0;
font-size: 20px;
padding: 3px;
text-shadow: 0 0 2px white;
}
.deleted-projects-toggle .show-deleted {
color: #aaa;
}
.deleted-projects-toggle .hide-deleted {
color: #bbb;
}
| {% endblock %}
| {% block navigation_tabs %}
| {{ navigation_tabs(title) }}
| {% endblock navigation_tabs %}
| {% block body %}
.dashboard-container
section.dashboard-main
section#projects.bg-white
+nav-secondary()(id='sub-nav-tabs__list')
+nav-secondary-link(data-tab-toggle='own_projects', class="active")
| Own Projects
| {% if projects_user|length != 0 %}
span ({{ projects_user|length }})
| {% endif %}
+nav-secondary-link(data-tab-toggle='shared')
| Shared with me
| {% if projects_shared|length != 0 %}
span ({{ projects_shared|length }})
| {% endif %}
| {% if current_user.has_cap('subscriber') %}
+nav-secondary-link(
id="project-create",
data-url="{{ url_for('projects.create') }}",
href="{{ url_for('projects.create') }}")
span.text-success
| #[i.pi-plus] Create New Project
| {% elif current_user.has_cap('can-renew-subscription') %}
+nav-secondary-link(
id="project-create",
data-url="{{ url_for('projects.create') }}",
href="/renew",
target="_blank")
| #[i.pi-heart-filled.text-danger] Resubscribe to Create a Project
| {% endif %}
nav.nav-tabs__tab.active#own_projects
.deleted-projects-toggle
| {% if show_deleted_projects %}
a.hide-deleted(href="{{ request.base_url }}", title='Hide deleted projects')
i.pi-trash
| {% else %}
a.show-deleted(href="{{ request.base_url }}?deleted=1", title='Show deleted projects')
i.pi-trash
| {% endif %}
ul.projects__list
| {% for project in projects_deleted %}
li.projects__list-item.deleted
span.projects__list-thumbnail
| {% if project.picture_square %}
img(src="{{ project.picture_square.thumbnail('s', api=api) }}")
| {% else %}
i.pi-blender-cloud
| {% endif %}
.projects__list-details
span.title {{ project.name }}
ul.meta
li.status.deleted Deleted
li.edit
a(href="javascript:undelete_project('{{ project._id }}')") Restore project
| {% else %}
| {% if show_deleted_projects %}
li.projects__list-item.deleted You have no recenly deleted projects. Deleted projects can be restored within a month after deletion.
| {% endif %}
| {% endfor %}
| {% for project in projects_user %}
li.projects__list-item(
data-url="{{ url_for('projects.view', project_url=project.url) }}")
a.projects__list-thumbnail(
href="{{ url_for('projects.view', project_url=project.url) }}")
| {% if project.picture_square %}
img(src="{{ project.picture_square.thumbnail('s', api=api) }}")
| {% else %}
i.pi-blender-cloud
| {% endif %}
.projects__list-details
a.title(href="{{ url_for('projects.view', project_url=project.url) }}")
| {{ project.name }}
ul.meta
li.status(
class="{{ project.is_private | yesno('private,public,') }}",
title="{{ project.is_private | yesno('Private Project,Public Project,') }}")
| {{ project.is_private | yesno('Private,Public,') }}
li.when(title="{{ project._created }}") {{ project._created | pretty_date }}
li.edit
a(href="{{ url_for('projects.edit', project_url=project.url) }}") Edit
| {% if project.status == 'pending' and current_user.has_cap('view-pending-nodes') %}
li.pending Not Published
| {% endif %}
| {% else %}
| {% if current_user.has_cap('subscriber') %}
li.projects__list-item(data-url="{{ url_for('projects.create') }}")
a.projects__list-thumbnail
i.pi-plus
.projects__list-details
a.title(href="{{ url_for('projects.create') }}")
| Create a project to get started!
| {% elif current_user.has_cap('can-renew-subscription') %}
li.projects__list-item(data-url="https://store.blender.org/renew-my-subscription.php")
a.projects__list-thumbnail
i.pi-plus
.projects__list-details
a.title(href="https://store.blender.org/renew-my-subscription.php")
| Renew your Blender Cloud subscription to create your own projects!
| {% else %}
li.projects__list-item(data-url="/join")
a.projects__list-thumbnail
i.pi-plus
.projects__list-details
a.title(href="/join")
| Join Blender Cloud to create your own projects!
| {% endif %}
| {% endfor %}
section.nav-tabs__tab#shared(style='display: none')
ul.projects__list
| {% if projects_shared %}
| {% for project in projects_shared %}
li.projects__list-item(
data-url="{{ url_for('projects.view', project_url=project.url) }}")
a.projects__list-thumbnail(
href="{{ url_for('projects.view', project_url=project.url) }}")
| {% if project.picture_square %}
img(src="{{ project.picture_square.thumbnail('s', api=api) }}")
| {% else %}
i.pi-blender-cloud
| {% endif %}
.projects__list-details
a.title(href="{{ url_for('projects.view', project_url=project.url) }}")
| {{ project.name }}
ul.meta
li.status(
class="{{ project.is_private | yesno('private,public,') }}",
title="{{ project.is_private | yesno('Private Project,Public Project,') }}")
| {{ project.is_private | yesno('Private,Public,') }}
li.when {{ project._created | pretty_date }}
li.who by {{ project.user.full_name }}
li.edit
a(href="{{ url_for('projects.edit', project_url=project.url) }}") Edit
| {% if project.status == 'pending' and current_user.has_cap('view-pending-nodes') %}
li.pending Not Published
| {% endif %}
li.leave
span.user-remove-prompt
| Leave Project
span.user-remove
| Are you sure?
span.user-remove-confirm(
user-id="{{ current_user.objectid }}",
project-url="{{url_for('projects.sharing', project_url=project.url)}}")
i.pi-check
| Yes, leave
span.user-remove-cancel
i.pi-cancel
| No, cancel
| {% endfor %}
| {% else %}
li.projects__list-item
a.projects__list-thumbnail
i.pi-heart-broken
.projects__list-details
.title
| No projects shared with you... yet!
| {% endif %}
| {% endblock %}
| {% block footer_scripts %}
script.
$(document).ready(function() {
$('li.projects__list-item').click(function(e){
url = $(this).data('url');
if (typeof url === 'undefined') return;
window.location.href = url;
if (console) console.log(url);
$(this).addClass('active');
$(this).find('.projects__list-thumbnail i')
.removeAttr('class')
.addClass('pi-spin spin');
});
// Tabs behavior
var $nav_tabs_list = $('#sub-nav-tabs__list');
var $nav_tabs = $nav_tabs_list.find('a.nav-link');
$nav_tabs.on('click', function(e){
e.preventDefault();
$nav_tabs.removeClass('active');
$(this).addClass('active');
$('.nav-tabs__tab').hide();
$('#' + $(this).attr('data-tab-toggle')).show();
});
// Leave project
var $projects_list = $('ul.projects__list');
$projects_list.find('span.user-remove-prompt').on('click', function(e){
e.stopPropagation();
e.preventDefault();
$(this).next().show();
$(this).hide();
});
$projects_list.find('span.user-remove-cancel').on('click', function(e){
e.stopPropagation();
e.preventDefault();
$(this).parent().prev().show();
$(this).parent().hide();
});
$projects_list.find('span.user-remove-confirm').on('click', function(e){
e.stopPropagation();
e.preventDefault();
var parent = $(this).closest('.projects__list-item');
function removeUser(userId, projectUrl){
$.post(projectUrl, {user_id: userId, action: 'remove'})
.done(function (data) {
parent.remove();
});
}
removeUser($(this).attr('user-id'), $(this).attr('project-url'));
});
hopToTop(); // Display jump to top button
});
var patch_url = '{{ url_for('projects.patch.patch_project', project_id='PROJECTID') }}';
function undelete_project(project_id) {
console.log('undeleting project', project_id);
$.ajax({
url: patch_url.replace('PROJECTID', project_id),
method: 'PATCH',
data: JSON.stringify({'op': 'undelete'}),
contentType: 'application/json'
})
.done(function(data, textStatus, jqXHR) {
location.href = jqXHR.getResponseHeader('Location');
})
.fail(function(err) {
toastr.error(xhrErrorResponseMessage(err), 'Undeletion failed');
})
}
| {% endblock %}

View File

@@ -78,8 +78,6 @@ script(src="{{ url_for('static_pillar', filename='assets/js/vendor/videojs-hotke
| {% endblock %} | {% endblock %}
| {% block css %} | {% block css %}
link(href="{{ url_for('static_pillar', filename='assets/css/font-pillar.css') }}", rel="stylesheet")
link(href="{{ url_for('static_pillar', filename='assets/css/base.css') }}", rel="stylesheet")
link(href="{{ url_for('static_cloud', filename='assets/css/project-landing.css') }}", rel="stylesheet") link(href="{{ url_for('static_cloud', filename='assets/css/project-landing.css') }}", rel="stylesheet")
| {% endblock %} | {% endblock %}

View File

@@ -0,0 +1,688 @@
| {% extends 'layout.html' %}
| {% from '_macros/_add_new_menu.html' import add_new_menu %}
include ../mixins/components
| {% block page_title %}{{ project.name }}{% endblock%}
| {% set title = 'project' %}
| {% block og %}
meta(property="og:type", content="website")
| {% if og_picture %}
meta(property="og:image", content="{{ og_picture.thumbnail('l', api=api) }}")
meta(name="twitter:image", content="{{ og_picture.thumbnail('l', api=api) }}")
| {% elif node and node.picture %}
meta(property="og:image", content="{{ node.picture.thumbnail('l', api=api) }}")
meta(name="twitter:image", content="{{ node.picture.thumbnail('l', api=api) }}")
| {% elif project.picture_header %}
meta(property="og:image", content="{{ project.picture_header.thumbnail('l', api=api) }}")
meta(name="twitter:image", content="{{ project.picture_header.thumbnail('l', api=api) }}")
| {% endif %}
| {% if show_project %}
meta(property="og:title", content="{{ project.name }} - Blender Cloud")
meta(name="twitter:title", content="{{ project.name }} - Blender Cloud")
meta(property="og:description", content="{{ project.summary }}")
meta(name="twitter:description", content="{{ project.summary }}")
meta(property="og:url", content="{{ url_for('projects.view', project_url=project.url, _external=True) }}")
| {% else %}
| {% if node %}
meta(property="og:title", content="{{ node.name }} - Blender Cloud")
meta(name="twitter:title", content="{{ node.name }} on Blender Cloud")
| {% if node.node_type == 'post' %}
| {% if node.properties.content %}
meta(property="og:description", content="{{ node.properties.content | truncate(180) }}")
meta(name="twitter:description", content="{{ node.properties.content | truncate(180) }}")
| {% else %}
meta(property="og:description", content="Blender Cloud, your source for open content and training")
meta(name="twitter:description", content="Blender Cloud, your source for open content and training")
| {% endif %}
| {% else %}
| {% if node.description %}
meta(property="og:description", content="{{ node.description | truncate(180) }}")
meta(name="twitter:description", content="{{ node.description | truncate(180) }}")
| {% else %}
meta(property="og:description", content="Blender Cloud, your source for open content and training")
meta(name="twitter:description", content="Blender Cloud, your source for open content and training")
| {% endif %}
| {% endif %}
meta(property="og:url", content="{{url_for('projects.view_node', project_url=project.url, node_id=node._id)}}")
| {% else %}
meta(property="og:title", content="{{ project.name }} Blog on Blender Cloud")
meta(name="twitter:title", content="{{ project.name }} Blog on Blender Cloud")
meta(property="og:description", content="{{ project.summary }}")
meta(name="twitter:description", content="{{ project.summary }}")
meta(property="og:url", content="{{url_for('projects.view', project_url=project.url, _external=True)}}")
| {% endif %}
| {% endif %}
| {% endblock %}
| {% block head %}
link(href="{{ url_for('static_pillar', filename='assets/jstree/themes/default/style.min.css') }}", rel="stylesheet")
| {% if node %}
link(rel="amphtml", href="{{ url_for('nodes.view', node_id=node._id, _external=True, format='amp') }}")
| {% endif %}
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/videojs-6.2.8.min.js') }}")
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/videojs-ga-0.4.2.min.js') }}")
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/videojs-hotkeys-0.2.20.min.js') }}")
script(src="{{ url_for('static_pillar', filename='assets/js/video_plugins.min.js') }}")
| {% endblock %}
| {% block css %}
link(href="{{ url_for('static_pillar', filename='assets/css/font-pillar.css') }}", rel="stylesheet")
link(href="{{ url_for('static_pillar', filename='assets/css/project-main.css') }}", rel="stylesheet")
| {% endblock %}
| {% block navigation_tabs %}
+nav-secondary()(class="bg-white")
| {% if project.category == 'course' %}
li.text-capitalize
a.nav-link.text-muted.px-0(href="{{ url_for('cloud.courses') }}")
| Courses
| {% elif project.category == 'workshop' %}
li.text-capitalize
a.nav-link.text-muted.px-0(href="{{ url_for('cloud.workshops') }}")
| Workshops
li.px-1
i.pi-angle-right
| {% endif %}
+nav-secondary-link(
class="px-0",
href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
| {{ project.name }}
| {% if project.category == "open_project" %}
+nav-secondary-link(
class="active",
href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
| Explore
+nav-secondary-link(
href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
| Blog
+nav-secondary-link(
href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
| About
+nav-secondary-link(
href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
| Team
+nav-secondary-link(
href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
| Awards
| {% endif %}
| {% endblock navigation_tabs %}
| {% block body %}
#project-container
#project-side-container
#project_sidebar.bg-white
ul.project-tabs.p-0
//- li.tabs-thumbnail(class="{% if project.picture_square %}image{% endif %}")
//- a(href="{{url_for('projects.view', project_url=project.url)}}")
//- #project-loading
//- i.pi-spin
//- | {% if project.picture_square %}
//- img(src="{{ project.picture_square.thumbnail('b', api=api) }}")
//- | {% else %}
//- i.pi-home
//- | {% endif %}
li.tabs-browse(
title="Browse",
data-toggle="tooltip",
data-placement="right",
class="active")
a(href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
i.pi-folder
| {% if not project.is_private %}
| {% if current_user_is_subscriber %}
li.tabs-search(
title="Search",
data-toggle="tooltip",
data-placement="right")
a(href="{{ url_for('projects.search', project_url=project.url, _external=True)}} ")
i.pi-search
| {% else %}
li.tabs-search(
title="Search (subscribers only)",
data-toggle="tooltip",
data-placement="right")
a(href="{{ url_for('cloud.join') }}")
i.pi-search
| {% endif %}
| {% endif %}
| {{ extension_sidebar_links }}
| {% if project.has_method('PUT') %}
li(
title="Edit Project",
data-toggle="tooltip",
data-placement="right")
a(href="{{ url_for('projects.edit', project_url=project.url) }}")
i.pi-cog
| {% endif %}
#project_nav(class="{{ title }}")
#project_nav-container
| {% if title != 'about' %}
//- +nav-secondary(class="bg-white")
//- +nav-secondary-link(
//- class="active",
//- href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
//- | {{ project.name }}
//- #project_nav-header.bg-white
//- a.project-title.p-2.font-weight-bold.text-dark(
//- href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
//- | {{ project.name }}
| {% block project_tree %}
#project_tree.bg-white
| {% endblock project_tree %}
| {% endif %}
#project_context-container.border-left
| {% if project.has_method('PUT') %}
#project_context-header.bg-white
span#status-bar
ul.project-edit-tools.disabled
li.dropdown
button#item_add.project-mode-view.btn.btn-sm.btn-outline-secondary.dropdown-toggle(
type="button",
data-toggle="dropdown",
aria-haspopup="true",
aria-expanded="false")
i.button-add-icon.pi-collection-plus
| New...
ul.dropdown-menu.add_new-menu
| {{ add_new_menu(project.node_types) }}
li.button-edit
a#item_edit.project-mode-view.btn.btn-sm.btn-outline-secondary.ml-2(
href="javascript:void(0);",
title="Edit",
data-project_id="{{project._id}}")
i.button-edit-icon.pi-edit
| Edit Project
li.dropdown
button.dropdown-toggle.project-mode-view.btn.btn-sm.btn-outline-secondary.mx-2(
type="button",
data-toggle="dropdown",
aria-haspopup="true",
aria-expanded="false")
i.pi-more-vertical.p-0
ul.dropdown-menu
| {% if current_user.has_cap('admin') %}
li.dropdown-item
a#item_featured(
href="javascript:void(0);",
title="Feature on project's homepage",
data-toggle="tooltip",
data-placement="left")
i.pi-star
| Toggle Featured
li.dropdown-item
a#item_toggle_public(
href="javascript:void(0);",
title="Make it accessible to anyone",
data-toggle="tooltip",
data-placement="left")
i.pi-lock-open
| Toggle Public
| {% endif %}
li.dropdown-item
a#item_toggle_projheader(
href="javascript:void(0);",
title="Feature as project's header",
data-toggle="tooltip",
data-placement="left")
i.pi-star
| Toggle Project Header video
li.dropdown-item.button-move
a#item_move(
href="javascript:void(0);",
title="Move into a folder...",
data-toggle="tooltip",
data-placement="left")
i.button-move-icon.pi-move
| Move
li.dropdown-item.button-delete
a#item_delete(
href="javascript:void(0);",
title="Can be undone within a month",
data-toggle="tooltip",
data-placement="left")
i.pi-trash
| Delete Project
// Edit Mode
li.button-cancel
a#item_cancel.project-mode-edit.btn.btn-outline-secondary(
href="javascript:void(0);",
title="Cancel changes")
i.button-cancel-icon.pi-cancel
| Cancel
li.button-save
a#item_save.project-mode-edit.btn.btn-outline-success.mx-2(
href="javascript:void(0);",
title="Save changes")
i.button-save-icon.pi-check
| Save Changes
| {% endif %}
| {% set utm_source = request.args.get('utm_source') %}
| {% if config.UTM_LINKS and utm_source in config.UTM_LINKS %}
#utm_container
a(href="{{config.UTM_LINKS[utm_source]['link']}}")
img(src="{{config.UTM_LINKS[utm_source]['image']}}", alt="gift", class="img-responsive")
| {% endif %}
#project_context
| {% block project_context %}
| {% if show_project %}
| {% include "projects/view_embed.html" %}
| {% endif %}
| {% endblock project_context %}
#overlay-mode-move-container
.overlay-container
.title
i.pi-angle-left
| Select the <strong>folder</strong> where you want to move it
.buttons
button#item_move_accept.move.disabled
| Select a Folder
button#item_move_cancel.cancel
i.pi-cancel
| Cancel
| {% endblock %}
| {% block footer_container %}{% endblock %}
| {% block footer_scripts_pre %}
| {% if project.has_method('PUT') %}
| {# JS containing the Edit, Add, Featured, and Move functions #}
script(type="text/javascript", src="{{ url_for('static_pillar', filename='assets/js/project-edit.min.js') }}")
| {% endif %}
script.
function updateToggleProjHeaderMenuItem() {
var $toggle_projheader = $('#item_toggle_projheader');
if (ProjectUtils.isProject()) {
$toggle_projheader.hide();
return;
}
if (ProjectUtils.nodeType() == 'asset') {
$toggle_projheader.show();
} else {
$toggle_projheader.hide();
}
}
$(updateToggleProjHeaderMenuItem);
// Function to update the interface on loadNodeContent, and edit/saving assets
function updateUi(nodeId, mode) {
if (mode === 'view') {
$('.project-mode-view').displayAs('inline-block');
$('.project-mode-edit').hide();
$("#node-edit-form").unbind("submit");
$("#item_save").unbind("click");
$("#item_cancel").unbind("click");
} else if (mode === 'edit') {
$('.project-mode-view').hide();
$('.project-mode-edit').displayAs('inline-block');
} else {
if (console) console.log('Invalid mode:', mode);
}
// Prevent flicker by scrolling to top.
$("#project_context-container").scrollTop(0);
// Enable specific items under the Add New dropdown
if (ProjectUtils.nodeType() === 'group') {
addMenuEnable(['asset', 'group']);
} else if (ProjectUtils.nodeType() === 'group_texture') {
addMenuEnable(['group_texture', 'texture']);
} else if (ProjectUtils.nodeType() === 'group_hdri') {
addMenuEnable(['group_hdri', 'hdri']);
} else if (!ProjectUtils.isProject()) {
addMenuEnable(false);
}
updateToggleProjHeaderMenuItem();
// Set the page title on the document
var page_title = $('#node-title').text() + " - {{ project.name }} — Blender Cloud";
DocumentTitleAPI.set_page_title(page_title);
// TODO: Maybe remove this, now it's also in loadNodeContent(), but double-check
// it's done like that in all users of updateUi().
$('#project-loading').removeAttr('class');
}
| {% endblock %}
| {% block footer_scripts %}
script(src="{{ url_for('static_pillar', filename='assets/jstree/jstree.min.js') }}")
script.
{% if show_project %}
ProjectUtils.setProjectAttributes({projectId: "{{project._id}}", isProject: true, nodeId: ''});
{% else %}
{% if node %}
ProjectUtils.setProjectAttributes({projectId: "{{project._id}}", isProject: false, nodeId: '{{node._id}}'});
{% endif %}
{% endif %}
var projectTree = document.getElementById('project_tree');
var urlNodeMove = "{{url_for('projects.move_node')}}";
var urlNodeFeature = "{{url_for('projects.add_featured_node')}}";
var urlNodeDelete = "{{url_for('projects.delete_node')}}";
var urlNodeTogglePublic = "{{url_for('projects.toggle_node_public')}}";
var urlNodeToggleProjHeader = "{{url_for('projects.toggle_node_project_header')}}";
var urlProjectDelete = "{{url_for('projects.delete')}}";
var urlProjectEdit = "{{url_for('projects.edit', project_url=project.url)}}";
function loadNodeContent(url, nodeId) {
$('#project-loading').addClass('active');
$.get(url, function(dataHtml) {
// Update the DOM injecting the generate HTML into the page
$('#project_context').html(dataHtml);
})
.done(function(){
updateUi(nodeId, 'view');
})
.fail(function(dataResponse) {
$('#project_context').html($('<iframe id="server_error"/>'));
$('#server_error').attr('src', url);
})
.always(function(){
$('#project-loading').removeAttr('class');
$('.button-edit-icon').addClass('pi-edit').removeClass('pi-spin spin');
});
}
function loadProjectContent(url) {
$('#project-loading').addClass('active');
$.get(url, function(dataHtml) {
// Update the DOM injecting the generated HTML into the page
$('#project_context').html(dataHtml);
})
.done(function() {
updateUi('', 'view');
addMenuEnable();
addMenuDisable(['texture']);
})
.fail(function(dataResponse) {
$('#project_context').html($('<iframe id="server_error"/>'));
$('#server_error').attr('src', url);
})
.always(function(){
$('#project-loading').removeAttr('class');
$('.button-edit-icon').addClass('pi-edit').removeClass('pi-spin spin');
});
}
function displayStorage(storageNodeId, path) {
var url = '/nodes/' + storageNodeId + '/view?path=' + path;
loadNodeContent(url);
}
function displayNode(nodeId, pushState) {
// Remove the 'n_' suffix from the id
if (nodeId.substring(0, 2) == 'n_') {
nodeId = nodeId.substr(2);
}
var url = '/nodes/' + nodeId + '/view';
loadNodeContent(url, nodeId);
// Determine whether we should push the new state or not.
pushState = (typeof pushState !== 'undefined') ? pushState : true;
if (!pushState) return;
// Push the correct URL onto the history.
var push_state = {nodeId: nodeId, url: url};
var push_url = '{{url_for("projects.view", project_url=project.url)}}' + nodeId;
// console.log('Pushing state ', push_state, ' with URL ', push_url);
window.history.pushState(
push_state,
'Node ' + nodeId, // TODO: use sensible title
push_url
);
}
function redirectToNode(nodeId) {
var generic_url = '{{ url_for("projects.view_node", project_url=project.url, node_id="theNodeId") }}';
var node_url = generic_url.replace('theNodeId', nodeId);
// This makes the user skip the current page when using the 'back' button,
// i.e. it works as a proper redirect.
location.replace(node_url);
}
window.onpopstate = function(event) {
var state = event.state;
// console.log('State popped. location:', document.location, 'state:', state);
// Deselect any selected node. We'll select the visited node (if any) later on.
var jstreeAPI = $(projectTree).jstree(true);
jstreeAPI.deselect_all(true);
if (state == null) {
// Went back to the project.
displayProject();
return;
}
// Went back to a node.
loadNodeContent(state.url, state.nodeId);
// Annoying hack because jstreeAPI.select_node() can only suppress the
// changed.jstree event, and NOT the selected_node.jstree event.
projectTree.dataset.ignoreSelectNode = true;
jstreeAPI.select_node('n_' + state.nodeId, true);
delete projectTree.dataset.ignoreSelectNode;
};
function displayProject() {
var url = "{{url_for('projects.view', project_url=project.url, embed=1)}}";
loadProjectContent(url);
}
function getHashId() {
if (console)
console.log('getHashId() should not be used any more!');
}
/* Loaded once, on page load */
function loadContent() {
var nodeId = ProjectUtils.nodeId();
var isProject = ProjectUtils.isProject();
if (isProject) {
// No need to asynchronously load the project, as it's embedded by Jinja.
// displayProject() is still needed, though, when people use 'back' to go there.
if (location.hash) {
// Handle old-style /p/{url}/#node-ID links, and redirect them to the correct spot.
redirectToNode(location.hash.substr(1));
}
$('.project-mode-view').displayAs('inline-block');
$('.project-mode-edit').hide();
} else {
displayNode(nodeId, false);
}
$(projectTree).jstree({
'core': {
'data': function (obj, callback) {
if(obj.id === '#') { //tree root
if (isProject) {
$.getJSON("{{url_for('projects.jstree', project_url=project.url)}}", function (jsonObject) {
callback.call(this, jsonObject['items']);
});
} else {
$.getJSON('/nodes/' + nodeId + '/jstree', function(jsonObject) {
callback.call(this, jsonObject['items']);
});
}
} else { //normal node
var childNodeId;
if (obj.original.type == 'group_storage') {
childNodeId = obj.original.storage_node;
$.getJSON('/nodes/' + childNodeId + '/jstree?children=1&path=' + obj.original.path, function(jsonObject) {
callback.call(this, jsonObject.children);
});
} else {
// Remove the 'n_' suffix from the id
childNodeId = obj.id.substring(2);
$.getJSON('/nodes/' + childNodeId + '/jstree?children=1', function(jsonObject) {
callback.call(this, jsonObject.children);
});
}
}
}
},
"types" : {
"#": {"valid_children": ["collection"]},
"chapter" : {"icon": "pi-folder"},
"group" : {"icon": "pi-folder"},
"group_texture" : {"icon": "pi-folder-texture"},
"group_hdri" : {"icon": "pi-folder-texture", "max_children": 0},
"group_storage" : {"icon": "pi-folder"},
"filesystem_node" : {"icon": "pi-folder"},
"file" : {"icon": "pi-document", "max_children": 0},
"filesystem_file" : {"icon": "pi-document", "max_children": 0},
"image" : {"icon": "pi-image", "max_children": 0},
"hdri" : {"icon": "pi-globe", "max_children": 0},
"texture" : {"icon": "pi-texture", "max_children": 0},
"video" : {"icon": "pi-play", "max_children": 0},
"blog" : {"icon": "pi-newspaper", "max_children": 0},
"page" : {"icon": "pi-document-text", "max_children": 0},
"default" : {"icon": "pi-document"}
},
"plugins": ["types",] //, "state", "sort"
});
var jstreeAPI = $(projectTree).jstree(true);
$(projectTree).on("select_node.jstree", function (e, data) {
var selectedNodeId = data.node.id.substr(2);
// Ignore events that can't be suppressed otherwise.
// This can be removed if jstreeAPI.select_node() allows suppressing
// the select_node.jstree event.
if (e.target.dataset.ignoreSelectNode === 'true') return;
if (typeof(data.node.original.path) === 'undefined') {
var movingMode = Cookies.getJSON('bcloud_moving_node');
// Check if we are in the process of moving a node
if (movingMode) {
// Allow moving nodes only inside of node_type group
if (data.node.original.type != 'group' || movingMode.node_id === selectedNodeId || movingMode.node_id === ProjectUtils.parentNodeId()) {
if (movingMode.node_type === 'texture') {
if (data.node.original.type === 'group_texture') {
$('#item_move_accept').html('<i class="pi-check"></i>Move Here').removeClass('disabled');
} else {
$('#item_move_accept').html('Select a Texture Folder').addClass('disabled');
}
} else if (movingMode.node_type === 'hdri') {
if (data.node.original.type === 'group_hdri') {
$('#item_move_accept').html('<i class="pi-check"></i>Move Here').removeClass('disabled');
} else {
$('#item_move_accept').html('Select an HDRi Folder').addClass('disabled');
}
} else {
$('#item_move_accept').html('Select a Folder').addClass('disabled');
}
} else {
$('#item_move_accept').html('<i class="pi-check"></i>Move Here').removeClass('disabled');
}
}
// Check the type of node and act accordingly
if (data.node.original.custom_view) {
window.location = data.node.a_attr.href;
} else {
var currentNodeId = ProjectUtils.nodeId();
if (currentNodeId != selectedNodeId) {
displayNode(selectedNodeId);
}
jstreeAPI.open_node(data.node);
}
} else {
displayStorage(data.node.original.storage_node, data.node.original.path);
jstreeAPI.toggle_node(data.node);
}
});
};
{% if is_embedded_edit is not defined or is_embedded_edit %}
// Initialize the page if we are not directly editing a node (most of the time)
loadContent();
{% endif %}
var project_container = document.getElementById('project-container');
/* UI Stuff */
$(window).on("load resize",function(){
containerResizeY($(window).height());
if ($(window).width() > 480) {
project_container.style.height = (window.innerHeight - project_container.offsetTop) + "px";
}
});
{% if current_user_is_subscriber %}
$(projectTree).addClass('is_subscriber');
{% endif %}
| {% endblock %}
| {% block comment_scripts %} {% endblock%}

View File

@@ -1,5 +1,7 @@
| {% extends 'layout.html' %} | {% extends 'layout.html' %}
include mixins/components
| {# Default case is Open Projects #} | {# Default case is Open Projects #}
| {% set page_title = '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_description = 'Full production data and tutorials from all open movies, for you to use freely' %}
@@ -9,13 +11,13 @@
| {% if title == 'courses' %} | {% if title == 'courses' %}
| {% set page_title = 'Courses' %} | {% set page_title = 'Courses' %}
| {% set page_description = 'Production quality training by 3D professionals' %} | {% 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_image = url_for('static', filename='assets/img/backgrounds/background_agent327_04.jpg') %}
| {% set page_header_text = 'Character modeling, 3D printing, VFX, rigging and more.' %} | {% set page_header_text = 'Character modeling, 3D printing, VFX, rigging and more.' %}
| {% elif title == 'workshops' %} | {% elif title == 'workshops' %}
| {% set page_title = 'Workshops' %} | {% set page_title = 'Workshops' %}
| {% set page_description = 'Production quality training by 3D professionals' %} | {% 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_image = url_for('static', filename='assets/img/backgrounds/background_agent327_04.jpg') %}
| {% set page_header_text = 'Enter the artist workshop and learn by example.' %} | {% set page_header_text = 'Enter the artist workshop and learn by example.' %}
| {% endif %} | {% endif %}
@@ -38,59 +40,70 @@ meta(name="twitter:image", content="{{ page_header_image }}")
| {{ page_title }} | {{ page_title }}
| {% endblock %} | {% endblock %}
| {% block body %} | {% block navigation_tabs %}
#project-container | {% if title in ['courses', 'workshops'] %}
+nav-secondary
+nav-secondary-link(
class="{% if title == 'workshops' %}active{% endif %}",
href="{{ url_for('cloud.workshops') }}")
| Workshops
#node_index-container +nav-secondary-link(
#node_index-header.collection class="{% if title == 'courses' %}active{% endif %}",
img.background-header(src="{{ page_header_image }}") href="{{ url_for('cloud.courses') }}")
#node_index-collection-info | Courses
.node_index-collection-name
span {{ page_title }}
.node_index-collection-description
span.
{{ page_header_text }}
.node_index-collection +nav-secondary-link(
class="{% if title == 'gallery' %}active{% endif %}",
| {% for project in projects %} href="{{ url_for('projects.view', project_url='gallery') }}")
| {% if (project.status == 'published') or (project.status == 'pending' and current_user.is_authenticated) and project._id != config.MAIN_PROJECT_ID %} | Art Gallery
.node_index-collection-card.project(
data-url="{{ url_for('projects.view', project_url=project.url) }}",
tabindex="{{ loop.index }}")
| {% if project.picture_header %}
a.item-header(
href="{{ url_for('projects.view', project_url=project.url) }}")
img(src="{{ project.picture_header.thumbnail('l', api=api) }}")
| {% endif %} | {% endif %}
.item-info | {% endblock navigation_tabs %}
a.item-title(
href="{{ url_for('projects.view', project_url=project.url) }}") | {% block body %}
.container.pb-5
.pt-4
h2.text-uppercase.font-weight-bold
| {{ page_title }}
.lead
| {{ page_header_text }}
hr.pb-2
+card-deck(3)
| {% for project in projects %}
| {% if (project.status == 'published') or (project.status == 'pending' and current_user.is_authenticated) and project._id != config.MAIN_PROJECT_ID %}
+card(data-url="{{ url_for('projects.view', project_url=project.url) }}", tabindex='{{ loop.index }}')
| {% if project.picture_header %}
a(href="{{ url_for('projects.view', project_url=project.url) }}")
img.card-img-top(
src="{{ project.picture_header.thumbnail('l', api=api) }}", alt="{{ project.name }}")
| {% endif %}
.card-body
h5.card-title
| {{ project.name }} | {{ project.name }}
| {% if project.status == 'pending' and current_user.is_authenticated and current_user.has_role('admin') %} | {% if project.status == 'pending' and current_user.is_authenticated and current_user.has_role('admin') %}
small (pending) small (pending)
| {% endif %} | {% endif %}
| {% if project.summary %} | {% if project.summary %}
p.item-description p.card-text
| {{project.summary|safe}} | {{project.summary|safe}}
| {% endif %} | {% endif %}
a.learn-more LEARN MORE
| {% endif %} | {% endif %}
| {% endfor %} | {% endfor %}
| {% endblock %} | {% endblock %}
| {% block footer_scripts %} | {% block footer_scripts %}
script. script.
$('.node_index-collection-card.project').on('click', function(e){ $('.js-project-go').on('click', function(e){
e.preventDefault(); e.preventDefault();
window.location.href = $(this).data('url'); window.location.href = $(this).data('url');
}); });

View File

@@ -1,6 +1,7 @@
| {% extends 'layout.html' %} | {% extends 'layout.html' %}
| {% block page_title %}Services{% endblock %} | {% block page_title %}Services{% endblock %}
| {% set title = 'services' %} | {% set title = 'services' %}
include mixins/components
| {% block og %} | {% block og %}
meta(property="og:type", content="website") meta(property="og:type", content="website")
@@ -20,26 +21,10 @@ meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/ba
| {% endblock %} | {% endblock %}
| {% block body %} | {% block body %}
#page-container - var header_text = "On Blender Cloud you can create and share personal projects, access our texture and HDRI library (or create your own), keep track of your production, manage your renders and much more!";
#page-header(style="background-image: url({{ url_for('static', filename='assets/img/backgrounds/services_projects.jpg')}})") +jumbotron("Services", header_text, "{{ url_for('static', filename='assets/img/backgrounds/services_projects.jpg')}}")
.container
.page-title
| Blender Cloud Services
.page-title-summary
span.text-background
p.
Blender Cloud is the creative hub for your projects, powered by Free and Open Source software.
p.
On Blender Cloud you can create and share personal projects, access our texture and HDRI
library (or create your own), keep track of your production, manage your renders and much more!
.navbar-backdrop-overlay
- var addon_text = 'Available through the <a href="{{ url_for(\'cloud.services\') }}#blender-cloud-add-on">Blender Cloud add-on</a>'
#page-content
- var addon_text = 'Available through the <a href="{{ url_for(\'cloud.services\') }}#blender-cloud-add-on">Blender Cloud add-on</a>';
section#blender-cloud-add-on.page-card section#blender-cloud-add-on.page-card
.page-card-side .page-card-side
h2.page-card-title h2.page-card-title
@@ -54,8 +39,8 @@ meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/ba
small Blender Cloud add-on requires Blender 2.78 or newer small Blender Cloud add-on requires Blender 2.78 or newer
a.page-card-cta.download( a.btn.btn-outline-success(
href="/r/downloads/blender_cloud-latest-addon.zip") href="https://cloud.blender.org/r/downloads/blender_cloud-latest-addon.zip")
i.pi-download i.pi-download
| Download add-on &nbsp;<small>v</small> {{ config.BLENDER_CLOUD_ADDON_VERSION }} | Download add-on &nbsp;<small>v</small> {{ config.BLENDER_CLOUD_ADDON_VERSION }}
@@ -76,28 +61,33 @@ meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/ba
.tip !{addon_text} .tip !{addon_text}
a.page-card-cta.download(
href="https://cloud.blender.org/r/downloads/blender_cloud-latest-addon.zip")
i.pi-download
| Download add-on &nbsp;<small>v</small> {{ config.BLENDER_CLOUD_ADDON_VERSION }}
a.page-card-cta( a.page-card-cta(
href="/blog/introducing-blender-sync") href="https://cloud.blender.org/blog/introducing-blender-sync")
| Learn More | Learn More
.page-card-side .page-card-side
img( img(
src="{{ url_for('static', filename='assets/img/features/sync_thumbnail.jpg')}}") src="{{ url_for('static', filename='assets/img/features/sync_thumbnail.jpg')}}")
.tip !{addon_text}
section#texture-browser.page-card.right section#texture-browser.page-card.right
.page-card-side .page-card-side
h2.page-card-title Texture & HDRI Browser h2.page-card-title Texture & HDRI Browser
.page-card-summary .page-card-summary
p. p.
Access the <a href="/p/textures/">Blender Cloud Textures</a> Access the <a href="https://cloud.blender.org/p/textures/">Blender Cloud Textures</a>
library from within Blender using our exclusive add-on. library from within Blender using our exclusive add-on.
Create, manage and share <em>your own</em> texture libraries! Create, manage and share <em>your own</em> texture libraries!
.tip !{addon_text} .tip !{addon_text}
a.page-card-cta.js-watch-video.download( a.btn.btn-outline-success.js-watch-video(
href="https://www.youtube.com/watch?v=-srXYv2Osjw", href="https://www.youtube.com/watch?v=-srXYv2Osjw",
data-youtube-id="-srXYv2Osjw") data-youtube-id="-srXYv2Osjw")
i.pi-play i.pi-play
@@ -107,6 +97,14 @@ meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/ba
img( img(
src="{{ url_for('static', filename='assets/img/features/tex_library_thumbnail.jpg')}}") src="{{ url_for('static', filename='assets/img/features/tex_library_thumbnail.jpg')}}")
section#texture-browser.page-card.right
.page-card-side
h2.page-card-title Texture & HDRI Browser
.page-card-summary
p.
Access the <a href="https://cloud.blender.org/p/textures/">Blender Cloud Textures</a>
library from within Blender using our exclusive add-on.
Create, manage and share <em>your own</em> texture libraries!
section#image-sharing.page-card.right section#image-sharing.page-card.right
.page-card-side .page-card-side
@@ -117,20 +115,21 @@ meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/ba
.tip !{addon_text} .tip !{addon_text}
a.page-card-cta.download.js-watch-video( a.btn.btn-outline-success.js-watch-video(
href="https://www.youtube.com/watch?v=yvtqeMBOAyk", href="https://www.youtube.com/watch?v=yvtqeMBOAyk",
data-youtube-id="yvtqeMBOAyk") data-youtube-id="yvtqeMBOAyk")
i.pi-play i.pi-play
| Watch Video | Watch Video
a.page-card-cta.outline( a.page-card-cta.outline(
href="/blog/introducing-image-sharing") href="https://cloud.blender.org/blog/introducing-image-sharing")
| Learn More | Learn More
.page-card-side .page-card-side
img( img(
src="{{ url_for('static', filename='assets/img/features/image_sharing_thumbnail.jpg')}}") src="{{ url_for('static', filename='assets/img/features/image_sharing_thumbnail.jpg')}}")
.tip !{addon_text}
section#projects.page-card.right section#projects.page-card.right
.page-card-side .page-card-side
@@ -140,7 +139,7 @@ meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/ba
Upload assets and collaborate with other Blender Cloud members. Upload assets and collaborate with other Blender Cloud members.
a.page-card-cta( a.page-card-cta(
href="/blog/introducing-private-projects") href="https://cloud.blender.org/blog/introducing-private-projects")
| Learn More | Learn More
.page-card-side .page-card-side
@@ -155,14 +154,14 @@ meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/ba
.page-card-summary. .page-card-summary.
Production-management software for your film, game, or commercial projects. Production-management software for your film, game, or commercial projects.
a.page-card-cta.download.js-watch-video( a.btn.btn-outline-success.js-watch-video(
href="https://www.youtube.com/watch?v=b9x1rlyyt_o", href="https://www.youtube.com/watch?v=b9x1rlyyt_o",
data-youtube-id="b9x1rlyyt_o") data-youtube-id="b9x1rlyyt_o")
i.pi-play i.pi-play
| Watch Video | Watch Video
a.page-card-cta( a.page-card-cta(
href="/blog/attract-and-flamenco-public-beta", href="https://cloud.blender.org/blog/attract-and-flamenco-public-beta",
title="Learn more about Attract") title="Learn more about Attract")
| Learn More | Learn More
@@ -170,6 +169,12 @@ meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/ba
img( img(
src="{{ url_for('static', filename='assets/img/features/attract_thumbnail.jpg')}}") src="{{ url_for('static', filename='assets/img/features/attract_thumbnail.jpg')}}")
section#attract.page-card.right
.page-card-side
h2.page-card-title
| Attract
.page-card-summary.
Production-management software for your film, game, or commercial projects.
section#flamenco.page-card.right section#flamenco.page-card.right
.page-card-side .page-card-side
@@ -178,7 +183,7 @@ meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/ba
.page-card-summary. .page-card-summary.
Take control of your computing infrastructure and get things done. Take control of your computing infrastructure and get things done.
a.page-card-cta.download.js-watch-video( a.btn.btn-outline-success.js-watch-video(
href="https://www.youtube.com/watch?v=7cnFKhsM67Q", href="https://www.youtube.com/watch?v=7cnFKhsM67Q",
data-youtube-id="7cnFKhsM67Q") data-youtube-id="7cnFKhsM67Q")
i.pi-play i.pi-play
@@ -193,17 +198,25 @@ meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/ba
img( img(
src="{{ url_for('static', filename='assets/img/features/flamenco_thumbnail.jpg')}}") src="{{ url_for('static', filename='assets/img/features/flamenco_thumbnail.jpg')}}")
section#flamenco.page-card.right
| {% if not current_user.has_role('subscriber') %}
section.page-card.subscribe(
style="background-image: url({{ url_for('static', filename='assets/img/backgrounds/pattern_01.jpg')}})")
.page-card-side .page-card-side
h2.page-card-title
| Flamenco
.page-card-summary.
Take control of your computing infrastructure and get things done.
| {% if not current_user.has_role('subscriber') %}
section.page-card(
style="background-image: url({{ url_for('static', filename='assets/img/backgrounds/pattern_01.jpg')}})")
.page-card-side
h2.page-card-title h2.page-card-title
| All of this, plus hours of training and production assets. | All of this, plus hours of training and production assets.
.page-card-summary
.page-card-summary.text-white
| Join us for only $9.90/month! | Join us for only $9.90/month!
a.page-card-cta(
href="https://store.blender.org/product/membership/") a.page-card-cta(href="https://store.blender.org/product/membership/")
| Subscribe Now | Subscribe Now
| {% endif %} | {% endif %}
@@ -212,12 +225,13 @@ meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/ba
| {% block footer_scripts %} | {% block footer_scripts %}
script. script.
// Click anywhere in the page to hide the overlay // Hide the video overlay.
function hideOverlay() { function hideOverlay() {
$('#page-overlay.video').removeClass('active'); $('#page-overlay.video').removeClass('active');
$('#page-overlay.video .video-embed').html(''); $('#page-overlay.video .video-embed').html('');
} }
// Click anywhere in the page or hit Esc to hide the overlay.
$(document).click(function() { $(document).click(function() {
hideOverlay(); hideOverlay();
}); });
@@ -229,12 +243,12 @@ script.
}); });
$('a.js-watch-video').click(function(e){ $('a.js-watch-video').click(function(e){
var videoId = $(this).attr('data-youtube-id');
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
$('#page-overlay.video').addClass('active'); $('#page-overlay.video').addClass('active');
var videoId = $(this).attr('data-youtube-id');
$('#page-overlay .video-embed').html('<iframe src="https://www.youtube.com/embed/' + videoId +'?rel=0&amp;showinfo=0;autoplay=1" frameborder="0" allowfullscreen></iframe>') $('#page-overlay .video-embed').html('<iframe src="https://www.youtube.com/embed/' + videoId +'?rel=0&amp;showinfo=0;autoplay=1" frameborder="0" allowfullscreen></iframe>')
}); });

View File

@@ -65,7 +65,7 @@ p Your organisation provides you with your subscription.
hr hr
p p
button#recheck_subscription.btn.btn-default(onclick="javascript:recheck_subscription(this)") Re-check my subscription button#recheck_subscription.btn.btn-outline-secondary(onclick="javascript:recheck_subscription(this)") Re-check my subscription
hr hr

View File

@@ -11,7 +11,7 @@
| {% endfor %} | {% endfor %}
.buttons .buttons
button.btn.btn-default.button-submit(type='submit') button.btn.btn-outline-success.button-submit(type='submit')
i.pi-check i.pi-check
| Save Changes | Save Changes
| {% endblock %} | {% endblock %}

View File

@@ -28,12 +28,12 @@ li
| {% endblock navigation_sections %} | {% endblock navigation_sections %}
| {% block navigation_user %} | {% block navigation_user %}
li.nav-item-sign-in li.pt-1.pr-1
| {% if current_user.is_anonymous %} | {% if current_user.is_anonymous %}
a.navbar-item(href="{{ url_for('users.login', next='/') }}") a.btn.btn-outline-success(href="{{ url_for('users.login', next='/') }}")
| Log in and Explore | Log in and Explore
| {% else %} | {% else %}
a.navbar-item(href="{{ url_for('main.homepage') }}") a.btn.btn-outline-success(href="{{ url_for('main.homepage') }}")
| Explore | Explore
| {% endif %} | {% endif %}
| {% endblock navigation_user %} | {% endblock navigation_user %}

View File

@@ -1,112 +0,0 @@
/* cyrillic-ext */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(0eC6fl06luXEYWpBSJvXCBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
}
/* cyrillic */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(Fl4y0QdOxyyTHEGMXX8kcRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(-L14Jk06m6pUHB-5mXQQnRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(I3S1wsgSg9YCurV6PUkTORJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(NYDWBdD4gIq26G5XYbHsFBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(Pru33qjShpZSmG3z6VYwnRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(Hgo13k-tfSpn0qi1SFdUfVtXRa8TVwTICgirnJhmVJw.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
}
/* cyrillic-ext */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(ek4gzZ-GeXAPcSbHtCeQI_esZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
}
/* cyrillic */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(mErvLBYg_cXG3rLvUsKT_fesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(-2n2p-_Y08sg57CNWQfKNvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(u0TOpm082MNkS5K0Q4rhqvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(NdF9MtnOpLzo-noMoG0miPesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(Fcx7Wwv8OzT71A3E1XOAjvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(CWB0XYA8bzo0kSThX0UTuA.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
}