fixed font size rounding issue in firefox, added contrib notes

This commit is contained in:
Josh Barr 2016-02-15 22:31:07 +13:00
parent 36d472ce74
commit a1a2940495
20 changed files with 496 additions and 459 deletions

View file

@ -11,6 +11,7 @@ linters:
Indentation:
severity: warning
width: 4
# because https://github.com/brigade/scss-lint/issues/409
allow_non_nested_indentation: true
character: space
@ -61,7 +62,7 @@ linters:
enabled: true
ImportantRule:
enabled: true
enabled: false
exclude:
- '**/_datetimepicker.scss'
@ -92,7 +93,7 @@ linters:
# There are regretably quite a few exlusions here, made necessary by
# a) the conversion of django field/widget names to underscored class names
# b) the use of third party code such as Hallo.js which uses classes with snakeCaseClasses.
exclude:
exclude:
- '**/rich-text.scss'
- '**/_forms.scss'
- '**/_streamfield.scss'

View file

@ -20,6 +20,7 @@ Changelog
* Page models now perform field validation, including testing slugs for uniqueness within a parent page, at the model level on saving
* Page slugs are now auto-generated at the model level on page creation if one has not been specified explicitly
* The `Page` model now has two new methods `get_site()` and `get_url_parts()` to aid with customising the page URL generation logic
* The `edit bird` on the frontend has been redesigned, and no longer depends on an iframe (Thomas Winter, Gareth Price).
* New translations for Hungarian, Swedish (Sweden) and Turkish
* Fix: Custom page managers no longer raise an error when used on an abstract model
* Fix: Wagtail's migrations are now all reversible (benjaoming)

View file

@ -107,7 +107,8 @@ Contributors
* Nigel Fletton
* Kait Crawford
* Adam Bolfik
* Thomas Winter
* Gareth Price
Translators
===========

View file

@ -4,10 +4,10 @@
Writing templates
=================
Wagtail uses Django's templating language. For developers new to Django, start with Django's own template documentation:
Wagtail uses Django's templating language. For developers new to Django, start with Django's own template documentation:
https://docs.djangoproject.com/en/dev/topics/templates/
Python programmers new to Django/Wagtail may prefer more technical documentation:
Python programmers new to Django/Wagtail may prefer more technical documentation:
https://docs.djangoproject.com/en/dev/ref/templates/api/
You should be familiar with Django templating basics before continuing with this documentation.
@ -47,7 +47,7 @@ Static assets
=============
Static files e.g CSS, JS and images are typically stored here::
name_of_project/
name_of_app/
static/
@ -57,7 +57,7 @@ Static files e.g CSS, JS and images are typically stored here::
images/
models.py
(The names "css", "js" etc aren't important, only their position within the tree.)
(The names "css", "js" etc aren't important, only their position within the tree.)
Any file within the static folder should be inserted into your HTML using the ``{% static %}`` tag. More about it: :ref:`static_tag`.
@ -204,12 +204,23 @@ This tag provides a contextual flyout menu on the top-right of a page for logged
...
{% wagtailuserbar %}
By default the User Bar appears in the top right of the browser window, flush with the edge. If this conflicts with your design it can be moved with a css rule in your own CSS files e.g to move it down from the top:
By default the User Bar appears in the bottom right of the browser window, inset from the edge. If this conflicts with your design it can be moved by passing a parameter to the template tag. These examples show you how to position the userbar in each corner of the screen:
.. code-block:: html+django
...
{% wagtailuserbar 'top-left' %}
{% wagtailuserbar 'top-right' %}
{% wagtailuserbar 'bottom-left' %}
{% wagtailuserbar 'bottom-right' %}
...
The userbar can be positioned where it works best with your design. Alternatively, you can position it with a css rule in your own CSS files, for example:
.. code-block:: css
#wagtail-userbar{
top:200px
.wagtail-userbar {
top: 200px !important;
left: 10px !important;
}

View file

@ -1,33 +1,54 @@
'use strict';
document.addEventListener('DOMContentLoaded', function() {
var trigger = document.querySelector('[data-wagtail-userbar-trigger]');
document.addEventListener('DOMContentLoaded', function userBar(e) {
var userbar = document.querySelector('[data-wagtail-userbar]');
var trigger = userbar.querySelector('[data-wagtail-userbar-trigger]');
var list = userbar.querySelector('ul');
var className = 'is-active';
var hasTouch = 'ontouchstart' in window;
var clickEvent = hasTouch ? 'touchstart' : 'click';
if ('ontouchstart' in window) {
if (!'classList' in userbar) {
return;
}
if (hasTouch) {
userbar.classList.add('touch');
} else {
userbar.classList.add('no-touch');
}
trigger.addEventListener('mouseenter', showUserbar, false);
userbar.addEventListener('mouseleave', hideUserbar, false);
trigger.addEventListener('touchstart', toggleUserbar, false);
trigger.addEventListener(clickEvent, toggleUserbar, false);
// make sure userbar is hidden when navigating back
window.addEventListener('pageshow', hideUserbar, false);
function showUserbar() {
function showUserbar(e) {
userbar.classList.add(className);
list.addEventListener(clickEvent, sandboxClick, false);
window.addEventListener(clickEvent, clickOutside, false);
}
function hideUserbar() {
function hideUserbar(e) {
userbar.classList.remove(className);
list.addEventListener(clickEvent, sandboxClick, false);
window.removeEventListener(clickEvent, clickOutside, false);
}
function toggleUserbar() {
userbar.classList.toggle(className);
function toggleUserbar(e) {
e.stopPropagation();
if (userbar.classList.contains(className)) {
hideUserbar();
} else {
showUserbar();
}
}
function sandboxClick(e) {
e.stopPropagation();
}
function clickOutside(e) {
hideUserbar();
}
});

View file

@ -0,0 +1,19 @@
// The wagtail font isn't available in WOFF2, so a @font-face is set here without a mixin.
@font-face {
font-family: 'wagtail';
src: url('#{$font-root}wagtail.eot');
src: url('#{$font-root}wagtail.eot?#iefix') format('embedded-opentype'),
url('#{$font-root}wagtail.ttf') format('truetype'),
url('#{$font-root}wagtail.svg#wagtail') format('svg'),
url('#{$font-root}wagtail.woff') format('woff');
font-weight: normal;
font-style: normal;
}
// One exception to the limited font formats used above is the Wagtail icon font for Windows, where using the SVG version improves antialiasing
@media screen and (-webkit-min-device-pixel-ratio: 0) {
@font-face {
font-family: 'wagtail';
src: url('#{$font-root}wagtail.svg#wagtail') format('svg');
}
}

View file

@ -14,16 +14,6 @@
//
// See https://css-tricks.com/snippets/css/using-font-face/ for more information.
@mixin webfont($fontname, $filestub, $weight, $style:normal) {
@font-face {
font-family: '#{$fontname}';
src: url('#{$font-root}#{$filestub}.woff2') format('woff2'),
url('#{$font-root}#{$filestub}.woff') format('woff'),
url('#{$font-root}#{$filestub}.ttf') format('truetype');
font-weight: $weight;
font-style: $style;
}
}
@include webfont(Open Sans, opensans-light, 300, normal);
@include webfont(Open Sans, opensans-regular, 400, normal);
@ -32,22 +22,4 @@
@include webfont(Roboto Slab, robotoslab-regular, 400, normal);
@include webfont(Roboto Slab, robotoslab-bold, 700, normal);
// The wagtail font isn't available in WOFF2, so a @font-face is set here without a mixin.
@font-face {
font-family: 'wagtail';
src: url('#{$font-root}wagtail.eot');
src: url('#{$font-root}wagtail.eot?#iefix') format('embedded-opentype'),
url('#{$font-root}wagtail.ttf') format('truetype'),
url('#{$font-root}wagtail.svg#wagtail') format('svg'),
url('#{$font-root}wagtail.woff') format('woff');
font-weight: normal;
font-style: normal;
}
// One exception to the limited font formats used above is the Wagtail icon font for Windows, where using the SVG version improves antialiasing
@media screen and (-webkit-min-device-pixel-ratio: 0) {
@font-face {
font-family: 'wagtail';
src: url('#{$font-root}wagtail.svg#wagtail') format('svg');
}
}
@import 'wagtailadmin/scss/font-icons';

View file

@ -1,3 +1,10 @@
// =============================================================================
// Mixins
// =============================================================================
// Please note that the mixins partial shouldn't include any classes. This is so
// it can be included in any file without accidentally producing output
@mixin clearfix() {
&:before,
&:after {
@ -11,14 +18,14 @@
}
@mixin unlist() {
&,
ul,
&,
ul,
li {
list-style-type: none;
font-style: normal;
}
&,
&,
ul {
margin-top: 0;
margin-bottom: 0;
@ -42,7 +49,7 @@
position: absolute;
width: 1px;
&:active,
&:active,
&:focus {
clip: auto;
height: auto;
@ -53,9 +60,6 @@
}
}
.visuallyhidden {
@include visuallyhidden;
}
@mixin visuallyvisible {
clip: none;
@ -66,6 +70,32 @@
position: initial;
}
.visuallyvisible {
@include visuallyvisible;
@mixin icon () {
font-family: 'wagtail';
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
speak: none;
text-decoration: none;
width: 1.3em;
line-height: 1em;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: left;
vertical-align: middle;
margin-right: 0.2em;
}
@mixin webfont($fontname, $filestub, $weight, $style:normal) {
@font-face {
font-family: '#{$fontname}';
src: url('#{$font-root}#{$filestub}.woff2') format('woff2'),
url('#{$font-root}#{$filestub}.woff') format('woff'),
url('#{$font-root}#{$filestub}.ttf') format('truetype');
font-weight: $weight;
font-style: $style;
}
}

View file

@ -0,0 +1,86 @@
$icons: (
'cogs': 'a',
'doc-empty-inverse': 'b',
'doc-empty': 'c',
'edit': 'd',
'arrow-up': 'e',
'arrow-down': 'q',
'search': 'f',
'cross': 'g',
'folder-open-1': 'i',
'folder-inverse': 'j',
'mail': 'k',
'arrows-up-down': 'l',
'locked': 'm',
'arrow-right': 'n',
'doc-full': 'h',
'file-text-alt': 'h',
'image': 'o',
'picture': 'o',
'unlocked': 'p',
'doc-full-inverse': 'r',
'folder': 's',
'plus': 't',
'tag': 'u',
'folder-open-inverse': 'v',
'cog': 'w',
'tick': 'x',
'user': 'y',
'arrow-left': 'z',
'tick-inverse': 'A',
'plus-inverse': 'B',
'snippet': 'D',
'wagtail': 'V',
'wagtail-inverse': '0',
'bold': 'C',
'italic': 'E',
'undo': 'H',
'repeat': 'I',
'list-ol': 'G',
'list-ul': 'F',
'link': 'J',
'radio-full': 'K',
'radio-empty': 'L',
'arrow-up-big': 'M',
'arrow-down-big': 'N',
'group': 'O',
'media': 'P',
'password': 'Q',
'download': 'S',
'order': 'T',
'grip': 'U',
'home': 'W',
'order-down': 'X',
'order-up': 'Y',
'bin': 'Z',
'spinner': '1',
'pick': '2',
'redirect': '3',
'view': '4',
'no-view': '^',
'collapse-down': '5',
'collapse-up': '6',
'date': '7',
'time': '8',
'success': '9',
'help': '?',
'warning': '!',
'form': '$',
'site': '@',
'placeholder': ' {',
'pilcrow': '\e600',
'title': '\f034',
'code': '\e601',
'openquote': '',
'horizontalrule': '\2014'
);
$icons-after: (
'arrow-up': 'e',
'arrow-down-after': 'q',
'arrow-right-after': 'n'
);

View file

@ -1,3 +1,5 @@
@import 'wagtailadmin/scss/variables-icons';
.icon.teal {
color: $color-teal;
}
@ -11,20 +13,7 @@
.hallotoolbar [class^='icon-'],
.hallotoolbar [class*=' icon-']:before,
.hallotoolbar [class^='icon-']:before {
font-family: 'wagtail';
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
speak: none;
text-decoration: none;
width: 1.3em;
line-height: 1em;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: left;
vertical-align: middle;
margin-right: 0.2em;
@include icon(); // from _mixins.scss
}
.icon:after,
@ -41,309 +30,51 @@
margin-right: 0;
}
.icon-cogs:before {
content: 'a';
}
.icon-doc-empty-inverse:before {
content: 'b';
}
// =============================================================================
// Icon factory methods
// =============================================================================
.icon-doc-empty:before {
content: 'c';
}
.icon-edit:before {
content: 'd';
}
.icon-arrow-up:before,
.icon-arrow-up-after:after {
content: 'e';
}
.icon-arrow-down:before,
.icon-arrow-down-after:after {
content: 'q';
}
.icon-search:before {
content: 'f';
}
.icon-cross:before {
content: 'g';
}
.icon-folder-open-1:before {
content: 'i';
}
.icon-folder-inverse:before {
content: 'j';
}
.icon-mail:before {
content: 'k';
}
.icon-arrows-up-down:before {
content: 'l';
}
.icon-locked:before {
content: 'm';
}
.icon-arrow-right:before,
.icon-arrow-right-after:after {
content: 'n';
}
.icon-doc-full:before,
.icon-file-text-alt:before {
content: 'h';
}
.icon-image:before,
.icon-picture:before {
content: 'o';
}
.icon-unlocked:before {
content: 'p';
}
.icon-doc-full-inverse:before {
content: 'r';
}
.icon-folder:before {
content: 's';
}
.icon-plus:before {
content: 't';
}
.icon-tag:before {
content: 'u';
}
.icon-folder-open-inverse:before {
content: 'v';
}
.icon-cog:before {
content: 'w';
}
.icon-tick:before {
content: 'x';
}
.icon-user:before {
content: 'y';
}
.icon-arrow-left:before {
content: 'z';
}
.icon-tick-inverse:before {
content: 'A';
}
.icon-plus-inverse:before {
content: 'B';
}
.icon-snippet:before {
content: 'D';
}
.icon-wagtail:before {
content: 'V';
}
.icon-wagtail-inverse:before {
content: '0';
}
.icon-bold:before {
content: 'C';
}
.icon-italic:before {
content: 'E';
}
.icon-undo:before {
content: 'H';
}
.icon-repeat:before {
content: 'I';
}
.icon-list-ol:before {
content: 'G';
}
.icon-list-ul:before {
content: 'F';
}
.icon-link:before {
content: 'J';
}
.icon-radio-full:before {
content: 'K';
}
.icon-radio-empty:before {
content: 'L';
}
.icon-arrow-up-big:before {
content: 'M';
}
.icon-arrow-down-big:before {
content: 'N';
}
.icon-group:before {
content: 'O';
}
.icon-media:before {
content: 'P';
}
.icon-horizontalrule {
&:before {
font-family: Open Sans, Arial, sans-serif;
content: '\2014';
@each $icon, $content in $icons {
.icon-#{$icon}:before {
content: quote(#{$content});
}
}
.icon-password:before {
content: 'Q';
@each $icon, $content in $icons-after {
.icon-#{$icon}:after {
content: #{$content};
}
}
.icon-download:before {
content: 'S'; // Credit: Icon made by Freepik from Flaticon.com
}
.icon-order:before {
content: 'T';
}
// =============================================================================
// Custom config for various icons
// =============================================================================
.icon-grip:before {
content: 'U';
}
.icon-home:before {
content: 'W';
}
.icon-order-down:before {
content: 'X';
}
.icon-order-up:before {
content: 'Y';
}
.icon-bin:before {
content: 'Z';
}
.icon-spinner:after {
width: 1em;
animation: spin 0.5s infinite linear;
content: '1';
}
.icon-pick:before {
content: '2';
}
.icon-redirect:before {
content: '3';
.icon-download {
// Credit: Icon made by Freepik from Flaticon.com
}
.icon-view:before,
.icon-no-view:before {
vertical-align: -3.5px;
font-size: 1.1rem;
font-size: 1.1rem;
}
.icon-view:before {
content: '4';
.icon-spinner:after,
.icon-spinner:before {
width: 1em;
animation: spin 0.5s infinite linear;
display: inline-block;
// content: '1';
}
.icon-no-view:before {
content: '^';
.icon-horizontalrule:before {
font-family: Open Sans, Arial, sans-serif;
}
.icon-collapse-down:before {
content: '5';
}
.icon-collapse-up:before {
content: '6';
}
.icon-date:before {
content: '7';
}
.icon-time:before {
content: '8';
}
.icon-success:before {
content: '9';
}
.icon-help:before {
content: '?';
}
.icon-warning:before {
content: '!';
}
.icon-form:before {
content: '$';
}
.icon-site:before {
content: '@';
}
.icon-placeholder:before {
content: ' {';
}
.icon-pilcrow:before {
content: '\e600';
}
.icon-title:before {
content: '\f034';
}
.icon-code:before {
content: '\e601';
}
.icon-openquote:before {
content: '';
}
.icon-larger:before {
font-size: 1.5em;
@ -366,11 +97,11 @@
}
@keyframes spin {
from {
0% {
transform: rotate(0deg);
}
to {
100% {
transform: rotate(360deg);
}
}

View file

@ -44,6 +44,14 @@ body {
}
}
.visuallyvisible {
@include visuallyvisible;
}
.visuallyhidden {
@include visuallyhidden;
}
.capabilitymessage {
display: block;
background-color: $color-red;

View file

@ -1,124 +1,199 @@
@import 'wagtailadmin/scss/variables';
@import 'wagtailadmin/scss/mixins';
@import 'wagtailadmin/scss/components/icons';
@import 'wagtailadmin/scss/fonts';
@import 'wagtailadmin/scss/font-icons';
@import 'wagtailadmin/scss/variables-icons';
// =============================================================================
// Variables
// =============================================================================
$size-home-button: 3.5em;
$position: 2rem;
$width-arrow: .6em;
$box-shadow-props: 0 0 1px 0 rgba(107, 214, 230, 1);
$max-items: 12;
$userbar-radius: 6px;
.wagtail-userbar {
position: fixed;
z-index: 9999;
bottom: 2em;
right: 2em;
// Classnames will start with this parameter, eg .wagtail-
$namespace: 'wagtail';
// Possible positions for the userbar to exist in. These are set through the
// {% wagtailuserbar 'bottom-left' %} template tag.
$positions: (
'top-left': (
'vertical': 'top',
'horizontal': 'left',
'arrow': 'bottom'
),
'top-right': (
'vertical': 'top',
'horizontal': 'right',
'arrow': 'bottom'
),
'bottom-left': (
'vertical': 'bottom',
'horizontal': 'left',
'arrow': 'top'
),
'bottom-right': (
'vertical': 'bottom',
'horizontal': 'right',
'arrow': 'top'
)
);
// =============================================================================
// Fonts
// =============================================================================
@include webfont(Open Sans, opensans-regular, 400, normal);
// =============================================================================
// Namespaced icon component
// =============================================================================
// TODO: refactor into a mixin
.#{$namespace}-icon:before {
@include icon();
}
.wagtail-userbar-trigger {
// =============================================================================
// Icons
// =============================================================================
@each $icon, $content in $icons {
.#{$namespace}-icon-#{$icon}:before {
content: quote(#{$content});
}
}
@each $icon, $content in $icons-after {
.#{$namespace}-icon-#{$icon}:after {
content: #{$content};
}
}
// =============================================================================
// Wagtail userbar proper
// =============================================================================
.#{$namespace}-userbar-reset {
all: initial;
}
.#{$namespace}-userbar {
position: fixed;
z-index: 9999;
font-size: initial;
line-height: initial;
margin: 0;
padding: 0;
display: block;
border: 0;
width: auto;
height: auto;
}
.#{$namespace}-userbar-trigger {
width: $size-home-button;
height: $size-home-button;
overflow: hidden;
background-color: $color-white;
border-radius: 50%;
color: $color-black;
padding: 0;
cursor: pointer;
box-shadow: 0 0 1px 0 rgba(107, 214, 230, 1), 0 1px 10px 0 rgba(107, 214, 230, .7);
box-shadow: $box-shadow-props, 0 1px 10px 0 rgba(107, 214, 230, .7);
transition: all 0.2s ease-in-out;
.wagtail-userbar.touch.is-active &,
.no-touch &:hover {
box-shadow: 0 0 1px 0 rgba(107, 214, 230, 1), 0 3px 15px 0 rgba(107, 214, 230, .95);
.#{$namespace}-userbar.touch.is-active &,
.#{$namespace}-userbar.no-touch &:hover {
box-shadow: $box-shadow-props, 0 3px 15px 0 rgba(107, 214, 230, .95);
}
&.icon:before {
@include transition(color .2s ease);
font-size: 35px;
margin: .25em .15em .2em .175em;
&.#{$namespace}-icon:before {
transition: color .2s ease;
font-size: 32px;
margin: .4em .15em .4em .375em;
display: block;
}
}
.wagtail-userbar-nav {
$width-arrow: .6em;
.#{$namespace}-userbar-items {
list-style: none;
position: absolute;
margin: 0;
min-width: 210px;
visibility: hidden;
font-family: 'Open Sans', sans-serif;
font-size: 14px;
box-sizing: border-box;
padding-left: 0;
ul {
list-style: none;
position: absolute;
bottom: 100%;
right: 0;
margin: 0;
padding-bottom: $width-arrow * 2;
min-width: 17em;
visibility: hidden;
.wagtail-userbar.is-active & {
visibility: visible;
}
.#{$namespace}-userbar.is-active & {
visibility: visible;
}
}
// bottom array
ul:after {
content: '';
position: absolute;
bottom: $width-arrow + .1em;
right: $size-home-button / 2 - $width-arrow / 2;
width: 0;
height: 0;
border-left: $width-arrow solid transparent;
border-right: $width-arrow solid transparent;
border-top: $width-arrow solid $color-grey-1;
// Arrow
.#{$namespace}-userbar-items:after {
content: '';
position: absolute;
width: 0;
height: 0;
opacity: 0;
border: solid $width-arrow transparent;
transition-duration: .15s;
transition-timing-function: cubic-bezier(.55, 0, .1, 1);
opacity: 0;
transform: translateY(-$width-arrow);
transition-duration: .15s;
transition-timing-function: cubic-bezier(.55, 0, .1, 1);
.wagtail-userbar.is-active & {
opacity: 1;
transform: translateY(0);
transition-delay: .3s;
}
.#{$namespace}-userbar.is-active & {
opacity: 1;
transform: translateY(0);
transition-delay: .3s;
}
}
.#{$namespace}-userbar-nav {
background: transparent !important;
padding: 0;
margin: 0;
li {
background-color: $color-grey-1;
transform: translateY(1em);
opacity: 0;
transition-duration: .125s;
transition-timing-function: cubic-bezier(.55, 0, .1, 1);
&:first-child {
border-top-left-radius: .5em;
border-top-right-radius: .5em;
border-top-left-radius: $userbar-radius;
border-top-right-radius: $userbar-radius;
}
&:last-child {
border-bottom-right-radius: .5em;
border-bottom-left-radius: .5em;
border-bottom-right-radius: $userbar-radius;
border-bottom-left-radius: $userbar-radius;
}
+ li {
border-top: 1px solid darken($color-grey-1, 3%);
}
.wagtail-userbar.is-active & {
transform: translateY(0);
opacity: 1;
@for $i from 1 through 10 {
&:nth-last-child(#{$i}) {
transition-delay: .05s * $i;
}
}
}
}
.#{$namespace}-action {
background: transparent;
}
li a,
li .action {
li .#{$namespace}-action {
color: #aaa;
display: block;
text-decoration: none;
@ -131,29 +206,106 @@ $size-home-button: 3.5em;
}
}
li .icon {
li .#{$namespace}-icon {
position: relative;
&:before {
position: absolute;
top: 50%;
transform: translateY(-50%);
left: 1.5em;
left: 14px;
}
}
li a,
li input {
font-size: 0.95em;
font-weight: 300;
font-size: 14px;
text-align: left;
padding: 0.8em 1.7em 0.8em 3.5em;
padding: 0.8rem 1.7rem 0.8rem 3.5rem;
}
li input {
// -webkit-appearance: none;
// appearance: none;
// margin: 0;
border: 0;
background: none;
width: 100%;
}
}
// =============================================================================
// Userbar positional classes (tl, tr, bl, br)
// =============================================================================
@each $pos, $attrs in $positions {
$vertical: map-get($attrs, vertical);
$horizontal: map-get($attrs, horizontal);
$arrow: map-get($attrs, arrow);
.#{$namespace}-userbar--#{$pos} {
#{$vertical}: $position;
#{$horizontal}: $position;
.#{$namespace}-userbar-items {
#{$vertical}: 100%;
#{$horizontal}: 0;
padding-#{$vertical}: $width-arrow * 2;
}
.#{$namespace}-userbar-nav li {
// Yes, we could use an @else, but there's a bug in scss-lint.
@if $vertical == 'bottom' {
transform: translateY(1rem);
}
@if $vertical == 'top' {
transform: translateY(-1rem);
}
}
.#{$namespace}-userbar-items:after {
#{$vertical}: 2px;
#{$horizontal}: $size-home-button / 2 - $width-arrow / 2;
border-#{$arrow}-color: $color-grey-1;
@if $vertical == 'bottom' {
transform: translateY(-$width-arrow);
}
@if $vertical == 'top' {
transform: translateY($width-arrow);
}
}
&.is-active li {
@for $i from 1 through $max-items {
@if $vertical == 'bottom' {
$prop: 'nth-last-child';
}
@if $vertical == 'top' {
$prop: 'nth-child';
}
&:#{unquote($prop)}(#{$i}) {
transition-delay: .05s * $i;
}
}
}
}
}
// =============================================================================
// States
// =============================================================================
// Active state for the list items comes last.
.#{$namespace}-userbar.is-active li {
transform: translateY(0);
opacity: 1;
}

View file

@ -1,15 +1,17 @@
{% load staticfiles i18n %}
<!-- Wagtail user bar embed code -->
<div class="wagtail-userbar" data-wagtail-userbar>
<link rel="stylesheet" href="{% static 'wagtailadmin/css/userbar.css' %}" type="text/css" />
<div class="wagtail-userbar-nav">
<div class="icon icon-wagtail wagtail-userbar-trigger" data-wagtail-userbar-trigger>{% trans 'Go to Wagtail admin interface' %}</div>
<ul>
{% for item in items %}
{{ item|safe }}
{% endfor %}
</ul>
<div class="wagtail-userbar-reset">
<div class="wagtail-userbar wagtail-userbar--{{ position|default:'bottom-right' }}" data-wagtail-userbar>
<link rel="stylesheet" href="{% static 'wagtailadmin/css/userbar.css' %}" type="text/css" />
<div class="wagtail-userbar-nav">
<div class="wagtail-icon wagtail-icon-wagtail wagtail-userbar-trigger" data-wagtail-userbar-trigger>{% trans 'Go to Wagtail admin interface' %}</div>
<ul class='wagtail-userbar-items'>
{% for item in items %}
{{ item|safe }}
{% endfor %}
</ul>
</div>
<script src="{% static 'wagtailadmin/js/userbar.js' %}"></script>
</div>
<script src="{% static 'wagtailadmin/js/userbar.js' %}"></script>
</div>
<!-- end Wagtail user bar embed code -->

View file

@ -2,7 +2,7 @@
{% load i18n %}
{% block item_content %}
<div class="action icon icon-wagtail">
<a href="{% url 'wagtailadmin_home' %}" target="_parent" class="">{% trans 'Go to Wagtail admin' %}</a>
</div>
<div class="wagtail-action wagtail-icon wagtail-icon-wagtail">
<a href="{% url 'wagtailadmin_home' %}" target="_parent" class="">{% trans 'Go to Wagtail admin' %}</a>
</div>
{% endblock %}

View file

@ -2,7 +2,7 @@
{% load i18n %}
{% block item_content %}
<div class="action icon icon-plus">
<a href="{% url 'wagtailadmin_pages:add_subpage' self.page.id %}" target="_parent">{% trans 'Add a child page' %}</a>
</div>
<div class="wagtail-action wagtail-icon wagtail-icon-plus">
<a href="{% url 'wagtailadmin_pages:add_subpage' self.page.id %}" target="_parent">{% trans 'Add a child page' %}</a>
</div>
{% endblock %}

View file

@ -4,7 +4,7 @@
{% block item_content %}
<form action="{% url 'wagtailadmin_pages:approve_moderation' self.revision.id %}" target="_parent" method="post">
{% csrf_token %}
<div class="action icon icon-tick">
<div class="wagtail-action wagtail-icon wagtail-icon-tick">
<input type="submit" value="{% trans 'Approve' %}" />
</div>
</form>

View file

@ -2,7 +2,7 @@
{% load i18n %}
{% block item_content %}
<div class="action icon icon-edit">
<div class="wagtail-action wagtail-icon wagtail-icon-edit">
<a href="{% url 'wagtailadmin_pages:edit' self.page.id %}" target="_parent">{% trans 'Edit this page' %}</a>
</div>
{% endblock %}

View file

@ -2,7 +2,7 @@
{% load i18n %}
{% block item_content %}
<div class="action icon icon-folder-open-inverse">
<div class="wagtail-action wagtail-icon wagtail-icon-folder-open-inverse">
<a href="{% url 'wagtailadmin_explore' self.parent_page.id %}" target="_parent">{% trans 'Show in Explorer' %}</a>
</div>
{% endblock %}

View file

@ -4,7 +4,7 @@
{% block item_content %}
<form action="{% url 'wagtailadmin_pages:reject_moderation' self.revision.id %}" target="_parent" method="post">
{% csrf_token %}
<div class="action icon icon-cross">
<div class="wagtail-action wagtail-icon wagtail-icon-cross">
<input type="submit" value="{% trans 'Reject' %}" />
</div>
</form>

View file

@ -26,10 +26,11 @@ def get_page_instance(context):
@register.simple_tag(takes_context=True)
def wagtailuserbar(context):
def wagtailuserbar(context, position='bottom-right'):
# Find request object
request = context['request']
# Don't render if user doesn't have permission to access the admin area
if not request.user.has_perm('wagtailadmin.access_admin'):
return ''
@ -78,6 +79,7 @@ def wagtailuserbar(context):
return render_to_string('wagtailadmin/userbar/base.html', {
'request': request,
'items': rendered_items,
'position': position,
'page': page,
'revision_id': revision_id
})