diff --git a/.gitignore b/.gitignore
index b9623fc..0aacd71 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,9 +3,12 @@
.coverage
*.pyc
__pycache__
+*.js.map
+*.css.map
/cloud/templates/
/cloud/static/assets/css/
+/cloud/static/assets/js/bootstrap.min.js
node_modules/
/config_local.py
diff --git a/gulpfile.js b/gulpfile.js
index 0245b31..5d2c110 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -1,5 +1,6 @@
var argv = require('minimist')(process.argv.slice(2));
var autoprefixer = require('gulp-autoprefixer');
+var cache = require('gulp-cached');
var chmod = require('gulp-chmod');
var concat = require('gulp-concat');
var git = require('gulp-git');
@@ -11,16 +12,16 @@ var plumber = require('gulp-plumber');
var rename = require('gulp-rename');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
-var uglify = require('gulp-uglify');
-var cache = require('gulp-cached');
+var uglify = require('gulp-uglify-es').default;
var enabled = {
uglify: argv.production,
- maps: argv.production,
+ maps: !argv.production,
failCheck: !argv.production,
prettyPug: !argv.production,
cachify: !argv.production,
cleanup: argv.production,
+ chmod: argv.production,
};
var destination = {
@@ -29,6 +30,12 @@ var destination = {
js: 'cloud/static/assets/js',
}
+var source = {
+ pillar: '../pillar/',
+ bootstrap: 'node_modules/bootstrap/',
+ popper: 'node_modules/popper.js/'
+}
+
/* CSS */
gulp.task('styles', function() {
@@ -73,7 +80,7 @@ gulp.task('scripts', function() {
.pipe(gulpif(enabled.uglify, uglify()))
.pipe(rename({suffix: '.min'}))
.pipe(gulpif(enabled.maps, sourcemaps.write(".")))
- .pipe(chmod(644))
+ .pipe(gulpif(enabled.chmod, chmod(644)))
.pipe(gulp.dest(destination.js))
.pipe(gulpif(argv.livereload, livereload()));
});
@@ -88,12 +95,34 @@ gulp.task('scripts_concat_tutti', function() {
.pipe(concat("tutti.min.js"))
.pipe(gulpif(enabled.uglify, uglify()))
.pipe(gulpif(enabled.maps, sourcemaps.write(".")))
- .pipe(chmod(644))
+ .pipe(gulpif(enabled.chmod, chmod(644)))
.pipe(gulp.dest(destination.js))
.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'
gulp.task('watch',function() {
@@ -103,6 +132,8 @@ gulp.task('watch',function() {
}
gulp.watch('src/styles/**/*.sass',['styles']);
+ gulp.watch(source.pillar + 'src/styles/**/*.sass',['styles']);
+
gulp.watch('src/templates/**/*.pug',['templates']);
gulp.watch('src/scripts/*.js',['scripts']);
gulp.watch('src/scripts/tutti/**/*.js',['scripts_concat_tutti']);
@@ -125,4 +156,5 @@ gulp.task('cleanup', function() {
// Run 'gulp' to build everything at once
var tasks = [];
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']));
diff --git a/package.json b/package.json
index f988f0b..1894f5d 100644
--- a/package.json
+++ b/package.json
@@ -8,20 +8,24 @@
},
"devDependencies": {
"gulp": "~3.9.1",
- "gulp-autoprefixer": "~2.3.1",
- "gulp-cached": "~1.1.0",
- "gulp-chmod": "~1.3.0",
- "gulp-concat": "~2.6.0",
- "gulp-if": "^2.0.1",
- "gulp-git": "~2.4.2",
- "gulp-pug": "~3.2.0",
- "gulp-jade": "~1.1.0",
- "gulp-livereload": "~3.8.1",
- "gulp-plumber": "~1.1.0",
- "gulp-rename": "~1.2.2",
- "gulp-sass": "~2.3.1",
- "gulp-sourcemaps": "~1.6.0",
- "gulp-uglify": "~1.5.3",
+ "gulp-autoprefixer": "~6.0.0",
+ "gulp-cached": "~1.1.1",
+ "gulp-chmod": "~2.0.0",
+ "gulp-concat": "~2.6.1",
+ "gulp-if": "^2.0.2",
+ "gulp-git": "~2.8.0",
+ "gulp-livereload": "~4.0.0",
+ "gulp-plumber": "~1.2.0",
+ "gulp-pug": "~4.0.1",
+ "gulp-rename": "~1.4.0",
+ "gulp-sass": "~4.0.1",
+ "gulp-sourcemaps": "~2.6.4",
+ "gulp-uglify-es": "^1.0.4",
"minimist": "^1.2.0"
+ },
+ "dependencies": {
+ "bootstrap": "^4.1.3",
+ "jquery": "^3.3.1",
+ "popper.js": "^1.14.4"
}
}
diff --git a/src/styles/_homepage.sass b/src/styles/_homepage.sass
index ece9b66..0109102 100644
--- a/src/styles/_homepage.sass
+++ b/src/styles/_homepage.sass
@@ -1,613 +1,406 @@
-.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
- max-width: 100%
+.title-underline
+ padding-bottom: 5px
+ position: relative
+ margin-bottom: 20px
- section.dashboard-main
- +container-box
- width: 52%
-
- section.dashboard-secondary
- width: 46%
- flex-direction: column
- margin-right: auto
-
- span.section-lead
+ &:before
+ background-color: $primary
+ content: ' '
display: block
- padding: 10px 0
- color: $color-text-dark-secondary
+ height: 2px
+ top: 125%
+ position: absolute
+ width: 50px
- section.dashboard-main,
- section.dashboard-secondary
- h4
- padding-bottom: 5px
- margin-bottom: 20px
- position: relative
- &:before
- position: absolute
- width: 50px
- height: 2px
- top: 125%
- content: ' '
- display: block
- background-color: $color-primary
+nav#nav-tabs,
+nav#sub-nav-tabs
+ ul#nav-tabs__list,
+ ul#sub-nav-tabs__list
+ margin: 0
+ padding: 0
+ list-style: none
+ border-bottom: thin solid $color-background
+ +clearfix
+
+ li.nav-tabs__list-tab
+ float: left
+ border: none
+ border-bottom: 3px solid transparent
+ color: $color-text-dark-primary
+ user-select: none
+
+ &:hover
+ border-color: rgba($color-secondary, .3)
+ cursor: pointer
+ color: $color-text-dark
+ a
+ color: $color-text-dark
a
- color: $color-text
-
- &:hover
- color: $color-primary
- cursor: pointer
-
- nav#nav-tabs,
- nav#sub-nav-tabs
- ul#nav-tabs__list,
- ul#sub-nav-tabs__list
- margin: 0
- padding: 0
- list-style: none
- border-bottom: thin solid $color-background
- +clearfix
-
- li.nav-tabs__list-tab
- float: left
- border: none
- border-bottom: 3px solid transparent
+ display: block
+ text-decoration: none
+ padding: 10px 15px 5px
color: $color-text-dark-primary
- user-select: none
- &:hover
- border-color: rgba($color-secondary, .3)
- cursor: pointer
- color: $color-text-dark
- a
- color: $color-text-dark
+ i
+ margin-right: 5px
+ color: $color-text-dark-secondary
+ font-size: .9em
- a
- display: block
- text-decoration: none
- padding: 10px 15px 5px
- color: $color-text-dark-primary
+ &.pi-blender
+ margin-right: 10px
- i
- margin-right: 5px
- color: $color-text-dark-secondary
- font-size: .9em
+ span
+ color: $color-text-dark-hint
+ margin-left: 5px
- &.pi-blender
- margin-right: 10px
-
- span
- color: $color-text-dark-hint
- margin-left: 5px
-
- &.active
- border-color: $color-secondary
+ &.active
+ border-color: $color-secondary
+ color: $color-secondary-dark
+ a, i
color: $color-secondary-dark
- a, i
- color: $color-secondary-dark
- &.disabled
- border-color: $color-background-light
+ &.disabled
+ border-color: $color-background-light
+ color: $color-text-dark-hint
+ cursor: default
+ a, i
color: $color-text-dark-hint
- cursor: default
- a, i
- color: $color-text-dark-hint
-
- &:hover
- border-color: $color-background-light
- pointer-events: none
-
- li.create
- cursor: pointer
- 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
-
- ul.activity-stream__list
- list-style: none
- margin: 0
- padding: 0
-
- $activity-stream-thumbnail-size: 110px
- > li
- position: relative
- display: flex
- padding: 10px 0
- overflow: hidden
- border-top: thin solid $color-background-dark
-
- &:first-child
- border: none
-
- &.active .activity-stream__list-details .title
- color: $color-primary
&:hover
- .title
- text-decoration: underline
- &.video
- a.image
- &:hover
- i
- font-size: 3.5em
- img
- opacity: .9
- img
- opacity: .7
- z-index: 0
- transition: opacity 150ms ease-in-out
+ border-color: $color-background-light
+ pointer-events: none
+.dashboard-container
+ word-break: break-word
+
+section.stream
+ ul.activity-stream__list
+ $activity-stream-thumbnail-size: 110px
+
+ > li
+ position: relative
+ display: flex
+ padding: 10px 0
+ overflow: hidden
+ border-top: thin solid $color-background-dark
+
+ &:first-child
+ border: none
+
+ &.active .activity-stream__list-details .title
+ color: $color-primary
+
+ &:hover
+ .title
+ text-decoration: underline
+ &.video
+ a.image
+ &:hover
i
- +position-center-translate
- z-index: 1
- color: rgba(white, .6)
- font-size: 3em
- transition: font-size 100ms ease-in-out
-
- &.comment
- .activity-stream__list-thumbnail
- background: transparent
- color: $node-type-comment
- font-size: 1.2em
- box-shadow: none
+ font-size: 3.5em
+ img
+ opacity: .9
+ img
+ opacity: .7
+ z-index: 0
+ transition: opacity 150ms ease-in-out
i
+position-center-translate
- left: 22px
- top: 19px
+ z-index: 1
+ color: rgba(white, .6)
+ font-size: 3em
+ transition: font-size 100ms ease-in-out
- .activity-stream__list-details
- padding: 0
- .title
- color: $color-text-dark
- padding: 7px 10px 2px 10px
- font-size: 1em
- margin: 0
+ &.comment
+ .activity-stream__list-details
+ padding: 0
+ .title
+ color: $color-text-dark
+ padding: 7px 10px 2px 10px
+ font-size: 1em
+ margin: 0
- ul.meta
- padding: 0 10px 7px 10px
+ ul.meta
+ +list-meta
+ font-size: .9em
+ padding: 0 10px 7px 10px
- li
- &.where-parent:before
- content: '\e83a'
- font-family: 'pillar-font'
+ li
+ &.where-parent:before
+ content: '\e83a'
+ font-family: 'pillar-font'
- &.what:before
- display: none
+ &.what:before
+ display: none
- &.post
- .activity-stream__list-thumbnail
- border-color: $node-type-post
- background-color: $node-type-post
- .activity-stream__list-details .title
- color: darken($node-type-post, 15%)
- font:
- size: 1.3em
- weight: 500
+ &.post
+ .activity-stream__list-thumbnail
+ border-color: $node-type-post
+ background-color: $node-type-post
+ .activity-stream__list-details .title
+ color: darken($node-type-post, 15%)
+ font:
+ size: 1.3em
+ weight: 500
- &.asset, &.comment, &.post
+ &.asset, &.comment, &.post
+ &:hover
+ cursor: pointer
+ &.empty
+ display: none
+ color: $color-text-dark-primary
+ padding: 20px
+ text-align: center
+ span
+ color: $color-primary
&:hover
+ text-decoration: underline
cursor: pointer
- &.empty
- display: none
- color: $color-text-dark-primary
- padding: 20px
- text-align: center
- span
- color: $color-primary
- &:hover
- text-decoration: underline
- cursor: pointer
- &.with-picture
- min-height: $activity-stream-thumbnail-size
-
- .activity-stream__list-thumbnail
- background-color: black
- width: $activity-stream-thumbnail-size * 1.69
- min-width: $activity-stream-thumbnail-size * 1.69
-
- .activity-stream__list-thumbnail-icon
- position: absolute
- top: 0
- left: 0
- right: 0
- bottom: 0
- font-size: 1.3em
- text-shadow: 1px 1px 0 rgba(black, .2)
- background-image: linear-gradient(10deg, rgba(black, .5) 0%, transparent 40%)
-
- i
- position: absolute
- bottom: -8px
- left: 20px
- top: initial
- right: initial
- color: white
+ &.with-picture
+ min-height: $activity-stream-thumbnail-size
.activity-stream__list-thumbnail
- position: relative
- display: flex
- justify-content: center
- align-items: center
- overflow: hidden
- width: 35px
- height: auto
- min-width: 35px
- min-height: auto
+ background-color: black
+ width: $activity-stream-thumbnail-size * 1.69
+ min-width: $activity-stream-thumbnail-size * 1.69
- +media-xs
- display: none
+ .activity-stream__list-thumbnail-icon
+ position: absolute
+ top: 0
+ left: 0
+ right: 0
+ bottom: 0
+ font-size: 1.3em
+ text-shadow: 1px 1px 0 rgba(black, .2)
+ background-image: linear-gradient(10deg, rgba(black, .5) 0%, transparent 40%)
+
+ i
+ position: absolute
+ bottom: -8px
+ left: 20px
+ top: initial
+ right: initial
+ color: white
+
+ .activity-stream__list-thumbnail
+ position: relative
+ display: flex
+ justify-content: center
+ align-items: center
+ overflow: hidden
+ width: 35px
+ height: auto
+ min-width: 35px
+ min-height: auto
+
+ +media-xs
+ display: none
- &.image i
- color: $node-type-asset_image
- &.file i
- color: $node-type-asset_file
- &.video i
- color: $node-type-asset_video
+ &.image i
+ color: $node-type-asset_image
+ &.file i
+ color: $node-type-asset_file
+ &.video i
+ color: $node-type-asset_video
- i
- +position-center-translate
- left: 23px
- top: 21px
- font-size: 1.1em
+ i
+ +position-center-translate
+ left: 23px
+ top: 21px
+ font-size: 1.1em
- img
- max-height: $activity-stream-thumbnail-size
- +position-center-translate
+ img
+ max-height: $activity-stream-thumbnail-size
+ +position-center-translate
- .activity-stream__list-details
- display: flex
- flex-direction: column
- justify-content: space-around
- flex: 1
- overflow: hidden
- position: relative
- max-width: 100%
- margin-right: auto
- padding: 10px 0
-
- +media-xs
- margin-left: 0
-
- .ribbon
- +ribbon
- right: -47px
- top: 5px
- font:
- size: 12px
- weight: 500
-
- span
- padding: 1px 50px
-
- .title
- display: inline-block
- padding: 0 10px
- color: $color-text-dark
- font-size: 1.1em
-
- span
- @include badge(hsl(hue($color-success), 60%, 45%), 3px)
- font-size: .7em
- padding: 1px 5px
- margin-right: 5px
-
- ul.meta
- +list-meta
- padding: 5px 10px 0 10px
- font-size: .85em
- color: $color-text-dark-secondary
- display: flex
- white-space: nowrap
-
- &.extra
- margin-top: auto
-
- li
- padding-left: 10px
- &:before
- left: -5px
- &.where-project
- +text-overflow-ellipsis
-
- section.comments
- padding: 0 15px 5px
-
- ul
- padding: 0
-
- > ul
- list-style-type: none
- margin: 10px 0 0
-
- > li
- +text-overflow-ellipsis
- border-top: thin solid $color-background-dark
- padding: 10px 0
-
- &:first-child
- border: none
-
- > a
- +text-overflow-ellipsis
- color: $color-text
- display: block
- padding-bottom: 5px
-
- section.blog-stream
- +media-md
- padding-left: 10px
- +media-sm
- padding-left: 10px
- position: relative
-
- .feed
- position: absolute
- top: 10px
- right: 10px
- font-size: 1.4em
- color: lighten($color-text-dark-hint, 10%)
-
- &:hover
- color: $color-primary
-
- > ul
- margin: 0
- padding: 0
- list-style: none
- border-top: thin solid $color-background
-
- .blog_index-item
- +container-box
+ .activity-stream__list-details
display: flex
flex-direction: column
- margin-bottom: 50px
+ justify-content: space-around
+ flex: 1
+ overflow: hidden
+ position: relative
+ max-width: 100%
+ padding: 10px 0
- &:before
- height: 1px
- background-color: $color-background-dark
- position: absolute
- bottom: -26px
- left: 25px
- right: 25px
- content: ' '
+ +media-xs
+ margin-left: 0
- &:last-child
- margin-bottom: 0
+ .ribbon
+ +ribbon
+ right: -47px
+ top: 5px
+ font-size: 12px
- &:before
- display: none
+ span
+ padding: 1px 50px
- video
- max-width: 100%
+ .title
+ padding: 0 10px
+ color: $color-text-dark
- a.item-title
+ span
+ @include badge(hsl(hue($color-success), 60%, 45%), 3px)
+ font-size: .7em
+ padding: 1px 5px
+ margin-right: 5px
+
+section.comments
+ padding: 0 15px 5px
+
+ ul
+ padding: 0
+
+ > ul
+ list-style-type: none
+ margin: 10px 0 0
+
+ > li
+ +text-overflow-ellipsis
+ border-top: thin solid $color-background-dark
+ padding: 10px 0
+
+ &:first-child
+ border: none
+
+ > a
+ +text-overflow-ellipsis
+ color: $color-text
+ display: block
+ padding-bottom: 5px
+
+section.random-asset
+ border-bottom: thin solid $color-background-dark
+
+ ul.random-asset__list
+ list-style: none
+ padding: 0
+
+ > li
+ align-items: center
+ border-top: thin solid $color-background
+ display: flex
+ padding: 7px 0
+ position: relative
+ overflow: hidden
+
+ &:first-child
+ border-top: none
+
+ .ribbon
+ +ribbon
+ right: -47px
+ top: 5px
+ font:
+ size: 12px
+ weight: 500
+
+ z-index: 1
+
+ span
+ padding: 1px 50px
+
+ .random-asset__list-thumbnail
+ background-color: $color-background
+ display: block
+ height: 50px
+ margin-right: 15px
+ min-height: 50px
+ min-width: 50px
+ overflow: hidden
+ position: relative
+ width: 50px
+
+ img
+ width: 100%
+
+ i
+ +position-center-translate
font-size: 1.6em
- padding: 5px 15px
+ color: $color-text-light
+
+ &.image
+ background-color: $node-type-asset_image
+ &.file
+ background-color: $node-type-asset_file
+ font-size: .8em
+ &.video
+ background-color: $node-type-asset_video
+ font-size: .8em
+ &.None
+ background-color: $node-type-group
+
+ .random-asset__list-details
+ .title
display: block
- color: $color-text
+ font-size: 1em
+ color: $color-text-dark-primary
&:hover
color: $color-primary
ul.meta
+list-meta
+ padding-top: 5px
font-size: .9em
- padding: 15px 15px 5px
+ li
+ &:before
+ left: -5px
+ &.what
+ text-transform: capitalize
- &.blog-non-featured
- border-radius: 0
- margin: 0
+ &.featured
+ align-items: flex-start
+ flex-direction: column
+ padding: 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
-
- ul.random-asset__list
- list-style: none
- padding: 0
-
- > li
- align-items: center
- border-top: thin solid $color-background
- display: flex
- padding: 7px 0
- position: relative
- overflow: hidden
-
- &:first-child
- border-top: none
-
- .ribbon
- +ribbon
- right: -47px
- top: 5px
- font:
- size: 12px
- weight: 500
-
- z-index: 1
-
- span
- padding: 1px 50px
-
- .random-asset__list-thumbnail
- background-color: $color-background
+ a.title
+ font-size: 1.1em
+ padding: 10px 0 5px
+ display: block
+ color: $color-text
+
+ &:hover
+ color: $color-primary
+
+ a.random-asset__thumbnail
display: block
- height: 50px
- margin-right: 15px
- min-height: 50px
- min-width: 50px
- overflow: hidden
position: relative
- width: 50px
+
+ &.video
+ background-color: black
+ img
+ opacity: .7
img
+ transition: opacity 150ms ease-in-out
width: 100%
+ max-width: 100%
i
+position-center-translate
- font-size: 1.6em
- color: $color-text-light
-
- &.image
- background-color: $node-type-asset_image
- &.file
- background-color: $node-type-asset_file
- font-size: .8em
- &.video
- background-color: $node-type-asset_video
- font-size: .8em
- &.None
- background-color: $node-type-group
-
- .random-asset__list-details
- .title
- display: block
- font-size: 1em
- color: $color-text-dark-primary
-
- &:hover
- color: $color-primary
-
- ul.meta
- +list-meta
- padding-top: 5px
- font-size: .9em
-
- li
- &:before
- left: -5px
- &.what
- text-transform: capitalize
-
- &.featured
- align-items: flex-start
- flex-direction: column
- padding: 0
-
- a.title
- font-size: 1.1em
- padding: 10px 0 5px
- display: block
- color: $color-text
-
- &:hover
- color: $color-primary
-
- a.random-asset__thumbnail
- display: block
- position: relative
-
- &.video
- background-color: black
- img
- opacity: .7
-
- img
- transition: opacity 150ms ease-in-out
- width: 100%
- max-width: 100%
+ color: white
+ font-size: 3em
+ text-shadow: 0 0 25px black
+ transition: font-size 150ms ease-in-out
+ &:hover
i
- +position-center-translate
- color: white
- font-size: 3em
- text-shadow: 0 0 25px black
- transition: font-size 150ms ease-in-out
+ font-size: 3.5em
+ img
+ opacity: .85
- &:hover
- i
- font-size: 3.5em
- img
- opacity: .85
-
- ul.meta
- +list-meta
- padding-bottom: 10px
+ ul.meta
+ +list-meta
+ padding-bottom: 10px
section.announcement
@@ -653,10 +446,6 @@ section.announcement
.title
padding-bottom: 10px
- font:
- family: $font-body
- size: 1.4em
- weight: 300
+media-xs
font-size: 1.4em
@@ -693,60 +482,21 @@ section.announcement
justify-content: space-around
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
- .dashboard-container
- .dashboard-main
- +media-xs
- width: 100%
- background-color: transparent
- box-shadow: none
- width: 60%
+ .blog
+ // Custom tweak to Bootstrap grid for the only case when
+ // the post is inside a column (it's usually centered in the page).
+ .col-md-9
+ flex: 1
+ max-width: 100%
- .dashboard-secondary
- +container-box
- +media-xs
- width: 100%
- width: 38%
+ .jumbotron
+ padding-top: 6em
+ padding-bottom: 6em
- > section
- padding: 15px
+ *
+ font-size: $h1-font-size
+
+ .lead
+ font-size: $font-size-base
diff --git a/src/styles/_welcome.sass b/src/styles/_welcome.sass
index 99f92c5..ae4f5df 100644
--- a/src/styles/_welcome.sass
+++ b/src/styles/_welcome.sass
@@ -10,9 +10,6 @@
li a.navbar-item
color: $color-text
- .navbar-container
- +container-behavior
-
.navbar-toggle
border: 2px solid $color-text-dark-primary
color: $color-text
@@ -267,22 +264,6 @@
+media-xs
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
+media-sm
@@ -334,9 +315,7 @@ section.pricing
+button($color-primary, 3px, true)
h3
- font:
- size: 1.8em
- family: $font-body
+ font-size: 1.8em
padding-bottom: 0
margin: 25px 0 0 10px
diff --git a/src/styles/main.sass b/src/styles/main.sass
index 6d2da95..d7524a5 100644
--- a/src/styles/main.sass
+++ b/src/styles/main.sass
@@ -1,26 +1,99 @@
-@import ../../../pillar/src/styles/_normalize
-@import ../../../pillar/src/styles/_config
-@import ../../../pillar/src/styles/_utils
+// Bootstrap variables and utilities.
+@import "../../node_modules/bootstrap/scss/functions"
+@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 */
-@import ../../../pillar/src/styles/_project
-@import ../../../pillar/src/styles/_project-sharing
-@import ../../../pillar/src/styles/_project-dashboard
-@import ../../../pillar/src/styles/_user
+@import "../../../pillar/src/styles/_project"
+@import "../../../pillar/src/styles/_project-sharing"
+@import "../../../pillar/src/styles/_project-dashboard"
+@import "../../../pillar/src/styles/_user"
+
@import _welcome
@import _homepage
@import _services
@import _about
-@import ../../../pillar/src/styles/_search
-@import ../../../pillar/src/styles/_organizations
+@import "../../../pillar/src/styles/_search"
+@import "../../../pillar/src/styles/_organizations"
/* 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 */
-@import ../../../pillar/src/styles/plugins/_jstree
-@import ../../../pillar/src/styles/plugins/_js_select2
+@import "../../../pillar/src/styles/plugins/_jstree"
+@import "../../../pillar/src/styles/plugins/_js_select2"
/* CSS for pillar-font comes from fontello.com using static/assets/font/config.json */
diff --git a/src/styles/project-landing.sass b/src/styles/project-landing.sass
index 7eaa671..3d65012 100644
--- a/src/styles/project-landing.sass
+++ b/src/styles/project-landing.sass
@@ -1,47 +1,88 @@
-@import ../../../pillar/src/styles/_config
-@import ../../../pillar/src/styles/_utils
+// Bootstrap variables and utilities.
+@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-gallery-thumbnail-size: 200px
-body
- background-color: white
-.page-body
- background-color: white
nav.navbar
- background-color: white
.navbar-header
+media-xs
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
border: none
color: $color-text
@@ -57,11 +98,11 @@ nav.navbar
.node-details-container
max-width: 620px
- font-family: $font-body
font-size: 1.3em
line-height: 1.5em
margin: 0 auto 40px auto
padding-bottom: 40px
+
+media-xs
padding-left: 10px
padding-right: 10px
@@ -106,20 +147,10 @@ section
border-top: thin solid $color-background
margin: 0 auto
-a.btn
- margin: 20px auto
- font-size: 1.3em
- padding: 9px 18px
- border-radius: 8px
- color: $color-text-dark
-
.navbar-secondary
max-width: 620px
margin: 0 auto
- .navbar-container
- border-bottom: 1px solid #dddddd
-
.navbar-collapse
padding-left: 0
diff --git a/src/templates/_macros/_navigation.pug b/src/templates/_macros/_navigation.pug
new file mode 100644
index 0000000..46290fe
--- /dev/null
+++ b/src/templates/_macros/_navigation.pug
@@ -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 %}
diff --git a/src/templates/homepage.pug b/src/templates/homepage.pug
index 485255c..ca4eba8 100644
--- a/src/templates/homepage.pug
+++ b/src/templates/homepage.pug
@@ -18,238 +18,229 @@ 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 %}")
| {% endblock %}
+| {% block navigation_tabs %}
+| {{ navigation_tabs(title) }}
+| {% endblock navigation_tabs %}
+
| {% block body %}
-.dashboard-container
- section.dashboard-main
+.container-fluid.dashboard-container.imgs-fluid
+ .row
+ .col-md-8
+ section.blog
+ ul.list-unstyled
+ | {% if latest_posts %}
+ | {% for node in latest_posts %}
+ | {{ render_blog_post(node) }}
+ | {% endfor %}
+ | {% else %}
+ li
+ | No blog entries... yet!
+ | {% endif %}
- section.blog-stream
- ul.blog-stream__list
- | {% if latest_posts %}
- | {% for node in latest_posts %}
- | {{ render_blog_post(node) }}
- | {% endfor %}
- | {% else %}
- li
- .blog-stream__list-details
- ul.meta
- li.when No blog entries... yet!
- | {% endif %}
+ .d-block.text-center
+ a.d-inline-block.p-3.text-muted(href="{{ url_for('main.main_blog') }}")
+ | See All Blog Posts
- .more
- a(href="{{ url_for('main.main_blog') }}")
- | See All Blog Posts
+ a.d-inline-block.p-3.text-muted(
+ href="{{ url_for('main.feeds_blogs') }}",
+ title="Blogs Feed",
+ data-toggle="tooltip",
+ data-placement="left")
+ i.pi-rss
+ | RSS Feed
- a.feed(
- href="{{ url_for('main.feeds_blogs') }}",
- title="Blogs Feed",
- data-toggle="tooltip",
- data-placement="left")
- i.pi-rss
+ .col-md-4
+ .dashboard-sidebar
+ section.pt-3
+ h6.title-underline In Production
+ a(href="/p/spring/")
+ img(src="{{ url_for('static', filename='assets/img/projects/spring_450x150.jpg')}}")
+ p.text-muted.pt-2.
+ A poetic short film about a mountain spirit and her wise little dog. #[a(href="/p/spring/") Check it out].
- section.dashboard-secondary
- | {{ navigation_tabs(title) }}
+ section.stream.py-3
+ h6.title-underline Latest Assets
- section.dashboard-in-production
- 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')}}")
- p.
- #[strong Spring] - A poetic short film about a mountain spirit and her wise little dog.
-
- a.in-production-project(href="/p/hero/")
- img(src="{{ url_for('static', filename='assets/img/projects/hero_450x150.jpg')}}")
- p.
- #[strong Hero] - A '2D' trailer-style movie focused on getting grease pencil
- production ready for Blender 2.8.
-
- section.stream
-
- h4 Latest Assets
-
- ul.activity-stream__list
- | {% for n in activity_stream %}
- li(
- class="{{ n.node_type }} {{ n.properties.content_type }} {% if n.picture %}with-picture{% endif %}",
- data-url="{{ n.url }}")
- a.activity-stream__list-thumbnail(
- class="{{ n.properties.content_type }}",
- href="{{ n.url }}")
- | {% if n.picture %}
- img(src="{{ n.picture.thumbnail('m', api=api) }}")
- | {% endif %}
-
- .activity-stream__list-thumbnail-icon
- | {% if n.node_type == 'asset' %}
- | {% if n.properties.content_type == 'video' %}
- i.pi-play
- | {% elif n.properties.content_type == 'image' %}
- i.pi-picture
- | {% elif n.properties.content_type == 'file' %}
- i.pi-file-archive
- | {% else %}
- i.pi-folder
- | {% endif %}
- | {% endif %}
-
-
- .activity-stream__list-details
- a.title(href="{{ n.url }}")
- | {{ n.name }}
-
- | {% if n.permissions.world %}
- .ribbon
- span free
- | {% endif %}
- ul.meta
- | {% if not n.picture %}
- li.when
- a(href="{{ n.url }}", title="{{ n._created }}") {{ n._created | pretty_date_time }}
- li.who {{ n.user.full_name }}
- | {% endif %}
-
- | {% if n.attached_to %}
- li.where-parent
- a(href="{{ n.attached_to.url }}") {{ n.attached_to.name }}
- | {% endif %}
- li.where-project
- a.project(href="{{ url_for('projects.view', project_url=n.project.url) }}") {{ n.project.name }}
- li.what
- | {% if n.node_type == 'asset' %}
- | {{ n.properties.content_type | undertitle }}
+ ul.activity-stream__list.list-unstyled
+ | {% for n in activity_stream %}
+ li(
+ class="{{ n.node_type }} {{ n.properties.content_type }} {% if n.picture %}with-picture{% endif %}",
+ data-url="{{ n.url }}")
+ a.activity-stream__list-thumbnail(
+ class="{{ n.properties.content_type }}",
+ href="{{ n.url }}")
+ | {% if n.picture %}
+ img(src="{{ n.picture.thumbnail('m', api=api) }}")
| {% endif %}
- | {% if n.picture %}
- ul.meta.extra
- li.when
- a(href="{{ n.url }}", title="{{ n._created }}") {{ n._created | pretty_date_time }}
- li.who {{ n.user.full_name }}
- | {% endif %}
- | {% endfor %}
-
- li.activity-stream__list-item.empty#activity-stream__empty
- | No items to list.
+ .activity-stream__list-thumbnail-icon
+ | {% if n.node_type == 'asset' %}
+ | {% if n.properties.content_type == 'video' %}
+ i.pi-play
+ | {% elif n.properties.content_type == 'image' %}
+ i.pi-picture
+ | {% elif n.properties.content_type == 'file' %}
+ i.pi-file-archive
+ | {% else %}
+ i.pi-folder
+ | {% endif %}
+ | {% endif %}
- section.random-asset
- h4
- a(href="/search") Explore the Cloud
- span.section-lead Random selection of the best assets & tutorials
+ .activity-stream__list-details
+ a.title(href="{{ n.url }}")
+ | {{ n.name }}
- ul.random-asset__list
- | {% for n in random_featured %}
- | {% if n.picture and loop.first %}
- li.random-asset__list-item.project
- | {% if n.project.picture_square %}
- a.random-asset__list-thumbnail(
- href="{{ n.project.url }}")
- img.image(src="{{ n.project.picture_square.thumbnail('s', api=api) }}")
- | {% endif %}
- .random-asset__list-details
- a.title(href="{{ n.project.url }}") {{ n.project.name }}
- | {% if n.project.summary %}
- ul.meta
- li.what
- a(href="{{ n.project.url }}") {{ n.project.summary }}
- | {% endif %}
+ | {% if n.permissions.world %}
+ .ribbon
+ span free
+ | {% endif %}
+ ul.list-unstyled.d-flex.text-muted
+ | {% if not n.picture %}
+ li.when
+ a(href="{{ n.url }}", title="{{ n._created }}") {{ n._created | pretty_date_time }}
+ li.who {{ n.user.full_name }}
+ | {% endif %}
- li.random-asset__list-item.featured
- | {% if n.permissions.world %}
- .ribbon
- span free
- | {% endif %}
- a.random-asset__thumbnail(
- href="{{ n.url }}",
- class="{{ n.properties.content_type }}")
- | {% if n.picture %}
- img(src="{{ n.picture.thumbnail('l', api=api) }}")
+ | {% if n.attached_to %}
+ li.where-parent
+ a(href="{{ n.attached_to.url }}") {{ n.attached_to.name }}
+ | {% endif %}
+ li.where-project
+ a.project(href="{{ url_for('projects.view', project_url=n.project.url) }}") {{ n.project.name }}
+ li.what
+ | {% if n.node_type == 'asset' %}
+ | {{ n.properties.content_type | undertitle }}
+ | {% endif %}
- | {% if n.properties.content_type == 'video' %}
- i.pi-play
- | {% endif %}
+ | {% if n.picture %}
+ ul.list-unstyled.d-flex.text-muted.extra
+ li.when
+ a(href="{{ n.url }}", title="{{ n._created }}") {{ n._created | pretty_date_time }}
+ li.who {{ n.user.full_name }}
+ | {% endif %}
+ | {% endfor %}
- | {% endif %}
+ li.activity-stream__list-item.empty#activity-stream__empty
+ | No items to list.
- a.title(href="{{ n.url }}")
- | {{ n.name }}
- ul.meta
- li.what
- a(href="{{ n.url }}")
- | {% if n.properties.content_type %}{{ n.properties.content_type | undertitle }}{% else %}Folder{% endif %}
- li.where
- a(href="{{ n.project.url }}")
- | {{ n.project.name }}
- | {% else %}
- li
- | {% if n.permissions.world %}
- .ribbon
- span free
- | {% endif %}
- a.random-asset__list-thumbnail(
- href="{{ n.url }}",
- class="{{ n.properties.content_type }}")
- | {% if n.picture %}
- img.image(src="{{ n.picture.thumbnail('s', api=api) }}")
+ section.random-asset.py-3
+ h6.title-underline
+ a(href="/search") Explore the Cloud
+ .pb-3.text-muted Random selection of the best assets & tutorials
+
+ ul.random-asset__list.list-unstyled
+ | {% for n in random_featured %}
+ | {% if n.picture and loop.first %}
+ li.random-asset__list-item.project
+ | {% if n.project.picture_square %}
+ a.random-asset__list-thumbnail(
+ href="{{ n.project.url }}")
+ img.image(src="{{ n.project.picture_square.thumbnail('s', api=api) }}")
+ | {% endif %}
+ .random-asset__list-details
+ a.title(href="{{ n.project.url }}") {{ n.project.name }}
+ | {% if n.project.summary %}
+ ul.list-unstyled.d-flex.text-muted
+ li.what
+ a(href="{{ n.project.url }}") {{ n.project.summary }}
+ | {% endif %}
+
+ li.random-asset__list-item.featured
+ | {% if n.permissions.world %}
+ .ribbon
+ span free
+ | {% endif %}
+ a.random-asset__thumbnail(
+ href="{{ n.url }}",
+ class="{{ n.properties.content_type }}")
+ | {% if n.picture %}
+ img(src="{{ n.picture.thumbnail('l', api=api) }}")
+
+ | {% if n.properties.content_type == 'video' %}
+ i.pi-play
+ | {% endif %}
+
+ | {% endif %}
+
+ a.title(href="{{ n.url }}")
+ | {{ n.name }}
+ ul.list-unstyled.d-flex.text-muted
+ li.what
+ a(href="{{ n.url }}")
+ | {% if n.properties.content_type %}{{ n.properties.content_type | undertitle }}{% else %}Folder{% endif %}
+ li.where
+ a(href="{{ n.project.url }}")
+ | {{ n.project.name }}
| {% else %}
- | {% if n.properties.content_type == 'video' %}
- i.pi-film-thick
- | {% elif n.properties.content_type == 'image' %}
- i.pi-picture
- | {% elif n.properties.content_type == 'file' %}
- i.pi-file-archive
+
+ li
+ | {% if n.permissions.world %}
+ .ribbon
+ span free
+ | {% endif %}
+ a.random-asset__list-thumbnail(
+ href="{{ n.url }}",
+ class="{{ n.properties.content_type }}")
+ | {% if n.picture %}
+ img.image(src="{{ n.picture.thumbnail('s', api=api) }}")
+ | {% else %}
+ | {% if n.properties.content_type == 'video' %}
+ i.pi-film-thick
+ | {% elif n.properties.content_type == 'image' %}
+ i.pi-picture
+ | {% elif n.properties.content_type == 'file' %}
+ i.pi-file-archive
+ | {% else %}
+ i.pi-folder
+ | {% endif %}
+ | {% endif %}
+ .random-asset__list-details
+ a.title(href="{{ n.url }}") {{ n.name }}
+ ul.list-unstyled.d-flex.text-muted
+ li.what
+ a(href="{{ n.url }}")
+ | {% if n.properties.content_type %}{{ n.properties.content_type }}{% else %}Folder{% endif %}
+ li.where
+ a(href="{{ n.project.url }}") {{ n.project.name }}
+
+ | {% endif %}
+ | {% endfor %}
+
+
+ section.comments.py-3
+ h6.title-underline Latest Comments
+
+ ul.list-unstyled
+ | {% if latest_comments %}
+ | {% for n in latest_comments %}
+ li(
+ class="{{ n.node_type }}",
+ data-url="{{ n.url }}")
+
+ a.comment-content(href="{{ n.url }}")
+ | {{ n.properties.content | striptags | truncate(200) }}
+
+ ul.list-unstyled.d-flex.text-muted
+ li.who {{ n.user.full_name }}
+ | {% if n.attached_to %}
+
+ li.where-parent
+ a(href="{{ n.attached_to.url }}") {{ n.attached_to.name }}
+ | {% endif %}
+
+ li.when
+ a(href="{{ n.url }}", title="{{ n._created }}")
+ | {{ n._created | pretty_date_time }}
+ | {% endfor %}
+
| {% else %}
- i.pi-folder
+ li.activity-stream__list-item.empty#activity-stream__empty
+ | No comments... yet!
+
| {% endif %}
- | {% endif %}
- .random-asset__list-details
- a.title(href="{{ n.url }}") {{ n.name }}
- ul.meta
- li.what
- a(href="{{ n.url }}")
- | {% if n.properties.content_type %}{{ n.properties.content_type }}{% else %}Folder{% endif %}
- li.where
- a(href="{{ n.project.url }}") {{ n.project.name }}
-
- | {% endif %}
- | {% endfor %}
-
-
- section.comments
-
- h4 Latest Comments
-
- ul
- | {% if latest_comments %}
- | {% for n in latest_comments %}
- li(
- class="{{ n.node_type }}",
- data-url="{{ n.url }}")
-
- a.comment-content(href="{{ n.url }}")
- | {{ n.properties.content | striptags | truncate(200) }}
-
- ul.meta
- li.who {{ n.user.full_name }}
- | {% if n.attached_to %}
-
- li.where-parent
- a(href="{{ n.attached_to.url }}") {{ n.attached_to.name }}
- | {% endif %}
-
- li.when
- a(href="{{ n.url }}", title="{{ n._created }}")
- | {{ n._created | pretty_date_time }}
- | {% endfor %}
-
- | {% else %}
- li.activity-stream__list-item.empty#activity-stream__empty
- | No comments... yet!
-
- | {% endif %}
| {% endblock %}
diff --git a/src/templates/layout.pug b/src/templates/layout.pug
index 82c69ed..5281f75 100644
--- a/src/templates/layout.pug
+++ b/src/templates/layout.pug
@@ -3,7 +3,7 @@ html(lang="en")
head
meta(charset="utf-8")
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="author", content="Blender Institute")
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/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 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")
| {% if title == 'blog' %}
link(href="{{ url_for('static_pillar', filename='assets/css/blog.css') }}", rel="stylesheet")
| {% else %}
@@ -61,216 +57,331 @@ html(lang="en")
| {% endif %}
| {% endblock css %}
-
- | {% if not title %}{% set title="default" %}{% endif %}
-
+ | {% if not title %}{% set title="default" %}{% endif %}
body(class="{{ title }}")
- .container-page
- | {% with messages = get_flashed_messages(with_categories=True) %}
- | {% if messages %}
+ | {% with messages = get_flashed_messages(with_categories=True) %}
+ | {% if messages %}
+ | {% for (category, message) in messages %}
+ .alert(role="alert", class="alert-{{ category }}")
+ i.alert-icon(class="{{ category }}")
+ span {{ message }}
+ button.close(type="button", data-dismiss="alert")
+ i.pi-cancel
+ | {% endfor %}
+ | {% endif %}
+ | {% endwith %}
- | {% for (category, message) in messages %}
- .alert(role="alert", class="alert-{{ category }}")
- i.alert-icon(class="{{ category }}")
- span {{ message }}
- button.close(type="button", data-dismiss="alert")
- i.pi-cancel
- | {% endfor %}
+ nav.navbar.navbar-expand-md.fixed-top.bg-white
+ a.navbar-brand(
+ href="{{ url_for('main.homepage') }}",
+ title="Blender Cloud")
+ span.app-logo
+ i.pi-blender-cloud
- | {% endif %}
- | {% endwith %}
+ 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
- nav.navbar
- .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(
- href="{{ url_for('main.homepage') }}",
- title="Blender Cloud")
- span.app-logo
- i.pi-blender-cloud
+ | {% block navigation_tabs %}
+ | {% endblock navigation_tabs %}
- | {% block navigation_search %}
- .search-input
- input#cloud-search(
- type="text",
- placeholder="Search assets, tutorials...")
- i.search-icon.pi-search
- | {% endblock navigation_search %}
+ | {% block navigation_search %}
+ // TODO (pablo) - bring it back asap
+ .search-input
+ input#cloud-search(
+ type="text",
+ placeholder="Search assets, tutorials...")
+ i.search-icon.pi-search
+ | {% endblock navigation_search %}
- nav.collapse.navbar-collapse
- ul.nav.navbar-nav.navbar-right
- | {% if node and node.properties and node.properties.category %}
- | {% set category = node.properties.category %}
- | {% else %}
- | {% set category = title %}
- | {% endif %}
+ .collapse.navbar-collapse
+ ul.navbar-nav.ml-auto
+ | {% if node and node.properties and node.properties.category %}
+ | {% set category = node.properties.category %}
+ | {% else %}
+ | {% set category = title %}
+ | {% endif %}
- | {% block navigation_sections %}
+ | {% block navigation_sections %}
+ li
+ a.navbar-item(
+ href="{{ url_for('main.main_blog') }}",
+ title="Blender Cloud Blog",
+ data-toggle="tooltip",
+ data-placement="bottom",
+ class="{% if category == 'blog' %}active{% endif %}")
+ span Blog
+
+ li.dropdown
+ a.navbar-item.dropdown-toggle(
+ href="",
+ data-toggle="dropdown",
+ title="Libraries")
+ span Libraries
+ i.pi-angle-down
+
+ ul.dropdown-menu.p-0
li
a.navbar-item(
- href="{{ url_for('main.main_blog') }}",
- title="Blender Cloud Blog",
+ href="{{ url_for('projects.view', project_url='hdri') }}",
+ title="HDRI Library",
data-toggle="tooltip",
- data-placement="bottom",
- class="{% if category == 'blog' %}active{% endif %}")
- span Blog
-
- li(class="dropdown libraries")
- a.navbar-item.dropdown-toggle(
- href="",
- data-toggle="dropdown",
- title="Libraries")
- span Libraries
- i.pi-angle-down
-
- ul.dropdown-menu
- li
- a.navbar-item(
- href="{{ url_for('projects.view', project_url='hdri') }}",
- title="HDRI Library",
- data-toggle="tooltip",
- data-placement="left")
- i.pi-globe
- | HDRI
- li
- a.navbar-item(
- href="{{ url_for('projects.view', project_url='textures') }}",
- title="Textures Library",
- data-toggle="tooltip",
- data-placement="left")
- i.pi-folder-texture
- | Textures
- li
- a.navbar-item(
- href="{{ url_for('projects.view', project_url='characters') }}",
- title="Character Library",
- data-toggle="tooltip",
- data-placement="left")
- i.pi-character
- | Characters
-
-
- li(class="dropdown libraries")
- a.navbar-item.dropdown-toggle(
- href="",
- data-toggle="dropdown",
- title="Training")
- span Training
- i.pi-angle-down
-
- ul.dropdown-menu
- li
- a.navbar-item(
- href="{{ url_for('cloud.courses') }}",
- title="Courses",
- data-toggle="tooltip",
- data-placement="left")
- i.pi-graduation-cap
- | Courses
- li
- a.navbar-item(
- href="{{ url_for('cloud.workshops') }}",
- title="Workshops",
- data-toggle="tooltip",
- data-placement="left")
- i.pi-lightbulb
- | Workshops
- li
- a.navbar-item(
- href="{{ url_for('projects.view', project_url='gallery') }}",
- title="Curated artwork collection",
- data-toggle="tooltip",
- data-placement="left")
- i.pi-image
- | Art Gallery
-
+ data-placement="left")
+ i.pi-globe
+ | HDRI
li
a.navbar-item(
- href="{{ url_for('cloud.open_projects') }}",
- title="Browse all the Open Projects",
+ href="{{ url_for('projects.view', project_url='textures') }}",
+ title="Textures Library",
data-toggle="tooltip",
- data-placement="bottom",
- class="{% if category in ['open-projects', 'film'] %}active{% endif %}")
- span Open Projects
+ data-placement="left")
+ i.pi-folder-texture
+ | Textures
li
a.navbar-item(
- href="{{ url_for('cloud.services') }}",
- title="Blender Cloud Services",
+ href="{{ url_for('projects.view', project_url='characters') }}",
+ title="Character Library",
data-toggle="tooltip",
- data-placement="bottom",
- class="{% if category == 'services' %}active{% endif %}")
- span Services
- | {% endblock navigation_sections %}
+ data-placement="left")
+ i.pi-character
+ | Characters
- | {% if current_user.is_anonymous %}
+ li(class="dropdown")
+ a.navbar-item.dropdown-toggle(
+ href="{{ url_for('cloud.workshops') }}"
+ data-toggle="dropdown",
+ title="Training")
+ span Training
+ i.pi-angle-down
+
+ ul.dropdown-menu
li
a.navbar-item(
- href="https://store.blender.org/product/membership/",
- title="Sign up") Sign up
- | {% endif %}
+ href="{{ url_for('cloud.courses') }}",
+ title="Courses",
+ data-toggle="tooltip",
+ data-placement="left")
+ i.pi-graduation-cap
+ | Courses
+ li
+ a.navbar-item(
+ href="{{ url_for('cloud.workshops') }}",
+ title="Workshops",
+ data-toggle="tooltip",
+ data-placement="left")
+ i.pi-lightbulb
+ | Workshops
+ li
+ a.navbar-item(
+ href="{{ url_for('projects.view', project_url='gallery') }}",
+ title="Curated artwork collection",
+ data-toggle="tooltip",
+ data-placement="left")
+ i.pi-image
+ | Art Gallery
+ li(class="dropdown")
+ a.navbar-item.dropdown-toggle(
+ href="{{ url_for('cloud.open_projects') }}",
+ title="Browse all the Open Projects",
+ data-toggle="dropdown",
+ class="{% if category in ['open-projects', 'film'] %}active{% endif %}")
+ span Open Projects
+ i.pi-angle-down
- | {% block navigation_user %}
+ 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
- | {% include 'menus/notifications.html' %}
- | {% include 'menus/user.html' %}
+ li.dropdown-divider
- | {% endblock navigation_user %}
+ 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
- .page-content
- #search-overlay
- | {% block page_overlay %}
- #page-overlay
- | {% endblock page_overlay %}
- .page-body
- | {% block body %}{% endblock %}
+ 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
+ a.navbar-item(
+ href="{{ url_for('cloud.services') }}",
+ title="All Blender Cloud services",
+ data-toggle="tooltip",
+ data-placement="left")
+ i.pi-list
+ | All Services
+
+ | {% endblock navigation_sections %}
+
+ | {% block navigation_user %}
+ | {% include 'menus/notifications.html' %}
+ | {% include 'menus/user.html' %}
+ | {% endblock navigation_user %}
+
+ | {% if current_user.is_anonymous %}
+ li.pt-1
+ a.btn.btn-sm.btn-primary.px-3.mx-1(
+ href="https://store.blender.org/product/membership/",
+ title="Sign up") Sign up
+ | {% endif %}
+
+ .page-content
+ #search-overlay
+ | {% block page_overlay %}
+ #page-overlay
+ | {% endblock page_overlay %}
+ .page-body
+ | {% block body %}{% endblock %}
| {% block footer_container %}
- #footer-container
+ .footer-wrapper
| {% block footer_navigation %}
- #footer-navigation
+ .footer-navigation
.container
.row
.col-md-4.col-xs-6
- .footer-support
- h4 Support & Feedback
- p.
- 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
- ul.footer-social
- li
- a(href="https://www.facebook.com/BlenderCloudOfficial/",
- title="Follow us on Facebook")
- i.pi-social-facebook
- li
- a(href="https://twitter.com/Blender_Cloud",
- title="Follow us on Twitter")
- i.pi-social-twitter
-
- .col-md-2.col-xs-6
h4
a(href="{{ url_for('main.homepage') }}")
- | Blender Cloud
- ul.footer-links
+ i.pi-blender-cloud-logo
+
+ p.pl-2.
+ Blender Cloud is the creative hub for your projects,
+ powered by Free and Open Source Software.
+
+ h5.d-flex
+ a.px-2(href="https://twitter.com/Blender_Cloud",
+ title="Follow us on Twitter")
+ i.pi-social-youtube
+
+ a.px-2(href="https://twitter.com/Blender_Cloud",
+ title="Follow us on 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
+ h7.font-weight-bold
+ | TRAINING
+
+ 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
a(href="{{ url_for('main.main_blog') }}",
title="Blender Cloud Blog")
- | Blog
+ | HDRIs
li
a(href="{{ url_for('cloud.services') }}",
title="Blender Cloud Services")
- | Services
+ | Textures
li
a(href="{{ url_for('cloud.about') }}",
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
a(href="{{ url_for('cloud.terms_and_conditions') }}",
title="Terms and Conditions")
@@ -279,33 +390,11 @@ html(lang="en")
a(href="{{ url_for('cloud.privacy') }}",
title="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
MEDIA Programme of the European Union
- img(alt="MEDIA Programme of the European Union",
- src="https://gooseberry.blender.org/wp-content/uploads/2014/01/media_programme.png")
| {% endblock footer_navigation %}
- | {% block footer %}
- footer.container
- #hop(title="Be awesome in space")
- i.pi-angle-up
- | {% endblock footer %}
+ #hop(title="Be awesome in space")
+ i.pi-angle-up
+
| {% endblock footer_container %}
#notification-pop(data-url="", data-read-toggle="")
@@ -318,10 +407,7 @@ html(lang="en")
span.nc-date
a(href="")
- noscript
- 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') }}")
+ script(src="{{ url_for('static_cloud', filename='assets/js/bootstrap.min.js') }}")
| {% if current_user.is_authenticated %}
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/jquery.typewatch-3.0.0.min.js') }}")
diff --git a/src/templates/mixins/components.pug b/src/templates/mixins/components.pug
new file mode 100644
index 0000000..68826aa
--- /dev/null
+++ b/src/templates/mixins/components.pug
@@ -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.
diff --git a/src/templates/nodes/custom/blog/_macros.pug b/src/templates/nodes/custom/blog/_macros.pug
new file mode 100644
index 0000000..84ec904
--- /dev/null
+++ b/src/templates/nodes/custom/blog/_macros.pug
@@ -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 %}
diff --git a/src/templates/organizations/index.pug b/src/templates/organizations/index.pug
new file mode 100644
index 0000000..4c3f6eb
--- /dev/null
+++ b/src/templates/organizations/index.pug
@@ -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('
Opening ' + item_type + ' failed. There possibly was ' + + 'an error connecting to the server. Please check your network connection and ' + + 'try again.
'); + } + }); + + // 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 = $('').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 %}
diff --git a/src/templates/projects/home_index.pug b/src/templates/projects/home_index.pug
new file mode 100644
index 0000000..610ff0d
--- /dev/null
+++ b/src/templates/projects/home_index.pug
@@ -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.
+
+ | 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 v{{ 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
+