mirror of
https://github.com/getformwork/formwork.git
synced 2025-01-17 13:38:22 +01:00
Merge pull request #567 from getformwork/feature/history-and-preview-updates
Add pages history and live preview
This commit is contained in:
commit
b7b24d0657
@ -132,10 +132,6 @@ final class App
|
||||
|
||||
$response->send();
|
||||
|
||||
if ($this->config()->get('system.statistics.enabled') && $this->site()->currentPage() !== null && !$this->site()->currentPage()->isErrorPage()) {
|
||||
$this->container->get(Statistics::class)->trackVisit();
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ use Formwork\Pages\Page;
|
||||
use Formwork\Pages\Site;
|
||||
use Formwork\Router\RouteParams;
|
||||
use Formwork\Router\Router;
|
||||
use Formwork\Statistics\Statistics;
|
||||
use Formwork\Utils\FileSystem;
|
||||
use Formwork\View\ViewFactory;
|
||||
|
||||
@ -23,7 +24,7 @@ class PageController extends AbstractController
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function load(RouteParams $routeParams, ViewFactory $viewFactory): Response
|
||||
public function load(RouteParams $routeParams, ViewFactory $viewFactory, Statistics $statistics): Response
|
||||
{
|
||||
if ($this->site->get('maintenance.enabled') && !$this->app->panel()?->isLoggedIn()) {
|
||||
if ($this->site->get('maintenance.page') !== null) {
|
||||
@ -68,6 +69,10 @@ class PageController extends AbstractController
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->config->get('system.statistics.enabled')) {
|
||||
$statistics->trackVisit();
|
||||
}
|
||||
|
||||
if ($page->isPublished() && $page->routable()) {
|
||||
return $this->getPageResponse($page);
|
||||
}
|
||||
|
68
formwork/src/Panel/ContentHistory/ContentHistory.php
Normal file
68
formwork/src/Panel/ContentHistory/ContentHistory.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace Formwork\Panel\ContentHistory;
|
||||
|
||||
use Formwork\Parsers\Json;
|
||||
use Formwork\Utils\Arr;
|
||||
use Formwork\Utils\FileSystem;
|
||||
|
||||
class ContentHistory
|
||||
{
|
||||
public const HISTORY_FILENAME = '.history';
|
||||
|
||||
public const HISTORY_DEFAULT_LIMIT = 1;
|
||||
|
||||
protected ContentHistoryItemCollection $items;
|
||||
|
||||
public function __construct(
|
||||
protected string $path,
|
||||
protected int $limit = self::HISTORY_DEFAULT_LIMIT
|
||||
) {
|
||||
}
|
||||
|
||||
public function path(): string
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function exists(): bool
|
||||
{
|
||||
return FileSystem::exists(FileSystem::joinPaths($this->path, self::HISTORY_FILENAME));
|
||||
}
|
||||
|
||||
public function items(): ContentHistoryItemCollection
|
||||
{
|
||||
if (isset($this->items)) {
|
||||
return $this->items;
|
||||
}
|
||||
if (!$this->exists()) {
|
||||
return $this->items = new ContentHistoryItemCollection();
|
||||
}
|
||||
$items = Json::parse(FileSystem::read(FileSystem::joinPaths($this->path, self::HISTORY_FILENAME)));
|
||||
return $this->items = new ContentHistoryItemCollection(Arr::map($items, fn ($item) => ContentHistoryItem::fromArray($item)));
|
||||
}
|
||||
|
||||
public function lastItem(): ?ContentHistoryItem
|
||||
{
|
||||
return $this->items()->last();
|
||||
}
|
||||
|
||||
public function isJustCreated(): bool
|
||||
{
|
||||
return $this->lastItem()?->event() === ContentHistoryEvent::Created;
|
||||
}
|
||||
|
||||
public function update(ContentHistoryEvent $contentHistoryEvent, string $user, int $timestamp): void
|
||||
{
|
||||
$this->items()->add(new ContentHistoryItem($contentHistoryEvent, $user, $timestamp));
|
||||
if ($this->items()->count() > $this->limit) {
|
||||
$this->items = $this->items()->slice(-$this->limit);
|
||||
}
|
||||
}
|
||||
|
||||
public function save(): void
|
||||
{
|
||||
$data = $this->items()->map(fn ($item) => $item->toArray())->toArray();
|
||||
FileSystem::write(FileSystem::joinPaths($this->path, self::HISTORY_FILENAME), Json::encode($data));
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Formwork\Panel\ContentHistory;
|
||||
|
||||
enum ContentHistoryEvent: string
|
||||
{
|
||||
case Created = 'created';
|
||||
case Edited = 'edited';
|
||||
}
|
54
formwork/src/Panel/ContentHistory/ContentHistoryItem.php
Normal file
54
formwork/src/Panel/ContentHistory/ContentHistoryItem.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Formwork\Panel\ContentHistory;
|
||||
|
||||
use Formwork\Data\Contracts\ArraySerializable;
|
||||
|
||||
class ContentHistoryItem implements ArraySerializable
|
||||
{
|
||||
final public function __construct(
|
||||
protected ContentHistoryEvent $contentHistoryEvent,
|
||||
protected string $user,
|
||||
protected int $time
|
||||
) {
|
||||
}
|
||||
|
||||
public function event(): ContentHistoryEvent
|
||||
{
|
||||
return $this->contentHistoryEvent;
|
||||
}
|
||||
|
||||
public function user(): string
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function time(): int
|
||||
{
|
||||
return $this->time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{event: string, user: string, time: int}
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'event' => $this->contentHistoryEvent->value,
|
||||
'user' => $this->user,
|
||||
'time' => $this->time,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{event: string, user: string, time: int} $data
|
||||
*/
|
||||
public static function fromArray(array $data): static
|
||||
{
|
||||
return new static(
|
||||
ContentHistoryEvent::from($data['event']),
|
||||
$data['user'],
|
||||
$data['time']
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Formwork\Panel\ContentHistory;
|
||||
|
||||
use Formwork\Data\AbstractCollection;
|
||||
|
||||
class ContentHistoryItemCollection extends AbstractCollection
|
||||
{
|
||||
protected bool $associative = false;
|
||||
|
||||
protected ?string $dataType = ContentHistoryItem::class;
|
||||
|
||||
protected bool $mutable = true;
|
||||
}
|
@ -16,10 +16,13 @@ use Formwork\Http\Response;
|
||||
use Formwork\Images\Image;
|
||||
use Formwork\Pages\Page;
|
||||
use Formwork\Pages\Site;
|
||||
use Formwork\Panel\ContentHistory\ContentHistory;
|
||||
use Formwork\Panel\ContentHistory\ContentHistoryEvent;
|
||||
use Formwork\Parsers\Yaml;
|
||||
use Formwork\Router\RouteParams;
|
||||
use Formwork\Schemes\Schemes;
|
||||
use Formwork\Utils\Arr;
|
||||
use Formwork\Utils\Constraint;
|
||||
use Formwork\Utils\Date;
|
||||
use Formwork\Utils\FileSystem;
|
||||
use Formwork\Utils\MimeType;
|
||||
@ -169,13 +172,22 @@ class PagesController extends AbstractController
|
||||
$data = $this->request->input();
|
||||
|
||||
// Validate fields against data
|
||||
$fields->setValues($data, null)->validate();
|
||||
$fields->setValues($data, null);
|
||||
|
||||
$forceUpdate = false;
|
||||
|
||||
if ($this->request->query()->has('publish')) {
|
||||
$fields->setValues(['published' => Constraint::isTruthy($this->request->query()->get('publish'))]);
|
||||
$forceUpdate = true;
|
||||
}
|
||||
|
||||
$fields->validate();
|
||||
|
||||
$error = false;
|
||||
|
||||
// Update the page
|
||||
try {
|
||||
$page = $this->updatePage($page, $data, $fields);
|
||||
$page = $this->updatePage($page, $data, $fields, force: $forceUpdate);
|
||||
} catch (TranslatedException $e) {
|
||||
$error = true;
|
||||
$this->panel()->notify($e->getTranslatedMessage(), 'error');
|
||||
@ -218,6 +230,10 @@ class PagesController extends AbstractController
|
||||
|
||||
$this->modal('renameFile');
|
||||
|
||||
$contentHistory = $page->path()
|
||||
? new ContentHistory($page->path())
|
||||
: null;
|
||||
|
||||
return new Response($this->view('pages.editor', [
|
||||
'title' => $this->translate('panel.pages.editPage', $page->title()),
|
||||
'page' => $page,
|
||||
@ -225,9 +241,42 @@ class PagesController extends AbstractController
|
||||
'templates' => $this->site()->templates()->keys(),
|
||||
'parents' => $this->site()->descendants()->sortBy('relativePath'),
|
||||
'currentLanguage' => $routeParams->get('language', $page->language()?->code()),
|
||||
'history' => $contentHistory,
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Pages@preview action
|
||||
*/
|
||||
public function preview(RouteParams $routeParams): Response
|
||||
{
|
||||
$page = $this->site()->findPage($routeParams->get('page'));
|
||||
|
||||
if ($page === null) {
|
||||
$this->panel()->notify($this->translate('panel.pages.page.cannotPreview.pageNotFound'), 'error');
|
||||
return $this->redirectToReferer(default: '/pages/');
|
||||
}
|
||||
|
||||
$this->site()->setCurrentPage($page);
|
||||
|
||||
// Load data from POST variables
|
||||
$requestData = $this->request->input();
|
||||
|
||||
// Validate fields against data
|
||||
$page->fields()->setValues($requestData)->validate();
|
||||
|
||||
if ($page->template()->name() !== ($template = $requestData->get('template'))) {
|
||||
$page->reload(['template' => $this->site()->templates()->get($template)]);
|
||||
}
|
||||
|
||||
if ($page->parent() !== ($parent = $this->resolveParent($requestData->get('parent')))) {
|
||||
$this->panel()->notify($this->translate('panel.pages.page.cannotPreview.parentChanged'), 'error');
|
||||
return $this->redirectToReferer(default: '/pages/');
|
||||
}
|
||||
|
||||
return new Response($page->render(), $page->responseStatus(), $page->headers());
|
||||
}
|
||||
|
||||
/**
|
||||
* Pages@reorder action
|
||||
*/
|
||||
@ -547,13 +596,18 @@ class PagesController extends AbstractController
|
||||
|
||||
FileSystem::write($path . $filename, $fileContent);
|
||||
|
||||
$contentHistory = new ContentHistory($path);
|
||||
|
||||
$contentHistory->update(ContentHistoryEvent::Created, $this->user()->username(), time());
|
||||
$contentHistory->save();
|
||||
|
||||
return $this->site()->retrievePage($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a page
|
||||
*/
|
||||
protected function updatePage(Page $page, RequestData $requestData, FieldCollection $fieldCollection): Page
|
||||
protected function updatePage(Page $page, RequestData $requestData, FieldCollection $fieldCollection, bool $force = false): Page
|
||||
{
|
||||
if ($page->contentFile() === null) {
|
||||
throw new RuntimeException('Unexpected missing content file');
|
||||
@ -597,7 +651,7 @@ class PagesController extends AbstractController
|
||||
|
||||
$differ = $frontmatter !== $page->contentFile()->frontmatter() || $content !== $page->data()['content'] || $language !== $page->language();
|
||||
|
||||
if ($differ) {
|
||||
if ($force || $differ) {
|
||||
$filename = $requestData->get('template');
|
||||
$filename .= empty($language) ? '' : '.' . $language;
|
||||
$filename .= $this->config->get('system.content.extension');
|
||||
@ -615,6 +669,11 @@ class PagesController extends AbstractController
|
||||
FileSystem::write($page->path() . $filename, $fileContent);
|
||||
FileSystem::touch($this->site()->path());
|
||||
|
||||
$contentHistory = new ContentHistory($page->path());
|
||||
|
||||
$contentHistory->update(ContentHistoryEvent::Edited, $this->user()->username(), time());
|
||||
$contentHistory->save();
|
||||
|
||||
// Update page with the new data
|
||||
$page->reload();
|
||||
|
||||
|
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
46
panel/assets/js/app.min.js
vendored
46
panel/assets/js/app.min.js
vendored
File diff suppressed because one or more lines are too long
@ -113,6 +113,12 @@ return [
|
||||
'methods' => ['GET', 'POST'],
|
||||
],
|
||||
|
||||
'panel.pages.preview' => [
|
||||
'path' => '/pages/{page}/preview/',
|
||||
'action' => 'Formwork\Panel\Controllers\PagesController@preview',
|
||||
'methods' => ['POST'],
|
||||
],
|
||||
|
||||
'panel.pages.edit.lang' => [
|
||||
'path' => '/pages/{page}/edit/language/{language}/',
|
||||
'action' => 'Formwork\Panel\Controllers\PagesController@edit',
|
||||
|
@ -154,3 +154,18 @@
|
||||
margin-right: $focusring-width;
|
||||
}
|
||||
}
|
||||
|
||||
.button-indicator {
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
border-radius: 50%;
|
||||
background-color: var(--color-accent-500);
|
||||
content: " ";
|
||||
}
|
||||
}
|
||||
|
@ -7,34 +7,34 @@ import { serializeForm } from "../utils/forms";
|
||||
export class Form {
|
||||
inputs: Inputs;
|
||||
originalData: string;
|
||||
element: HTMLFormElement;
|
||||
|
||||
constructor(form: HTMLFormElement) {
|
||||
this.element = form;
|
||||
|
||||
this.inputs = new Inputs(form);
|
||||
|
||||
// Serialize after inputs are loaded
|
||||
this.originalData = serializeForm(form);
|
||||
|
||||
const handleBeforeunload = (event: Event) => {
|
||||
if (this.hasChanged()) {
|
||||
event.preventDefault();
|
||||
event.returnValue = false;
|
||||
}
|
||||
};
|
||||
|
||||
const removeBeforeUnload = () => {
|
||||
window.removeEventListener("beforeunload", handleBeforeunload);
|
||||
};
|
||||
|
||||
window.addEventListener("beforeunload", handleBeforeunload);
|
||||
|
||||
form.addEventListener("submit", removeBeforeUnload);
|
||||
|
||||
const hasChanged = (checkFileInputs = true) => {
|
||||
const fileInputs = $$("input[type=file]", form) as NodeListOf<HTMLInputElement>;
|
||||
|
||||
if (checkFileInputs === true && fileInputs.length > 0) {
|
||||
for (const fileInput of Array.from(fileInputs)) {
|
||||
if (fileInput.files && fileInput.files.length > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return serializeForm(form) !== this.originalData;
|
||||
};
|
||||
|
||||
$$('a[href]:not([href^="#"]):not([target="_blank"]):not([target^="formwork-"])').forEach((element: HTMLAnchorElement) => {
|
||||
element.addEventListener("click", (event) => {
|
||||
if (hasChanged()) {
|
||||
if (this.hasChanged()) {
|
||||
event.preventDefault();
|
||||
app.modals["changesModal"].show(undefined, (modal) => {
|
||||
const continueCommand = $("[data-command=continue]", modal.element);
|
||||
@ -48,7 +48,7 @@ export class Form {
|
||||
|
||||
$$("input[type=file][data-auto-upload]", form).forEach((element) => {
|
||||
element.addEventListener("change", () => {
|
||||
if (!hasChanged(false)) {
|
||||
if (!this.hasChanged(false)) {
|
||||
form.requestSubmit($("[type=submit]", form));
|
||||
}
|
||||
});
|
||||
@ -56,17 +56,6 @@ export class Form {
|
||||
|
||||
registerModalExceptions();
|
||||
|
||||
function handleBeforeunload(event: Event) {
|
||||
if (hasChanged()) {
|
||||
event.preventDefault();
|
||||
event.returnValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
function removeBeforeUnload() {
|
||||
window.removeEventListener("beforeunload", handleBeforeunload);
|
||||
}
|
||||
|
||||
function registerModalExceptions() {
|
||||
const changesModal = document.getElementById("changesModal");
|
||||
const deletePageModal = document.getElementById("deletePageModal");
|
||||
@ -99,4 +88,18 @@ export class Form {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hasChanged(checkFileInputs: boolean = true) {
|
||||
const fileInputs = $$("input[type=file]", this.element) as NodeListOf<HTMLInputElement>;
|
||||
|
||||
if (checkFileInputs === true && fileInputs.length > 0) {
|
||||
for (const fileInput of Array.from(fileInputs)) {
|
||||
if (fileInput.files && fileInput.files.length > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return serializeForm(this.element) !== this.originalData;
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,8 @@ export class Inputs {
|
||||
element.addEventListener("click", () => {
|
||||
const target = document.getElementById(targetId) as HTMLInputElement;
|
||||
target.value = "";
|
||||
target.dispatchEvent(new Event("change"));
|
||||
target.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
target.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -66,6 +66,8 @@ export class DateInput {
|
||||
if (dateInput !== null) {
|
||||
inputValues[dateInput.id] = date;
|
||||
dateInput.value = formatDateTime(date);
|
||||
dateInput.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
dateInput.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
}
|
||||
},
|
||||
} satisfies DateInputOptions;
|
||||
@ -103,6 +105,8 @@ export class DateInput {
|
||||
case "Backspace":
|
||||
input.value = "";
|
||||
input.blur();
|
||||
input.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
input.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
break;
|
||||
case "Escape":
|
||||
input.blur();
|
||||
|
@ -96,6 +96,8 @@ export class DurationInput {
|
||||
seconds = Math.min(seconds, parseInt(hiddenInput.max));
|
||||
}
|
||||
hiddenInput.value = `${Math.round(seconds / TIME_INTERVALS[options.unit])}`;
|
||||
hiddenInput.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
hiddenInput.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
}
|
||||
|
||||
function updateInnerInputs() {
|
||||
|
@ -106,6 +106,8 @@ export class EditorInput {
|
||||
"changes",
|
||||
debounce(() => {
|
||||
textarea.value = editor.getValue();
|
||||
textarea.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
textarea.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
if (editor.historySize().undo < 1) {
|
||||
($("[data-command=undo]") as HTMLButtonElement).disabled = true;
|
||||
} else {
|
||||
|
@ -34,6 +34,8 @@ export class ImagePicker {
|
||||
const selectedThumbnailFilename = selectedThumbnail.dataset.filename;
|
||||
if (target && selectedThumbnailFilename) {
|
||||
target.value = selectedThumbnailFilename;
|
||||
target.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
target.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -352,7 +352,8 @@ export class SelectInput {
|
||||
function setCurrent(item: HTMLElement) {
|
||||
select.value = item.dataset.value as string;
|
||||
labelInput.value = item.innerText;
|
||||
select.dispatchEvent(new Event("change"));
|
||||
select.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
select.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
}
|
||||
|
||||
function getCurrent() {
|
||||
|
@ -233,6 +233,8 @@ export class TagInput {
|
||||
|
||||
function updateTags() {
|
||||
hiddenInput.value = tags.join(", ");
|
||||
hiddenInput.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
hiddenInput.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
updatePlaceholder();
|
||||
}
|
||||
|
||||
|
@ -8,10 +8,11 @@ import Sortable from "sortablejs";
|
||||
|
||||
export class Pages {
|
||||
constructor() {
|
||||
const commandExpandAllPages = $("[data-command=expand-all-pages]");
|
||||
const commandCollapseAllPages = $("[data-command=collapse-all-pages]");
|
||||
const commandReorderPages = $("[data-command=reorder-pages]");
|
||||
const commandChangeSlug = $("[data-command=change-slug]");
|
||||
const commandExpandAllPages = $("[data-command=expand-all-pages]") as HTMLButtonElement;
|
||||
const commandCollapseAllPages = $("[data-command=collapse-all-pages]") as HTMLButtonElement;
|
||||
const commandReorderPages = $("[data-command=reorder-pages]") as HTMLButtonElement;
|
||||
const commandPreview = $("[data-command=preview]") as HTMLButtonElement;
|
||||
const commandChangeSlug = $("[data-command=change-slug]") as HTMLButtonElement;
|
||||
|
||||
const searchInput = $(".page-search");
|
||||
|
||||
@ -168,6 +169,29 @@ export class Pages {
|
||||
});
|
||||
}
|
||||
|
||||
if (commandPreview) {
|
||||
const editorForm = app.forms["page-editor-form"];
|
||||
|
||||
const pageParent = $("#page-parent", editorForm.element) as HTMLInputElement;
|
||||
const previousParent = pageParent.value;
|
||||
|
||||
if (editorForm) {
|
||||
editorForm.element.addEventListener(
|
||||
"input",
|
||||
debounce(() => {
|
||||
if (pageParent.value !== previousParent) {
|
||||
// Prevent preview if the parent page has changed
|
||||
commandPreview.disabled = true;
|
||||
commandPreview.classList.remove("button-indicator");
|
||||
return;
|
||||
}
|
||||
commandPreview.disabled = false;
|
||||
commandPreview.classList.toggle("button-indicator", editorForm.hasChanged());
|
||||
}, 500),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (slugModal && commandChangeSlug) {
|
||||
commandChangeSlug.addEventListener("click", () => {
|
||||
app.modals["slugModal"].show(undefined, (modal) => {
|
||||
@ -204,7 +228,7 @@ export class Pages {
|
||||
if (slug.length > 0) {
|
||||
const route = ($(".page-route-inner") as HTMLElement).innerHTML;
|
||||
($("#newSlug", slugModal) as HTMLInputElement).value = slug;
|
||||
($("#slug", slugModal) as HTMLInputElement).value = slug;
|
||||
($("#slug") as HTMLInputElement).value = slug;
|
||||
($(".page-route-inner") as HTMLElement).innerHTML = route.replace(/\/[a-z0-9-]+\/$/, `/${slug}/`);
|
||||
}
|
||||
|
||||
|
@ -188,6 +188,8 @@ panel.pages.file.info.uri: URI
|
||||
panel.pages.file.position: Position
|
||||
panel.pages.file.preview: Vorschau
|
||||
panel.pages.files: Dateien
|
||||
panel.pages.history.event.created: Seite erstellt von %s %s.
|
||||
panel.pages.history.event.edited: Seite bearbeitet von %s %s.
|
||||
panel.pages.languages: Sprachen
|
||||
panel.pages.languages.addLanguage: "%s hinzufügen"
|
||||
panel.pages.languages.editLanguage: "%s bearbeiten"
|
||||
@ -227,6 +229,8 @@ panel.pages.page.cannotEdit.varMissing: Seite kann nicht bearbeitet werden, es f
|
||||
panel.pages.page.cannotGetFileInfo.fileNotFound: Dateiinfo kann nicht abgerufen werden, Datei nicht gefunden
|
||||
panel.pages.page.cannotGetFileInfo.pageNotFound: Dateiinfo kann nicht abgerufen werden, Seite nicht gefunden
|
||||
panel.pages.page.cannotMove: Seite kann nicht verschoben werden
|
||||
panel.pages.page.cannotPreview.pageNotFound: Vorschau der Seite nicht möglich, Seite nicht gefunden
|
||||
panel.pages.page.cannotPreview.parentChanged: Vorschau der Seite nicht möglich, übergeordnete Seite wurde geändert
|
||||
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
|
||||
@ -263,10 +267,12 @@ panel.pages.preview: Vorschau
|
||||
panel.pages.previewFile: Vorschau
|
||||
panel.pages.previous: Vorherige Seite
|
||||
panel.pages.previousFile: Vorherige Datei
|
||||
panel.pages.publish: Veröffentlichen
|
||||
panel.pages.renameFile: Datei umbenennen
|
||||
panel.pages.renameFile.name: Name
|
||||
panel.pages.replaceFile: Datei ersetzen
|
||||
panel.pages.save: Speichern
|
||||
panel.pages.saveOnly: Speichern ohne zu veröffentlichen
|
||||
panel.pages.status.notPublished: Nicht veröffentlicht
|
||||
panel.pages.status.notRoutable: Nicht routbar
|
||||
panel.pages.status.published: Veröffentlicht
|
||||
@ -275,6 +281,7 @@ panel.pages.summary: Zusammenfassung
|
||||
panel.pages.template: Vorlage
|
||||
panel.pages.text: Text
|
||||
panel.pages.toggleChildren: Untergeordnete Seiten umschalten
|
||||
panel.pages.viewPage: Seite anzeigen
|
||||
panel.panel: Administrationspanel
|
||||
panel.register.createUser: Formwork ist installiert, aber es wurden keine Benutzer gefunden. Bitte registrieren Sie jetzt einen Benutzer.
|
||||
panel.register.register: Neuen Benutzer registrieren
|
||||
|
@ -188,6 +188,8 @@ panel.pages.file.info.uri: URI
|
||||
panel.pages.file.position: Position
|
||||
panel.pages.file.preview: Preview
|
||||
panel.pages.files: Files
|
||||
panel.pages.history.event.created: Page created by %s %s.
|
||||
panel.pages.history.event.edited: Page edited by %s %s.
|
||||
panel.pages.languages: Languages
|
||||
panel.pages.languages.addLanguage: Add %s
|
||||
panel.pages.languages.editLanguage: Edit %s
|
||||
@ -227,6 +229,8 @@ panel.pages.page.cannotEdit.varMissing: Cannot edit page, missing a variable
|
||||
panel.pages.page.cannotGetFileInfo.fileNotFound: Cannot get file info, file not found
|
||||
panel.pages.page.cannotGetFileInfo.pageNotFound: Cannot get file info, page not found
|
||||
panel.pages.page.cannotMove: Cannot move page
|
||||
panel.pages.page.cannotPreview.pageNotFound: Cannot preview page, page not found
|
||||
panel.pages.page.cannotPreview.parentChanged: Cannot preview page, parent page has been changed
|
||||
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
|
||||
@ -263,10 +267,12 @@ panel.pages.preview: Preview
|
||||
panel.pages.previewFile: Preview
|
||||
panel.pages.previous: Previous page
|
||||
panel.pages.previousFile: Previous file
|
||||
panel.pages.publish: Publish
|
||||
panel.pages.renameFile: Rename file
|
||||
panel.pages.renameFile.name: Name
|
||||
panel.pages.replaceFile: Replace file
|
||||
panel.pages.save: Save
|
||||
panel.pages.saveOnly: Save without publishing
|
||||
panel.pages.status.notPublished: Not published
|
||||
panel.pages.status.notRoutable: Not routable
|
||||
panel.pages.status.published: Published
|
||||
@ -275,6 +281,7 @@ panel.pages.summary: Summary
|
||||
panel.pages.template: Template
|
||||
panel.pages.text: Text
|
||||
panel.pages.toggleChildren: Toggle children pages
|
||||
panel.pages.viewPage: View page
|
||||
panel.panel: Administration panel
|
||||
panel.register.createUser: Formwork is installed but no users were found. Please register a user now.
|
||||
panel.register.register: Register new user
|
||||
|
@ -188,6 +188,8 @@ panel.pages.file.info.uri: URI
|
||||
panel.pages.file.position: Posición
|
||||
panel.pages.file.preview: Vista previa
|
||||
panel.pages.files: Archivos
|
||||
panel.pages.history.event.created: Página creada por %s %s.
|
||||
panel.pages.history.event.edited: Página editada por %s %s.
|
||||
panel.pages.languages: Idiomas
|
||||
panel.pages.languages.addLanguage: Añadir %s
|
||||
panel.pages.languages.editLanguage: Editar %s
|
||||
@ -227,6 +229,8 @@ panel.pages.page.cannotEdit.varMissing: No se puede editar la página, falta una
|
||||
panel.pages.page.cannotGetFileInfo.fileNotFound: No se pueden obtener las información del archivo, archivo no encontrado
|
||||
panel.pages.page.cannotGetFileInfo.pageNotFound: No se pueden obtener las información del archivo, página no encontrada
|
||||
panel.pages.page.cannotMove: No se puede mover la página
|
||||
panel.pages.page.cannotPreview.pageNotFound: No se puede previsualizar la página, página no encontrada
|
||||
panel.pages.page.cannotPreview.parentChanged: No se puede previsualizar la página, la página principal ha sido cambiada
|
||||
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
|
||||
@ -263,10 +267,12 @@ panel.pages.preview: Vista previa
|
||||
panel.pages.previewFile: Vista previa
|
||||
panel.pages.previous: Página anterior
|
||||
panel.pages.previousFile: Archivo anterior
|
||||
panel.pages.publish: Publicar
|
||||
panel.pages.renameFile: Renombrar archivo
|
||||
panel.pages.renameFile.name: Nombre
|
||||
panel.pages.replaceFile: Reemplazar archivo
|
||||
panel.pages.save: Guardar
|
||||
panel.pages.saveOnly: Guardar sin publicar
|
||||
panel.pages.status.notPublished: No publicado
|
||||
panel.pages.status.notRoutable: No enrutable
|
||||
panel.pages.status.published: Publicado
|
||||
@ -275,6 +281,7 @@ panel.pages.summary: Resumen
|
||||
panel.pages.template: Plantilla
|
||||
panel.pages.text: Texto
|
||||
panel.pages.toggleChildren: Alternar páginas secundarias
|
||||
panel.pages.viewPage: Ver página
|
||||
panel.panel: Panel de administración
|
||||
panel.register.createUser: Formwork está instalado pero no se encontraron usuarios. Por favor, registra un usuario ahora.
|
||||
panel.register.register: Registrar nuevo usuario
|
||||
|
@ -188,6 +188,8 @@ panel.pages.file.info.uri: URI
|
||||
panel.pages.file.position: Position
|
||||
panel.pages.file.preview: Aperçu
|
||||
panel.pages.files: Fichiers
|
||||
panel.pages.history.event.created: Page créée par %s %s.
|
||||
panel.pages.history.event.edited: Page modifiée par %s %s.
|
||||
panel.pages.languages: Langues
|
||||
panel.pages.languages.addLanguage: Ajouter %s
|
||||
panel.pages.languages.editLanguage: Éditer %s
|
||||
@ -227,6 +229,8 @@ panel.pages.page.cannotEdit.varMissing: Impossible de modifier la page, il manqu
|
||||
panel.pages.page.cannotGetFileInfo.fileNotFound: Impossible de récupérer les informations sur le fichier, fichier non trouvé
|
||||
panel.pages.page.cannotGetFileInfo.pageNotFound: Impossible de récupérer les informations sur le fichier, page non trouvée
|
||||
panel.pages.page.cannotMove: Impossible de déplacer la page
|
||||
panel.pages.page.cannotPreview.pageNotFound: Impossible de prévisualiser la page, page non trouvée
|
||||
panel.pages.page.cannotPreview.parentChanged: Impossible de prévisualiser la page, la page parente a été modifiée
|
||||
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
|
||||
@ -263,10 +267,12 @@ 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.publish: Publier
|
||||
panel.pages.renameFile: Renommer le fichier
|
||||
panel.pages.renameFile.name: Nom
|
||||
panel.pages.replaceFile: Remplacer le fichier
|
||||
panel.pages.save: Enregistrer
|
||||
panel.pages.saveOnly: Enregistrer sans publier
|
||||
panel.pages.status.notPublished: Brouillon
|
||||
panel.pages.status.notRoutable: Inaccessible
|
||||
panel.pages.status.published: Publié
|
||||
@ -275,6 +281,7 @@ panel.pages.summary: Résumé
|
||||
panel.pages.template: Modèle
|
||||
panel.pages.text: Texte
|
||||
panel.pages.toggleChildren: Afficher/Masquer les sous-pages
|
||||
panel.pages.viewPage: Voir la page
|
||||
panel.panel: Panneau d’administration
|
||||
panel.register.createUser: Le compte panel est installé mais aucun utilisateur n’a été trouvé. Veuillez enregistrer un utilisateur maintenant.
|
||||
panel.register.register: Enregistrer un nouvel utilisateur
|
||||
|
@ -188,6 +188,8 @@ panel.pages.file.info.uri: URI
|
||||
panel.pages.file.position: Posizione
|
||||
panel.pages.file.preview: Anteprima
|
||||
panel.pages.files: File
|
||||
panel.pages.history.event.created: Pagina creata da %s %s.
|
||||
panel.pages.history.event.edited: Pagina modificata da %s %s.
|
||||
panel.pages.languages: Lingue
|
||||
panel.pages.languages.addLanguage: Aggiungi %s
|
||||
panel.pages.languages.editLanguage: Modifica %s
|
||||
@ -227,6 +229,8 @@ panel.pages.page.cannotEdit.varMissing: Impossibile modificare la pagina, manca
|
||||
panel.pages.page.cannotGetFileInfo.fileNotFound: Impossibile ottenere le informazioni sul file, file non trovato
|
||||
panel.pages.page.cannotGetFileInfo.pageNotFound: Impossibile ottenere le informazioni sul file, pagina non trovata
|
||||
panel.pages.page.cannotMove: Impossibile spostare la pagina
|
||||
panel.pages.page.cannotPreview.pageNotFound: Impossibile visualizzare l’anteprima, pagina non trovata
|
||||
panel.pages.page.cannotPreview.parentChanged: Impossible visualizzare l’anteprima, la pagina superiore è stata modificata
|
||||
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
|
||||
@ -263,10 +267,12 @@ panel.pages.preview: Anteprima
|
||||
panel.pages.previewFile: Anteprima
|
||||
panel.pages.previous: Pagina precedente
|
||||
panel.pages.previousFile: File precedente
|
||||
panel.pages.publish: Pubblica
|
||||
panel.pages.renameFile: Rinomina file
|
||||
panel.pages.renameFile.name: Nome
|
||||
panel.pages.replaceFile: Sostituisci file
|
||||
panel.pages.save: Salva
|
||||
panel.pages.saveOnly: Salva senza pubblicare
|
||||
panel.pages.status.notPublished: Non pubblicato
|
||||
panel.pages.status.notRoutable: Non raggiungibile
|
||||
panel.pages.status.published: Pubblicato
|
||||
@ -275,6 +281,7 @@ panel.pages.summary: Riassunto
|
||||
panel.pages.template: Template
|
||||
panel.pages.text: Testo
|
||||
panel.pages.toggleChildren: Mostra/nascondi sottopagine
|
||||
panel.pages.viewPage: Visualizza pagina
|
||||
panel.panel: Pannello di amministrazione
|
||||
panel.register.createUser: Formwork è installato ma non è stato trovato alcun utente. Registrane uno ora.
|
||||
panel.register.register: Registra nuovo utente
|
||||
|
@ -188,6 +188,8 @@ 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.history.event.created: Página criada por %s %s.
|
||||
panel.pages.history.event.edited: Página editada por %s %s.
|
||||
panel.pages.languages: Idiomas
|
||||
panel.pages.languages.addLanguage: Criar %s
|
||||
panel.pages.languages.editLanguage: Editar %s
|
||||
@ -227,6 +229,8 @@ panel.pages.page.cannotEdit.varMissing: Não é possível editar a página, falt
|
||||
panel.pages.page.cannotGetFileInfo.fileNotFound: Não é possível obter informações do arquivo, arquivo não encontrado
|
||||
panel.pages.page.cannotGetFileInfo.pageNotFound: Não é possível obter informações do arquivo, página não encontrada
|
||||
panel.pages.page.cannotMove: Não é possível mover a página
|
||||
panel.pages.page.cannotPreview.pageNotFound: Não é possível pré-visualizar a página, página não encontrada
|
||||
panel.pages.page.cannotPreview.parentChanged: Não é possível pré-visualizar a página, a página mãe foi alterada
|
||||
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
|
||||
@ -263,10 +267,12 @@ panel.pages.preview: Preview
|
||||
panel.pages.previewFile: Preview
|
||||
panel.pages.previous: Página anterior
|
||||
panel.pages.previousFile: Ficheiro anterior
|
||||
panel.pages.publish: Publicar
|
||||
panel.pages.renameFile: Renomear arquivo
|
||||
panel.pages.renameFile.name: Nome
|
||||
panel.pages.replaceFile: Substituir ficheiro
|
||||
panel.pages.save: Guardar
|
||||
panel.pages.saveOnly: Guardar sem publicar
|
||||
panel.pages.status.notPublished: Não publicado
|
||||
panel.pages.status.notRoutable: Não roteável
|
||||
panel.pages.status.published: Publicado
|
||||
@ -275,6 +281,7 @@ panel.pages.summary: Resumo
|
||||
panel.pages.template: Template
|
||||
panel.pages.text: Texto
|
||||
panel.pages.toggleChildren: Expandir páginas
|
||||
panel.pages.viewPage: Ver página
|
||||
panel.panel: Painel de administração
|
||||
panel.register.createUser: O Formwork está instalado, mas nenhum utilizador foi encontrado. Por favor, registre um agora.
|
||||
panel.register.register: Registrar novo utilizador
|
||||
|
@ -188,6 +188,8 @@ panel.pages.file.info.uri: URI
|
||||
panel.pages.file.position: Позиция
|
||||
panel.pages.file.preview: Просмотр
|
||||
panel.pages.files: Файлы
|
||||
panel.pages.history.event.created: Страница создана %s %s.
|
||||
panel.pages.history.event.edited: Страница изменена %s %s.
|
||||
panel.pages.languages: Языки
|
||||
panel.pages.languages.addLanguage: Добавлять %s
|
||||
panel.pages.languages.editLanguage: Редактировать %s
|
||||
@ -227,6 +229,8 @@ panel.pages.page.cannotEdit.varMissing: Не могу редактировать
|
||||
panel.pages.page.cannotGetFileInfo.fileNotFound: Невозможно получить информацию о файле, файл не найден
|
||||
panel.pages.page.cannotGetFileInfo.pageNotFound: Невозможно получить информацию о файле, страница не найдена
|
||||
panel.pages.page.cannotMove: Невозможно переместить страницу
|
||||
panel.pages.page.cannotPreview.pageNotFound: Невозможно показать предварительный просмотр, страница не найдена
|
||||
panel.pages.page.cannotPreview.parentChanged: Невозможно показать предварительный просмотр, родительская страница изменена
|
||||
panel.pages.page.cannotRenameFile.fileAlreadyExists: Невозможно переименовать файл, файл с таким именем уже существует
|
||||
panel.pages.page.cannotRenameFile.fileNotFound: Невозможно переименовать файл, файл не найден
|
||||
panel.pages.page.cannotRenameFile.pageNotFound: Невозможно переименовать файл, страница не найдена
|
||||
@ -263,10 +267,12 @@ panel.pages.preview: Предварительный просмотр
|
||||
panel.pages.previewFile: Предварительный просмотр
|
||||
panel.pages.previous: Предыдущая страница
|
||||
panel.pages.previousFile: Предыдущий файл
|
||||
panel.pages.publish: Опубликовать
|
||||
panel.pages.renameFile: Переименовать файл
|
||||
panel.pages.renameFile.name: Имя
|
||||
panel.pages.replaceFile: Заменить файл
|
||||
panel.pages.save: Сохранить
|
||||
panel.pages.saveOnly: Сохранить без публикации
|
||||
panel.pages.status.notPublished: Не Опубликовано
|
||||
panel.pages.status.notRoutable: Не маршрутизируемый
|
||||
panel.pages.status.published: Опубликованный
|
||||
@ -275,6 +281,7 @@ panel.pages.summary: Сводка
|
||||
panel.pages.template: Шаблон
|
||||
panel.pages.text: Текст
|
||||
panel.pages.toggleChildren: Переключить дочерние страницы
|
||||
panel.pages.viewPage: Просмотреть страницу
|
||||
panel.panel: Панель администрирования
|
||||
panel.register.createUser: Formwork Администратор установлен, но не было найдено ни одного пользователя. Пожалуйста зарегистрировать пользователя в настоящее время.
|
||||
panel.register.register: Регистрация нового пользователя
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php $this->layout('panel') ?>
|
||||
<form method="post" data-form="page-editor-form" enctype="multipart/form-data">
|
||||
<input type="submit" <?= $this->attr(['hidden' => true, 'aria-hidden' => 'true', 'data-command' => 'save', 'formaction' => $history?->isJustCreated() ? '?publish=false' : null]) ?>>
|
||||
<div class="header">
|
||||
<div class="min-w-0 flex-grow-1">
|
||||
<div class="header-title"><?= $this->icon($page->get('icon', 'page')) ?> <?= $this->escape($page->title()) ?></div>
|
||||
@ -21,7 +22,8 @@
|
||||
<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>
|
||||
<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-view-page-<?= $page->uid() ?>" title="<?= $this->translate('panel.pages.viewPage') ?>" aria-label="<?= $this->translate('panel.pages.viewPage') ?>"><?= $this->icon('arrow-right-up-box') ?></a>
|
||||
<button type="submit" class="<?= $this->classes(['button', 'button-link']) ?>" data-command="preview" formaction="<?= $panel->uri('/pages/' . trim($page->route(), '/') . '/preview/') ?>" formtarget=" formwork-preview-<?= $page->uid() ?>" title="<?= $this->translate('panel.pages.preview') ?>" aria-label="<?= $this->translate('panel.pages.preview') ?>"><?= $this->icon('eye') ?></button>
|
||||
<?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>
|
||||
<?php endif ?>
|
||||
@ -35,11 +37,32 @@
|
||||
</div>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
<button type="submit" class="button button-accent mb-0" data-command="save"><?= $this->icon('check-circle') ?> <?= $this->translate('panel.pages.save') ?></button>
|
||||
<?php if ($history?->isJustCreated()): ?>
|
||||
<div class="dropdown mb-0">
|
||||
<div class="button-group">
|
||||
<button type="submit" class="button button-accent" formaction="?publish=true"><?= $this->icon('check-circle') ?> <?= $this->translate('panel.pages.publish') ?></button>
|
||||
<button type="button" class="button button-accent dropdown-button caret" data-dropdown="dropdown-save-options"></button>
|
||||
</div>
|
||||
<div class="dropdown-menu" id="dropdown-save-options">
|
||||
<button type="submit" class="dropdown-item" formaction="?publish=false"><?= $this->translate('panel.pages.saveOnly') ?></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<button type="submit" class="button button-accent mb-0"><?= $this->icon('check-circle') ?> <?= $this->translate('panel.pages.save') ?></button>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<?php $this->insert('fields', ['fields' => $fields]) ?>
|
||||
</div>
|
||||
<input type="hidden" name="csrf-token" value="<?= $csrfToken ?>">
|
||||
<?php if ($history !== null && !$history->items()->isEmpty()): ?>
|
||||
<div class="text-size-sm text-color-gray-medium"><?= $this->icon('clock-rotate-left') ?>
|
||||
<?= $this->translate(
|
||||
'panel.pages.history.event.' . $history->lastItem()->event()->value,
|
||||
'<a href="' . $panel->uri('/users/' . $history->lastItem()->user() . '/profile/') . '">' . $history->lastItem()->user() . '</a>',
|
||||
'<span title="' . $this->datetime($history->lastItem()->time()) . '">' . $this->timedistance($history->lastItem()->time()) . '</span>'
|
||||
) ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
</form>
|
@ -52,7 +52,7 @@
|
||||
<span class="page-status-label"><?= $this->translate('panel.pages.status.' . $page->status()) ?></span>
|
||||
</div>
|
||||
<div class="pages-tree-item-cell page-actions">
|
||||
<a class="<?= $this->classes(['button', 'button-link', 'disabled' => !$page->published() || !$page->routable()]) ?>" role="button" <?php if ($page->published() && $page->routable()) : ?>href="<?= $page->uri(includeLanguage: false) ?>" <?php endif ?> target="formwork-preview-<?= $page->uid() ?>" title="<?= $this->translate('panel.pages.preview') ?>" aria-label="<?= $this->translate('panel.pages.preview') ?>"><?= $this->icon('eye') ?></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: false) ?>" <?php endif ?> target="formwork-view-page-<?= $page->uid() ?>" title="<?= $this->translate('panel.pages.viewPage') ?>" aria-label="<?= $this->translate('panel.pages.viewPage') ?>"><?= $this->icon('arrow-right-up-box') ?></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/') ?>" title="<?= $this->translate('panel.pages.deletePage') ?>" aria-label="<?= $this->translate('panel.pages.deletePage') ?>" <?php if (!$page->isDeletable()) : ?> disabled<?php endif ?>><?= $this->icon('trash') ?></button>
|
||||
<?php endif ?>
|
||||
|
Loading…
x
Reference in New Issue
Block a user