(Grav GitSync) Automatic Commit from dan

This commit is contained in:
dan 2022-02-01 19:52:23 +13:00 committed by GitSync
parent c14ca8a858
commit 0877ed33d8
36 changed files with 105701 additions and 6806 deletions

View File

@ -1,3 +1,18 @@
# v1.10.29
## 01/28/2022
1. [](#new)
* Require **Grav 1.7.29**
3. [](#improved)
* Made path handling unicode-safe, use new `Utils::basename()` and `Utils::pathinfo()` everywhere
# v1.10.28
## 01/24/2022
1. [](#bugfix)
* Clean file names before displaying errors/metadata modals
* Recompiled JS for production [#2225](https://github.com/getgrav/grav-plugin-admin/issues/2225)
# v1.10.27
## 01/12/2022

View File

@ -480,7 +480,7 @@ class AdminPlugin extends Plugin
Admin::DEBUG && Admin::addDebugMessage("Admin page: {$this->template}");
$page->init(new \SplFileInfo(__DIR__ . "/pages/admin/{$this->template}.md"));
$page->slug(basename($this->template));
$page->slug(Utils::basename($this->template));
return $page;
}
@ -501,7 +501,7 @@ class AdminPlugin extends Plugin
Admin::DEBUG && Admin::addDebugMessage("Admin page: plugin {$plugin->name}/{$this->template}");
$page->init(new \SplFileInfo($path));
$page->slug(basename($this->template));
$page->slug(Utils::basename($this->template));
return $page;
}
@ -525,7 +525,7 @@ class AdminPlugin extends Plugin
$error_file = $this->grav['locator']->findResource('plugins://admin/pages/admin/error.md');
$page = new Page();
$page->init(new \SplFileInfo($error_file));
$page->slug(basename($this->route));
$page->slug(Utils::basename($this->route));
$page->routable(true);
}
@ -537,7 +537,7 @@ class AdminPlugin extends Plugin
$login_file = $this->grav['locator']->findResource('plugins://admin/pages/admin/login.md');
$page = new Page();
$page->init(new \SplFileInfo($login_file));
$page->slug(basename($this->route));
$page->slug(Utils::basename($this->route));
unset($this->grav['page']);
$this->grav['page'] = $page;
}
@ -1304,7 +1304,7 @@ class AdminPlugin extends Plugin
$options = [];
$theme_files = glob(__dir__ . '/themes/grav/css/codemirror/themes/*.css');
foreach ($theme_files as $theme_file) {
$theme = basename(basename($theme_file, '.css'));
$theme = Utils::basename(Utils::basename($theme_file, '.css'));
$options[$theme] = Inflector::titleize($theme);
}
}

View File

@ -1,7 +1,7 @@
name: Admin Panel
slug: admin
type: plugin
version: 1.10.27
version: 1.10.29
description: Adds an advanced administration panel to manage your site
icon: empire
author:
@ -15,7 +15,7 @@ docs: https://github.com/getgrav/grav-plugin-admin/blob/develop/README.md
license: MIT
dependencies:
- { name: grav, version: '>=1.7.27' }
- { name: grav, version: '>=1.7.29' }
- { name: form, version: '>=5.1.0' }
- { name: login, version: '>=3.6.2' }
- { name: email, version: '>=3.1.0' }

View File

@ -980,7 +980,7 @@ class Admin
$obj->file = $file;
$obj->page = $pages->get(dirname($obj->path));
$fileInfo = pathinfo($obj->title);
$fileInfo = Utils::pathinfo($obj->title);
$filename = str_replace(['@3x', '@2x'], '', $fileInfo['filename']);
if (isset($fileInfo['extension'])) {
$filename .= '.' . $fileInfo['extension'];
@ -1979,7 +1979,7 @@ class Admin
$page = $path ? $pages->find($path, true) : $pages->root();
if (!$page) {
$slug = basename($path);
$slug = Utils::basename($path);
if ($slug === '') {
return null;

View File

@ -374,7 +374,7 @@ class AdminBaseController
// since php removes it from the upload location
$tmp_dir = Admin::getTempDir();
$tmp_file = $upload->file->tmp_name;
$tmp = $tmp_dir . '/uploaded-files/' . basename($tmp_file);
$tmp = $tmp_dir . '/uploaded-files/' . Utils::basename($tmp_file);
Folder::create(dirname($tmp));
if (!move_uploaded_file($tmp_file, $tmp)) {
@ -423,7 +423,7 @@ class AdminBaseController
// Generate random name if required
if ($settings->random_name) { // TODO: document
$extension = pathinfo($upload->file->name, PATHINFO_EXTENSION);
$extension = Utils::pathinfo($upload->file->name, PATHINFO_EXTENSION);
$upload->file->name = Utils::generateRandomString(15) . '.' . $extension;
}
@ -929,7 +929,7 @@ class AdminBaseController
$type = $uri->param('type');
$field = $uri->param('field');
$filename = basename($this->post['filename'] ?? '');
$filename = Utils::basename($this->post['filename'] ?? '');
if ($filename === '') {
$this->admin->json_response = [
'status' => 'error',
@ -1068,7 +1068,7 @@ class AdminBaseController
if ($file->exists()) {
$resultRemoveMedia = $file->delete();
$fileParts = pathinfo($filename);
$fileParts = Utils::pathinfo($filename);
foreach (scandir($fileParts['dirname']) as $file) {
$regex_pattern = '/' . preg_quote($fileParts['filename'], '/') . "@\d+x\." . $fileParts['extension'] . "(?:\.meta\.yaml)?$|" . preg_quote($fileParts['basename'], '/') . "\.meta\.yaml$/";

View File

@ -521,7 +521,7 @@ class AdminController extends AdminBaseController
try {
if ($download) {
$filename = basename(base64_decode(urldecode($download)));
$filename = Utils::basename(base64_decode(urldecode($download)));
$file = $this->grav['locator']->findResource("backup://{$filename}", true);
if (!$file || !Utils::endsWith($filename, '.zip', false)) {
header('HTTP/1.1 401 Unauthorized');
@ -584,7 +584,7 @@ class AdminController extends AdminBaseController
$backup = $this->grav['uri']->param('backup', null);
if (null !== $backup) {
$filename = basename(base64_decode(urldecode($backup)));
$filename = Utils::basename(base64_decode(urldecode($backup)));
$file = $this->grav['locator']->findResource("backup://{$filename}", true);
if ($file && Utils::endsWith($filename, '.zip', false)) {
@ -2244,7 +2244,7 @@ class AdminController extends AdminBaseController
// Check extension
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
$extension = strtolower(Utils::pathinfo($filename, PATHINFO_EXTENSION));
// If not a supported type, return
if (!$extension || !$config->get("media.types.{$extension}")) {
@ -2293,7 +2293,7 @@ class AdminController extends AdminBaseController
// Add metadata if needed
$include_metadata = Grav::instance()['config']->get('system.media.auto_metadata_exif', false);
$basename = str_replace(['@3x', '@2x'], '', pathinfo($filename, PATHINFO_BASENAME));
$basename = str_replace(['@3x', '@2x'], '', Utils::pathinfo($filename, PATHINFO_BASENAME));
$metadata = [];
@ -2423,7 +2423,7 @@ class AdminController extends AdminBaseController
return false;
}
$filename = !empty($this->post['filename']) ? basename($this->post['filename']) : null;
$filename = !empty($this->post['filename']) ? Utils::basename($this->post['filename']) : null;
// Handle bad filenames.
if (!$filename || !Utils::checkFilename($filename)) {
@ -2442,7 +2442,7 @@ class AdminController extends AdminBaseController
if ($locator->isStream($targetPath)) {
$targetPath = $locator->findResource($targetPath, true, true);
}
$fileParts = pathinfo($filename);
$fileParts = Utils::pathinfo($filename);
$found = false;
@ -2626,7 +2626,7 @@ class AdminController extends AdminBaseController
$payload = [
'name' => $file_page ? $file_page->title() : $fileName,
'value' => $file_page ? $file_page->rawRoute() : $file_path,
'item-key' => basename($file_page ? $file_page->route() : $file_path),
'item-key' => Utils::basename($file_page ? $file_page->route() : $file_path),
'filename' => $fileName,
'extension' => $type === 'dir' ? '' : $fileInfo->getExtension(),
'type' => $type,

View File

@ -15,6 +15,7 @@ use Grav\Common\Page\Pages;
use Grav\Common\Uri;
use Grav\Common\User\Interfaces\UserCollectionInterface;
use Grav\Common\User\Interfaces\UserInterface;
use Grav\Common\Utils;
use Grav\Framework\RequestHandler\Exception\PageExpiredException;
use Grav\Framework\RequestHandler\Exception\RequestException;
use Grav\Plugin\Admin\Admin;
@ -111,7 +112,7 @@ class LoginController extends AdminController
{
$uri = (string)$this->getRequest()->getUri();
$ext = pathinfo($uri, PATHINFO_EXTENSION);
$ext = Utils::pathinfo($uri, PATHINFO_EXTENSION);
$accept = $this->getAccept(['application/json', 'text/html']);
if ($ext === 'json' || $accept === 'application/json') {
return $this->createErrorResponse(new RequestException($this->getRequest(), $this->translate('PLUGIN_ADMIN.LOGGED_OUT'), 401));

View File

@ -316,7 +316,7 @@ class Gpm
$bad_chars = array_merge(array_map('chr', range(0, 31)), ['<', '>', ':', '"', '/', '\\', '|', '?', '*']);
$filename = $package->slug . str_replace($bad_chars, '', basename($package->zipball_url));
$filename = $package->slug . str_replace($bad_chars, '', \Grav\Common\Utils::basename($package->zipball_url));
$filename = preg_replace('/[\\\\\/:"*?&<>|]+/m', '-', $filename);
file_put_contents($tmp_dir . DS . $filename . '.zip', $contents);

View File

@ -224,7 +224,7 @@ export default class FilesField {
file,
data: response,
mode: 'removeFile',
msg: `<p>${translations.PLUGIN_ADMIN.FILE_ERROR_UPLOAD} <strong>${file.name}</strong></p>
msg: `<p>${translations.PLUGIN_ADMIN.FILE_ERROR_UPLOAD} <strong>{{fileName}}</strong></p>
<pre>${response.message}</pre>`
});
}
@ -240,7 +240,7 @@ export default class FilesField {
file,
data,
mode: 'removeFile',
msg: `<p>${translations.PLUGIN_ADMIN.FILE_ERROR_ADD} <strong>${file.name}</strong></p>
msg: `<p>${translations.PLUGIN_ADMIN.FILE_ERROR_ADD} <strong>{{fileName}}</strong></p>
<pre>${data.message}</pre>`
});
}
@ -325,7 +325,9 @@ export default class FilesField {
}
let modal = $('[data-remodal-id="generic"]');
modal.find('.error-content').html(msg);
const cleanName = file.name.replace('<', '&lt;').replace('>', '&gt;');
modal.find('.error-content').html(msg.replace('{{fileName}}', cleanName));
$.remodal.lookup[modal.data('remodal')].open();
}
}

View File

@ -155,6 +155,7 @@ export default class PageMedia extends FilesField {
const target = $(e.currentTarget);
const file = target.parent('.dz-preview').find('.dz-filename');
const filename = encodeURI(file.text());
const cleanName = file.text().replace('<', '&lt;').replace('>', '&gt;');
let fileObj = this.dropzone.files.filter((file) => file.name === global.decodeURI(filename)).shift() || {};
@ -163,7 +164,7 @@ export default class PageMedia extends FilesField {
}
if (Array.isArray(fileObj.extras.metadata) && !fileObj.extras.metadata.length) {
fileObj.extras.metadata = { '': `${global.decodeURI(filename)}.meta.yaml doesn't exist` };
fileObj.extras.metadata = { '': `${cleanName}.meta.yaml doesn't exist` };
}
fileObj = fileObj.extras;
@ -171,14 +172,15 @@ export default class PageMedia extends FilesField {
const modal_element = $('body').find('[data-remodal-id="metadata"]');
const modal = $.remodal.lookup[modal_element.data('remodal')];
modal_element.find('h1 strong').html(filename);
modal_element.find('h1 strong').html(cleanName);
if (fileObj.url) {
modal_element.find('.meta-preview').html(`<img src="${fileObj.url}" />`);
}
const container = modal_element.find('.meta-content').html('<ul />').find('ul');
Object.keys(fileObj.metadata).forEach((meta) => {
container.append(`<li><strong>${meta ? meta + ':' : ''}</strong> ${fileObj.metadata[meta]}</li>`);
const cleanMeta = fileObj.metadata[meta].replace('<', '&lt;').replace('>', '&gt;');
container.append(`<li><strong>${meta ? meta + ':' : ''}</strong> ${cleanMeta}</li>`);
});
modal.open();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,11 @@
# v1.1.8
## 01/28/2022
1. [](#new)
* Require **Grav 1.7.29**
3. [](#improved)
* Made path handling unicode-safe, use new `Utils::basename()` and `Utils::pathinfo()` everywhere
# v1.1.7
## 01/03/2022

View File

@ -13,7 +13,7 @@ The **Flex Objects** Plugin is for [Grav CMS](https://github.com/getgrav/grav).
## System Requirements
Plugin requires **Grav** v1.7.19 or later version in order to run. Additionally you need **Form Plugin** v5.1.0 and optionally **Admin Plugin** v1.10.19 or later version.
Plugin requires **Grav** v1.7.25 or later version in order to run. Additionally you need **Form Plugin** v5.1.0 and optionally **Admin Plugin** v1.10.25 or later version.
## Installation

View File

@ -16,7 +16,7 @@
{%- if title_config.template -%}
{{- include(template_from_string(title_config.template, 'configure title template')) -}}
{%- else -%}
{{- directory.title }} {{ 'PLUGIN_ADMIN.CONFIGURATION'|tu -}}
{{- directory.title|tu }} - {{ 'PLUGIN_ADMIN.CONFIGURATION'|tu -}}
{% endif %}
{%- endset %}

View File

@ -64,7 +64,7 @@
{% if allowed and user.authorize('admin.super') %}
{% if directory and object or action == 'add' %}
{% set save_location = object.getStorageFolder() ?? directory.getStorageFolder() %}
<div class="alert notice">{{ "PLUGIN_ADMIN.SAVE_LOCATION"|tu }}: <b>{{ url(save_location, false, true)|trim('/') }} {{ not object.exists ? '[NEW]' }}</b></div>
<div class="alert notice">{{ "PLUGIN_ADMIN.SAVE_LOCATION"|tu }}: <b>{{ url(save_location, false, true)|trim('/') }} {{ not object.exists ? '[' ~ 'PLUGIN_FLEX_OBJECTS.NEW'|tu|upper ~ ']' }}</b></div>
{% endif %}
{% endif %}
{% if object.exists and form.flash.exists %}

View File

@ -40,7 +40,7 @@
{%- if title_config.template -%}
{{- include(template_from_string(title_config.template, 'configure title template')) -}}
{%- else -%}
{{- directory.title -}}
{{- directory.title|tu -}}
{% endif %}
{%- endset %}

View File

@ -35,7 +35,7 @@
<h1>
{% if allowed %}
<i class="fa fa-fw {{ title_icon }}"></i>
{{ not object.exists ? '[NEW]' }} {{ title }}
{{ not object.exists ? '[' ~ 'PLUGIN_FLEX_OBJECTS.NEW'|tu|upper ~ ']' }} {{ title|tu }}
{% else %}
<i class="fa fa-fw fa-exclamation-triangle"></i>
{{ 'PLUGIN_ADMIN.ERROR'|tu }}

View File

@ -19,7 +19,7 @@
<h1>
{% if allowed %}
<i class="fa fa-fw {{ title_icon }}"></i>
{{ "PLUGIN_ADMIN.PREVIEW"|tu }}: {{ not object.exists ? '[NEW]' }} <strong>{{ title }}</strong>
{{ "PLUGIN_ADMIN.PREVIEW"|tu }}: {{ not object.exists ? '[' ~ 'PLUGIN_FLEX_OBJECTS.NEW'|tu|upper ~ ']' }} <strong>{{ title }}</strong>
{% else %}
<i class="fa fa-fw fa-exclamation-triangle"></i>
{{ 'PLUGIN_ADMIN.ERROR'|tu }}

View File

@ -89,7 +89,7 @@
{% if allowed and user.authorize('admin.super') %}
<div class="alert notice">
{% set save_location = object.getStorageFolder() ?: directory.getStorageFolder() %}
{{ "PLUGIN_ADMIN.SAVE_LOCATION"|tu }}: <b>{{ url(save_location, false, true)|trim('/') }} {{ not object.exists ? '[NEW]' }}</b> (type: <b>{{ (form.getValue('name') ?: 'default') }}</b>)
{{ "PLUGIN_ADMIN.SAVE_LOCATION"|tu }}: <b>{{ url(save_location, false, true)|trim('/') }} {{ not object.exists ? '[' ~ 'PLUGIN_FLEX_OBJECTS.NEW'|tu|upper ~ ']' }}</b> (type: <b>{{ (form.getValue('name') ?: 'default') }}</b>)
</div>
{% endif %}
{% if object.exists and form.flash.exists %}

View File

@ -60,7 +60,7 @@
{% set translation = (grav.twig.twig.filters['tu'] is defined ? text|tu : text|t)|trim %}
<label for="{{ id ~ '_no' }}">{{ (macro.spanToggle(translation, maxLen)|trim)|raw }}</label>
</div>
<span title="{{ directory.description }}">{{ directory.title }}</span>
<span title="{{ directory.description|tu }}">{{ directory.title|tu }}</span>
</div>
{% endfor %}
{% else %}

View File

@ -1,7 +1,7 @@
name: Flex Objects
slug: flex-objects
type: plugin
version: 1.1.7
version: 1.1.8
description: Flex Objects plugin allows you to manage Flex Objects in Grav Admin.
icon: list-alt
author:
@ -14,7 +14,7 @@ docs: https://github.com/trilbymedia/grav-plugin-flex-objects/blob/develop/READM
license: MIT
dependencies:
- { name: grav, version: '>=1.7.25' }
- { name: grav, version: '>=1.7.29' }
- { name: form, version: '>=5.1.0' }
form:

View File

@ -115,7 +115,7 @@ class MediaController extends AbstractController
$media = $object->getMedia();
$media->add($filename, $medium);
$basename = str_replace(['@3x', '@2x'], '', pathinfo($filename, PATHINFO_BASENAME));
$basename = str_replace(['@3x', '@2x'], '', Utils::pathinfo($filename, PATHINFO_BASENAME));
if (isset($media[$basename])) {
$metadata = $media[$basename]->metadata() ?: [];
}
@ -132,6 +132,43 @@ class MediaController extends AbstractController
return $this->createJsonResponse($response);
}
public function taskMediaUploadMeta(): ResponseInterface
{
$this->checkAuthorization('media.create');
$object = $this->getObject();
if (null === $object) {
throw new RuntimeException('Not Found', 404);
}
if (!method_exists($object, 'checkUploadedMediaFile')) {
throw new RuntimeException('Not Found', 404);
}
// Get updated object from Form Flash.
$flash = $this->getFormFlash($object);
if ($flash->exists()) {
$object = $flash->getObject() ?? $object;
$object->update([], $flash->getFilesByFields());
}
// Get field and data for the uploaded media.
$field = $this->getPost('field');
$data = $this->getPost('data');
$filename = Utils::basename($data['name']);
$response = [
'code' => 200,
'status' => 'success',
'message' => $this->translate('PLUGIN_ADMIN.FILE_UPLOADED_SUCCESSFULLY'),
'field' => $field,
'filename' => $filename,
'metadata' => $data
];
return $this->createJsonResponse($response);
}
/**
* @return ResponseInterface
*/
@ -207,7 +244,7 @@ class MediaController extends AbstractController
$metadata = [];
$include_metadata = $this->grav['config']->get('system.media.auto_metadata_exif', false);
if ($include_metadata) {
$basename = str_replace(['@3x', '@2x'], '', pathinfo($filename, PATHINFO_BASENAME));
$basename = str_replace(['@3x', '@2x'], '', Utils::pathinfo($filename, PATHINFO_BASENAME));
$media = $object->getMedia();
if (isset($media[$basename])) {
$metadata = $media[$basename]->metadata() ?: [];

View File

@ -65,7 +65,7 @@ class Flex implements FlexInterface
// Backwards compatibility to v1.0.0-rc.3
$blueprint = $legacy[$blueprint] ?? $blueprint;
$type = basename((string)$blueprint, '.yaml');
$type = Utils::basename((string)$blueprint, '.yaml');
if ($type) {
$this->managed[] = $type;
}
@ -238,7 +238,7 @@ class Flex implements FlexInterface
$directories = [];
$all = Folder::all('blueprints://flex-objects', $params);
foreach ($all as $url) {
$type = basename($url, '.yaml');
$type = Utils::basename($url, '.yaml');
$directory = new FlexDirectory($type, $url);
if ($directory->getConfig('hidden') !== true) {
$directories[$type] = $directory;

View File

@ -3,6 +3,7 @@
namespace Grav\Plugin\Console;
use Exception;
use Grav\Common\Utils;
use Grav\Common\Yaml;
use Grav\Console\ConsoleCommand;
use Symfony\Component\Console\Input\InputOption;
@ -51,7 +52,7 @@ class FlexConvertDataCommand extends ConsoleCommand
$out_raw = null;
$in = $input->getOption('in');
$in_parts = pathinfo($in);
$in_parts = Utils::pathinfo($in);
$in_extension = $in_parts['extension'];
$out_extension = $input->getOption('out');

View File

@ -9,6 +9,7 @@ use Grav\Common\Page\Pages;
use Grav\Common\Page\Types;
use Grav\Common\Plugin;
use Grav\Common\User\Interfaces\UserInterface;
use Grav\Common\Utils;
use Grav\Events\FlexRegisterEvent;
use Grav\Events\PermissionsRegisterEvent;
use Grav\Events\PluginsLoadedEvent;
@ -479,7 +480,7 @@ class FlexObjectsPlugin extends Plugin
foreach ($types as $blueprint) {
// Backwards compatibility to v1.0.0-rc.3
$blueprint = $map[$blueprint] ?? $blueprint;
$type = basename((string)$blueprint, '.yaml');
$type = Utils::basename((string)$blueprint, '.yaml');
if (!$type) {
continue;
}

View File

@ -14,6 +14,17 @@ PLUGIN_FLEX_OBJECTS:
CSV: "CSV"
PARENTS: "Eltern"
CONTROLLER:
TASK_DELETE_SUCCESS: 'Eintrag erfolgreich gelöscht'
TASK_DELETE_FAILURE: 'Löschen des Eintrags fehlgeschlagen: %s'
TASK_NEW_FOLDER_SUCCESS: 'Ordner erfolgreich angelegt'
TASK_COPY_SUCCESS: 'Kopie erfolgreich angelegt'
TASK_COPY_FAILURE: 'Kopieren des Eintrags fehlgeschlagen: %s'
TASK_SAVE_SUCCESS: 'Eintrag erfolgreich gespeichert'
TASK_SAVE_FAILURE: 'Speichern des Eintrags fehlgeschlagen: %s'
TASK_CONFIGURE_SUCCESS: 'Konfiguration erfolgreich gespeichert'
TASK_CONFIGURE_FAILURE: 'Speichern der Konfiguration fehlgeschlagen: %s'
ACTION:
CREATE_NEW: Neuen Eintrag anlegen
EDIT_ITEM: Eintrag bearbeiten
@ -57,4 +68,4 @@ PLUGIN_FLEX_OBJECTS:
BLUEPRINT_NO_LIST_TEMPLATE: "Bitte leg für diesen Typ ein Template an <b>flex-objects/types/%s/list.html.twig</b>"
LIST_EMPTY: "Keine Einträge vorhanden."
LIST_EMPTY_ADD: "Keine Einträge vorhanden. Klicke den <a href=\"%s\">Hinzufügen</a> Button um einen Eintrag anzulegen."
NO_FLEX_DIRECTORIES: "Keine Flex Verzeichnisse erkannt"
NO_FLEX_DIRECTORIES: "Keine Flex Verzeichnisse erkannt"

View File

@ -5,7 +5,7 @@ PLUGIN_FLEX_OBJECTS:
TITLE: Flex Objects
TYPES_TITLE: Directories
AFTER_SAVE: After Save…
LIST_INFO: 'Displaying {from} to {to} out of {total} records'
LIST_INFO: "Displaying {from} to {to} out of {total} records"
EMPTY_RESULT: The requested query returns no result
USE_BUILT_IN_CSS: "Use built in CSS"
@ -13,21 +13,23 @@ PLUGIN_FLEX_OBJECTS:
DIRECTORIES: "Directories"
CSV: "CSV"
PARENTS: "Parents"
NEW: "New"
CONTROLLER:
TASK_DELETE_SUCCESS: 'Entry deleted successfully'
TASK_DELETE_FAILURE: 'Failed to delete entry: %s'
TASK_NEW_FOLDER_SUCCESS: 'Folder created successfully'
TASK_COPY_SUCCESS: 'Copy created successfully'
TASK_COPY_FAILURE: 'Failed to create copy: %s'
TASK_SAVE_SUCCESS: 'Entry saved successfully'
TASK_SAVE_FAILURE: 'Failed to save entry: %s'
TASK_CONFIGURE_SUCCESS: 'Configuration saved successfully'
TASK_CONFIGURE_FAILURE: 'Failed to save configuration: %s'
TASK_DELETE_SUCCESS: "Entry deleted successfully"
TASK_DELETE_FAILURE: "Failed to delete entry: %s"
TASK_NEW_FOLDER_SUCCESS: "Folder created successfully"
TASK_COPY_SUCCESS: "Copy created successfully"
TASK_COPY_FAILURE: "Failed to create copy: %s"
TASK_SAVE_SUCCESS: "Entry saved successfully"
TASK_SAVE_FAILURE: "Failed to save entry: %s"
TASK_CONFIGURE_SUCCESS: "Configuration saved successfully"
TASK_CONFIGURE_FAILURE: "Failed to save configuration: %s"
ACTION:
CREATE_NEW: Create New Item
EDIT_ITEM: Edit Item
LIST_ITEMS: "List Items"
LIST_ITEM: List Items
DELETE_N: "Delete" # In some languages 'delete OBJECT' may need a special declination
REALLY_DELETE: "Are you sure you want to permanently delete the %s?"
@ -35,7 +37,6 @@ PLUGIN_FLEX_OBJECTS:
ADVANCED_OPTIONS: "Advanced Options"
APPLY_FILTERS: "Apply Filters"
RESET_FILTERS: "Reset to Defaults"
LIST_ITEMS: "List Items"
FILTER:
PAGE_ATTRIBUTES: "Page Attributes"
@ -68,5 +69,5 @@ PLUGIN_FLEX_OBJECTS:
BLUEPRINT_NO_LIST_ADVISE: "Please add list of fields to blueprints file."
BLUEPRINT_NO_LIST_TEMPLATE: "Please create template file for the type in <b>flex-objects/types/%s/list.html.twig</b>"
LIST_EMPTY: "There are currently no entries."
LIST_EMPTY_ADD: "There are currently no entries, click the <a href=\"%s\">Add</a> button to create a new one…"
NO_FLEX_DIRECTORIES: "No Flex Directories detected"
LIST_EMPTY_ADD: "There are currently no entries. Click the <a href=\"%s\">Add</a> button to create a new one…"
NO_FLEX_DIRECTORIES: "No Flex Directories detected"

View File

@ -0,0 +1,73 @@
PLUGIN_FLEX_OBJECTS:
PLUGIN_NAME: "Flex Objects"
PLUGIN_DESCRIPTION: "El plugin Flex Objects permite manejar Objetos Flex en Grav Admin."
TITLE: Flex Objects
TYPES_TITLE: Directorios
AFTER_SAVE: "Después de guardar…"
LIST_INFO: "Mostrando de {from} a {to} de {total} registros"
EMPTY_RESULT: The requested query returns no result
USE_BUILT_IN_CSS: "Usar CSS incorporado"
EXTRA_ADMIN_TWIG_PATH: "Ruta extra de twig para Admin"
DIRECTORIES: "Directorios"
CSV: "CSV"
PARENTS: "Madres"
NEW: Nuevo
CONTROLLER:
TASK_DELETE_SUCCESS: "Entrada eliminada exitosamente"
TASK_DELETE_FAILURE: "Falla al eliminar la entrada: %s"
TASK_NEW_FOLDER_SUCCESS: "Carpeta creada exitosamente"
TASK_COPY_SUCCESS: "Copia creada exitosamente"
TASK_COPY_FAILURE: "Falla al crear la copia: %s"
TASK_SAVE_SUCCESS: "Entrada guardada exitosamente"
TASK_SAVE_FAILURE: "Falla al guardar la entrada: %s"
TASK_CONFIGURE_SUCCESS: "Configuración gardada exitosamente"
TASK_CONFIGURE_FAILURE: "Falla al guardar la configuración: %s"
ACTION:
CREATE_NEW: "Crear nuevo ítem"
EDIT_ITEM: "Editar ítem"
LIST_ITEMS: "Listar ítems"
LIST_ITEM: "Listar ítem"
DELETE_N: "Eliminar"
REALLY_DELETE: "¿Realmente quieres eliminar %s permanentemente?"
SEARCH_PLACEHOLDER: "Buscar…"
ADVANCED_OPTIONS: "Opciones avazadas"
APPLY_FILTERS: "Aplicar filtros"
RESET_FILTERS: "Restablecer filtros"
FILTER:
PAGE_ATTRIBUTES: "Atributos de página"
PAGE_TYPES: "Tipos de página"
MODULAR_TYPES: "Tipos de módulo"
LANGUAGE:
USING_DEFAULT: "Usando archivo de idioma <b>Predeterminado</b>."
UNUSED_DEFAULT: "También existe un archvivo de idioma <b>Predeterminado</b>."
USING_OVERRIDE: "Usando el idioma de remplazo <b>%s</b>."
NOT_TRANSLATED_YET: "¡Esta página aún no ha sido traducida a <i class=\"fa fa-flag-o\"></i> <b>%s</b>!"
NO_FALLBACK_FOUND: "No se han encontrado traducciones de apoyo."
FALLING_BACK: "Retrocediendo a <b>%s</b>."
STATE:
LOADING: "Cargando…"
CREATED_SUCCESSFULLY: "Creado exitosamente"
UPDATED_SUCCESSFULLY: "Actualizado exitosamente"
DELETED_SUCCESSFULLY: "Eliminado exitosamente"
EDITING_DRAFT: "Estás editando un borrador."
NOT_CREATED_YET: "Esta página no existe hasta que se guarde."
ERROR:
BAD_DIRECTORY: "Directorio errado"
PAGE_NOT_FOUND: "Página no encontrada"
PAGE_NOT_EXIST: "¡Uy! Parece que esta página no existe."
PAGE_FORBIDDEN: "¡Uy! Parece que no tienes permiso para ver esta página."
LAYOUT_NOT_FOUND: "Maquetación de objeto '%s' no encontrada."
BLUEPRINT_NO_LIST: "Plano para <i>%s</i> no define campos mostrados ni remplazo de página de lista."
BLUEPRINT_NO_LIST_ADVISE: "Por favor agrega una lista de campos para el archivo de planos."
BLUEPRINT_NO_LIST_TEMPLATE: "Por favor crea un archivo de plantilla para el tipo en <b>flex-objects/types/%s/list.html.twig</b>"
LIST_EMPTY: "No hay entradas por el momento."
LIST_EMPTY_ADD: "No hay entradas por el momento. Da clic en el botón <a href=\"%s\">Agregar</a> para crear una nueva…"
NO_FLEX_DIRECTORIES: "No se detectan Directorios Flex"

View File

@ -1884,9 +1884,9 @@ flatted@^3.1.0:
integrity sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==
follow-redirects@^1.14.0:
version "1.14.4"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.4.tgz#838fdf48a8bbdd79e52ee51fb1c94e3ed98b9379"
integrity sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==
version "1.14.7"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685"
integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==
fs.realpath@^1.0.0:
version "1.0.0"
@ -2368,9 +2368,9 @@ nanocolors@^0.1.5:
integrity sha512-2pvTw6vYRaBLGir2xR7MxaJtyWkrn+C53EpW8yPotG+pdAwBvt0Xwk4VJ6VHLY0aLthVZPvDfm9TdZvrvAm5UQ==
nanoid@^3.1.25:
version "3.1.25"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152"
integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==
version "3.2.0"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c"
integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==
natural-compare@^1.4.0:
version "1.4.0"

View File

@ -1,8 +1,15 @@
# v5.1.5
## 01/24/2022
1. [](#bugfix)
* Fixed case in selectize field where custom new entries would not be stored in non `multiple` lists
# v5.1.4
## 11/16/2021
1. [](#bugfix)
* Fixed buttons no longer rendered [#537](https://github.com/getgrav/grav-plugin-form/issues/537)
* Allow `select` field to customize `autocomplete` attribute
# v5.1.3
## 10/26/2021

View File

@ -1,6 +1,6 @@
# Grav Form Plugin
The **form plugin** for [Grav](http://github.com/getgrav/grav) adds the ability to create and use forms. This is currently used extensively by the **admin** and **login** plugins.
The **form plugin** for [Grav](https://github.com/getgrav/grav) adds the ability to create and use forms. This is currently used extensively by the **admin** and **login** plugins.
# Installation
@ -22,7 +22,7 @@ enabled: true
The Learn site has two pages describing how to use the Form Plugin:
- [Forms](https://learn.getgrav.org/forms)
- [Add a contact form](http://learn.getgrav.org/forms/forms/example-form)
- [Add a contact form](https://learn.getgrav.org/forms/forms/example-form)
# Using email

View File

@ -1,7 +1,7 @@
name: Form
slug: form
type: plugin
version: 5.1.4
version: 5.1.5
description: Enables the forms handling
icon: check-square
author:

View File

@ -9,7 +9,7 @@
{
"name": "Team Grav",
"email": "devs@getgrav.org",
"homepage": "http://getgrav.org",
"homepage": "https://getgrav.org",
"role": "Developer"
}
],

View File

@ -95,6 +95,6 @@
</script>
<script src="https://www.google.com/recaptcha/api.js?onload=captchaOnloadCallback_{{ formName }}&render=explicit&hl={{ grav.language.language }}&theme={{ theme }} "
async defer></script>
<div class="g-recaptcha" id="g-recaptcha-{{ formName }}"></div>
<div class="g-recaptcha" id="g-recaptcha-{{ formName }}" data-theme="{{ theme }}"></div>
{% endif %}
{% endblock %}

View File

@ -19,6 +19,7 @@
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}
{% if field.tabindex %}tabindex="{{ field.tabindex }}"{% endif %}
{% if field.form %}form="{{ field.form }}"{% endif %}
{% if field.autocomplete is defined %}autocomplete="{{ field.autocomplete }}"{% endif %}
{% if field.key %}
data-key-observe="{{ (scope ~ field.name)|fieldName }}"
{% endif %}
@ -31,8 +32,9 @@
{% if field.placeholder %}<option value="" disabled selected>{{ field.placeholder|t|raw }}</option>{% endif %}
{% set options = field.options %}
{% if field.selectize.create and field.multiple %}
{% set options = options|merge(value|default([]))|array_unique %}
{% if field.selectize.create and value %}
{% set custom_value = field.multiple ? value : { (value): value } %}
{% set options = options|merge(custom_value|default([]))|array_unique %}
{% endif %}
{% set value = value is iterable ? value : value|string %}