Merge branch 'release/1.5.2'

This commit is contained in:
Andy Miller
2017-08-16 11:03:11 -06:00
29 changed files with 7321 additions and 66 deletions

View File

@@ -1,3 +1,21 @@
# v1.5.2
## 08/16/2017
1. [](#new)
* Added a new icon quick-tray in side navigation that plugins can utilize
* Added ability to set and retrieve temporary admin messages
1. [](#improved)
* Allow different field to be used as page label in list of pages [#1122](https://github.com/getgrav/grav-plugin-admin/pull/1122)
* Updated `en` language for `cache-control` + `clear_images_by_default` system settings
* Allow sorting of page based on custom ordering [#1182](https://github.com/getgrav/grav-plugin-admin/pull/1182)
* Search for pages by slug and folder name [#1183](https://github.com/getgrav/grav-plugin-admin/pull/1183)
* Allow all page data to be used during `onAdminCreatePageFrontmatter()` event [#1175](https://github.com/getgrav/grav-plugin-admin/pull/1175)
* Remove single quotes when slugifying title [#1178](https://github.com/getgrav/grav-plugin-admin/pull/1178)
1. [](#bugfix)
* Ignore missing Twig files [#1169](https://github.com/getgrav/grav-plugin-admin/issues/1169)
* If from is already defined, don't override it [#1129](https://github.com/getgrav/grav-plugin-admin/issues/1129)
* Fixed SelectUnique field not working with files with spaces
# v1.5.1
## 07/19/2017

View File

@@ -1,6 +1,7 @@
<?php
namespace Grav\Plugin;
use Grav\Common\Data;
use Grav\Common\File\CompiledYamlFile;
use Grav\Common\Grav;
use Grav\Common\Inflector;
@@ -210,9 +211,7 @@ class AdminPlugin extends Plugin
$action = $event['action'];
switch ($action) {
case 'register_admin_user':
if (!$this->config->get('plugins.login.enabled')) {
throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.PLUGIN_LOGIN_DISABLED'));
}
@@ -290,7 +289,6 @@ class AdminPlugin extends Plugin
{
// Only activate admin if we're inside the admin path.
if ($this->active) {
// Store this version and prefer newer method
if (method_exists($this, 'getBlueprint')) {
$this->version = $this->getBlueprint()->version;
@@ -475,7 +473,6 @@ class AdminPlugin extends Plugin
$twig_paths[] = __DIR__ . '/themes/' . $this->theme . '/templates';
$this->grav['twig']->twig_paths = $twig_paths;
}
/**
@@ -498,11 +495,23 @@ class AdminPlugin extends Plugin
$twig->twig_vars['admin'] = $this->admin;
$twig->twig_vars['admin_version'] = $this->version;
$fa_icons_file = CompiledYamlFile::instance($this->grav['locator']->findResource('plugin://admin/themes/grav/templates/forms/fields/iconpicker/icons' . YAML_EXT, true, true));
$fa_icons = $fa_icons_file->content();
$fa_icons = array_map(function ($icon) {
//only pick used values
return ['id' => $icon['id'], 'unicode' => $icon['unicode']];
}, $fa_icons['icons']);
$twig->twig_vars['fa_icons'] = $fa_icons;
// add form if it exists in the page
$header = $page->header();
if (isset($header->form)) {
// preserve form validation
if (!isset($twig->twig_vars['form'])) {
$twig->twig_vars['form'] = new Form($page);
}
}
// Gather Plugin-hooked nav items
$this->grav->fireEvent('onAdminMenu');
@@ -872,5 +881,4 @@ class AdminPlugin extends Plugin
return $types;
}
}

View File

@@ -26,6 +26,7 @@ warnings:
edit_mode: normal
frontend_pages_target: _blank
show_github_msg: true
pages_list_display_field: title
google_fonts: true
enable_auto_updates_check: true
notifications:

View File

@@ -1,5 +1,5 @@
name: Admin Panel
version: 1.5.1
version: 1.5.2
description: Adds an advanced administration panel to manage your site
icon: empire
author:
@@ -172,6 +172,12 @@ form:
type: bool
help: Show the "Found an issue? Please report it on GitHub." message.
pages_list_display_field:
type: text
size: small
label: Pages List Display Field
help: "Field of the page to use in the list of pages if present. Defaults/Fallback to title."
enable_auto_updates_check:
type: toggle
label: Automatically check for updates

View File

@@ -107,6 +107,11 @@ class Admin
*/
protected $loading_additional_files_in_background = false;
/**
* @var array
*/
protected $temp_messages = [];
/**
* Constructor.
*
@@ -402,6 +407,16 @@ class Admin
$messages->add($msg, $type);
}
public function addTempMessage($msg, $type)
{
$this->temp_messages[] = ['message' => $msg, 'scope' => $type];
}
public function getTempMessages()
{
return $this->temp_messages;
}
/**
* Translate a string to the user-defined language
*
@@ -1393,7 +1408,8 @@ class Admin
$page->name($name . '.md');
// Fire new event to allow plugins to manipulate page frontmatter
$this->grav->fireEvent('onAdminCreatePageFrontmatter', new Event(['header' => &$header]));
$this->grav->fireEvent('onAdminCreatePageFrontmatter', new Event(['header' => &$header,
'data' => $data]));
$page->header($header);
$page->frontmatter(Yaml::dump((array)$page->header(), 10, 2, false));

View File

@@ -396,7 +396,7 @@ class AdminBaseController
*
* @return bool True if authorized. False if not.
*/
protected function authorizeTask($task = '', $permissions = [])
public function authorizeTask($task = '', $permissions = [])
{
if (!$this->admin->authorize($permissions)) {
if ($this->grav['uri']->extension() === 'json') {

View File

@@ -1479,6 +1479,7 @@ class AdminController extends AdminBaseController
foreach ($queries as $query) {
$query = trim($query);
if (stripos($page->getRawContent(), $query) === false && stripos($page->title(),
$query) === false && stripos($page->slug(), \Grav\Plugin\Admin\Utils::slug($query)) === false && stripos($page->folder(),
$query) === false
) {
$collection->remove($page);

View File

@@ -323,6 +323,8 @@ PLUGIN_ADMIN:
HTTP_HEADERS: "HTTP Headers"
EXPIRES: "Expires"
EXPIRES_HELP: "Sets the expires header. The value is in seconds."
CACHE_CONTROL: "HTTP Cache-Control"
CACHE_CONTROL_HELP: "Set to a valid cache-control value such as `no-cache, no-store, must-revalidate`"
LAST_MODIFIED: "Last modified"
LAST_MODIFIED_HELP: "Sets the last modified header that can help optimize proxy and browser caching"
ETAG: "ETag"
@@ -640,6 +642,8 @@ PLUGIN_ADMIN:
ALLOW_WEBSERVER_GZIP: "Allow WebServer Gzip"
ALLOW_WEBSERVER_GZIP_HELP: "Off by default. When enabled, WebServer-configured Gzip/Deflate compression will work, but http connection will not be closed before onShutDown() event causing slower page loading"
OFFLINE_WARNING: "The connection to the GPM cannot be established"
CLEAR_IMAGES_BY_DEFAULT: "Clear image cache by default"
CLEAR_IMAGES_BY_DEFAULT_HELP: "By default processed images are cleared for all cache clears, this can be disabled"
CLI_COMPATIBILITY: "CLI Compatibility"
CLI_COMPATIBILITY_HELP: "Ensures that only non-volatile Cache drivers are used (file, redis, memcache, etc.)"
REINSTALL_PLUGIN: "Reinstall Plugin"

View File

@@ -0,0 +1,288 @@
import $ from 'jquery';
/* Icon Picker by QueryLoop
* Author: @eliorivero
* URL: http://queryloop.com/
* License: GPLv2
*/
var defaults = {
'mode': 'dialog', // show overlay 'dialog' panel or slide down 'inline' panel
'closeOnPick': true, // whether to close panel after picking or 'no'
'save': 'class', // save icon 'class' or 'code'
'size': '',
'classes': {
'launcher': '', // extra classes for launcher buttons
'clear': 'remove-times', // extra classes for button that removes preview and clears field
'highlight': '', // extra classes when highlighting an icon
'close': '' // extra classes for close button
},
'iconSets': { // example data structure. Used to specify which launchers will be created
'genericon': 'Genericon', // create a launcher to pick genericon icons
'fa': 'FontAwesome' // create a launcher to pick fontawesome icons
}
};
class QL_Icon_Picker {
constructor(element, options) {
this.iconSet = '';
this.iconSetName = '';
this.$field = '';
this.element = element;
this.settings = $.extend({}, defaults, options);
this._defaults = defaults;
this.init();
}
init() {
var $brick = $(this.element);
var pickerId = $brick.data('pickerid');
var $preview = $('<div class="icon-preview icon-preview-' + pickerId + '" />');
this.$field = $brick.find('input');
// Add preview area
this.makePreview($brick, pickerId, $preview);
// Make button to clear field and remove preview
this.makeClear(pickerId, $preview);
// Make buttons that open the panel of icons
this.makeLaunchers($brick, pickerId);
// Prepare display styles, inline and dialog
this.makeDisplay($brick);
}
makePreview($brick, pickerId, $preview) {
var $icon = $('<i />');
var iconValue = this.$field.val();
$preview.prependTo($brick);
$icon.prependTo($preview);
if (iconValue !== '') {
$preview.addClass('icon-preview-on');
$icon.addClass(iconValue);
}
}
makeClear(pickerId, $preview) {
var base = this;
var $clear = $('<a class="remove-icon ' + base.settings.classes.clear + '" />');
// Hide button to remove icon and preview and append it to preview area
$clear.hide().prependTo($preview);
// If there's a icon saved in the field, show remove icon button
if (base.$field.val() !== '') {
$clear.show();
}
$preview.on('click', '.remove-icon', function(e) {
e.preventDefault();
base.$field.val('');
$preview.removeClass('icon-preview-on').find('i').removeClass();
$(this).hide();
});
}
makeDisplay($brick) {
var base = this;
var close = base.settings.classes.close;
var $body = $('body');
var $close = $('<a href="#" class="icon-picker-close"/>');
if (base.settings.mode === 'inline') {
$brick.find('.icon-set').append($close).removeClass('dialog').addClass('inline ' + base.settings.size).parent().addClass('icon-set-wrap');
} else if (base.settings.mode === 'dialog') {
$('.icon-set').addClass('dialog ' + base.settings.size);
if ($('.icon-picker-overlay').length <= 0) {
$body.append('<div class="icon-picker-overlay"/>').append($close);
}
}
$body
.on('click', '.icon-picker-close, .icon-picker-overlay', function(e) {
e.preventDefault();
base.closePicker($brick, $(base.iconSet), base.settings.mode);
})
.on('mouseenter mouseleave', '.icon-picker-close', function(e) {
if (e.type === 'mouseenter') {
$(this).addClass(close);
} else {
$(this).removeClass(close);
}
});
}
makeLaunchers($brick) {
var base = this;
var dataIconSets = $brick.data('iconsets');
var iconSet;
if (typeof dataIconSets === 'undefined') {
dataIconSets = base.settings.iconSets;
}
for (iconSet in dataIconSets) {
if (dataIconSets.hasOwnProperty(iconSet)) {
$brick.append('<a class="launch-icons button ' + base.settings.classes.launcher + '" data-icons="' + iconSet + '">' + dataIconSets[iconSet] + '</a>');
}
}
$brick.find('.launch-icons').on('click', function(e) {
e.preventDefault();
var $self = $(this);
var theseIcons = $self.data('icons');
base.iconSetName = theseIcons;
base.iconSet = '.' + theseIcons + '-set';
// Initialize picker
base.iconPick($brick);
// Show icon picker
base.showPicker($brick, $(base.iconSet), base.settings.mode);
});
}
iconPick($brick) {
var base = this;
var highlight = 'icon-highlight ' + base.settings.classes.highlight;
$(base.iconSet).on('click', 'li', function(e) {
e.preventDefault();
var $icon = $(this);
var icon = $icon.data(base.settings.save);
// Mark as selected
$('.icon-selected').removeClass('icon-selected');
$icon.addClass('icon-selected');
if (base.$field.data('format') === 'short') {
icon = icon.slice(6);
}
// Save icon value to field
base.$field.val(icon);
// Close icon picker
if (base.settings.closeOnPick) {
base.closePicker($brick, $icon.closest(base.iconSet), base.settings.mode);
}
// Set preview
base.setPreview($icon.data('class'));
// Broadcast event passing the selected icon.
$('body').trigger('iconselected.queryloop', icon);
});
$(base.iconSet).on('mouseenter mouseleave', 'li', function(e) {
if (e.type === 'mouseenter') {
$(this).addClass(highlight);
} else {
$(this).removeClass(highlight);
}
});
}
showPicker($brick, $icons, mode) {
if (mode === 'inline') {
$('.icon-set').removeClass('inline-open');
$brick.find($icons).toggleClass('inline-open');
} else if (mode === 'dialog') {
$brick.find('.icon-picker-close').addClass('make-visible');
$brick.find('.icon-picker-overlay').addClass('make-visible');
$icons.addClass('dialog-open');
}
$icons.find('.icon-selected').removeClass('icon-selected');
var selectedIcon = this.$field.val().replace(' ', '.');
if (selectedIcon !== '') {
if (this.settings.save === 'class') {
$icons.find('.' + selectedIcon).addClass('icon-selected');
} else {
$icons.find('[data-code="' + selectedIcon + '"]').addClass('icon-selected');
}
}
// Broadcast event when the picker is shown passing the picker mode.
$('body').trigger('iconpickershow.queryloop', mode);
}
closePicker($brick, $icons, mode) {
// Remove event so they don't fire from a different picker
$(this.iconSet).off('click', 'li');
if (mode === 'inline') {
$brick.find($icons).removeClass('inline-open');
} else if (mode === 'dialog') {
$('.icon-picker-close, .icon-picker-overlay').removeClass('make-visible');
}
// Broadcast event when the picker is closed passing the picker mode.
$('body').trigger('iconpickerclose.queryloop', mode);
$('.icon-set').removeClass('dialog-open');
}
setPreview(preview) {
var $preview = $(this.element).find('.icon-preview');
$preview.addClass('icon-preview-on').find('i').removeClass()
.addClass(this.iconSetName)
.addClass(preview);
$preview.find('a').show();
}
};
export default class IconpickerField {
constructor(options) {
this.items = $();
this.options = Object.assign({}, this.defaults, options);
$('[data-grav-iconpicker]').each((index, element) => this.addItem(element));
$('body').on('mutation._grav', this._onAddedNodes.bind(this));
}
_onAddedNodes(event, target/* , record, instance */) {
let fields = $(target).find('[data-grav-iconpicker]');
if (!fields.length) { return; }
fields.each((index, field) => {
field = $(field);
if (!~this.items.index(field)) {
this.addItem(field);
}
});
}
addItem(element) {
element = $(element);
this.items = this.items.add(element);
$.fn.qlIconPicker = function(options) {
this.each(function() {
if (!$.data(this, 'plugin_qlIconPicker')) {
$.data(this, 'plugin_qlIconPicker', new QL_Icon_Picker(this, options));
}
});
return this;
};
$('.icon-picker').qlIconPicker({
'save': 'class'
});
}
}
export let Instance = new IconpickerField();
$.fn.qlIconPicker = function(options) {
this.each(function() {
if (!$.data(this, 'plugin_qlIconPicker')) {
$.data(this, 'plugin_qlIconPicker', new QL_Icon_Picker(this, options));
}
});
return this;
};
$('.icon-picker').qlIconPicker({
'save': 'class'
});

View File

@@ -9,6 +9,7 @@ import FilesField, { Instance as FilesFieldInstance } from './files';
import MediapickerField, { Instance as MediapickerInstance } from './mediapicker';
import MultilevelField, { Instance as MultilevelInstance } from './multilevel';
import SelectUniqueField, { Instance as SelectUniqueInstance } from './selectunique';
import IconpickerField, { Instance as IconpickerInstance } from './iconpicker';
export default {
FilepickerField: {
@@ -54,6 +55,10 @@ export default {
MultilevelField: {
MultilevelField,
Instance: MultilevelInstance
},
IconpickerField: {
IconpickerField,
Instance: IconpickerInstance
}
};

View File

@@ -9,6 +9,8 @@ import Scrollbar, { Instance as contentScrollbar } from './utils/scrollbar';
import './plugins';
import './themes';
import { Filter as MediaFilter, Instance as MediaFilterInstance} from './media';
import toastr from './utils/toastr';
import request from './utils/request';
// bootstrap jQuery extensions
import 'bootstrap/js/transition';
@@ -70,5 +72,6 @@ export default {
MediaFilter: {
MediaFilter,
Instance: MediaFilterInstance
}
},
Utils: { request, toastr }
};

View File

@@ -20,7 +20,7 @@ title.on('input focus blur', (event) => {
if (custom) { return true; }
let elements = getFields('title', event.currentTarget);
let slug = $.slugify(elements.title.val());
let slug = $.slugify(elements.title.val(), {custom: {"'": ''}});
elements.folder.val(slug);
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

221
themes/grav/css/iconpicker.css Executable file
View File

@@ -0,0 +1,221 @@
/* Icon Picker by QueryLoop
* Author: @eliorivero
* URL: http://queryloop.com/
* License: GPLv2
*/
.icon-set {
display: none;
background: #fff;
overflow-y: auto;
-webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.15);
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.15);
}
.icon-set ul {
list-style: none;
padding: 0;
margin: 0;
}
.icon-set li {
display: inline-block;
cursor: pointer;
padding: 8px;
margin: 0 0 5px;
width: 48px;
height: 48px;
font-size: 24px;
text-align: center;
}
.icon-set li:hover:before, .icon-set .icon-selected:before {
font-size: 32px;
position: relative;
top: 5px;
line-height: 1px;
width: 32px;
display: inline-block;
}
.icon-set.large li {
width: 32px;
height: 32px;
font-size: 32px;
}
.icon-set.large li:hover:before, .icon-set.large .icon-selected:before {
font-size: 48px;
width: 48px;
line-height: 24px;
}
.icon-highlight {
background: #00a6cf;
color: #fff;
}
.dialog {
display: block;
margin: 20px 0 0;
position: fixed;
right: 30%;
bottom: 30%;
width: 40%;
height: 40%;
max-height: 315px;
z-index: 19998;
visibility:hidden;
opacity: 0;
-webkit-box-shadow: 0 2px 4px rgba(0,0,0,0.25);
box-shadow: 0 2px 4px rgba(0,0,0,0.25);
-webkit-transform: scale(0.7) translateZ(0);
-ms-transform: scale(0.7) translateZ(0);
transform: scale(0.7) translateZ(0);
-webkit-transition: all 0.2s;
transition: all 0.2s;
}
.dialog-open {
padding: 10px;
visibility:visible;
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
opacity: 1;
}
.icon-set-wrap {
position: relative;
}
.inline {
display: block;
width: 276px;
height: 0;
opacity: 0;
visibility:hidden;
-webkit-transform: scaleX(0.5) rotateX(90deg);
-ms-transform: scaleX(0.5) rotateX(90deg);
transform: scaleX(0.5) rotateX(90deg);
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transform-origin: 50% 0;
transform-origin: 50% 0;
-webkit-transition: transform 0.3s ease-out;
transition: transform 0.3s ease-out;
}
.inline-open {
padding: 10px;
border: 1px solid #eee;
height: auto;
visibility:visible;
-webkit-transform: scaleX(1) rotateY(0deg);
-ms-transform: scaleX(1) rotateY(0deg);
transform: scaleX(1) rotateY(0deg);
opacity: 1;
}
.dialog, .icon-picker-close {
top: 30%;
left: 30%;
}
.icon-picker-close {
opacity: 0;
visibility: hidden;
display: block;
width: 20px;
height: 20px;
color: #fff;
background: #333;
font-size: 19px;
margin: 30px 0 0 20px;
position: fixed;
z-index: 19999;
-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.25);
box-shadow: 0 1px 3px rgba(0,0,0,0.25);
-webkit-transition: all 0.2s;
transition: all 0.2s;
}
.icon-picker-close:after {
content: "\00D7";
width: 20px;
display: block;
position: absolute;
text-align: center;
}
.icon-picker-overlay {
opacity: 0;
visibility: hidden;
background: #222;
background: rgba(0, 0, 0, 0.5);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 19997;
-webkit-transition: all 0.2s;
transition: all 0.2s;
}
.icon-picker-close.make-visible {
margin: 10px 0 0 -10px;
}
.inline .icon-picker-close {
position: absolute;
z-index: 8;
top: 0;
right: 0;
left: auto;
opacity: 1;
visibility: visible;
margin: 0;
}
.make-visible {
visibility: visible;
opacity: 1;
}
.icon-selected {
background: #349886;
color: #fff;
}
.icon-preview {
display: none;
margin: 10px 0;
position: relative;
}
.icon-preview-on {
display: inline-block;
}
.icon-preview i {
width: 48px;
height: 48px;
text-align: center;
border: 1px solid #d5d5d5;
border-radius: 3px;
background: #fff;
}
.icon-preview i:before {
font-size: 32px;
line-height: 48px;
}
.remove-icon {
background-color: #00a6cf;
color: #fff !important;
border-radius: 3px;
transition: background .2s ease-out;
position: absolute;
top: -10px;
right: -10px;
}
.remove-icon:hover {
color: #fff !important;
background-color: #00a6cf;
cursor: pointer;
}
.remove-times {
width: 20px;
height: 20px;
font-size: 21px;
text-align: center;
line-height: 99%;
}
.remove-times:after {
content: "\00D7";
}
.launch-icons {
margin: 5px 3px 0 0;
}
.launch-icons:active {
margin: 5px 3px 0 0;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -345,6 +345,20 @@ tr {
}
}
#admin-nav-quick-tray {
background: $logo-bg;
border-bottom: 1px solid lighten($nav-bg, 5%);
color: $nav-link;
i:hover {
@if (lightness($nav-bg) < 50) {
color: lighten($nav-link, 10%);
} @else {
color: darken($nav-link, 10%);
}
}
}
.block-userinfo {
img {
border: 4px solid $form-border;

View File

@@ -380,6 +380,25 @@ $sidebar-padding: 2rem;
}
}
#admin-nav-quick-tray {
margin: 0;
list-style: none;
padding: 3px 10px 5px 25px;
li {
cursor: pointer;
width: 24px;
}
i {
transition: all .2s ease-in-out;
&:hover {
transform: scale(1.2);
}
}
}
.content-padding {
#messages.default-box-shadow {
margin-bottom: 2.5rem;

View File

@@ -0,0 +1,45 @@
{% extends "forms/field.html.twig" %}
{% set originalValue = originalValue is defined ? originalValue : value %}
{% set value = (value is null ? field.default : value) %}
{% block global_attributes %}
data-grav-iconpicker
data-name="{{field.name}}"
data-value="{{value}}"
{{ parent() }}
{% endblock %}
{% block input %}
<div class="form-list-wrapper {{ field.size }}" data-type="collection">
<div class="icon-picker" data-pickerid="fa" data-iconsets='{"fa":"FontAwesome Icons"}'>
<input
{# required attribute structures #}
name="{{ (scope ~ field.name)|fieldName }}"
data-format="{{ field.format == 'short' ? 'short' : 'long' }}"
value="{{ value|raw|join(', ') }}"
type="text"
{# input attribute structures #}
{% block input_attributes %}
{% if field.classes is defined %}class="{{ field.classes }}" {% endif %}
{% if field.id is defined %}id="{{ field.id|e }}" {% endif %}
{% if field.style is defined %}style="{{ field.style|e }}" {% endif %}
{% if field.disabled %}disabled="disabled"{% endif %}
{% if field.placeholder %}placeholder="{{ field.placeholder }}"{% endif %}
{% if field.autofocus in ['on', 'true', 1] %}autofocus="autofocus"{% endif %}
{% if field.novalidate in ['on', 'true', 1] %}novalidate="novalidate"{% endif %}
{% if field.readonly in ['on', 'true', 1] %}readonly="readonly"{% endif %}
{% if field.autocomplete in ['on', 'off'] %}autocomplete="{{ field.autocomplete }}"{% endif %}
{% if field.validate.required in ['on', 'true', 1] %}required="required"{% endif %}
{% endblock %}
/>
</div>
<div class="fa-set icon-set">
<ul>
{% for icon in fa_icons %}
<li data-code="{{icon.unicode}}" data-class="fa fa-{{icon.id}}" class="fa fa-{{icon.id}}"></li>
{% endfor %}
</ul>
</div>
</div>
{% endblock %}

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@
{% block input %}
<div class="form-input-wrapper {{ field.size }}">
<select
value="{{ value|e('html_attr')|join(', ') }}"
value="{{ value|raw|join(', ') }}"
name="{{ (scope ~ field.name)|fieldName }}"
data-select-observe
{% block input_attributes %}

View File

@@ -47,6 +47,7 @@
{% macro loop(page, depth, twig_vars) %}
{% set separator = twig_vars['config'].system.param_sep %}
{% set display_field = twig_vars['config'].plugins.admin.pages_list_display_field %}
{% set base_url = twig_vars['base_url_relative'] %}
{% set base_url_simple = twig_vars['base_url_simple'] %}
{% set admin_route = twig_vars['admin_route'] %}
@@ -55,8 +56,11 @@
{% set uri = twig_vars['uri'] %}
{% if page.header.admin.children_display_order == 'collection' and page.header.content.order.by %}
{% if page.header.content.order.custom %}
{% set pcol = page.children().order(page.header.content.order.by, page.header.content.order.dir|default('asc'), page.header.content.order.custom) %}
{% else %}
{% set pcol = page.children().order(page.header.content.order.by, page.header.content.order.dir|default('asc')) %}
{{ dump(pcol) }}
{% endif %}
{% else %}
{% set pcol = page.children() %}
{% endif %}
@@ -84,7 +88,8 @@
<div class="page-item__content">
<div class="page-item__content-name">
<span data-hint="{{ description|trim(' &bull; ')|raw }}" class="hint--top page-item__content-hint">
<a href="{{ page_url }}" class="page-edit">{{ p.title|e }}</a>
{% set page_label = attribute(p.header, display_field)|defined(attribute(p, display_field))|defined(p.title) %}
<a href="{{ page_url }}" class="page-edit">{{ page_label|e }}</a>
</span>
{% if p.language %}
<span class="badge lang {% if p.language == admin_lang %}info{% endif %}">{{p.language}}</span>
@@ -364,7 +369,7 @@
{% include 'partials/page-move.html.twig' with { blueprints: admin.blueprints('admin/pages/move'), data: context } %}
</div>
<div class="remodal" data-remodal-id="revisions" data-remodal-options="hashTracking: false">
{% include ['partials/page-revisions.html.twig', 'empty.html.twig'] with { data: context } %}
{% include ['partials/page-revisions.html.twig', 'empty.html.twig'] ignore missing with { data: context } %}
</div>
{% endif %}

View File

@@ -1,4 +1,5 @@
{% set admin_messages = admin.messages %}
{% set admin_messages = admin.messages|merge(admin.getTempMessages()) %}
{{ dump(admin_messages) }}
{% set form_message = form.message %}
<div id="messages" class="top-notifications-container{{ admin_messages|length or form_message ? ' default-box-shadow' : '' }}">
<div class="single-notification info alert hidden" data-gpm-grav></div>
@@ -8,4 +9,7 @@
{%- if form_message -%}
<div class="error alert">{{ form_message|raw }}</div>
{%- endif -%}
{%- for message in plugin_messages -%}
<div class="{{ message.scope|e }} alert">{{ message.message|raw }}</div>
{%- endfor -%}
</div>

View File

@@ -0,0 +1,23 @@
{% if grav.twig.plugins_quick_tray %}
<ul id="admin-nav-quick-tray">
{% for label, item in grav.twig.plugins_quick_tray %}
{% if authorize((item.authorize is defined and item.authorize is iterable) ? item.authorize : [item.authorize ?: ('admin.' ~ (item.location ?: item.route)), 'admin.super']) %}
{% set data_tags = '' %}
{% if (item.data) %}
{% for key, value in item.data %}
{% set data_tags = data_tags ~ ' data-' ~ key ~ '="' ~ value ~ '"' %}
{% endfor %}
{% endif %}
<li class="{{ item.class }} hint--bottom" data-hint="{{ item.hint }}" {{ data_tags|raw }}>
{% if item.route %}
<a href="{{ url(item.route) }}">
<i class="fa fa-fw {{ item.icon }}"></i>
</a>
{% else %}
<i class="fa fa-fw {{ item.icon }}"></i>
{% endif %}
</li>
{% endif %}
{% endfor %}
</ul>
{% endif %}

View File

@@ -10,6 +10,8 @@
{% include 'partials/nav-user-details.html.twig' %}
{% include 'partials/nav-quick-tray.html.twig' %}
<div class="admin-menu-wrapper">
<ul id="admin-menu">
<li class="{{ (location == 'dashboard') ? 'selected' : '' }}">

View File

@@ -10,6 +10,7 @@
{% do assets.addCss(theme_url~'/css/chartist.min.css') %}
{% do assets.addCss(theme_url~'/css/selectize.min.css') %}
{% do assets.addCss(theme_url~'/css/hint.base.min.css') %}
{% do assets.addCss(theme_url~'/css/iconpicker.css') %}
{% if browser.getBrowser == 'msie' and browser.getVersion >= 8 and browser.getVersion <= 9 %}
{% do assets.addCss(theme_url~'/css/nucleus-ie9.css') %}
{% do assets.addCss(theme_url~'/css/pure-0.5.0/grids-min.css') %}