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,61 +1,22 @@
.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 nav#nav-tabs,
color: $color-primary nav#sub-nav-tabs
cursor: pointer
nav#nav-tabs,
nav#sub-nav-tabs
ul#nav-tabs__list, ul#nav-tabs__list,
ul#sub-nav-tabs__list ul#sub-nav-tabs__list
margin: 0 margin: 0
@@ -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
background-color: white
border-bottom: thin solid $color-background-dark
section.stream
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,25 +252,7 @@
padding: 1px 5px padding: 1px 5px
margin-right: 5px margin-right: 5px
ul.meta section.comments
+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
padding: 0 15px 5px padding: 0 15px 5px
ul ul
@@ -371,119 +276,7 @@
display: block display: block
padding-bottom: 5px padding-bottom: 5px
section.blog-stream section.random-asset
+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
border-bottom: thin solid $color-background-dark border-bottom: thin solid $color-background-dark
ul.random-asset__list ul.random-asset__list
@@ -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 navigation_tabs %}
| {% if title in ['courses', 'workshops'] %}
+nav-secondary
+nav-secondary-link(
class="{% if title == 'workshops' %}active{% endif %}",
href="{{ url_for('cloud.workshops') }}")
| Workshops
+nav-secondary-link(
class="{% if title == 'courses' %}active{% endif %}",
href="{{ url_for('cloud.courses') }}")
| Courses
+nav-secondary-link(
class="{% if title == 'gallery' %}active{% endif %}",
href="{{ url_for('projects.view', project_url='gallery') }}")
| Art Gallery
| {% endif %}
| {% endblock navigation_tabs %}
| {% block body %} | {% block body %}
#project-container .container.pb-5
.pt-4
h2.text-uppercase.font-weight-bold
| {{ page_title }}
.lead
| {{ page_header_text }}
#node_index-container hr.pb-2
#node_index-header.collection
img.background-header(src="{{ page_header_image }}")
#node_index-collection-info
.node_index-collection-name
span {{ page_title }}
.node_index-collection-description
span.
{{ page_header_text }}
.node_index-collection
+card-deck(3)
| {% for project in projects %} | {% for project in projects %}
| {% if (project.status == 'published') or (project.status == 'pending' and current_user.is_authenticated) and project._id != config.MAIN_PROJECT_ID %}
.node_index-collection-card.project( | {% if (project.status == 'published') or (project.status == 'pending' and current_user.is_authenticated) and project._id != config.MAIN_PROJECT_ID %}
data-url="{{ url_for('projects.view', project_url=project.url) }}", +card(data-url="{{ url_for('projects.view', project_url=project.url) }}", tabindex='{{ loop.index }}')
tabindex="{{ loop.index }}")
| {% if project.picture_header %} | {% if project.picture_header %}
a.item-header( a(href="{{ url_for('projects.view', project_url=project.url) }}")
href="{{ url_for('projects.view', project_url=project.url) }}") img.card-img-top(
img(src="{{ project.picture_header.thumbnail('l', api=api) }}") src="{{ project.picture_header.thumbnail('l', api=api) }}", alt="{{ project.name }}")
| {% endif %} | {% endif %}
.item-info .card-body
a.item-title( h5.card-title
href="{{ url_for('projects.view', project_url=project.url) }}") | {{ 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,27 +21,11 @@ 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. - var addon_text = 'Available through the <a href="{{ url_for(\'cloud.services\') }}#blender-cloud-add-on">Blender Cloud add-on</a>';
On Blender Cloud you can create and share personal projects, access our texture and HDRI section#blender-cloud-add-on.page-card
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
section#blender-cloud-add-on.page-card
.page-card-side .page-card-side
h2.page-card-title h2.page-card-title
| Blender Cloud add-on | Blender Cloud add-on
@@ -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 }}
@@ -63,7 +48,7 @@ meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/ba
img( img(
src="{{ url_for('static', filename='assets/img/features/blender_cloud_addon_thumbnail.png')}}") src="{{ url_for('static', filename='assets/img/features/blender_cloud_addon_thumbnail.png')}}")
section#blender-sync.page-card.right section#blender-sync.page-card.right
.page-card-side .page-card-side
h2.page-card-title Blender Sync h2.page-card-title Blender Sync
.page-card-summary .page-card-summary
@@ -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,8 +97,16 @@ 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
h2.page-card-title Image Sharing h2.page-card-title Image Sharing
.page-card-summary .page-card-summary
@@ -117,22 +115,23 @@ 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
h2.page-card-title Private Projects h2.page-card-title Private Projects
.page-card-summary. .page-card-summary.
@@ -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
@@ -148,6 +147,28 @@ meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/ba
src="{{ url_for('static', filename='assets/img/features/projects_thumbnail.jpg')}}") src="{{ url_for('static', filename='assets/img/features/projects_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.
a.btn.btn-outline-success.js-watch-video(
href="https://www.youtube.com/watch?v=b9x1rlyyt_o",
data-youtube-id="b9x1rlyyt_o")
i.pi-play
| Watch Video
a.page-card-cta(
href="https://cloud.blender.org/blog/attract-and-flamenco-public-beta",
title="Learn more about Attract")
| Learn More
.page-card-side
img(
src="{{ url_for('static', filename='assets/img/features/attract_thumbnail.jpg')}}")
section#attract.page-card.right section#attract.page-card.right
.page-card-side .page-card-side
h2.page-card-title h2.page-card-title
@@ -155,30 +176,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( section#flamenco.page-card.right
href="https://www.youtube.com/watch?v=b9x1rlyyt_o",
data-youtube-id="b9x1rlyyt_o")
i.pi-play
| Watch Video
a.page-card-cta(
href="/blog/attract-and-flamenco-public-beta",
title="Learn more about Attract")
| Learn More
.page-card-side
img(
src="{{ url_for('static', filename='assets/img/features/attract_thumbnail.jpg')}}")
section#flamenco.page-card.right
.page-card-side .page-card-side
h2.page-card-title h2.page-card-title
| Flamenco | Flamenco
.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,31 +198,40 @@ 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 %}
| {% endblock %} | {% endblock %}
| {% 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;
}