mirror of
https://github.com/getformwork/formwork.git
synced 2025-01-17 21:49:04 +01:00
Improve Pages and Files management in the panel
This commit is contained in:
parent
024448f1af
commit
d9a0f08203
@ -40,14 +40,7 @@ fields:
|
||||
file: '${%SYSTEM_PATH%}/fields/dynamic/vars.php'
|
||||
|
||||
files:
|
||||
allowedExtensions:
|
||||
- .jpg
|
||||
- .jpeg
|
||||
- .png
|
||||
- .gif
|
||||
- .svg
|
||||
- .webp
|
||||
- .pdf
|
||||
allowedExtensions: []
|
||||
|
||||
images:
|
||||
jpegQuality: 85
|
||||
|
@ -3,6 +3,7 @@
|
||||
use Formwork\App;
|
||||
use Formwork\Languages\LanguageCodes;
|
||||
use Formwork\Panel\Utils\DateFormats;
|
||||
use Formwork\Utils\MimeType;
|
||||
|
||||
return function (App $app) {
|
||||
return [
|
||||
@ -19,5 +20,9 @@ return function (App $app) {
|
||||
'languages' => [
|
||||
'names' => LanguageCodes::names(),
|
||||
],
|
||||
|
||||
'mimeTypes' => [
|
||||
'extensionTypes' => MimeType::extensionTypes(),
|
||||
],
|
||||
];
|
||||
};
|
||||
|
@ -80,6 +80,7 @@ fields:
|
||||
type: tags
|
||||
label: '{{panel.options.system.files.allowedExtensions}}'
|
||||
pattern: '^\.[a-zA-Z0-9]+$'
|
||||
options@: mimeTypes.extensionTypes
|
||||
|
||||
cache.enabled:
|
||||
type: togglegroup
|
||||
|
@ -2,17 +2,18 @@
|
||||
|
||||
namespace Formwork\Files;
|
||||
|
||||
use Formwork\Config\Config;
|
||||
use Formwork\Exceptions\TranslatedException;
|
||||
use Formwork\Http\Files\UploadedFile;
|
||||
use Formwork\Utils\Arr;
|
||||
use Formwork\Utils\FileSystem;
|
||||
use Formwork\Utils\MimeType;
|
||||
use Formwork\Utils\Str;
|
||||
|
||||
class FileUploader
|
||||
{
|
||||
public function __construct(protected Config $config)
|
||||
/**
|
||||
* @param list<string> $allowedMimeTypes
|
||||
*/
|
||||
public function __construct(protected array $allowedMimeTypes)
|
||||
{
|
||||
}
|
||||
|
||||
@ -21,20 +22,20 @@ class FileUploader
|
||||
*/
|
||||
public function allowedMimeTypes(): array
|
||||
{
|
||||
return Arr::map($this->config->get('system.files.allowedExtensions'), fn (string $ext) => MimeType::fromExtension($ext));
|
||||
return $this->allowedMimeTypes;
|
||||
}
|
||||
|
||||
public function upload(UploadedFile $uploadedFile, string $destinationPath, ?string $name = null): File
|
||||
public function upload(UploadedFile $uploadedFile, string $destinationPath, ?string $name = null, bool $overwrite = false): File
|
||||
{
|
||||
$mimeType = MimeType::fromFile($uploadedFile->tempPath());
|
||||
|
||||
if (!in_array($mimeType, $this->allowedMimeTypes(), true)) {
|
||||
if (!in_array($mimeType, $this->allowedMimeTypes, true)) {
|
||||
throw new TranslatedException(sprintf('Invalid mime type %s for file uploads', $mimeType), 'upload.error.mimeType');
|
||||
}
|
||||
|
||||
$filename = Str::slug($name ?? pathinfo($uploadedFile->clientName(), PATHINFO_FILENAME)) . '.' . MimeType::toExtension($mimeType);
|
||||
|
||||
$uploadedFile->move($destinationPath, $filename);
|
||||
$uploadedFile->move($destinationPath, $filename, $overwrite);
|
||||
|
||||
return new File(FileSystem::joinPaths($destinationPath, $filename));
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace Formwork\Images\Exif;
|
||||
|
||||
use Formwork\Data\Contracts\Arrayable;
|
||||
use Formwork\Utils\Str;
|
||||
use Generator;
|
||||
|
||||
class ExifData implements Arrayable
|
||||
@ -77,4 +78,114 @@ class ExifData implements Arrayable
|
||||
? $this->tags[$key][1] ?? $this->tags[$key][0]
|
||||
: $default;
|
||||
}
|
||||
|
||||
public function hasPositionData(): bool
|
||||
{
|
||||
return $this->hasMultiple(['GPSLatitude', 'GPSLongitude']);
|
||||
}
|
||||
|
||||
public function dateTimeOriginal(): ?ExifDateTime
|
||||
{
|
||||
/** @var ExifDateTime|null */
|
||||
return $this->get('DateTimeOriginal');
|
||||
}
|
||||
|
||||
public function makeAndModel(): ?string
|
||||
{
|
||||
$make = (string) $this->get('Make');
|
||||
$model = (string) $this->get('Model');
|
||||
|
||||
if ($model === '') {
|
||||
return $make ?: null;
|
||||
}
|
||||
|
||||
return $make . ' ' . Str::after($model, $make . ' ');
|
||||
}
|
||||
|
||||
public function lensModel(): ?string
|
||||
{
|
||||
return $this->get('LensModel') ? str_replace('f/', 'ƒ/', (string) $this->get('LensModel')) : null;
|
||||
}
|
||||
|
||||
public function focalLength(): ?string
|
||||
{
|
||||
return $this->get('FocalLength') ? $this->get('FocalLength') . ' mm' : null;
|
||||
}
|
||||
|
||||
public function exposureTime(): ?string
|
||||
{
|
||||
return $this->get('ExposureTime') ? $this->get('ExposureTime') . ' s' : null;
|
||||
}
|
||||
|
||||
public function aperture(): ?string
|
||||
{
|
||||
return $this->get('FNumber') ? 'ƒ/' . $this->get('FNumber') : null;
|
||||
}
|
||||
|
||||
public function photographicSensitivity(): ?string
|
||||
{
|
||||
return $this->get('PhotographicSensitivity') ? 'ISO ' . $this->get('PhotographicSensitivity') : null;
|
||||
}
|
||||
|
||||
public function exposureCompensation(): ?string
|
||||
{
|
||||
/** @var float|null */
|
||||
$compensation = $this->get('ExposureBiasValue');
|
||||
return $compensation ? round($compensation, 2) . ' EV' : null;
|
||||
}
|
||||
|
||||
public function exposureProgram(): ?string
|
||||
{
|
||||
/** @var int */
|
||||
$exposureProgram = $this->getRaw('ExposureProgram', 0);
|
||||
|
||||
if ($exposureProgram < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return match ($exposureProgram) {
|
||||
2 => 'P',
|
||||
3 => 'A',
|
||||
4 => 'S',
|
||||
1 => 'M',
|
||||
default => 'AUTO',
|
||||
};
|
||||
}
|
||||
|
||||
public function hasAutoWhiteBalance(): ?bool
|
||||
{
|
||||
return $this->has('WhiteBalance') ? $this->getRaw('WhiteBalance') === 0 : null;
|
||||
}
|
||||
|
||||
public function hasFlashFired(): ?bool
|
||||
{
|
||||
return $this->has('Flash') ? (bool) ($this->getRaw('Flash') % 2) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 'average'|'evaluative'|'partial'|'spot'|null
|
||||
*/
|
||||
public function meteringMode(): ?string
|
||||
{
|
||||
/** @var int|null */
|
||||
$meteringMode = $this->getRaw('MeteringMode');
|
||||
if ($meteringMode === null) {
|
||||
return null;
|
||||
}
|
||||
if ($meteringMode <= 2 || $meteringMode > 6) {
|
||||
return 'average';
|
||||
}
|
||||
if ($meteringMode === 3) {
|
||||
return 'spot';
|
||||
}
|
||||
if ($meteringMode === 4 || $meteringMode == 5) {
|
||||
return 'evaluative';
|
||||
}
|
||||
return 'partial';
|
||||
}
|
||||
|
||||
public function colorSpace(): ?string
|
||||
{
|
||||
return $this->get('ColorSpace');
|
||||
}
|
||||
}
|
||||
|
@ -355,8 +355,6 @@ class Image extends File
|
||||
return [
|
||||
...parent::toArray(),
|
||||
'imageInfo' => $this->info()->toArray(),
|
||||
'exif' => $this->getExifData()?->toArray(),
|
||||
'colorProfile' => $this->getColorProfile()?->name(),
|
||||
'uri' => $this->uri(),
|
||||
];
|
||||
}
|
||||
|
@ -587,8 +587,7 @@ class Page extends Model implements Stringable
|
||||
'preferred' => $site->languages()->preferred(),
|
||||
]);
|
||||
|
||||
$this->files ??= new FileCollection($files);
|
||||
$this->files->sortBy('path');
|
||||
$this->files ??= (new FileCollection($files))->sort();
|
||||
|
||||
$this->data = [...$this->defaults(), ...$this->data];
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ use Formwork\Router\RouteParams;
|
||||
use Formwork\Utils\Arr;
|
||||
use Formwork\Utils\Date;
|
||||
use Formwork\Utils\FileSystem;
|
||||
use Formwork\Utils\MimeType;
|
||||
use Formwork\Utils\Str;
|
||||
use Formwork\Utils\Uri;
|
||||
use RuntimeException;
|
||||
@ -191,12 +192,8 @@ class PagesController extends AbstractController
|
||||
throw new UnexpectedValueException('Unexpected missing page route');
|
||||
}
|
||||
|
||||
// Redirect if page route has changed
|
||||
if ($routeParams->get('page') !== ($route = trim($page->route(), '/'))) {
|
||||
return $this->redirect($this->generateRoute('panel.pages.edit', ['page' => $route]));
|
||||
}
|
||||
|
||||
break;
|
||||
// Redirect to avoid ERR_CACHE_MISS
|
||||
return $this->redirect($this->generateRoute('panel.pages.edit', ['page' => $page->route()]));
|
||||
}
|
||||
|
||||
$this->modal('changes');
|
||||
@ -394,31 +391,97 @@ class PagesController extends AbstractController
|
||||
if ($newName !== $previousName) {
|
||||
if ($page->files()->has($newName)) {
|
||||
$this->panel()->notify($this->translate('panel.pages.page.cannotRenameFile.fileAlreadyExists'), 'error');
|
||||
return $this->redirect($this->generateRoute('panel.pages.edit', ['page' => $routeParams->get('page')]));
|
||||
}
|
||||
|
||||
} else {
|
||||
FileSystem::move($page->path() . $previousName, $page->path() . $newName);
|
||||
$this->panel()->notify($this->translate('panel.pages.page.fileRenamed'), 'success');
|
||||
}
|
||||
}
|
||||
|
||||
$previousFileRoute = $this->generateRoute('panel.pages.file', ['page' => $routeParams->get('page'), 'filename' => $previousName]);
|
||||
|
||||
if (Str::removeEnd((string) Uri::path($request->referer()), '/') === $this->site()->uri($previousFileRoute)) {
|
||||
return $this->redirect($this->generateRoute('panel.pages.file', ['page' => $routeParams->get('page'), 'filename' => $newName]));
|
||||
}
|
||||
|
||||
return $this->redirect($this->generateRoute('panel.pages.edit', ['page' => $routeParams->get('page')]));
|
||||
}
|
||||
|
||||
public function getFileInfo(RouteParams $routeParams): JsonResponse
|
||||
/**
|
||||
* Pages@replaceFile action
|
||||
*/
|
||||
public function replaceFile(RouteParams $routeParams): RedirectResponse
|
||||
{
|
||||
$this->ensurePermission('pages.getFileInfo');
|
||||
$this->ensurePermission('pages.replaceFiles');
|
||||
|
||||
$page = $this->site()->findPage($routeParams->get('page'));
|
||||
|
||||
$filename = $routeParams->get('filename');
|
||||
|
||||
if ($page === null) {
|
||||
return JsonResponse::error($this->translate('panel.pages.page.cannotRenameFile.pageNotFound'));
|
||||
$this->panel()->notify($this->translate('panel.pages.page.cannotReplaceFile.pageNotFound'), 'error');
|
||||
return $this->redirectToReferer(default: '/pages/');
|
||||
}
|
||||
|
||||
if (!$page->files()->has($routeParams->get('filename'))) {
|
||||
return JsonResponse::error($this->translate('panel.pages.page.cannotRenameFile.fileNotFound'));
|
||||
if (!$page->files()->has($filename)) {
|
||||
$this->panel()->notify($this->translate('panel.pages.page.cannotReplaceFile.fileNotFound'), 'error');
|
||||
return $this->redirectToReferer(default: '/pages/');
|
||||
}
|
||||
|
||||
return JsonResponse::success('Yes!', data: $page->files()->get($routeParams->get('filename'))->toArray());
|
||||
if (!$this->request->files()->isEmpty()) {
|
||||
$files = $this->request->files()->getAll();
|
||||
|
||||
if (count($files) > 1) {
|
||||
$this->panel()->notify($this->translate('panel.pages.page.cannotReplaceFile.multipleFiles'), 'error');
|
||||
return $this->redirectToReferer(default: '/pages/');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->processPageUploads($this->request->files()->getAll(), $page, [$page->files()->get($filename)->mimeType()], FileSystem::name($filename), true);
|
||||
} catch (TranslatedException $e) {
|
||||
$this->panel()->notify($this->translate('upload.error', $e->getTranslatedMessage()), 'error');
|
||||
return $this->redirect($this->generateRoute('panel.pages.edit', ['page' => $routeParams->get('page')]));
|
||||
}
|
||||
}
|
||||
|
||||
$this->panel()->notify($this->translate('panel.uploader.uploaded'), 'success');
|
||||
return $this->redirectToReferer(default: '/pages/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Pages@file action
|
||||
*/
|
||||
public function file(RouteParams $routeParams): Response
|
||||
{
|
||||
$this->ensurePermission('pages.file');
|
||||
|
||||
$page = $this->site()->findPage($routeParams->get('page'));
|
||||
|
||||
$filename = $routeParams->get('filename');
|
||||
|
||||
if ($page === null) {
|
||||
$this->panel()->notify($this->translate('panel.pages.page.cannotReplaceFile.pageNotFound'), 'error');
|
||||
return $this->redirectToReferer(default: '/pages/');
|
||||
}
|
||||
|
||||
if (!$page->files()->has($filename)) {
|
||||
$this->panel()->notify($this->translate('panel.pages.page.cannotReplaceFile.fileNotFound'), 'error');
|
||||
return $this->redirect($this->generateRoute('panel.pages.edit', ['page' => $routeParams->get('page')]));
|
||||
}
|
||||
|
||||
$files = $page->files();
|
||||
$file = $files->get($filename);
|
||||
$fileIndex = $files->indexOf($file);
|
||||
|
||||
$this->modal('renameFile');
|
||||
$this->modal('deleteFile');
|
||||
|
||||
return new Response($this->view('pages.file', [
|
||||
'title' => $this->translate('panel.pages.editPage', $page->title()),
|
||||
'page' => $page,
|
||||
'file' => $file,
|
||||
'previousFile' => $files->nth($fileIndex - 1),
|
||||
'nextFile' => $files->nth($fileIndex + 1),
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -616,10 +679,13 @@ class PagesController extends AbstractController
|
||||
* Process page uploads
|
||||
*
|
||||
* @param array<UploadedFile> $files
|
||||
* @param list<string> $mimeTypes
|
||||
*/
|
||||
protected function processPageUploads(array $files, Page $page): void
|
||||
protected function processPageUploads(array $files, Page $page, ?array $mimeTypes = null, ?string $name = null, bool $overwrite = false): void
|
||||
{
|
||||
$fileUploader = new FileUploader($this->config);
|
||||
$mimeTypes ??= Arr::map($this->config->get('system.files.allowedExtensions'), fn (string $ext) => MimeType::fromExtension($ext));
|
||||
|
||||
$fileUploader = new FileUploader($mimeTypes);
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (!$file->isUploaded()) {
|
||||
@ -628,7 +694,7 @@ class PagesController extends AbstractController
|
||||
if ($page->path() === null) {
|
||||
throw new UnexpectedValueException('Unexpected missing page path');
|
||||
}
|
||||
$uploadedFile = $fileUploader->upload($file, $page->path());
|
||||
$uploadedFile = $fileUploader->upload($file, $page->path(), $name, $overwrite);
|
||||
// Process JPEG and PNG images according to system options (e.g. quality)
|
||||
if ($this->config->get('system.uploads.processImages') && in_array($uploadedFile->mimeType(), ['image/jpeg', 'image/png'], true)) {
|
||||
$image = new Image($uploadedFile->path(), $this->config->get('system.images'));
|
||||
|
@ -14,7 +14,9 @@ use Formwork\Panel\Security\Password;
|
||||
use Formwork\Panel\Users\User;
|
||||
use Formwork\Parsers\Yaml;
|
||||
use Formwork\Router\RouteParams;
|
||||
use Formwork\Utils\Arr;
|
||||
use Formwork\Utils\FileSystem;
|
||||
use Formwork\Utils\MimeType;
|
||||
use RuntimeException;
|
||||
|
||||
class UsersController extends AbstractController
|
||||
@ -205,7 +207,9 @@ class UsersController extends AbstractController
|
||||
{
|
||||
$imagesPath = FileSystem::joinPaths($this->config->get('system.panel.paths.assets'), '/images/users/');
|
||||
|
||||
$fileUploader = new FileUploader($this->config);
|
||||
$mimeTypes = Arr::map($this->config->get('system.files.allowedExtensions'), fn (string $ext) => MimeType::fromExtension($ext));
|
||||
|
||||
$fileUploader = new FileUploader($mimeTypes);
|
||||
|
||||
$uploadedFile = $fileUploader->upload($file, $imagesPath, FileSystem::randomName());
|
||||
|
||||
|
@ -179,4 +179,12 @@ class MimeType
|
||||
{
|
||||
return static::getAssociatedExtensions($mimeType)[0] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function extensionTypes(): array
|
||||
{
|
||||
return Arr::mapKeys(Arr::map(self::MIME_TYPES, fn ($value, $key) => sprintf('.%s (%s)', $key, $value)), fn ($key) => '.' . $key);
|
||||
}
|
||||
}
|
||||
|
2
panel/assets/css/panel-dark.min.css
vendored
2
panel/assets/css/panel-dark.min.css
vendored
File diff suppressed because one or more lines are too long
2
panel/assets/css/panel.min.css
vendored
2
panel/assets/css/panel.min.css
vendored
File diff suppressed because one or more lines are too long
1
panel/assets/icons/svg/arrow-left-circle.svg
Normal file
1
panel/assets/icons/svg/arrow-left-circle.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg class="icon" width="16" height="16" viewBox="0 0 16 16" fill="currentColor"><g clip-path="url(#arrow-left-circle__a)"><path d="M6.146 4.854A.5.5 0 0 1 7 5.207v5.586a.5.5 0 0 1-.854.353L3.354 8.354a.5.5 0 0 1 0-.708l2.792-2.792Z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M12.75 8a.75.75 0 0 0-.75-.75H7a.75.75 0 0 0 0 1.5h5a.75.75 0 0 0 .75-.75Z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M8 1.5a6.5 6.5 0 1 1 0 13 6.5 6.5 0 0 1 0-13ZM16 8A8 8 0 1 0 0 8a8 8 0 0 0 16 0Z"/></g><defs><clipPath id="arrow-left-circle__a"><path d="M16 0H0v16h16z"/></clipPath></defs></svg>
|
After Width: | Height: | Size: 590 B |
1
panel/assets/icons/svg/page-down.svg
Normal file
1
panel/assets/icons/svg/page-down.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg class="icon" width="16" height="16" viewBox="0 0 16 16" fill="currentColor"><path d="M8.75 9h2.043a.5.5 0 0 1 .353.854l-2.792 2.792a.5.5 0 0 1-.708 0L4.854 9.854A.5.5 0 0 1 5.207 9H7.25V5a.75.75 0 0 1 1.5 0v4Z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M3.5 0A1.5 1.5 0 0 0 2 1.5v13A1.5 1.5 0 0 0 3.5 16h9a1.5 1.5 0 0 0 1.5-1.5v-13A1.5 1.5 0 0 0 12.5 0h-9Zm9 1.5h-9v13h9v-13Z"/></svg>
|
After Width: | Height: | Size: 398 B |
1
panel/assets/icons/svg/page-up.svg
Normal file
1
panel/assets/icons/svg/page-up.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg class="icon" width="16" height="16" viewBox="0 0 16 16" fill="currentColor"><path d="M8.75 8h2.043a.5.5 0 0 0 .353-.854L8.354 4.354a.5.5 0 0 0-.708 0L4.854 7.146A.5.5 0 0 0 5.207 8H7.25v4a.75.75 0 0 0 1.5 0V8Z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M3.5 0A1.5 1.5 0 0 0 2 1.5v13A1.5 1.5 0 0 0 3.5 16h9a1.5 1.5 0 0 0 1.5-1.5v-13A1.5 1.5 0 0 0 12.5 0h-9Zm9 1.5h-9v13h9v-13Z"/></svg>
|
After Width: | Height: | Size: 398 B |
1
panel/assets/icons/svg/sparks.svg
Normal file
1
panel/assets/icons/svg/sparks.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M9.328 2.625A9.395 9.395 0 0 1 9.22 3a8.082 8.082 0 0 1-1.127 2.33c-.547.766-1.207 1.356-1.934 1.728l-.926.475a.4.4 0 0 0-.17.181.643.643 0 0 0-.064.286c0 .101.022.201.064.285a.4.4 0 0 0 .17.181l.926.475c.727.372 1.387.962 1.934 1.727a8.08 8.08 0 0 1 1.127 2.33c.038.125.074.25.107.377l.339 1.297c.025.096.07.178.13.237s.13.09.203.09a.291.291 0 0 0 .204-.09.512.512 0 0 0 .13-.237l.339-1.296c.033-.128.069-.253.107-.377a8.08 8.08 0 0 1 1.127-2.33c.547-.766 1.207-1.356 1.933-1.728l.926-.475a.4.4 0 0 0 .17-.181A.643.643 0 0 0 15 8a.643.643 0 0 0-.064-.286.4.4 0 0 0-.17-.181l-.926-.475c-.726-.372-1.386-.962-1.933-1.727a8.08 8.08 0 0 1-1.127-2.33 9.378 9.378 0 0 1-.107-.377l-.34-1.298a.511.511 0 0 0-.129-.237A.291.291 0 0 0 10 1a.291.291 0 0 0-.203.09.511.511 0 0 0-.13.237l-.34 1.298ZM10 5.07c.203.398.432.778.686 1.133a7.28 7.28 0 0 0 1.809 1.798 7.279 7.279 0 0 0-1.809 1.797A8.874 8.874 0 0 0 10 10.93a8.89 8.89 0 0 0-.685-1.133A7.28 7.28 0 0 0 7.506 8a7.28 7.28 0 0 0 1.809-1.798A8.88 8.88 0 0 0 10 5.069Z" clip-rule="evenodd"/><path d="M2.867 2.13a.204.204 0 0 1 .052-.094A.116.116 0 0 1 3 2c.03 0 .058.013.082.036a.205.205 0 0 1 .052.095l.135.519a3.3 3.3 0 0 0 .494 1.083c.219.306.482.542.773.69l.37.19a.16.16 0 0 1 .068.073A.257.257 0 0 1 5 4.8c0 .041-.009.08-.026.114a.16.16 0 0 1-.067.073l-.37.19a2.19 2.19 0 0 0-.774.69 3.3 3.3 0 0 0-.494 1.084l-.135.518a.205.205 0 0 1-.052.095A.116.116 0 0 1 3 7.6a.116.116 0 0 1-.081-.036.204.204 0 0 1-.052-.095l-.136-.518a3.3 3.3 0 0 0-.493-1.083 2.196 2.196 0 0 0-.774-.691l-.37-.19a.16.16 0 0 1-.068-.073A.257.257 0 0 1 1 4.8c0-.04.009-.08.026-.114a.16.16 0 0 1 .067-.073l.371-.19c.29-.148.555-.384.774-.69A3.3 3.3 0 0 0 2.73 2.65l.136-.52Zm1.536 7.351a.205.205 0 0 1 .052-.094.116.116 0 0 1 .081-.036c.03 0 .058.012.082.036a.205.205 0 0 1 .052.094l.135.52a3.3 3.3 0 0 0 .494 1.082c.219.307.483.542.773.691l.37.19a.16.16 0 0 1 .068.073.257.257 0 0 1 .026.114c0 .04-.009.08-.026.114a.16.16 0 0 1-.067.072l-.37.19c-.291.15-.555.385-.774.691a3.299 3.299 0 0 0-.494 1.083l-.135.519a.204.204 0 0 1-.052.095.117.117 0 0 1-.082.036.117.117 0 0 1-.081-.036.204.204 0 0 1-.052-.095l-.136-.519a3.299 3.299 0 0 0-.493-1.083 2.195 2.195 0 0 0-.774-.69l-.37-.19a.16.16 0 0 1-.068-.073.257.257 0 0 1-.026-.114c0-.041.01-.08.026-.114a.16.16 0 0 1 .068-.073l.37-.19c.29-.149.555-.384.774-.69A3.3 3.3 0 0 0 4.267 10l.136-.519Z"/><path fill-rule="evenodd" d="M4.848 10.152c-.015-.05-.03-.1-.043-.152l-.135-.519a.205.205 0 0 0-.052-.094.116.116 0 0 0-.082-.036.116.116 0 0 0-.081.036.205.205 0 0 0-.052.094l-.136.52a3.783 3.783 0 0 1-.084.277 3.38 3.38 0 0 1-.193.451 2.938 2.938 0 0 1-.216.354 2.387 2.387 0 0 1-.485.508c-.093.071-.19.132-.289.183l-.37.19a.16.16 0 0 0-.068.073.257.257 0 0 0-.026.114c0 .04.01.08.026.114a.16.16 0 0 0 .068.072l.37.19a1.907 1.907 0 0 1 .32.207c.165.132.318.295.454.484.078.11.15.229.216.354a3.386 3.386 0 0 1 .277.73l.136.518c.01.038.028.071.052.095a.117.117 0 0 0 .081.036c.03 0 .058-.013.082-.036a.204.204 0 0 0 .052-.095l.135-.519a3.783 3.783 0 0 1 .085-.278 3.38 3.38 0 0 1 .193-.451c.065-.125.137-.243.216-.354a2.387 2.387 0 0 1 .485-.508c.092-.07.189-.132.288-.183l.37-.19a.16.16 0 0 0 .068-.072.257.257 0 0 0 .026-.114.255.255 0 0 0-.026-.114.16.16 0 0 0-.067-.073l-.37-.19a1.91 1.91 0 0 1-.32-.207 2.386 2.386 0 0 1-.454-.484 2.938 2.938 0 0 1-.216-.354 3.38 3.38 0 0 1-.235-.577Z" clip-rule="evenodd"/></svg>
|
After Width: | Height: | Size: 3.4 KiB |
42
panel/assets/js/app.min.js
vendored
42
panel/assets/js/app.min.js
vendored
File diff suppressed because one or more lines are too long
@ -144,6 +144,18 @@ return [
|
||||
'methods' => ['POST'],
|
||||
],
|
||||
|
||||
'panel.pages.replaceFile' => [
|
||||
'path' => '/pages/{page}/file/{filename}/replace/',
|
||||
'action' => 'Formwork\Panel\Controllers\PagesController@replaceFile',
|
||||
'methods' => ['POST'],
|
||||
],
|
||||
|
||||
'panel.pages.file' => [
|
||||
'path' => '/pages/{page}/file/{filename}/',
|
||||
'action' => 'Formwork\Panel\Controllers\PagesController@file',
|
||||
'methods' => ['GET'],
|
||||
],
|
||||
|
||||
'panel.pages.delete' => [
|
||||
'path' => '/pages/{page}/delete/',
|
||||
'action' => 'Formwork\Panel\Controllers\PagesController@delete',
|
||||
|
@ -78,3 +78,11 @@ pre {
|
||||
::placeholder {
|
||||
color: $color-base-300;
|
||||
}
|
||||
|
||||
.link-secondary {
|
||||
color: $color-base-300;
|
||||
|
||||
&:hover {
|
||||
color: $color-base-200;
|
||||
}
|
||||
}
|
||||
|
@ -116,3 +116,15 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin checkbox-background($size, $color) {
|
||||
$half: $size * 0.5;
|
||||
|
||||
background-image: linear-gradient(45deg, $color 25%, transparent 25%), linear-gradient(-45deg, $color 25%, transparent 25%), linear-gradient(45deg, transparent 75%, $color 75%), linear-gradient(-45deg, transparent 75%, $color 75%);
|
||||
background-position:
|
||||
0 0,
|
||||
0 $half,
|
||||
$half (-$half),
|
||||
(-$half) 0;
|
||||
background-size: $size $size;
|
||||
}
|
||||
|
@ -106,3 +106,28 @@
|
||||
.pages-tree.is-filtered .pages-tree-item .page-details {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.page-file-preview-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background-color: $color-base-600;
|
||||
}
|
||||
|
||||
.page-file-preview-link {
|
||||
cursor: zoom-in;
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
.page-file-preview-image {
|
||||
max-height: 40.5rem;
|
||||
object-fit: contain;
|
||||
@include checkbox-background(1.5rem, rgba($color-black, 0.125));
|
||||
}
|
||||
|
||||
.page-file-info-entry-title {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.page-file-info-entry-uri {
|
||||
word-break: break-word;
|
||||
}
|
||||
|
@ -22,10 +22,10 @@ export class Files {
|
||||
});
|
||||
}
|
||||
|
||||
$$("video.file-thumbnail", filesList).forEach((video: HTMLVideoElement) => {
|
||||
video.addEventListener("click", () => {
|
||||
if (!video.controls) {
|
||||
video.controls = true;
|
||||
$$(".files-item", filesList).forEach((item: HTMLElement) => {
|
||||
item.addEventListener("click", (event) => {
|
||||
if (!(event.target as HTMLElement).closest(".dropdown") && typeof item.dataset.href === "string") {
|
||||
location.href = item.dataset.href;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -224,6 +224,34 @@ export class Pages {
|
||||
});
|
||||
});
|
||||
|
||||
$$("[data-command=replaceFile]").forEach((element) => {
|
||||
element.addEventListener("click", () => {
|
||||
const form = document.createElement("form");
|
||||
form.hidden = true;
|
||||
form.action = element.dataset.action as string;
|
||||
form.method = "post";
|
||||
form.enctype = "multipart/form-data";
|
||||
|
||||
const fileInput = document.createElement("input");
|
||||
fileInput.name = "file";
|
||||
fileInput.type = "file";
|
||||
fileInput.accept = element.dataset.extension as string;
|
||||
form.appendChild(fileInput);
|
||||
|
||||
const csrfInput = document.createElement("input");
|
||||
csrfInput.name = "csrf-token";
|
||||
csrfInput.value = ($("meta[name=csrf-token]") as HTMLMetaElement).content;
|
||||
form.appendChild(csrfInput);
|
||||
|
||||
fileInput.click();
|
||||
|
||||
fileInput.addEventListener("change", () => {
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function expandAllPages() {
|
||||
$$(".pages-tree-item").forEach((element) => {
|
||||
element.classList.add("is-expanded");
|
||||
|
@ -135,6 +135,38 @@ panel.pages.editor.redo: Wiederholen
|
||||
panel.pages.editor.summary: Zusammenfassung
|
||||
panel.pages.editor.undo: Rückgängig
|
||||
panel.pages.editPage: Seite bearbeiten %s
|
||||
panel.pages.file.backToPage: Zurück zur Seite
|
||||
panel.pages.file.exif: EXIF
|
||||
panel.pages.file.info: Info
|
||||
panel.pages.file.info.image.colorDepth: Farbtiefe
|
||||
panel.pages.file.info.image.colorNumber: Anzahl der Farben
|
||||
panel.pages.file.info.image.colorProfile: Farbprofil
|
||||
panel.pages.file.info.image.colorSpace: Farbraum
|
||||
panel.pages.file.info.image.dimensions: Abmessungen
|
||||
panel.pages.file.info.image.dimensions.widthByHeightPixels: '%d × %d Pixel'
|
||||
panel.pages.file.info.image.exif.aperture: Blende
|
||||
panel.pages.file.info.image.exif.camera: Kamera
|
||||
panel.pages.file.info.image.exif.creationDateAndTime: Erstellungsdatum und -zeit
|
||||
panel.pages.file.info.image.exif.exposureCompensation: Belichtungskorrektur
|
||||
panel.pages.file.info.image.exif.exposureProgram: Belichtungsprogramm
|
||||
panel.pages.file.info.image.exif.exposureTime: Belichtungszeit
|
||||
panel.pages.file.info.image.exif.flash: Blitz
|
||||
panel.pages.file.info.image.exif.focalLength: Brennweite
|
||||
panel.pages.file.info.image.exif.lensModel: Objektivmodell
|
||||
panel.pages.file.info.image.exif.meteringMode: Belichtungsmessmethode
|
||||
panel.pages.file.info.image.exif.sensitivity: Empfindlichkeit
|
||||
panel.pages.file.info.image.exif.whiteBalance: Weißabgleich
|
||||
panel.pages.file.info.image.frames: '%d Frames'
|
||||
panel.pages.file.info.image.framesCount: Anzahl der Frames
|
||||
panel.pages.file.info.image.repeats: '%d Wiederholungen'
|
||||
panel.pages.file.info.image.repeatsCount: Anzahl der Wiederholungen
|
||||
panel.pages.file.info.image.resolution: Auflösung
|
||||
panel.pages.file.info.lastModifiedTime: Letzte Änderungszeit
|
||||
panel.pages.file.info.mimeType: MIME-Typ
|
||||
panel.pages.file.info.size: Größe
|
||||
panel.pages.file.info.uri: URI
|
||||
panel.pages.file.position: Position
|
||||
panel.pages.file.preview: Vorschau
|
||||
panel.pages.files: Dateien
|
||||
panel.pages.languages: Sprachen
|
||||
panel.pages.languages.addLanguage: "%s hinzufügen"
|
||||
@ -146,6 +178,8 @@ panel.pages.newPage.slug: Seiten-Slug
|
||||
panel.pages.newPage.slugSuggestion: Nur Buchstaben, Zahlen und Bindestriche
|
||||
panel.pages.newPage.template: Vorlage
|
||||
panel.pages.newPage.title: Titel
|
||||
panel.pages.next: Nächste Seite
|
||||
panel.pages.nextFile: Nächste Datei
|
||||
panel.pages.options: Optionen
|
||||
panel.pages.page: Seite
|
||||
panel.pages.page.actions: Aktionen
|
||||
@ -174,6 +208,9 @@ panel.pages.page.cannotMove: Seite kann nicht verschoben werden
|
||||
panel.pages.page.cannotRenameFile.fileAlreadyExists: Datei kann nicht umbenannt werden, eine Datei mit demselben Namen existiert bereits
|
||||
panel.pages.page.cannotRenameFile.fileNotFound: Datei kann nicht umbenannt werden, Datei nicht gefunden
|
||||
panel.pages.page.cannotRenameFile.pageNotFound: Datei kann nicht umbenannt werden, Seite nicht gefunden
|
||||
panel.pages.page.cannotReplaceFile.fileNotFound: Datei kann nicht ersetzt werden, Datei nicht gefunden
|
||||
panel.pages.page.cannotReplaceFile.multipleFiles: Datei kann nicht ersetzt werden, mehrere Dateien angegeben
|
||||
panel.pages.page.cannotReplaceFile.pageNotFound: Datei kann nicht ersetzt werden, Seite nicht gefunden
|
||||
panel.pages.page.cannotUploadFile.pageNotFound: Datei kann nicht hochgeladen werden, Seite nicht gefunden
|
||||
panel.pages.page.created: Seite erstellt!
|
||||
panel.pages.page.deleted: Seite gelöscht
|
||||
@ -202,8 +239,11 @@ panel.pages.pages.search: Seiten durchsuchen...
|
||||
panel.pages.parent: Übergeordnete Seite
|
||||
panel.pages.preview: Vorschau
|
||||
panel.pages.previewFile: Vorschau
|
||||
panel.pages.previous: Vorherige Seite
|
||||
panel.pages.previousFile: Vorherige Datei
|
||||
panel.pages.renameFile: Datei umbenennen
|
||||
panel.pages.renameFile.name: Name
|
||||
panel.pages.replaceFile: Datei ersetzen
|
||||
panel.pages.save: Speichern
|
||||
panel.pages.status.notPublished: Nicht veröffentlicht
|
||||
panel.pages.status.notRoutable: Nicht routbar
|
||||
|
@ -135,6 +135,38 @@ panel.pages.editor.redo: Redo
|
||||
panel.pages.editor.summary: Summary
|
||||
panel.pages.editor.undo: Undo
|
||||
panel.pages.editPage: Edit Page %s
|
||||
panel.pages.file.backToPage: Back to Page
|
||||
panel.pages.file.exif: EXIF
|
||||
panel.pages.file.info: Info
|
||||
panel.pages.file.info.image.colorDepth: Color Depth
|
||||
panel.pages.file.info.image.colorNumber: Color Number
|
||||
panel.pages.file.info.image.colorProfile: Color Profile
|
||||
panel.pages.file.info.image.colorSpace: Color Space
|
||||
panel.pages.file.info.image.dimensions: Dimensions
|
||||
panel.pages.file.info.image.dimensions.widthByHeightPixels: '%d × %d pixels'
|
||||
panel.pages.file.info.image.exif.aperture: Aperture
|
||||
panel.pages.file.info.image.exif.camera: Camera
|
||||
panel.pages.file.info.image.exif.creationDateAndTime: Creation Date and Time
|
||||
panel.pages.file.info.image.exif.exposureCompensation: Exposure Compensation
|
||||
panel.pages.file.info.image.exif.exposureProgram: Exposure Program
|
||||
panel.pages.file.info.image.exif.exposureTime: Exposure Time
|
||||
panel.pages.file.info.image.exif.flash: Flash
|
||||
panel.pages.file.info.image.exif.focalLength: Focal Length
|
||||
panel.pages.file.info.image.exif.lensModel: Lens Model
|
||||
panel.pages.file.info.image.exif.meteringMode: Metering Mode
|
||||
panel.pages.file.info.image.exif.sensitivity: Sensitivity
|
||||
panel.pages.file.info.image.exif.whiteBalance: White Balance
|
||||
panel.pages.file.info.image.frames: '%d frames'
|
||||
panel.pages.file.info.image.framesCount: Frames Count
|
||||
panel.pages.file.info.image.repeats: '%d repeats'
|
||||
panel.pages.file.info.image.repeatsCount: Repeats Count
|
||||
panel.pages.file.info.image.resolution: Resolution
|
||||
panel.pages.file.info.lastModifiedTime: Last Modified Time
|
||||
panel.pages.file.info.mimeType: MIME Type
|
||||
panel.pages.file.info.size: Size
|
||||
panel.pages.file.info.uri: URI
|
||||
panel.pages.file.position: Position
|
||||
panel.pages.file.preview: Preview
|
||||
panel.pages.files: Files
|
||||
panel.pages.languages: Languages
|
||||
panel.pages.languages.addLanguage: Add %s
|
||||
@ -146,6 +178,8 @@ panel.pages.newPage.slug: Page Slug
|
||||
panel.pages.newPage.slugSuggestion: letters, numbers and dashes only
|
||||
panel.pages.newPage.template: Template
|
||||
panel.pages.newPage.title: Title
|
||||
panel.pages.next: Next Page
|
||||
panel.pages.nextFile: Next File
|
||||
panel.pages.options: Options
|
||||
panel.pages.page: Page
|
||||
panel.pages.page.actions: Actions
|
||||
@ -174,6 +208,9 @@ panel.pages.page.cannotMove: Cannot move page
|
||||
panel.pages.page.cannotRenameFile.fileAlreadyExists: Cannot rename file, a file with the same name already exists
|
||||
panel.pages.page.cannotRenameFile.fileNotFound: Cannot rename file, file not found
|
||||
panel.pages.page.cannotRenameFile.pageNotFound: Cannot rename file, page not found
|
||||
panel.pages.page.cannotReplaceFile.fileNotFound: Cannot replace file, file not found
|
||||
panel.pages.page.cannotReplaceFile.multipleFiles: Cannot replace file, multiple file given
|
||||
panel.pages.page.cannotReplaceFile.pageNotFound: Cannot replace file, page not found
|
||||
panel.pages.page.cannotUploadFile.pageNotFound: Cannot upload file, page not found
|
||||
panel.pages.page.created: Page created!
|
||||
panel.pages.page.deleted: Page deleted
|
||||
@ -202,8 +239,11 @@ panel.pages.pages.search: Search Pages...
|
||||
panel.pages.parent: Parent Page
|
||||
panel.pages.preview: Preview
|
||||
panel.pages.previewFile: Preview
|
||||
panel.pages.previous: Previous Page
|
||||
panel.pages.previousFile: Previous File
|
||||
panel.pages.renameFile: Rename File
|
||||
panel.pages.renameFile.name: Name
|
||||
panel.pages.replaceFile: Replace File
|
||||
panel.pages.save: Save
|
||||
panel.pages.status.notPublished: Not Published
|
||||
panel.pages.status.notRoutable: Not Routable
|
||||
|
@ -135,6 +135,38 @@ panel.pages.editor.redo: Rehacer
|
||||
panel.pages.editor.summary: Resumen
|
||||
panel.pages.editor.undo: Deshacer
|
||||
panel.pages.editPage: Editar página %s
|
||||
panel.pages.file.backToPage: Volver a la página
|
||||
panel.pages.file.exif: EXIF
|
||||
panel.pages.file.info: Información
|
||||
panel.pages.file.info.image.colorDepth: Profundidad de color
|
||||
panel.pages.file.info.image.colorNumber: Número de colores
|
||||
panel.pages.file.info.image.colorProfile: Perfil de color
|
||||
panel.pages.file.info.image.colorSpace: Espacio de color
|
||||
panel.pages.file.info.image.dimensions: Dimensiones
|
||||
panel.pages.file.info.image.dimensions.widthByHeightPixels: '%d × %d píxeles'
|
||||
panel.pages.file.info.image.exif.aperture: Apertura
|
||||
panel.pages.file.info.image.exif.camera: Cámara
|
||||
panel.pages.file.info.image.exif.creationDateAndTime: Fecha y hora de creación
|
||||
panel.pages.file.info.image.exif.exposureCompensation: Compensación de exposición
|
||||
panel.pages.file.info.image.exif.exposureProgram: Programa de exposición
|
||||
panel.pages.file.info.image.exif.exposureTime: Tiempo de exposición
|
||||
panel.pages.file.info.image.exif.flash: Flash
|
||||
panel.pages.file.info.image.exif.focalLength: Longitud focal
|
||||
panel.pages.file.info.image.exif.lensModel: Modelo de lente
|
||||
panel.pages.file.info.image.exif.meteringMode: Modo de medición
|
||||
panel.pages.file.info.image.exif.sensitivity: Sensibilidad
|
||||
panel.pages.file.info.image.exif.whiteBalance: Balance de blancos
|
||||
panel.pages.file.info.image.frames: '%d frames'
|
||||
panel.pages.file.info.image.framesCount: Cantidad de frames
|
||||
panel.pages.file.info.image.repeats: '%d repeticiones'
|
||||
panel.pages.file.info.image.repeatsCount: Cantidad de repeticiones
|
||||
panel.pages.file.info.image.resolution: Resolución
|
||||
panel.pages.file.info.lastModifiedTime: Última modificación
|
||||
panel.pages.file.info.mimeType: Tipo MIME
|
||||
panel.pages.file.info.size: Tamaño
|
||||
panel.pages.file.info.uri: URI
|
||||
panel.pages.file.position: Posición
|
||||
panel.pages.file.preview: Vista previa
|
||||
panel.pages.files: Archivos
|
||||
panel.pages.languages: Idiomas
|
||||
panel.pages.languages.addLanguage: Añadir %s
|
||||
@ -146,6 +178,8 @@ panel.pages.newPage.slug: Slug de la página
|
||||
panel.pages.newPage.slugSuggestion: solo letras, números y guiones
|
||||
panel.pages.newPage.template: Plantilla
|
||||
panel.pages.newPage.title: Título
|
||||
panel.pages.next: Página siguiente
|
||||
panel.pages.nextFile: Archivo siguiente
|
||||
panel.pages.options: Opciones
|
||||
panel.pages.page: Página
|
||||
panel.pages.page.actions: Acciones
|
||||
@ -174,6 +208,9 @@ panel.pages.page.cannotMove: No se puede mover la página
|
||||
panel.pages.page.cannotRenameFile.fileAlreadyExists: No se puede renombrar el archivo, ya existe un archivo con el mismo nombre
|
||||
panel.pages.page.cannotRenameFile.fileNotFound: No se puede renombrar el archivo, archivo no encontrado
|
||||
panel.pages.page.cannotRenameFile.pageNotFound: No se puede renombrar el archivo, página no encontrada
|
||||
panel.pages.page.cannotReplaceFile.fileNotFound: No se puede reemplazar el archivo, archivo no encontrado
|
||||
panel.pages.page.cannotReplaceFile.multipleFiles: No se puede reemplazar el archivo, se proporcionaron varios archivos
|
||||
panel.pages.page.cannotReplaceFile.pageNotFound: No se puede reemplazar el archivo, página no encontrada
|
||||
panel.pages.page.cannotUploadFile.pageNotFound: No se puede subir el archivo, página no encontrada
|
||||
panel.pages.page.created: ¡Página creada!
|
||||
panel.pages.page.deleted: Página eliminada
|
||||
@ -202,8 +239,11 @@ panel.pages.pages.search: Buscar páginas...
|
||||
panel.pages.parent: Página principal
|
||||
panel.pages.preview: Vista previa
|
||||
panel.pages.previewFile: Vista previa
|
||||
panel.pages.previous: Página anterior
|
||||
panel.pages.previousFile: Archivo anterior
|
||||
panel.pages.renameFile: Renombrar archivo
|
||||
panel.pages.renameFile.name: Nombre
|
||||
panel.pages.replaceFile: Reemplazar archivo
|
||||
panel.pages.save: Guardar
|
||||
panel.pages.status.notPublished: No publicado
|
||||
panel.pages.status.notRoutable: No enrutable
|
||||
|
@ -135,6 +135,38 @@ panel.pages.editor.redo: Refaire
|
||||
panel.pages.editor.summary: Résumé
|
||||
panel.pages.editor.undo: Annuler
|
||||
panel.pages.editPage: Modifier la page %s
|
||||
panel.pages.file.backToPage: Retour à la page
|
||||
panel.pages.file.exif: EXIF
|
||||
panel.pages.file.info: Info
|
||||
panel.pages.file.info.image.colorDepth: Profondeur de couleur
|
||||
panel.pages.file.info.image.colorNumber: Nombre de couleurs
|
||||
panel.pages.file.info.image.colorProfile: Profil de couleur
|
||||
panel.pages.file.info.image.colorSpace: Espace de couleur
|
||||
panel.pages.file.info.image.dimensions: Dimensions
|
||||
panel.pages.file.info.image.dimensions.widthByHeightPixels: '%d × %d pixels'
|
||||
panel.pages.file.info.image.exif.aperture: Ouverture
|
||||
panel.pages.file.info.image.exif.camera: Appareil photo
|
||||
panel.pages.file.info.image.exif.creationDateAndTime: Date et heure de création
|
||||
panel.pages.file.info.image.exif.exposureCompensation: Compensation d'exposition
|
||||
panel.pages.file.info.image.exif.exposureProgram: Programme d'exposition
|
||||
panel.pages.file.info.image.exif.exposureTime: Temps d'exposition
|
||||
panel.pages.file.info.image.exif.flash: Flash
|
||||
panel.pages.file.info.image.exif.focalLength: Longueur focale
|
||||
panel.pages.file.info.image.exif.lensModel: Modèle d'objectif
|
||||
panel.pages.file.info.image.exif.meteringMode: Mode de mesure
|
||||
panel.pages.file.info.image.exif.sensitivity: Sensibilité
|
||||
panel.pages.file.info.image.exif.whiteBalance: Balance des blancs
|
||||
panel.pages.file.info.image.frames: '%d trames'
|
||||
panel.pages.file.info.image.framesCount: Nombre de trames
|
||||
panel.pages.file.info.image.repeats: '%d répétitions'
|
||||
panel.pages.file.info.image.repeatsCount: Nombre de répétitions
|
||||
panel.pages.file.info.image.resolution: Résolution
|
||||
panel.pages.file.info.lastModifiedTime: Dernière modification
|
||||
panel.pages.file.info.mimeType: Type MIME
|
||||
panel.pages.file.info.size: Taille
|
||||
panel.pages.file.info.uri: URI
|
||||
panel.pages.file.position: Position
|
||||
panel.pages.file.preview: Aperçu
|
||||
panel.pages.files: Fichiers
|
||||
panel.pages.languages: Langues
|
||||
panel.pages.languages.addLanguage: Ajouter %s
|
||||
@ -146,6 +178,8 @@ panel.pages.newPage.slug: Permalien
|
||||
panel.pages.newPage.slugSuggestion: lettres, chiffres et tirets seulement
|
||||
panel.pages.newPage.template: Modèle (Template)
|
||||
panel.pages.newPage.title: Titre
|
||||
panel.pages.next: Page suivante
|
||||
panel.pages.nextFile: Fichier suivant
|
||||
panel.pages.options: Options
|
||||
panel.pages.page: Page
|
||||
panel.pages.page.actions: Actions
|
||||
@ -174,6 +208,9 @@ panel.pages.page.cannotMove: Impossible de déplacer la page
|
||||
panel.pages.page.cannotRenameFile.fileAlreadyExists: Impossible de renommer le fichier, un fichier portant le même nom existe déjà
|
||||
panel.pages.page.cannotRenameFile.fileNotFound: Impossible de renommer le fichier, fichier introuvable
|
||||
panel.pages.page.cannotRenameFile.pageNotFound: Impossible de renommer le fichier, page introuvable
|
||||
panel.pages.page.cannotReplaceFile.fileNotFound: Impossible de remplacer le fichier, fichier non trouvé
|
||||
panel.pages.page.cannotReplaceFile.multipleFiles: Impossible de remplacer le fichier, plusieurs fichiers spécifiés
|
||||
panel.pages.page.cannotReplaceFile.pageNotFound: Impossible de remplacer le fichier, page non trouvée
|
||||
panel.pages.page.cannotUploadFile.pageNotFound: Impossible de téléverser le fichier, page introuvable
|
||||
panel.pages.page.created: Page créée !
|
||||
panel.pages.page.deleted: Page supprimée
|
||||
@ -202,8 +239,11 @@ panel.pages.pages.search: Rechercher dans les Pages…
|
||||
panel.pages.parent: Parent
|
||||
panel.pages.preview: Aperçu
|
||||
panel.pages.previewFile: Aperçu
|
||||
panel.pages.previous: Page précédente
|
||||
panel.pages.previousFile: Fichier précédent
|
||||
panel.pages.renameFile: Renommer le fichier
|
||||
panel.pages.renameFile.name: Nom
|
||||
panel.pages.replaceFile: Remplacer le fichier
|
||||
panel.pages.save: Enregistrer
|
||||
panel.pages.status.notPublished: Brouillon
|
||||
panel.pages.status.notRoutable: Inaccessible
|
||||
|
@ -135,6 +135,38 @@ panel.pages.editor.redo: Ripeti
|
||||
panel.pages.editor.summary: Sommario
|
||||
panel.pages.editor.undo: Annulla
|
||||
panel.pages.editPage: Modifica pagina %s
|
||||
panel.pages.file.backToPage: Torna alla pagina
|
||||
panel.pages.file.exif: EXIF
|
||||
panel.pages.file.info: Informazioni
|
||||
panel.pages.file.info.image.colorDepth: Profondità colore
|
||||
panel.pages.file.info.image.colorNumber: Numero di colori
|
||||
panel.pages.file.info.image.colorProfile: Profilo colore
|
||||
panel.pages.file.info.image.colorSpace: Spazio colore
|
||||
panel.pages.file.info.image.dimensions: Misure
|
||||
panel.pages.file.info.image.dimensions.widthByHeightPixels: '%d × %d pixel'
|
||||
panel.pages.file.info.image.exif.aperture: Apertura
|
||||
panel.pages.file.info.image.exif.camera: Fotocamera
|
||||
panel.pages.file.info.image.exif.creationDateAndTime: Data e ora di creazione
|
||||
panel.pages.file.info.image.exif.exposureCompensation: Compensazione esposizione
|
||||
panel.pages.file.info.image.exif.exposureProgram: Programma di esposizione
|
||||
panel.pages.file.info.image.exif.exposureTime: Tempo di esposizione
|
||||
panel.pages.file.info.image.exif.flash: Flash
|
||||
panel.pages.file.info.image.exif.focalLength: Lunghezza focale
|
||||
panel.pages.file.info.image.exif.lensModel: Obiettivo
|
||||
panel.pages.file.info.image.exif.meteringMode: Modalità di misurazione
|
||||
panel.pages.file.info.image.exif.sensitivity: Sensibilità
|
||||
panel.pages.file.info.image.exif.whiteBalance: Bilanciamento del bianco
|
||||
panel.pages.file.info.image.frames: '%d fotogrammi'
|
||||
panel.pages.file.info.image.framesCount: Numero di fotogrammi
|
||||
panel.pages.file.info.image.repeats: '%d ripetizioni'
|
||||
panel.pages.file.info.image.repeatsCount: Numero di ripetizioni
|
||||
panel.pages.file.info.image.resolution: Risoluzione
|
||||
panel.pages.file.info.lastModifiedTime: Ultime modifiche
|
||||
panel.pages.file.info.mimeType: Tipo MIME
|
||||
panel.pages.file.info.size: Dimensioni file
|
||||
panel.pages.file.info.uri: URI
|
||||
panel.pages.file.position: Posizione
|
||||
panel.pages.file.preview: Anteprima
|
||||
panel.pages.files: File
|
||||
panel.pages.languages: Lingue
|
||||
panel.pages.languages.addLanguage: Aggiungi %s
|
||||
@ -146,6 +178,8 @@ panel.pages.newPage.slug: Indirizzo pagina
|
||||
panel.pages.newPage.slugSuggestion: solo lettere, numeri e trattini
|
||||
panel.pages.newPage.template: Template
|
||||
panel.pages.newPage.title: Titolo
|
||||
panel.pages.next: Pagina successiva
|
||||
panel.pages.nextFile: File successivo
|
||||
panel.pages.options: Opzioni
|
||||
panel.pages.page: Pagina
|
||||
panel.pages.page.actions: Azioni
|
||||
@ -174,6 +208,9 @@ panel.pages.page.cannotMove: Impossibile spostare la pagina
|
||||
panel.pages.page.cannotRenameFile.fileAlreadyExists: Impossibile rinominare il file, un file con lo stesso nome esiste già
|
||||
panel.pages.page.cannotRenameFile.fileNotFound: Impossibile rinominare il file, file non trovato
|
||||
panel.pages.page.cannotRenameFile.pageNotFound: Impossibile rinominare il file, pagina non trovata
|
||||
panel.pages.page.cannotReplaceFile.fileNotFound: Impossibile sostituire il file, file non trovato
|
||||
panel.pages.page.cannotReplaceFile.multipleFiles: Impossibile sostituire il file, forniti più file
|
||||
panel.pages.page.cannotReplaceFile.pageNotFound: Impossibile sostituire il file, pagina non trovata
|
||||
panel.pages.page.cannotUploadFile.pageNotFound: Impossibile caricare il file, pagina non trovata
|
||||
panel.pages.page.created: Pagina creata!
|
||||
panel.pages.page.deleted: Pagina eliminata
|
||||
@ -202,8 +239,11 @@ panel.pages.pages.search: Cerca pagine...
|
||||
panel.pages.parent: Pagina superiore
|
||||
panel.pages.preview: Anteprima
|
||||
panel.pages.previewFile: Anteprima
|
||||
panel.pages.previous: Pagina precedente
|
||||
panel.pages.previousFile: File precedente
|
||||
panel.pages.renameFile: Rinomina file
|
||||
panel.pages.renameFile.name: Nome
|
||||
panel.pages.replaceFile: Sostituisci file
|
||||
panel.pages.save: Salva
|
||||
panel.pages.status.notPublished: Non pubblicato
|
||||
panel.pages.status.notRoutable: Non raggiungibile
|
||||
|
@ -135,6 +135,38 @@ panel.pages.editor.redo: Refazer
|
||||
panel.pages.editor.summary: Sumário
|
||||
panel.pages.editor.undo: Desfazer
|
||||
panel.pages.editPage: Editar Página %s
|
||||
panel.pages.file.backToPage: Voltar à Página
|
||||
panel.pages.file.exif: EXIF
|
||||
panel.pages.file.info: Informações
|
||||
panel.pages.file.info.image.colorDepth: Profundidade de Cor
|
||||
panel.pages.file.info.image.colorNumber: Número de Cores
|
||||
panel.pages.file.info.image.colorProfile: Perfil de Cor
|
||||
panel.pages.file.info.image.colorSpace: Espaço de Cor
|
||||
panel.pages.file.info.image.dimensions: Dimensões
|
||||
panel.pages.file.info.image.dimensions.widthByHeightPixels: '%d × %d píxeis'
|
||||
panel.pages.file.info.image.exif.aperture: Abertura
|
||||
panel.pages.file.info.image.exif.camera: Câmara
|
||||
panel.pages.file.info.image.exif.creationDateAndTime: Data e Hora de Criação
|
||||
panel.pages.file.info.image.exif.exposureCompensation: Compensação de Exposição
|
||||
panel.pages.file.info.image.exif.exposureProgram: Programa de Exposição
|
||||
panel.pages.file.info.image.exif.exposureTime: Tempo de Exposição
|
||||
panel.pages.file.info.image.exif.flash: Flash
|
||||
panel.pages.file.info.image.exif.focalLength: Distância Focal
|
||||
panel.pages.file.info.image.exif.lensModel: Modelo da Lente
|
||||
panel.pages.file.info.image.exif.meteringMode: Modo de Medição
|
||||
panel.pages.file.info.image.exif.sensitivity: Sensibilidade
|
||||
panel.pages.file.info.image.exif.whiteBalance: Balanço de Branco
|
||||
panel.pages.file.info.image.frames: '%d frames'
|
||||
panel.pages.file.info.image.framesCount: Contagem de Frames
|
||||
panel.pages.file.info.image.repeats: '%d repetições'
|
||||
panel.pages.file.info.image.repeatsCount: Contagem de Repetições
|
||||
panel.pages.file.info.image.resolution: Resolução
|
||||
panel.pages.file.info.lastModifiedTime: Última Modificação
|
||||
panel.pages.file.info.mimeType: Tipo MIME
|
||||
panel.pages.file.info.size: Tamanho
|
||||
panel.pages.file.info.uri: URI
|
||||
panel.pages.file.position: Posição
|
||||
panel.pages.file.preview: Pré-visualização
|
||||
panel.pages.files: Ficheiros
|
||||
panel.pages.languages: Idiomas
|
||||
panel.pages.languages.addLanguage: Criar %s
|
||||
@ -146,6 +178,8 @@ panel.pages.newPage.slug: Slug da Página
|
||||
panel.pages.newPage.slugSuggestion: letras, números e hifens apenas
|
||||
panel.pages.newPage.template: Template
|
||||
panel.pages.newPage.title: Título
|
||||
panel.pages.next: Próxima Página
|
||||
panel.pages.nextFile: Próximo Ficheiro
|
||||
panel.pages.options: Opções
|
||||
panel.pages.page: Página
|
||||
panel.pages.page.actions: Acções
|
||||
@ -174,6 +208,9 @@ panel.pages.page.cannotMove: Não é possível mover a página
|
||||
panel.pages.page.cannotRenameFile.fileAlreadyExists: Não é possível renomear o arquivo, um arquivo com o mesmo nome já existe
|
||||
panel.pages.page.cannotRenameFile.fileNotFound: Não é possível renomear o arquivo, arquivo não encontrado
|
||||
panel.pages.page.cannotRenameFile.pageNotFound: Não é possível renomear o arquivo, página não encontrada
|
||||
panel.pages.page.cannotReplaceFile.fileNotFound: Não é possível substituir o ficheiro, ficheiro não encontrado
|
||||
panel.pages.page.cannotReplaceFile.multipleFiles: Não é possível substituir o ficheiro, vários ficheiros fornecidos
|
||||
panel.pages.page.cannotReplaceFile.pageNotFound: Não é possível substituir o ficheiro, página não encontrada
|
||||
panel.pages.page.cannotUploadFile.pageNotFound: Não é possível efectuar envio do ficheiro, página não encontrada
|
||||
panel.pages.page.created: Página criada!
|
||||
panel.pages.page.deleted: Página removida
|
||||
@ -202,8 +239,11 @@ panel.pages.pages.search: Procurar Páginas...
|
||||
panel.pages.parent: Página Parente
|
||||
panel.pages.preview: Preview
|
||||
panel.pages.previewFile: Preview
|
||||
panel.pages.previous: Página Anterior
|
||||
panel.pages.previousFile: Ficheiro Anterior
|
||||
panel.pages.renameFile: Renomear Arquivo
|
||||
panel.pages.renameFile.name: Nome
|
||||
panel.pages.replaceFile: Substituir Ficheiro
|
||||
panel.pages.save: Guardar
|
||||
panel.pages.status.notPublished: Não Publicado
|
||||
panel.pages.status.notRoutable: Não Roteável
|
||||
|
@ -135,6 +135,38 @@ panel.pages.editor.redo: Выбор
|
||||
panel.pages.editor.summary: Краткий
|
||||
panel.pages.editor.undo: Открыть
|
||||
panel.pages.editPage: Отредактировать страницу %s
|
||||
panel.pages.file.backToPage: Назад к странице
|
||||
panel.pages.file.exif: EXIF
|
||||
panel.pages.file.info: Информация
|
||||
panel.pages.file.info.image.colorDepth: Глубина цвета
|
||||
panel.pages.file.info.image.colorNumber: Количество цветов
|
||||
panel.pages.file.info.image.colorProfile: Профиль цвета
|
||||
panel.pages.file.info.image.colorSpace: Цветовое пространство
|
||||
panel.pages.file.info.image.dimensions: Размеры
|
||||
panel.pages.file.info.image.dimensions.widthByHeightPixels: '%d × %d пикселей'
|
||||
panel.pages.file.info.image.exif.aperture: Диафрагма
|
||||
panel.pages.file.info.image.exif.camera: Камера
|
||||
panel.pages.file.info.image.exif.creationDateAndTime: Дата и время создания
|
||||
panel.pages.file.info.image.exif.exposureCompensation: Компенсация экспозиции
|
||||
panel.pages.file.info.image.exif.exposureProgram: Программа экспозиции
|
||||
panel.pages.file.info.image.exif.exposureTime: Время экспозиции
|
||||
panel.pages.file.info.image.exif.flash: Вспышка
|
||||
panel.pages.file.info.image.exif.focalLength: Фокусное расстояние
|
||||
panel.pages.file.info.image.exif.lensModel: Модель объектива
|
||||
panel.pages.file.info.image.exif.meteringMode: Режим измерения
|
||||
panel.pages.file.info.image.exif.sensitivity: Чувствительность
|
||||
panel.pages.file.info.image.exif.whiteBalance: Баланс белого
|
||||
panel.pages.file.info.image.frames: '%d кадров'
|
||||
panel.pages.file.info.image.framesCount: Количество кадров
|
||||
panel.pages.file.info.image.repeats: '%d повторов'
|
||||
panel.pages.file.info.image.repeatsCount: Количество повторений
|
||||
panel.pages.file.info.image.resolution: Разрешение
|
||||
panel.pages.file.info.lastModifiedTime: Последнее изменение
|
||||
panel.pages.file.info.mimeType: Тип MIME
|
||||
panel.pages.file.info.size: Размер
|
||||
panel.pages.file.info.uri: URI
|
||||
panel.pages.file.position: Позиция
|
||||
panel.pages.file.preview: Просмотр
|
||||
panel.pages.files: Файлы
|
||||
panel.pages.languages: Языки
|
||||
panel.pages.languages.addLanguage: Добавлять %s
|
||||
@ -146,6 +178,8 @@ panel.pages.newPage.slug: Страница Slug
|
||||
panel.pages.newPage.slugSuggestion: буквы, цифры и дефис только
|
||||
panel.pages.newPage.template: Шаблон
|
||||
panel.pages.newPage.title: Заглавие
|
||||
panel.pages.next: Следующая страница
|
||||
panel.pages.nextFile: Следующий файл
|
||||
panel.pages.options: Параметры
|
||||
panel.pages.page: Страница
|
||||
panel.pages.page.actions: Действия
|
||||
@ -174,6 +208,9 @@ panel.pages.page.cannotMove: Невозможно переместить стр
|
||||
panel.pages.page.cannotRenameFile.fileAlreadyExists: Невозможно переименовать файл, файл с таким именем уже существует
|
||||
panel.pages.page.cannotRenameFile.fileNotFound: Невозможно переименовать файл, файл не найден
|
||||
panel.pages.page.cannotRenameFile.pageNotFound: Невозможно переименовать файл, страница не найдена
|
||||
panel.pages.page.cannotReplaceFile.fileNotFound: Невозможно заменить файл, файл не найден
|
||||
panel.pages.page.cannotReplaceFile.multipleFiles: Невозможно заменить файл, указаны несколько файлов
|
||||
panel.pages.page.cannotReplaceFile.pageNotFound: Невозможно заменить файл, страница не найдена
|
||||
panel.pages.page.cannotUploadFile.pageNotFound: Невозможно загрузить файл, страница не найдена
|
||||
panel.pages.page.created: Страница сгенерирована!
|
||||
panel.pages.page.deleted: Страница удалена
|
||||
@ -202,8 +239,11 @@ panel.pages.pages.search: Поиск Страницы ...
|
||||
panel.pages.parent: Родитель страницы
|
||||
panel.pages.preview: Предварительный просмотр
|
||||
panel.pages.previewFile: Предварительный просмотр
|
||||
panel.pages.previous: Предыдущая страница
|
||||
panel.pages.previousFile: Предыдущий файл
|
||||
panel.pages.renameFile: Переименовать файл
|
||||
panel.pages.renameFile.name: Имя
|
||||
panel.pages.replaceFile: Заменить файл
|
||||
panel.pages.save: Сохранить
|
||||
panel.pages.status.notPublished: Не Опубликовано
|
||||
panel.pages.status.notRoutable: Не маршрутизируемый
|
||||
|
@ -7,8 +7,8 @@
|
||||
</div>
|
||||
|
||||
<div class="files-items">
|
||||
<?php foreach ($page->files()->sort() as $file) : ?>
|
||||
<div class="files-item">
|
||||
<?php foreach ($page->files() as $file) : ?>
|
||||
<div class="files-item" data-href="<?= $panel->uri('/pages/' . trim($page->route(), '/') . '/file/' . $file->name() . '/') ?>">
|
||||
<?php if ($file->type() === 'image') : ?>
|
||||
<div class="file-thumbnail" style="background-image:url('<?= $file->square(300, 'contain')->uri() ?>');"></div>
|
||||
<?php endif ?>
|
||||
@ -22,10 +22,14 @@
|
||||
<div class="dropdown">
|
||||
<button type="button" class="button button-link dropdown-button" title="<?= $this->translate('panel.files.actions') ?>" data-dropdown="dropdown-<?= $file->hash() ?>"><?= $this->icon('ellipsis-v') ?></button>
|
||||
<div class="dropdown-menu" id="dropdown-<?= $file->hash() ?>">
|
||||
<a class="dropdown-item" href="<?= $panel->uri('/pages/' . trim($page->route(), '/') . '/file/' . $file->name() . '/') ?>"><?= $this->icon('info-circle') ?> <?= $this->translate('panel.pages.file.info') ?></a>
|
||||
<a class="dropdown-item" href="<?= $page->uri($file->name(), includeLanguage: false) ?>" target="formwork-preview-file-<?= $file->hash() ?>"><?= $this->icon('eye') ?> <?= $this->translate('panel.pages.previewFile') ?></a>
|
||||
<?php if ($panel->user()->permissions()->has('pages.renameFiles')) : ?>
|
||||
<a class="dropdown-item" data-modal="renameFileModal" data-modal-action="<?= $panel->uri('/pages/' . trim($page->route(), '/') . '/file/' . $file->name() . '/rename/') ?>" data-filename="<?= $file->name() ?>"><?= $this->icon('pencil') ?> <?= $this->translate('panel.pages.renameFile') ?></a>
|
||||
<?php endif ?>
|
||||
<?php if ($panel->user()->permissions()->has('pages.replaceFiles')) : ?>
|
||||
<a class="dropdown-item" data-command="replaceFile" data-action="<?= $panel->uri('/pages/' . trim($page->route(), '/') . '/file/' . $file->name() . '/replace/') ?>" data-extension=".<?= $file->extension() ?>"><?= $this->icon('cloud-upload') ?> <?= $this->translate('panel.pages.replaceFile') ?></a>
|
||||
<?php endif ?>
|
||||
<?php if ($panel->user()->permissions()->has('pages.deleteFiles')) : ?>
|
||||
<a class="dropdown-item" data-modal="deleteFileModal" data-modal-action="<?= $panel->uri('/pages/' . trim($page->route(), '/') . '/file/' . $file->name() . '/delete/') ?>"><?= $this->icon('trash') ?> <?= $this->translate('panel.pages.deleteFile') ?></a>
|
||||
<?php endif ?>
|
||||
|
@ -11,7 +11,7 @@
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="button button-secondary" data-dismiss="slugModal"><?= $this->icon('times-circle') ?> <?= $this->translate('panel.modal.action.cancel') ?></button>
|
||||
<button type="button" class="button button-accent button-right" data-command="continue"><?= $this->icon('check-circle') ?> <?= $this->translate('panel.modal.action.continue') ?></button>
|
||||
<button type="button" class="button button-link button-right" data-command="generate-slug" title="<?= $this->translate('panel.pages.changeSlug.generate') ?>"><?= $this->icon('bolt') ?></button>
|
||||
<button type="button" class="button button-link button-right" data-command="generate-slug" title="<?= $this->translate('panel.pages.changeSlug.generate') ?>"><?= $this->icon('sparks') ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -19,6 +19,8 @@
|
||||
<input type="hidden" id="language" name="language" value="<?= $currentLanguage ?>">
|
||||
<?php endif ?>
|
||||
<div>
|
||||
<a class="<?= $this->classes(['button', 'button-link', 'show-from-md', 'disabled' => !$page->previousSibling()]) ?>" role="button" <?php if ($page->previousSibling()) : ?>href="<?= $panel->uri('/pages/' . trim($page->previousSibling()->route(), '/') . '/edit/') ?>" <?php endif ?> title="<?= $this->translate('panel.pages.previous') ?>" aria-label="<?= $this->translate('panel.pages.previous') ?>"><?= $this->icon('chevron-left') ?></a>
|
||||
<a class="<?= $this->classes(['button', 'button-link', 'show-from-md', 'disabled' => !$page->nextSibling()]) ?>" role="button" <?php if ($page->nextSibling()) : ?>href="<?= $panel->uri('/pages/' . trim($page->nextSibling()->route(), '/') . '/edit/') ?>" <?php endif ?> title="<?= $this->translate('panel.pages.next') ?>" aria-label="<?= $this->translate('panel.pages.next') ?>"><?= $this->icon('chevron-right') ?></a>
|
||||
<a class="<?= $this->classes(['button', 'button-link', 'disabled' => !$page->published() || !$page->routable()]) ?>" role="button" <?php if ($page->published() && $page->routable()) : ?>href="<?= $page->uri(includeLanguage: $currentLanguage ?: true) ?>" <?php endif ?> target="formwork-preview-<?= $page->uid() ?>" title="<?= $this->translate('panel.pages.preview') ?>" aria-label="<?= $this->translate('panel.pages.preview') ?>"><?= $this->icon('eye') ?></a>
|
||||
<?php if ($panel->user()->permissions()->has('pages.delete')) : ?>
|
||||
<button type="button" class="button button-link" data-modal="deletePageModal" data-modal-action="<?= $panel->uri('/pages/' . trim($page->route(), '/') . '/delete/' . ($currentLanguage ? 'language/' . $currentLanguage . '/' : '')) ?>" title="<?= $this->translate('panel.pages.deletePage') ?>" aria-label="<?= $this->translate('panel.pages.deletePage') ?>" <?php if (!$page->isDeletable()) : ?> disabled<?php endif ?>><?= $this->icon('trash') ?></button>
|
||||
|
94
panel/views/pages/file.php
Normal file
94
panel/views/pages/file.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?php $this->layout('panel') ?>
|
||||
<div class="header">
|
||||
<div class="min-w-0 flex-grow-1">
|
||||
<div class="header-title"><?= $this->icon(is_null($file->type()) ? 'file' : 'file-' . $file->type()) ?> <?= $file->name() ?></div>
|
||||
<div><a class="link-secondary text-size-sm" href="<?= $panel->uri('/pages/' . trim($page->route(), '/') . '/edit/') ?>"><span class="mr-2"><?= $this->icon('arrow-left-circle') ?></span><?= $this->translate('panel.pages.file.backToPage') ?></a></div>
|
||||
</div>
|
||||
<a class="<?= $this->classes(['button', 'button-link', 'show-from-md', 'disabled' => !$previousFile]) ?>" role="button" <?php if ($previousFile) : ?>href="<?= $panel->uri('/pages/' . trim($page->route(), '/') . '/file/' . ($previousFile->name()) . '/') ?>" <?php endif ?> title="<?= $this->translate('panel.pages.previousFile') ?>" aria-label="<?= $this->translate('panel.pages.previousFile') ?>"><?= $this->icon('chevron-left') ?></a>
|
||||
<a class="<?= $this->classes(['button', 'button-link', 'show-from-md', 'disabled' => !$nextFile]) ?>" role="button" <?php if ($nextFile) : ?>href="<?= $panel->uri('/pages/' . trim($page->route(), '/') . '/file/' . ($nextFile->name()) . '/') ?>" <?php endif ?> title="<?= $this->translate('panel.pages.nextFile') ?>" aria-label="<?= $this->translate('panel.pages.nextFile') ?>"><?= $this->icon('chevron-right') ?></a>
|
||||
<?php if ($panel->user()->permissions()->has('pages.renameFiles')) : ?>
|
||||
<button type="button" class="button button-link" data-modal="renameFileModal" data-modal-action="<?= $panel->uri('/pages/' . trim($page->route(), '/') . '/file/' . $file->name() . '/rename/') ?>" data-filename="<?= $file->name() ?>" title="<?= $this->translate('panel.pages.renameFile') ?>" aria-label="<?= $this->translate('panel.pages.renameFile') ?>"><?= $this->icon('pencil') ?></button>
|
||||
<?php endif ?>
|
||||
<?php if ($panel->user()->permissions()->has('pages.replaceFiles')) : ?>
|
||||
<button type="button" class="button button-link" data-command="replaceFile" data-action="<?= $panel->uri('/pages/' . trim($page->route(), '/') . '/file/' . $file->name() . '/replace/') ?>" data-extension=".<?= $file->extension() ?>" title="<?= $this->translate('panel.pages.replaceFile') ?>" aria-label="<?= $this->translate('panel.pages.replaceFile') ?>"><?= $this->icon('cloud-upload') ?></button>
|
||||
<?php endif ?>
|
||||
<?php if ($panel->user()->permissions()->has('pages.deleteFiles')) : ?>
|
||||
<button type="button" class="button button-link" data-modal="deleteFileModal" data-modal-action="<?= $panel->uri('/pages/' . trim($page->route(), '/') . '/file/' . $file->name() . '/delete/') ?>" title="<?= $this->translate('panel.pages.deleteFile') ?>" aria-label="<?= $this->translate('panel.pages.deleteFile') ?>"><?= $this->icon('trash') ?></button>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
<?php if ($file->type() === 'image') : ?>
|
||||
<div class="sections">
|
||||
<section class="section">
|
||||
<div class="section-header">
|
||||
<span class="caption"><?= $this->translate('panel.pages.file.preview') ?></span>
|
||||
</div>
|
||||
<div class="section-content page-file-preview-container">
|
||||
<a class="page-file-preview-link" href="<?= $file->uri() ?>"><img class="page-file-preview-image"" src=" <?= $file->uri() ?>"></a>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
<?php if ($file->type() === 'video') : ?>
|
||||
<section class="section">
|
||||
<div class="section-header">
|
||||
<span class="caption"><?= $this->translate('panel.pages.file.preview') ?></span>
|
||||
</div>
|
||||
<div class="section-content page-file-preview-container">
|
||||
<video style="width: 100%" controls playsinline>
|
||||
<source src="<?= $file->uri() ?>" type="<?= $file->mimeType() ?>" />
|
||||
</video>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif ?>
|
||||
<section class="section">
|
||||
<div class="section-header">
|
||||
<span class="caption"><?= $this->translate('panel.pages.file.info') ?></span>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<div class="row">
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.mimeType') ?>:</div>
|
||||
<?= $file->mimeType() ?>
|
||||
</div>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.size') ?>:</div>
|
||||
<?= $file->size() ?>
|
||||
</div>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.lastModifiedTime') ?>:</div>
|
||||
<?= $this->datetime($file->lastModifiedTime()) ?>
|
||||
</div>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.uri') ?>:</div>
|
||||
<a class="page-file-info-entry-uri" href="<?= $file->uri() ?>"><?= $file->uri() ?></a>
|
||||
</div>
|
||||
<?php if ($file->type() === 'image') : ?>
|
||||
<?php $this->insert('_files/images/info/info', ['file' => $file]) ?>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<?php if ($file->type() === 'image') : ?>
|
||||
<?php if ($file->hasExifData() && $file->getExifData()->hasPositionData()) : ?>
|
||||
<section class="section collapsible">
|
||||
<div class="section-header">
|
||||
<button type="button" class="button section-toggle mr-2" title="<?= $this->translate('panel.sections.toggle') ?>" aria-label="<?= $this->translate('panel.sections.toggle') ?>"><?= $this->icon('chevron-up') ?></button>
|
||||
<span class="caption"><?= $this->translate('panel.pages.file.position') ?></span>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<?php $this->insert('_files/images/position/map', ['exif' => $file->getExifData()]) ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif ?>
|
||||
<?php if ($file->hasExifData()) : ?>
|
||||
<section class="section collapsible collapsed">
|
||||
<div class="section-header">
|
||||
<button type="button" class="button section-toggle mr-2" title="<?= $this->translate('panel.sections.toggle') ?>" aria-label="<?= $this->translate('panel.sections.toggle') ?>"><?= $this->icon('chevron-up') ?></button>
|
||||
<span class="caption"><?= $this->translate('panel.pages.file.exif') ?></span>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<?php $this->insert('_files/images/exif/data', ['exif' => $file->getExifData()]) ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif ?>
|
||||
<?php endif ?>
|
8
panel/views/partials/files/images/exif/data.php
Normal file
8
panel/views/partials/files/images/exif/data.php
Normal file
@ -0,0 +1,8 @@
|
||||
<table class="table table-bordered table-striped table-hoverable text-size-sm">
|
||||
<?php foreach ($exif->parsedTags() as $key => $value) : ?>
|
||||
<tr>
|
||||
<td class="table-cell truncate page-file-info-entry-title" style="width: 25%;"><?= $key ?></td>
|
||||
<td class="table-cell"><?= $this->escape(is_array($value) ? implode(', ', $value) : (string) $value) ?></td>
|
||||
</tr>
|
||||
<?php endforeach ?>
|
||||
</table>
|
48
panel/views/partials/files/images/info/exif.php
Normal file
48
panel/views/partials/files/images/info/exif.php
Normal file
@ -0,0 +1,48 @@
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.exif.creationDateAndTime') ?>:</div>
|
||||
<?= $exif->dateTimeOriginal() ?? '-' ?>
|
||||
</div>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.exif.camera') ?>:</div>
|
||||
<?= $exif->makeAndModel() ?? '–' ?>
|
||||
</div>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.exif.lensModel') ?>:</div>
|
||||
<?= $exif->lensModel() ?? '–' ?>
|
||||
</div>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.exif.focalLength') ?>:</div>
|
||||
<?= $exif->focalLength() ?? '–' ?>
|
||||
</div>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.exif.exposureTime') ?>:</div>
|
||||
<?= $exif->exposureTime() ?? '–' ?>
|
||||
</div>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.exif.aperture') ?>:</div>
|
||||
<?= $exif->aperture() ?? '–' ?>
|
||||
</div>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.exif.sensitivity') ?>:</div>
|
||||
<?= $exif->photographicSensitivity() ?? '–' ?>
|
||||
</div>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.exif.exposureCompensation') ?>:</div>
|
||||
<?= $exif->exposureCompensation() ?? '–' ?>
|
||||
</div>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.exif.exposureProgram') ?>:</div>
|
||||
<?= $exif->exposureProgram() ?? '–' ?>
|
||||
</div>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.exif.whiteBalance') ?>:</div>
|
||||
<?php if ($exif->hasAutoWhiteBalance() === true) : ?>AWB<?php else : ?>–<?php endif ?>
|
||||
</div>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.exif.flash') ?>:</div>
|
||||
<?php if ($exif->hasFlashFired() !== null) : ?> <?= $exif->hasFlashFired() ? $this->icon('camera-flash') : $this->icon('camera-no-flash') ?><?php else : ?>–<?php endif ?>
|
||||
</div>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.exif.meteringMode') ?>:</div>
|
||||
<?php if ($exif->meteringMode() !== null) : ?><?= $this->icon('camera-metering-' . $exif->meteringMode()) ?><?php else : ?>–<?php endif ?>
|
||||
</div>
|
45
panel/views/partials/files/images/info/info.php
Normal file
45
panel/views/partials/files/images/info/info.php
Normal file
@ -0,0 +1,45 @@
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.dimensions') ?>:</div>
|
||||
<?= $this->translate('panel.pages.file.info.image.dimensions.widthByHeightPixels', $file->info()->width(), $file->info()->height()) ?>
|
||||
</div>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.resolution') ?>:</div>
|
||||
<?= round(max($file->info()->width() * $file->info()->height() / 1e6, 0.1), 1) ?> MP
|
||||
</div>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.colorSpace') ?>:</div>
|
||||
<?= $file->info()->colorSpace()->value ?>
|
||||
</div>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.colorDepth') ?>:</div>
|
||||
<?= $file->info()->colorDepth() ?> bit
|
||||
</div>
|
||||
<?php if ($file->info()->colorSpace()->value === 'PALETTE') : ?>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.colorNumber') ?>:</div>
|
||||
<?= $file->info()->colorNumber() ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.colorProfile') ?>:</div>
|
||||
<?php if ($file->hasColorProfile() && $file->getColorProfile()->name()) : ?>
|
||||
<?= $file->getColorProfile()->name() ?>
|
||||
<?php elseif ($file->hasExifData() && $file->getExifData()->colorSpace()) : ?>
|
||||
<?= $file->getExifData()->colorSpace() ?> (EXIF)
|
||||
<?php else : ?>
|
||||
–
|
||||
<?php endif ?>
|
||||
</div>
|
||||
<?php if ($file->info()->isAnimation()) : ?>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.framesCount') ?>:</div>
|
||||
<?= $this->translate('panel.pages.file.info.image.frames', $file->info()->animationFrames()) ?>
|
||||
</div>
|
||||
<div class="col-sm-1-2 col-md-1-4 mb-4">
|
||||
<div class="page-file-info-entry-title"><?= $this->translate('panel.pages.file.info.image.repeatsCount') ?>:</div>
|
||||
<?php if ($file->info()->animationRepeatCount() > 0) : ?><?= $this->translate('panel.pages.file.info.image.repeats', $file->info()->animationRepeatCount()) ?><?php else : ?>∞<?php endif ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
<?php if ($file->hasExifData()) : ?>
|
||||
<?php $this->insert('_files/images/info/exif', ['exif' => $file->getExifData()]) ?>
|
||||
<?php endif ?>
|
1
panel/views/partials/files/images/position/map.php
Normal file
1
panel/views/partials/files/images/position/map.php
Normal file
@ -0,0 +1 @@
|
||||
<iframe style="width: 100%; height: 20rem;" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://www.openstreetmap.org/export/embed.html?bbox=<?= $exif->get('GPSLongitude') - 0.025 ?>,<?= $exif->get('GPSLatitude') - 0.025 ?>,<?= $exif->get('GPSLongitude') + 0.025 ?>,<?= $exif->get('GPSLatitude') + 0.025 ?>&marker=<?= $exif->get('GPSLatitude') ?>,<?= $exif->get('GPSLongitude') ?>"></iframe>
|
@ -0,0 +1,10 @@
|
||||
files:
|
||||
allowedExtensions:
|
||||
- .jpg
|
||||
- .jpeg
|
||||
- .png
|
||||
- .gif
|
||||
- .svg
|
||||
- .webp
|
||||
- .mp4
|
||||
- .webm
|
Loading…
x
Reference in New Issue
Block a user