mirror of
https://github.com/getgrav/grav-plugin-admin.git
synced 2025-11-15 09:46:06 +01:00
Merge branch 'release/1.5.2'
This commit is contained in:
18
CHANGELOG.md
18
CHANGELOG.md
@@ -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
|
# v1.5.1
|
||||||
## 07/19/2017
|
## 07/19/2017
|
||||||
|
|
||||||
|
|||||||
20
admin.php
20
admin.php
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Grav\Plugin;
|
namespace Grav\Plugin;
|
||||||
|
|
||||||
|
use Grav\Common\Data;
|
||||||
use Grav\Common\File\CompiledYamlFile;
|
use Grav\Common\File\CompiledYamlFile;
|
||||||
use Grav\Common\Grav;
|
use Grav\Common\Grav;
|
||||||
use Grav\Common\Inflector;
|
use Grav\Common\Inflector;
|
||||||
@@ -210,9 +211,7 @@ class AdminPlugin extends Plugin
|
|||||||
$action = $event['action'];
|
$action = $event['action'];
|
||||||
|
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
|
|
||||||
case 'register_admin_user':
|
case 'register_admin_user':
|
||||||
|
|
||||||
if (!$this->config->get('plugins.login.enabled')) {
|
if (!$this->config->get('plugins.login.enabled')) {
|
||||||
throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.PLUGIN_LOGIN_DISABLED'));
|
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.
|
// Only activate admin if we're inside the admin path.
|
||||||
if ($this->active) {
|
if ($this->active) {
|
||||||
|
|
||||||
// Store this version and prefer newer method
|
// Store this version and prefer newer method
|
||||||
if (method_exists($this, 'getBlueprint')) {
|
if (method_exists($this, 'getBlueprint')) {
|
||||||
$this->version = $this->getBlueprint()->version;
|
$this->version = $this->getBlueprint()->version;
|
||||||
@@ -475,7 +473,6 @@ class AdminPlugin extends Plugin
|
|||||||
$twig_paths[] = __DIR__ . '/themes/' . $this->theme . '/templates';
|
$twig_paths[] = __DIR__ . '/themes/' . $this->theme . '/templates';
|
||||||
|
|
||||||
$this->grav['twig']->twig_paths = $twig_paths;
|
$this->grav['twig']->twig_paths = $twig_paths;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -498,10 +495,22 @@ class AdminPlugin extends Plugin
|
|||||||
$twig->twig_vars['admin'] = $this->admin;
|
$twig->twig_vars['admin'] = $this->admin;
|
||||||
$twig->twig_vars['admin_version'] = $this->version;
|
$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
|
// add form if it exists in the page
|
||||||
$header = $page->header();
|
$header = $page->header();
|
||||||
if (isset($header->form)) {
|
if (isset($header->form)) {
|
||||||
$twig->twig_vars['form'] = new Form($page);
|
// preserve form validation
|
||||||
|
if (!isset($twig->twig_vars['form'])) {
|
||||||
|
$twig->twig_vars['form'] = new Form($page);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gather Plugin-hooked nav items
|
// Gather Plugin-hooked nav items
|
||||||
@@ -872,5 +881,4 @@ class AdminPlugin extends Plugin
|
|||||||
|
|
||||||
return $types;
|
return $types;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ warnings:
|
|||||||
edit_mode: normal
|
edit_mode: normal
|
||||||
frontend_pages_target: _blank
|
frontend_pages_target: _blank
|
||||||
show_github_msg: true
|
show_github_msg: true
|
||||||
|
pages_list_display_field: title
|
||||||
google_fonts: true
|
google_fonts: true
|
||||||
enable_auto_updates_check: true
|
enable_auto_updates_check: true
|
||||||
notifications:
|
notifications:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: Admin Panel
|
name: Admin Panel
|
||||||
version: 1.5.1
|
version: 1.5.2
|
||||||
description: Adds an advanced administration panel to manage your site
|
description: Adds an advanced administration panel to manage your site
|
||||||
icon: empire
|
icon: empire
|
||||||
author:
|
author:
|
||||||
@@ -172,6 +172,12 @@ form:
|
|||||||
type: bool
|
type: bool
|
||||||
help: Show the "Found an issue? Please report it on GitHub." message.
|
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:
|
enable_auto_updates_check:
|
||||||
type: toggle
|
type: toggle
|
||||||
label: Automatically check for updates
|
label: Automatically check for updates
|
||||||
|
|||||||
@@ -107,6 +107,11 @@ class Admin
|
|||||||
*/
|
*/
|
||||||
protected $loading_additional_files_in_background = false;
|
protected $loading_additional_files_in_background = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $temp_messages = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
@@ -402,6 +407,16 @@ class Admin
|
|||||||
$messages->add($msg, $type);
|
$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
|
* Translate a string to the user-defined language
|
||||||
*
|
*
|
||||||
@@ -1393,7 +1408,8 @@ class Admin
|
|||||||
$page->name($name . '.md');
|
$page->name($name . '.md');
|
||||||
|
|
||||||
// Fire new event to allow plugins to manipulate page frontmatter
|
// 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->header($header);
|
||||||
$page->frontmatter(Yaml::dump((array)$page->header(), 10, 2, false));
|
$page->frontmatter(Yaml::dump((array)$page->header(), 10, 2, false));
|
||||||
|
|||||||
@@ -396,7 +396,7 @@ class AdminBaseController
|
|||||||
*
|
*
|
||||||
* @return bool True if authorized. False if not.
|
* @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->admin->authorize($permissions)) {
|
||||||
if ($this->grav['uri']->extension() === 'json') {
|
if ($this->grav['uri']->extension() === 'json') {
|
||||||
|
|||||||
@@ -1479,6 +1479,7 @@ class AdminController extends AdminBaseController
|
|||||||
foreach ($queries as $query) {
|
foreach ($queries as $query) {
|
||||||
$query = trim($query);
|
$query = trim($query);
|
||||||
if (stripos($page->getRawContent(), $query) === false && stripos($page->title(),
|
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
|
$query) === false
|
||||||
) {
|
) {
|
||||||
$collection->remove($page);
|
$collection->remove($page);
|
||||||
|
|||||||
@@ -323,6 +323,8 @@ PLUGIN_ADMIN:
|
|||||||
HTTP_HEADERS: "HTTP Headers"
|
HTTP_HEADERS: "HTTP Headers"
|
||||||
EXPIRES: "Expires"
|
EXPIRES: "Expires"
|
||||||
EXPIRES_HELP: "Sets the expires header. The value is in seconds."
|
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: "Last modified"
|
||||||
LAST_MODIFIED_HELP: "Sets the last modified header that can help optimize proxy and browser caching"
|
LAST_MODIFIED_HELP: "Sets the last modified header that can help optimize proxy and browser caching"
|
||||||
ETAG: "ETag"
|
ETAG: "ETag"
|
||||||
@@ -640,6 +642,8 @@ PLUGIN_ADMIN:
|
|||||||
ALLOW_WEBSERVER_GZIP: "Allow WebServer Gzip"
|
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"
|
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"
|
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: "CLI Compatibility"
|
||||||
CLI_COMPATIBILITY_HELP: "Ensures that only non-volatile Cache drivers are used (file, redis, memcache, etc.)"
|
CLI_COMPATIBILITY_HELP: "Ensures that only non-volatile Cache drivers are used (file, redis, memcache, etc.)"
|
||||||
REINSTALL_PLUGIN: "Reinstall Plugin"
|
REINSTALL_PLUGIN: "Reinstall Plugin"
|
||||||
|
|||||||
288
themes/grav/app/forms/fields/iconpicker.js
Executable file
288
themes/grav/app/forms/fields/iconpicker.js
Executable 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'
|
||||||
|
});
|
||||||
@@ -9,6 +9,7 @@ import FilesField, { Instance as FilesFieldInstance } from './files';
|
|||||||
import MediapickerField, { Instance as MediapickerInstance } from './mediapicker';
|
import MediapickerField, { Instance as MediapickerInstance } from './mediapicker';
|
||||||
import MultilevelField, { Instance as MultilevelInstance } from './multilevel';
|
import MultilevelField, { Instance as MultilevelInstance } from './multilevel';
|
||||||
import SelectUniqueField, { Instance as SelectUniqueInstance } from './selectunique';
|
import SelectUniqueField, { Instance as SelectUniqueInstance } from './selectunique';
|
||||||
|
import IconpickerField, { Instance as IconpickerInstance } from './iconpicker';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
FilepickerField: {
|
FilepickerField: {
|
||||||
@@ -54,6 +55,10 @@ export default {
|
|||||||
MultilevelField: {
|
MultilevelField: {
|
||||||
MultilevelField,
|
MultilevelField,
|
||||||
Instance: MultilevelInstance
|
Instance: MultilevelInstance
|
||||||
|
},
|
||||||
|
IconpickerField: {
|
||||||
|
IconpickerField,
|
||||||
|
Instance: IconpickerInstance
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import Scrollbar, { Instance as contentScrollbar } from './utils/scrollbar';
|
|||||||
import './plugins';
|
import './plugins';
|
||||||
import './themes';
|
import './themes';
|
||||||
import { Filter as MediaFilter, Instance as MediaFilterInstance} from './media';
|
import { Filter as MediaFilter, Instance as MediaFilterInstance} from './media';
|
||||||
|
import toastr from './utils/toastr';
|
||||||
|
import request from './utils/request';
|
||||||
|
|
||||||
// bootstrap jQuery extensions
|
// bootstrap jQuery extensions
|
||||||
import 'bootstrap/js/transition';
|
import 'bootstrap/js/transition';
|
||||||
@@ -70,5 +72,6 @@ export default {
|
|||||||
MediaFilter: {
|
MediaFilter: {
|
||||||
MediaFilter,
|
MediaFilter,
|
||||||
Instance: MediaFilterInstance
|
Instance: MediaFilterInstance
|
||||||
}
|
},
|
||||||
|
Utils: { request, toastr }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ title.on('input focus blur', (event) => {
|
|||||||
if (custom) { return true; }
|
if (custom) { return true; }
|
||||||
let elements = getFields('title', event.currentTarget);
|
let elements = getFields('title', event.currentTarget);
|
||||||
|
|
||||||
let slug = $.slugify(elements.title.val());
|
let slug = $.slugify(elements.title.val(), {custom: {"'": ''}});
|
||||||
elements.folder.val(slug);
|
elements.folder.val(slug);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
2
themes/grav/css-compiled/preset.css
vendored
2
themes/grav/css-compiled/preset.css
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
themes/grav/css-compiled/template.css
vendored
2
themes/grav/css-compiled/template.css
vendored
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
221
themes/grav/css/iconpicker.css
Executable 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;
|
||||||
|
}
|
||||||
|
|
||||||
36
themes/grav/js/admin.min.js
vendored
36
themes/grav/js/admin.min.js
vendored
File diff suppressed because one or more lines are too long
55
themes/grav/js/vendor.min.js
vendored
55
themes/grav/js/vendor.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -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 {
|
.block-userinfo {
|
||||||
img {
|
img {
|
||||||
border: 4px solid $form-border;
|
border: 4px solid $form-border;
|
||||||
|
|||||||
@@ -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 {
|
.content-padding {
|
||||||
#messages.default-box-shadow {
|
#messages.default-box-shadow {
|
||||||
margin-bottom: 2.5rem;
|
margin-bottom: 2.5rem;
|
||||||
|
|||||||
@@ -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 %}
|
||||||
6570
themes/grav/templates/forms/fields/iconpicker/icons.yaml
Normal file
6570
themes/grav/templates/forms/fields/iconpicker/icons.yaml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,7 @@
|
|||||||
{% block input %}
|
{% block input %}
|
||||||
<div class="form-input-wrapper {{ field.size }}">
|
<div class="form-input-wrapper {{ field.size }}">
|
||||||
<select
|
<select
|
||||||
value="{{ value|e('html_attr')|join(', ') }}"
|
value="{{ value|raw|join(', ') }}"
|
||||||
name="{{ (scope ~ field.name)|fieldName }}"
|
name="{{ (scope ~ field.name)|fieldName }}"
|
||||||
data-select-observe
|
data-select-observe
|
||||||
{% block input_attributes %}
|
{% block input_attributes %}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
|
|
||||||
{% macro loop(page, depth, twig_vars) %}
|
{% macro loop(page, depth, twig_vars) %}
|
||||||
{% set separator = twig_vars['config'].system.param_sep %}
|
{% 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 = twig_vars['base_url_relative'] %}
|
||||||
{% set base_url_simple = twig_vars['base_url_simple'] %}
|
{% set base_url_simple = twig_vars['base_url_simple'] %}
|
||||||
{% set admin_route = twig_vars['admin_route'] %}
|
{% set admin_route = twig_vars['admin_route'] %}
|
||||||
@@ -55,8 +56,11 @@
|
|||||||
{% set uri = twig_vars['uri'] %}
|
{% set uri = twig_vars['uri'] %}
|
||||||
|
|
||||||
{% if page.header.admin.children_display_order == 'collection' and page.header.content.order.by %}
|
{% if page.header.admin.children_display_order == 'collection' and page.header.content.order.by %}
|
||||||
{% set pcol = page.children().order(page.header.content.order.by, page.header.content.order.dir|default('asc')) %}
|
{% if page.header.content.order.custom %}
|
||||||
{{ dump(pcol) }}
|
{% 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')) %}
|
||||||
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% set pcol = page.children() %}
|
{% set pcol = page.children() %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -84,7 +88,8 @@
|
|||||||
<div class="page-item__content">
|
<div class="page-item__content">
|
||||||
<div class="page-item__content-name">
|
<div class="page-item__content-name">
|
||||||
<span data-hint="{{ description|trim(' • ')|raw }}" class="hint--top page-item__content-hint">
|
<span data-hint="{{ description|trim(' • ')|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>
|
</span>
|
||||||
{% if p.language %}
|
{% if p.language %}
|
||||||
<span class="badge lang {% if p.language == admin_lang %}info{% endif %}">{{p.language}}</span>
|
<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 } %}
|
{% include 'partials/page-move.html.twig' with { blueprints: admin.blueprints('admin/pages/move'), data: context } %}
|
||||||
</div>
|
</div>
|
||||||
<div class="remodal" data-remodal-id="revisions" data-remodal-options="hashTracking: false">
|
<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>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|||||||
@@ -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 %}
|
{% set form_message = form.message %}
|
||||||
<div id="messages" class="top-notifications-container{{ admin_messages|length or form_message ? ' default-box-shadow' : '' }}">
|
<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>
|
<div class="single-notification info alert hidden" data-gpm-grav></div>
|
||||||
@@ -8,4 +9,7 @@
|
|||||||
{%- if form_message -%}
|
{%- if form_message -%}
|
||||||
<div class="error alert">{{ form_message|raw }}</div>
|
<div class="error alert">{{ form_message|raw }}</div>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
|
{%- for message in plugin_messages -%}
|
||||||
|
<div class="{{ message.scope|e }} alert">{{ message.message|raw }}</div>
|
||||||
|
{%- endfor -%}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
23
themes/grav/templates/partials/nav-quick-tray.html.twig
Normal file
23
themes/grav/templates/partials/nav-quick-tray.html.twig
Normal 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 %}
|
||||||
@@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
{% include 'partials/nav-user-details.html.twig' %}
|
{% include 'partials/nav-user-details.html.twig' %}
|
||||||
|
|
||||||
|
{% include 'partials/nav-quick-tray.html.twig' %}
|
||||||
|
|
||||||
<div class="admin-menu-wrapper">
|
<div class="admin-menu-wrapper">
|
||||||
<ul id="admin-menu">
|
<ul id="admin-menu">
|
||||||
<li class="{{ (location == 'dashboard') ? 'selected' : '' }}">
|
<li class="{{ (location == 'dashboard') ? 'selected' : '' }}">
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
{% do assets.addCss(theme_url~'/css/chartist.min.css') %}
|
{% do assets.addCss(theme_url~'/css/chartist.min.css') %}
|
||||||
{% do assets.addCss(theme_url~'/css/selectize.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/hint.base.min.css') %}
|
||||||
|
{% do assets.addCss(theme_url~'/css/iconpicker.css') %}
|
||||||
{% if browser.getBrowser == 'msie' and browser.getVersion >= 8 and browser.getVersion <= 9 %}
|
{% 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/nucleus-ie9.css') %}
|
||||||
{% do assets.addCss(theme_url~'/css/pure-0.5.0/grids-min.css') %}
|
{% do assets.addCss(theme_url~'/css/pure-0.5.0/grids-min.css') %}
|
||||||
|
|||||||
Reference in New Issue
Block a user