Merge branch 'develop' into feature/mobile

Conflicts:
	themes/grav/css-compiled/template.css.map
This commit is contained in:
unknown
2015-09-03 17:14:29 -04:00
32 changed files with 1076 additions and 101 deletions

View File

@@ -1,3 +1,31 @@
# v0.4.3
## 08/31/2015
1. [](#new)
* Added Japanese translation
* Support for independent file name and template override
1. [](#improved)
* Improved slug generation using `slugify.js`
* Allow the `title` twig variables to set the page title
* Improved Page media handling with several bugfixes
* Prevent error when there are no pages on a site
* If all updates are applied, show "Fully Updated" text in dashboard
* Better preview link (requires `rtrim` filter from Grav 0.9.40)
* Order all plugins and themes alphabetically
* Removed duplicate language entries
1. [](#bugfix)
* Fix for redirect after saving when multilang not enabled
* Fix for deleting responsive media
* Fix for HTML encoding in markdown field
# v0.4.2
## 08/25/2015
1. [](#bugfix)
* Fix for current admin lang not showing up in page lang dropdown
* Fix for incorrect NAME/CONTENT lang keys
* Fix for incorrect site link
# v0.4.1
## 08/24/2015

View File

@@ -67,7 +67,17 @@ Extract each archive file into your `user/plugins` folder, then ensure the folde
# Usage
Upon completion of the installation the next thing you need to do is create a user account in a file called `user/accounts/admin.yaml`. This **filename** is actually the **username** that you will use to login. The contents will contain the other information for the user.
### Create User with CLI
After this you need to create a user account with admin privileges:
```
$ bin/grav newuser
```
### Create User Manually
Alternatively, you can create a user account manually, in a file called `user/accounts/admin.yaml`. This **filename** is actually the **username** that you will use to login. The contents will contain the other information for the user.
```
password: 'password'
@@ -84,6 +94,8 @@ Of course you should edit your `email`, `password`, `fullname`, and `title` to s
> You can use any password when you manually put it in this `.yaml` file. However, when you change your password in the admin, it must contain at least one number and one uppercase and lowercase letter, and at least 8 or more characters.
# Accessing the Admin
By default, you can access the admin by pointing your browser to `http://yoursite.com/admin`. You can simply log in with the `username` and `password` set in the YAML file you configured earlier.
> After logging in, your **plaintext password** will be removed and replaced by an **encrypted** one.

View File

@@ -137,6 +137,13 @@ class AdminPlugin extends Plugin
$this->session->expert = false;
}
// check for existence of a user account
$account_dir = $file_path = $this->grav['locator']->findResource('account://');
$user_check = (array) glob($account_dir . '/*.yaml');
if (!count($user_check) > 0) {
$this->admin->setMessage($this->admin->translate('PLUGIN_ADMIN.NO_USER_ACCOUNTS'), 'info');
}
/** @var Pages $pages */
$pages = $this->grav['pages'];
@@ -207,7 +214,7 @@ class AdminPlugin extends Plugin
$ext = '.' . ($format ? $format : 'html') . TWIG_EXT;
$twig->twig_vars['location'] = $this->template;
$twig->twig_vars['base_url_relative_frontend'] = $twig->twig_vars['base_url_relative'];
$twig->twig_vars['base_url_relative_frontend'] = $twig->twig_vars['base_url_relative'] ?: '/';
$twig->twig_vars['admin_route'] = trim($this->config->get('plugins.admin.route'), '/');
$twig->twig_vars['base_url_relative'] .=
($twig->twig_vars['base_url_relative'] != '/' ? '/' : '') . $twig->twig_vars['admin_route'];
@@ -355,6 +362,8 @@ class AdminPlugin extends Plugin
'OF_THIS',
'HAVE_AN_UPDATE_AVAILABLE',
'UPDATE_AVAILABLE',
'UPDATES_AVAILABLE',
'FULLY_UPDATED',
'DAYS'];
foreach($strings as $string) {

View File

@@ -1,5 +1,5 @@
name: Admin Panel
version: 0.4.1
version: 0.4.3
description: Adds an advanced administration panel to manage your site
icon: empire
author:

View File

@@ -345,7 +345,9 @@ class Admin
public function gpm()
{
if (!$this->gpm) {
try {
$this->gpm = new GPM();
} catch (\Exception $e) {}
}
return $this->gpm;
@@ -583,11 +585,11 @@ class Admin
}
if ($data['type'] == 'modular') {
if ($data['name'] == 'modular') {
$header['body_classes'] = 'modular';
}
$name = $page->modular() ? str_replace('modular/', '', $data['type']) : $data['type'];
$name = $page->modular() ? str_replace('modular/', '', $data['name']) : $data['name'];
$page->name($name . '.md');
$page->header($header);
$page->frontmatter(Yaml::dump((array)$page->header(), 10, 2, false));
@@ -646,8 +648,11 @@ class Admin
$route = '/' . ltrim(Grav::instance()['admin']->route, '/');
$page = $pages->dispatch($route);
$parent_route = null;
if ($page) {
$parent = $page->parent();
$parent_route = $parent->rawRoute();
}
return $parent_route;
}
@@ -713,11 +718,13 @@ class Admin
$languages = ['en'];
}
foreach ((array)$languages as $lang) {
$translation = $this->grav['language']->getTranslation($lang, $lookup, $array_support);
if (!$translation) {
$translation = $this->grav['language']->getTranslation($this->grav['language']->getDefault(), $lookup, $array_support);
$language = $this->grav['language']->getDefault() ?: 'en';
$translation = $this->grav['language']->getTranslation($language, $lookup, $array_support);
}
if ($translation) {

View File

@@ -119,7 +119,8 @@ class AdminController
$base = $this->admin->base;
$this->redirect = '/' . ltrim($this->redirect, '/');
$multilang = (count($this->grav['config']->get('system.languages.supported', [])) > 1);
$multilang = $this->isMultilang();
$redirect = '';
if ($multilang) {
// if base path does not already contain the lang code, add it
@@ -153,6 +154,15 @@ class AdminController
$this->grav->redirect($redirect, $this->redirectCode);
}
/**
* Return true if multilang is active
*
* @return bool True if multilang is active
*/
protected function isMultilang() {
return count($this->grav['config']->get('system.languages.supported', [])) > 1;
}
/**
* Handle login.
*
@@ -507,7 +517,7 @@ class AdminController
$grav_limit = $config->get('system.media.upload_limit', 0);
// You should also check filesize here.
if ($grav_limit > 0 && $_FILES['file']['size'] > grav_limit) {
if ($grav_limit > 0 && $_FILES['file']['size'] > $grav_limit) {
$this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.EXCEEDED_GRAV_FILESIZE_LIMIT')];
return;
}
@@ -563,9 +573,32 @@ class AdminController
} else {
$this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.FILE_COULD_NOT_BE_DELETED') . ': '.$filename];
}
} else {
//Try with responsive images @1x, @2x, @3x
$ext = pathinfo($targetPath, PATHINFO_EXTENSION);
$filename = $page->path() . '/'. basename($targetPath, ".$ext");
$responsiveTargetPath = $filename . '@1x.' . $ext;
$deletedResponsiveImage = false;
if (file_exists($responsiveTargetPath) && unlink($responsiveTargetPath)) {
$deletedResponsiveImage = true;
}
$responsiveTargetPath = $filename . '@2x.' . $ext;
if (file_exists($responsiveTargetPath) && unlink($responsiveTargetPath)) {
$deletedResponsiveImage = true;
}
$responsiveTargetPath = $filename . '@3x.' . $ext;
if (file_exists($responsiveTargetPath) && unlink($responsiveTargetPath)) {
$deletedResponsiveImage = true;
}
if ($deletedResponsiveImage) {
$this->admin->json_response = ['status' => 'success', 'message' => $this->admin->translate('PLUGIN_ADMIN.FILE_DELETED') . ': '.$filename];
} else {
$this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.FILE_NOT_FOUND') . ': '.$filename];
}
}
} else {
$this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.NO_FILE_FOUND')];
}
@@ -909,16 +942,20 @@ class AdminController
if (method_exists($obj, 'unsetRouteSlug')) {
$obj->unsetRouteSlug();
}
$multilang = $this->isMultilang();
if ($multilang) {
if (!$obj->language()) {
$obj->language($this->grav['session']->admin_lang);
}
$this->setRedirect('/' . $obj->language(). '/admin/' . $this->view . $obj->route());
}
$this->setRedirect(($multilang ? ('/' . $obj->language()) : '') . '/admin/' . $this->view . $obj->route());
}
return true;
}
/**
* Continue to the new page.
*
@@ -1263,8 +1300,8 @@ class AdminController
$page->folder($ordering . $slug);
}
if (isset($input['type']) && !empty($input['type'])) {
$type = (string) strtolower($input['type']);
if (isset($input['name']) && !empty($input['name'])) {
$type = (string) strtolower($input['name']);
$name = preg_replace('|.*/|', '', $type);
if ($language) {
$name .= '.' . $language;

File diff suppressed because it is too large Load Diff

View File

@@ -738,6 +738,8 @@ form .checkboxes {
.form-label.block {
z-index: 10000; }
.form-label.block:hover {
z-index: 10005; }
table,
tbody,
@@ -1455,6 +1457,11 @@ tr {
#popularity .ct-chart .ct-chart-bar {
padding: 10px; }
#latest .page-title, #latest .page-route {
overflow: auto; }
#latest .last-modified {
padding-left: 10px; }
.pages-list {
list-style: none;
margin: 0;
@@ -2203,6 +2210,17 @@ body.remodal_active .remodal {
border-left: 0; }
.dropzone .dz-preview:hover .dz-insert {
right: inherit; }
.dropzone .dz-preview.dz-processing .dz-details {
overflow: hidden; }
.dropzone .dz-preview.dz-processing .dz-details img {
position: absolute;
left: 50%;
top: 50%;
height: auto;
width: 100%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%); }
.dropzone .dz-preview .dz-details {
width: 150px;
height: 100px;

File diff suppressed because one or more lines are too long

View File

@@ -78,6 +78,13 @@ $(function () {
UpdatesChart.on('draw', function(data){
if (data.index) { return; }
chart.find('.numeric span').text(Math.round(data.value) + '%');
var text = translations.PLUGIN_ADMIN.UPDATES_AVAILABLE;
if (data.value == 100) {
text = translations.PLUGIN_ADMIN.FULLY_UPDATED;
}
$('.js__updates-available-description').html(text)
$('.updates-chart .hidden').removeClass('hidden');
});
}

View File

@@ -4,8 +4,11 @@ $(document).ready(function(){
min = $input.attr('min'),
max = $input.attr('max'),
regex, match,
userOptions = $input.data('dateFormats') || {},
kendoOptions = { format: "dd-MM-yyyy HH:mm", timeFormat: "HH:mm" };
kendoOptions = $.extend({}, kendoOptions, userOptions);
if (min || max) {
regex = /(\d{2})-(\d{2})-(\d{4}) (\d{2}):(\d{2})/;
}

View File

@@ -81,7 +81,14 @@
$("#gravDropzone").delegate('[data-dz-insert]', 'click', function(e) {
var target = $(e.currentTarget).parent('.dz-preview').find('.dz-filename');
editor.focus();
editor.doc.replaceSelection('![](' + encodeURI(target.text()) + ')');
var filename = target.text();
filename = filename.replace(/@3x|@2x|@1x/, '');
if (filename.match(/\.(jpg|jpeg|png|gif)$/)) {
editor.doc.replaceSelection('![](' + encodeURI(filename) + ')');
} else {
editor.doc.replaceSelection('[' + filename + '](' + encodeURI(filename) + ')');
}
});
this.preview.container = this.preview;

View File

@@ -154,11 +154,14 @@ $(function(){
$('input[name="title"]').on('input', function(e){
if (!$('input[name="folder"]').data('user-custom-folder')) {
folder = $(this).val().toLowerCase().replace(/\s/g, '-').replace(/[^a-z0-9_\-]/g, '');
folder = $.slugify($(this).val());
$('input[name="folder"]').val(folder);
}
});
$('#slug-target').slugify('#slug-source');
$('input[name="folder"]').on('input', function(e){
value = $(this).val().toLowerCase().replace(/\s/g, '-').replace(/[^a-z0-9_\-]/g, '');
$(this).val(value);

3
themes/grav/js/slugify.min.js vendored Normal file
View File

@@ -0,0 +1,3 @@
/*! jquery-slugify - v1.2.1 - 2015-08-02
* Copyright (c) 2015 madflow; Licensed */
!function(a){a.fn.slugify=function(b,c){return this.each(function(){var d=a(this),e=a(b);d.on("keyup change",function(){""!==d.val()&&void 0!==d.val()?d.data("locked",!0):d.data("locked",!1)}),e.on("keyup change",function(){!0!==d.data("locked")&&(d.is("input")||d.is("textarea")?d.val(a.slugify(e.val(),c)):d.text(a.slugify(e.val(),c)))})})},a.slugify=function(b,c){return c=a.extend({},a.slugify.options,c),c.lang=c.lang||a("html").prop("lang"),"function"==typeof c.preSlug&&(b=c.preSlug(b)),b=c.slugFunc(b,c),"function"==typeof c.postSlug&&(b=c.postSlug(b)),b},a.slugify.options={preSlug:null,postSlug:null,slugFunc:function(a,b){return window.getSlug(a,b)}}}(jQuery);

7
themes/grav/js/speakingurl.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -631,8 +631,6 @@ $update-height: 3rem;
stroke: rgba($white, 0.2) !important;
}
}
}
}
@@ -643,8 +641,14 @@ $update-height: 3rem;
}
}
// Remodal Styling
#latest {
.page-title, .page-route {
overflow: auto;
}
.last-modified {
padding-left: 10px;
}
}

View File

@@ -162,6 +162,23 @@ $error-color: #D55A4E;
right: inherit;
}
&.dz-processing {
.dz-details {
overflow: hidden;
img {
position: absolute;
left: 50%;
top: 50%;
height: auto;
width: 100%;
-webkit-transform: translate(-50%,-50%);
-ms-transform: translate(-50%,-50%);
transform: translate(-50%,-50%);
}
}
}
.dz-details {
width: $preview-width;
height: $preview-height;

View File

@@ -455,4 +455,8 @@ form {
.form-label.block {
z-index: 10000;
&:hover {
z-index: 10005;
}
}

View File

@@ -35,9 +35,9 @@
<div class="updates-chart">
<div class="chart-wrapper">
<div class="ct-chart"></div>
<span class="numeric"><span>-</span><em>{{ "PLUGIN_ADMIN.UPDATED"|tu|lower }}</em></span>
<span class="numeric hidden"><span>-</span><em>{{ "PLUGIN_ADMIN.UPDATED"|tu|lower }}</em></span>
</div>
<p>{{ "PLUGIN_ADMIN.UPDATES_AVAILABLE"|tu }}</p>
<p class="js__updates-available-description">&nbsp;</p>
</div>
<div class="backups-chart">
<div class="chart-wrapper">
@@ -134,7 +134,7 @@
<h1>{{ "PLUGIN_ADMIN.LATEST_PAGE_UPDATES"|tu }}</h1>
<table>
{% for latest in admin.latestPages %}
<tr><td class="double"><a href="{{ base_url }}/pages/{{ latest.route|trim('/') }}"><i class="fa fa-fw fa-file-o"></i> {{ latest.title }}</a></td><td class="double">{{ latest.route }}</td><td><b>{{ latest.modified|nicetime }}</b></td></tr>
<tr><td class="double page-title"><a href="{{ base_url }}/pages/{{ latest.route|trim('/') }}"><i class="fa fa-fw fa-file-o"></i> {{ latest.title }}</a></td><td class="double page-route">{{ latest.route }}</td><td><b class="last-modified">{{ latest.modified|nicetime }}</b></td></tr>
{% endfor %}
</table>
</div>

View File

@@ -48,7 +48,7 @@
{% 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.placeholder %}placeholder="{{ field.placeholder|tu }}"{% 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 %}

View File

@@ -1,7 +1,7 @@
{% extends "forms/field.html.twig" %}
{% set value = (value is null ? field.default : value) %}
{% set value = (value is null ? value : value|date("d-m-Y H:i")) %}
{% set value = (value is null ? value : value|date('d-m-Y H:i')) %}
{% block input %}
<input

View File

@@ -23,6 +23,9 @@
var editor = CodeMirror.fromTextArea(document.getElementById('frontmatter'), {
mode: 'yaml',
theme: 'paper',
{% if field.autofocus %}
autofocus: true,
{% endif %}
indentUnit: 4,
indentWithTabs: false,
extraKeys: {Tab: function(cm) { cm.replaceSelection(" ", "end"); }}

View File

@@ -2,6 +2,6 @@
<div class="form-field">
<div class="form-data form-markdown-wrapper cm-s-paper">
<textarea data-grav-mdeditor="{{ { 'markdown': true }|json_encode|e('html_attr') }}" name="{{ (scope ~ field.name)|fieldName }}" data-grav-urlpreview="{{ base_url }}/media/{{ admin.route|trim('/') }}.json">{{ value|join("\n") }}</textarea>
<textarea data-grav-mdeditor="{{ { 'markdown': true }|json_encode|e('html_attr') }}" name="{{ (scope ~ field.name)|fieldName }}" data-grav-urlpreview="{{ base_url }}/media/{{ admin.route|trim('/') }}.json">{{ value|join("\n")|e('html') }}</textarea>
</div>
</div>

View File

@@ -1,26 +0,0 @@
{% extends "forms/field.html.twig" %}
{% block global_attributes %}
data-grav-selectize="{{ (field.selectize is defined ? field.selectize : {})|json_encode()|e('html_attr') }}"
data-grav-field="select"
data-grav-disabled="{{ originalValue is null ? 'true' : 'false' }}"
data-grav-default="{{ field.default|json_encode()|e('html_attr') }}"
{% endblock %}
{% block input %}
<div class="form-select-wrapper {{ field.size }}">
<select class="{{ field.classes }}" name="{{ (scope ~ field.name)|fieldName ~ (field.multiple ? '[]' : '') }}"
{% if field.autofocus in ['on', 'true', 1] %}autofocus="autofocus"{% endif %}
{% if field.novalidate in ['on', 'true', 1] %}novalidate="novalidate"{% endif %}
{% if field.validate.required in ['on', 'true', 1] %}required="required"{% endif %}
{% if field.multiple in ['on', 'true', 1] %}multiple="multiple"{% endif %}
>
{% if value not in field.options|keys %}
<option selected="selected" value="{{ value }}">{{ value|title }}</option>
{% endif %}
{% for key, text in field.options %}
<option {% if key == value %}selected="selected"{% endif %} value="{{ field.multiple ? text : key }}">{{ text }}</option>
{% endfor %}
</select>
</div>
{% endblock %}

View File

@@ -16,6 +16,6 @@
{% if field.validate.pattern %}pattern="{{ field.validate.pattern }}"{% endif %}
{% if field.validate.message %}title="{{ field.validate.message|tu }}"{% endif %}
{% endblock %}
>{{ value|trim }}</textarea>
>{{ value|trim|e('html') }}</textarea>
</div>
{% endblock %}

View File

@@ -72,7 +72,10 @@
var mockFile = { name: filename, size: data.size, accepted: true, extras: data };
thisDropzone.files.push(mockFile);
thisDropzone.options.addedfile.call(thisDropzone, mockFile);
if (filename.match(/\.(jpg|jpeg|png|gif)$/)) {
thisDropzone.options.thumbnail.call(thisDropzone, mockFile, data.url);
}
});
}
@@ -121,7 +124,12 @@
var dropzone = new Dropzone("#gravDropzone", { url: URI + '/task{{ config.system.param_sep }}addmedia', createImageThumbnails: { thumbnailWidth: 150} });
$("#gravDropzone").delegate('.dz-preview', 'dragstart', function(e){
var uri = $(this).find('.dz-filename').text(), shortcode = '![](' + encodeURI(uri) + ')';
var uri = $(this).find('.dz-filename').text();
var shortcode = '![](' + encodeURI(uri) + ')';
if (!uri.match(/\.(jpg|jpeg|png|gif)$/)) {
shortcode = '[' + uri + '](' + encodeURI(uri) + ')';
}
dropzone.disable();
$(this).addClass('hide-backface');
e.originalEvent.dataTransfer.effectAllowed = 'copy';

View File

@@ -11,6 +11,9 @@
{% if context.exists %}
{% set page_url = base_url ~ '/pages' ~ (context.header.routes.default ?: context.rawRoute) %}
{% set exists = true %}
{% set title = (context.exists ? "PLUGIN_ADMIN.EDIT"|tu : "PLUGIN_ADMIN.CREATE"|tu ) ~ " " ~ context.header.title %}
{% else %}
{% set title = "PLUGIN_ADMIN.ADD_PAGE"|tu %}
{% endif %}
{% else %}
{% set mode = 'list' %}
@@ -25,6 +28,7 @@
{% set page_lang = context.language %}
{% block stylesheets %}
{{ dump(base_url_relative_frontend ~ (context.home ? '' : context.route)) }}
{% if mode == 'edit' %}
{% do assets.addCss(theme_url~'/css/codemirror/codemirror.css') %}
{% endif %}
@@ -33,6 +37,8 @@
{% block javascripts %}
{% do assets.addJs(theme_url~'/js/pages-all.js') %}
{% do assets.addJs(theme_url~'/js/speakingurl.min.js') %}
{% do assets.addJs(theme_url~'/js/slugify.min.js') %}
{% if mode == 'edit' %}
{% do assets.addJs(theme_url~'/js/codemirror-compressed.js') %}
{% do assets.addJs(theme_url~'/js/mdeditor.js') %}
@@ -41,7 +47,8 @@
{{ parent() }}
{% endblock %}
{% set preview_link = '<a class="preview" href="'~ base_url_relative_frontend ~ (context.home ? '' : context.route) ~'"><i class="fa fa-fw fa-angle-double-right"></i></a>' %}
{% set preview_html = (base_url_relative_frontend|rtrim('/') ~ (context.home ? '' : context.route)) ?: '/' %}
{% set preview_link = context.routable ? '<a class="preview" target="_blank" href="' ~ preview_html ~ '"><i class="fa fa-fw fa-angle-double-right"></i></a>' : '' %}
{% macro loop(page, depth, twig_vars) %}
{% set separator = twig_vars['config'].system.param_sep %}
@@ -136,8 +143,6 @@
{% endif %}
{% endif %}
{{ dump(admin_lang) }}
<div class="button-group">
<button class="button" name="task" value="save" form="blueprints"><i class="fa fa-check"></i> {{ "PLUGIN_ADMIN.SAVE"|tu }}</button>
{% if exists and admin.multilang %}
@@ -147,7 +152,7 @@
</button>
<ul class="dropdown-menu lang-switcher">
{% for language in context.untranslatedLanguages %}
{% if language != page_lang and language != admin_lang %}
{% if language != page_lang %}
<li><button class="button task" name="task" value="saveas" lang="{{language}}" form="blueprints">{{ "PLUGIN_ADMIN.SAVE_AS"|tu }} {{ admin.siteLanguages[language]|capitalize }}</button>
{% endif %}
{% endfor %}
@@ -163,7 +168,7 @@
<h1><i class="fa fa-fw fa-file-text-o"></i> {{ "PLUGIN_ADMIN.ADD_PAGE"|tu }}</h1>
{% elseif mode == 'edit' %}
<h1><i class="fa fa-fw fa-file-text-o"></i>
{{ context.exists ? "PLUGIN_ADMIN.EDIT"|tu ~ " '#{context.menu}'" ~ preview_link : "PLUGIN_ADMIN.CREATE"|tu ~ " '#{context.menu}'" }}
{{ context.exists ? "PLUGIN_ADMIN.EDIT"|tu ~ " <i>#{context.menu}</i>" ~ preview_link : "PLUGIN_ADMIN.CREATE"|tu ~ " <i>#{context.menu}</i>" }}
</h1>
{% else %}
<h1><i class="fa fa-fw fa-file-text-o"></i> {{ "PLUGIN_ADMIN.MANAGE_PAGES"|tu }}</h1>

View File

@@ -1,10 +1,9 @@
{% set base_url_relative_frontend = base_url_relative_frontend is not empty ?: '/' %}
<!DOCTYPE html>
<html lang="en">
<head>
{% block head %}
<meta charset="utf-8" />
<title>{% if header.title %}{{ header.title }} | {% endif %}{{ site.title }}</title>
<title>{% if title %}{{ title }} | {% else %}{% if header.title %}{{ header.title }} | {% endif %}{% endif %}{{ site.title }}</title>
{% if header.description %}
<meta name="description" content="{{ header.description }}">
{% else %}

View File

@@ -5,8 +5,7 @@
</h1>
<table>
{% for slug, package in admin.plugins(not installing) %}
{% set plugin = package.toArray() %}
{% for slug, plugin in admin.plugins(not installing).toArray|ksort %}
{% set data = admin.data('plugins/' ~ slug) %}
<tr data-gpm-plugin="{{ slug|url_encode }}">

View File

@@ -5,8 +5,7 @@
</h1>
<div class="themes card-row grid fixed-blocks pure-g">
{% for slug, package in admin.themes(not installing) %}
{% set theme = package.toArray() %}
{% for slug, theme in admin.themes(not installing).toArray|ksort %}
{% set state = 'inactive' %}
{% if (installing) %}{% set state = 'installing' %}{% endif %}
{% if (config.get('system.pages.theme') == slug) %}{% set state = 'active' %}{% endif %}

View File

@@ -12,6 +12,7 @@
{% endif %}
{% set plugin = package.toArray() %}
{% set title = "PLUGIN_ADMIN.PLUGIN"|tu ~ ": " ~ plugin.name|e %}
{% endif %}
{% block titlebar %}

View File

@@ -12,6 +12,8 @@
{% endif %}
{% set theme = package.toArray() %}
{% set title = "PLUGIN_ADMIN.THEME"|tu ~ ": " ~ theme.name|e %}
{% endif %}
{% block titlebar %}