mirror of
https://github.com/typemill/typemill.git
synced 2025-08-06 14:16:46 +02:00
test php 8.2.11 and fill meta on publish
This commit is contained in:
@@ -1 +0,0 @@
|
||||
["# ToDos Version 2","[TOC]","## System settings","* DONE: Migrate from backend to frontend with vue and api\n* DONE: Redesign\n* DONE: License feature\n* DONE: Enhance with plugins","## Visual Editor","* DONE: Refactor and redesign\n* DONE: Fix toc component in new block\n* DONE: Fix hr component in new block\n* DONE: finish shortcode component\n* DONE: Fix inline formats\n* DONE: fix lenght of page\n* DONE: Fix design of new block at the end (background color)\n* DONE: Move Block\n* DONE: Fix headline design\n* DONE: Fix save on two enter\n* DONE: fix quote design\n* DONE: Fix toc preview\n* DONE: disable enable \n* DONE: Add load sign (from navigation)\n* DONE: File is not published from tmp to media\/files if you save the block.","## Raw Editor","* DONE: Refactor and redesign\n* DONE: Integrate highlighting","## Navigation","* DONE: Refactor and redesign\n* DONE: fix status in navigation\n* DONE: refresh navigation after changes","## Publish Controller","* DONE: Refactor and redesign\n* DONE: Create \n* DONE: publish\n* DONE: unpublish\n* DONE: discard\n* DONE: delete\n* DONE: save draft\n* DONE: switch to raw","## Meta Tabs","* DONE: Refactor and redesign\n* DONE: Enhance with plugins","## Medialib","* DONE: Refactor and redesign","## Posts","* DONE: Refactor and redesign","## Plugins","* Asset Class in progress","## Frontend","* DONE: Refactor\n* DONE: Test restrictions","## Other big tasks","* DONE: System setup\n* DONE: Recover Password","## Medium tasks","* DONE: Merge processAssets modell\n* DONE: Table of content duplicated for published pages\n* DONE: Session handling: csrf fail and session start error if restrictions are active\n* DONE: Image and files for meta","## Open tasks","* DONE: Sitemap and ping\n* DONE: Version check\n* DONE: Proxy support\n* DONE: SVG checker: https:\/\/github.com\/TribalSystems\/SVG-Sanitizer\n* DONE: Backend form builder\n* DONE: Image generation on the fly\n* DONE: Delete folder in base level\n* DONE: Make folder delete easier with glob or scandir\n* DONE: fix error messages (check models)\n* DONE: error status codes (check middleware)\n* DONE: Warn if open another block\n* DONE: Customfields not styled yet\n* DOING: Fix error api systemnavi + validate\n* FIXED: System stores html or sends wrong error messsages\n* FIXED: Wrong frontend navigation if unpublished pages\n* DONE: Icon for hidden pages\n* DOING: Responsive design\n* DONE: Captcha integration\n* DONE: Solution for logo and favicon\n* FIXED: Raw editor jumps if you edit long text at the end\n* Reference feature\n* Typemill Utilities\n* Markdown secure rendering\n* finish youtube component\n* Handle formdata centrally ???\n* BUG: Error fields in account form not styled correctly\n* DONE: Update CSS for themes\n* BUG: Codefield jumps on editing\n* False for owner on live?","## later","* Clear cache\n* Show security Log\n* User search only for +10 users\n* For api translations should be done completely in backoffice\n* Change translation files so they are loaded in settings instead of adding them manually to settings-defaults.yaml","## Cleanups:","* DONE: Events\n* DONE: Error messages\n* DONE: Translations","## Info: Select userroles","* Userroles for file restriction: in vue-blox-components loaded via api\n* Userroles for userfields: in php model user getUserFields()\n* Userroles for meta: in php controller apiAuthorMeta getMeta()\n* Plugins and themes: in php model extension getThemeDefinitions()","## Info: License Check","* On activation in apiControllerExtension. It checks the license in yaml.\n* In plugin php code with setPremiumLicense\n* In static plugins, it checks manual premium list and method setPremiumLicense and more ","## Plugins","* MAKER: Rebuild search\n* MAKER: Rebuild contactform with shortcode","## Status codes","| Status code | Description | \n|---|---|\n| 200 ok | cell | \n| 400 bad request | The request was unacceptable due to missing or invalid parameter. | \n| 401 unauthorized | The request requires an authorization. | \n| (402 request failed) | The parameters where there but the request failed for other reasons. | \n| 403 forbidden | The user is authenticated but he has not enough rights. | \n| 404 not found | new | \n| 500 internal server error | new |","## Upgrade","* Delete content of system folder\n* Upload new content of system folder with folders typemill and vendor\n* Backup and delete settings file \n* upload new index.php file\n* Upload new htaccess file\n* Delete theme folder\n* Uplload new cyanine-theme\n* Deactivate and delete all plugins."]
|
@@ -111,6 +111,9 @@
|
||||
* finish youtube component
|
||||
* Handle formdata centrally ???
|
||||
* BUG: Error fields in account form not styled correctly
|
||||
* DONE: Update CSS for themes
|
||||
* BUG: Codefield jumps on editing
|
||||
* False for owner on live?
|
||||
|
||||
## later
|
||||
|
||||
@@ -160,7 +163,10 @@
|
||||
|
||||
* Delete content of system folder
|
||||
* Upload new content of system folder with folders typemill and vendor
|
||||
* Delete settings file
|
||||
* Backup and delete settings file
|
||||
* upload new index.php file
|
||||
* Upload new htaccess file
|
||||
* Delete theme folder
|
||||
* Uplload new cyanine-theme
|
||||
* Deactivate and delete all plugins.
|
||||
|
File diff suppressed because one or more lines are too long
@@ -32,13 +32,13 @@
|
||||
navtitle: 'markdown test'
|
||||
hide: false
|
||||
noindex: false
|
||||
path: /00-welcome/04-markdown-test.md
|
||||
path: /00-welcome/05-markdown-test.md
|
||||
keyPath: '0.4'
|
||||
/welcome/todos:
|
||||
navtitle: 'To Dos'
|
||||
hide: false
|
||||
noindex: false
|
||||
path: /00-welcome/05-todos.txtmd
|
||||
path: /00-welcome/06-todos.md
|
||||
keyPath: '0.5'
|
||||
/cyanine-theme:
|
||||
navtitle: 'cyanine theme'
|
||||
|
File diff suppressed because one or more lines are too long
@@ -75,7 +75,7 @@ class ControllerApiAuthorArticle extends Controller
|
||||
# refresh navigation and item
|
||||
$navigation->clearNavigation();
|
||||
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
|
||||
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
|
||||
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
|
||||
$sitemap = new Sitemap();
|
||||
@@ -84,20 +84,21 @@ class ControllerApiAuthorArticle extends Controller
|
||||
# META is important e.g. for newsletter, so send it, too
|
||||
$meta = new Meta();
|
||||
$metadata = $meta->getMetaData($item);
|
||||
$metadata = $meta->addMetaDefaults($metadata, $item, $this->settings['author']);
|
||||
# $metadata = $meta->addMetaTitleDescription($metadata, $item, $markdownArray);
|
||||
$metadata = $meta->addMetaDefaults($metadata, $item, $this->settings['author'], $request->getAttribute('c_username'));
|
||||
$metadata = $meta->addMetaTitleDescription($metadata, $item, $draftMarkdown);
|
||||
|
||||
# dispatch event, e.g. send newsletter and more
|
||||
$data = [
|
||||
'markdown' => $draftMarkdown,
|
||||
'item' => $item,
|
||||
'meta' => $metadata
|
||||
'metadata' => $metadata
|
||||
];
|
||||
$this->c->get('dispatcher')->dispatch(new OnPagePublished($data), 'onPagePublished');
|
||||
|
||||
$response->getBody()->write(json_encode([
|
||||
'navigation' => $draftNavigation,
|
||||
'item' => $item
|
||||
'item' => $item,
|
||||
'metadata' => $metadata
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json');
|
||||
@@ -149,7 +150,7 @@ class ControllerApiAuthorArticle extends Controller
|
||||
# refresh navigation and item
|
||||
$navigation->clearNavigation();
|
||||
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
|
||||
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
|
||||
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
|
||||
$sitemap = new Sitemap();
|
||||
@@ -227,7 +228,7 @@ class ControllerApiAuthorArticle extends Controller
|
||||
# refresh navigation and item
|
||||
$navigation->clearNavigation();
|
||||
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
|
||||
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
|
||||
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
|
||||
# refresh content
|
||||
@@ -290,7 +291,7 @@ class ControllerApiAuthorArticle extends Controller
|
||||
# refresh navigation and item
|
||||
$navigation->clearNavigation();
|
||||
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
|
||||
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
|
||||
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
|
||||
$sitemap = new Sitemap();
|
||||
@@ -368,7 +369,7 @@ class ControllerApiAuthorArticle extends Controller
|
||||
# refresh navigation and item
|
||||
$navigation->clearNavigation();
|
||||
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
|
||||
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
|
||||
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
|
||||
# refresh content
|
||||
|
@@ -96,7 +96,7 @@ class ControllerApiAuthorBlock extends Controller
|
||||
$navigation->clearNavigation();
|
||||
|
||||
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
|
||||
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
|
||||
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
|
||||
$response->getBody()->write(json_encode([
|
||||
@@ -189,7 +189,7 @@ class ControllerApiAuthorBlock extends Controller
|
||||
$navigation->clearNavigation();
|
||||
|
||||
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
|
||||
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
|
||||
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
|
||||
$response->getBody()->write(json_encode([
|
||||
@@ -295,7 +295,7 @@ class ControllerApiAuthorBlock extends Controller
|
||||
$navigation->clearNavigation();
|
||||
|
||||
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
|
||||
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
|
||||
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
|
||||
$response->getBody()->write(json_encode([
|
||||
@@ -392,7 +392,7 @@ class ControllerApiAuthorBlock extends Controller
|
||||
$navigation->clearNavigation();
|
||||
|
||||
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
|
||||
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
|
||||
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
|
||||
$response->getBody()->write(json_encode([
|
||||
|
@@ -310,7 +310,7 @@ class ControllerApiAuthorMeta extends Controller
|
||||
if($store === true)
|
||||
{
|
||||
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
|
||||
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
|
||||
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
|
||||
$response->getBody()->write(json_encode([
|
||||
|
@@ -119,7 +119,7 @@ class ControllerWebAuthor extends Controller
|
||||
|
||||
# extend : $request->getAttribute('c_userrole')
|
||||
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $langattr);
|
||||
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $keyPathArray);
|
||||
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $keyPathArray);
|
||||
$draftNavigation = $this->c->get('dispatcher')->dispatch(new OnPagetreeLoaded($draftNavigation), 'onPagetreeLoaded')->getData();
|
||||
|
||||
$item = $navigation->getItemWithKeyPath($draftNavigation, $keyPathArray);
|
||||
|
@@ -83,14 +83,17 @@ class ControllerWebFrontend extends Controller
|
||||
$breadcrumb = $this->c->get('dispatcher')->dispatch(new OnBreadcrumbLoaded($breadcrumb), 'onBreadcrumbLoaded')->getData();
|
||||
|
||||
# CHECK IF WHOLE TREE IS PUBLISHED
|
||||
foreach($breadcrumb as $page)
|
||||
if($breadcrumb)
|
||||
{
|
||||
if($page->status == 'unpublished')
|
||||
foreach($breadcrumb as $page)
|
||||
{
|
||||
return $this->c->get('view')->render($response->withStatus(404), '404.twig', [
|
||||
'title' => 'Page not found',
|
||||
'description' => 'We did not find the page you where looking for.'
|
||||
]);
|
||||
if($page->status == 'unpublished')
|
||||
{
|
||||
return $this->c->get('view')->render($response->withStatus(404), '404.twig', [
|
||||
'title' => 'Page not found',
|
||||
'description' => 'We did not find the page you where looking for.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -361,7 +361,8 @@ class ParsedownExtension extends \ParsedownExtra
|
||||
}
|
||||
|
||||
$text = trim($Line['text'], '#');
|
||||
$headline = Slug::createSlug($Line['text'], $this->settings['langattr']);
|
||||
$lang = $this->settings['langattr'] ?? false;
|
||||
$headline = Slug::createSlug($Line['text'], $lang);
|
||||
|
||||
if ($this->strictMode and isset($text[0]) and $text[0] !== ' ')
|
||||
{
|
||||
|
@@ -368,25 +368,28 @@ class Navigation extends Folder
|
||||
# used with scan folder that generates own indexes for live version
|
||||
public function setActiveNaviItems($navigation, $breadcrumb)
|
||||
{
|
||||
foreach($breadcrumb as $crumbkey => $page)
|
||||
if($breadcrumb)
|
||||
{
|
||||
foreach($navigation as $itemkey => $item)
|
||||
foreach($breadcrumb as $crumbkey => $page)
|
||||
{
|
||||
if($page->urlRelWoF == $item->urlRelWoF)
|
||||
foreach($navigation as $itemkey => $item)
|
||||
{
|
||||
unset($breadcrumb[$crumbkey]);
|
||||
|
||||
if(empty($breadcrumb))
|
||||
if($page->urlRelWoF == $item->urlRelWoF)
|
||||
{
|
||||
$navigation[$itemkey]->active = true;
|
||||
}
|
||||
elseif(isset($navigation[$itemkey]->folderContent))
|
||||
{
|
||||
$navigation[$itemkey]->activeParent = true;
|
||||
$navigation[$itemkey]->folderContent = $this->setActiveNaviItems($navigation[$itemkey]->folderContent, $breadcrumb);
|
||||
}
|
||||
unset($breadcrumb[$crumbkey]);
|
||||
|
||||
break;
|
||||
if(empty($breadcrumb))
|
||||
{
|
||||
$navigation[$itemkey]->active = true;
|
||||
}
|
||||
elseif(isset($navigation[$itemkey]->folderContent))
|
||||
{
|
||||
$navigation[$itemkey]->activeParent = true;
|
||||
$navigation[$itemkey]->folderContent = $this->setActiveNaviItems($navigation[$itemkey]->folderContent, $breadcrumb);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -2124,6 +2124,11 @@ video {
|
||||
border-color: rgb(87 83 78 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.dark .dark\:border-stone-700 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(68 64 60 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.dark .dark\:bg-stone-600 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(87 83 78 / var(--tw-bg-opacity));
|
||||
@@ -2134,51 +2139,46 @@ video {
|
||||
background-color: rgb(68 64 60 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.dark .dark\:bg-stone-900 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(28 25 23 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.dark .dark\:bg-stone-200 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(231 229 228 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.dark .dark\:bg-stone-900 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(28 25 23 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.dark .dark\:text-gray-400 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(156 163 175 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark .dark\:text-stone-50 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(250 250 249 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark .dark\:text-stone-200 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(231 229 228 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark .dark\:text-stone-50 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(250 250 249 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark .dark\:text-stone-900 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(28 25 23 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark .hover\:dark\:border-stone-600:hover {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(87 83 78 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.dark .hover\:dark\:border-teal-500:hover {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(20 184 166 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.dark .hover\:dark\:border-stone-200:hover {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(231 229 228 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.dark .hover\:dark\:border-stone-600:hover {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(87 83 78 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.dark .hover\:dark\:bg-stone-900:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(28 25 23 / var(--tw-bg-opacity));
|
||||
@@ -2189,6 +2189,16 @@ video {
|
||||
background-color: rgb(231 229 228 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.dark .dark\:hover\:bg-teal-500:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(20 184 166 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.dark .dark\:hover\:bg-stone-200:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(231 229 228 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.dark .hover\:dark\:text-stone-900:hover {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(28 25 23 / var(--tw-text-opacity));
|
||||
|
@@ -1,13 +1,13 @@
|
||||
const navigation = Vue.createApp({
|
||||
template: `
|
||||
<div class="mr-3">
|
||||
<div class="mr-3 dark:text-stone-200">
|
||||
<div class="flex w-100 mb-8">
|
||||
<button class="w-1/2 hover:bg-stone-700 hover:border-stone-700 hover:text-stone-50 border-b-2 border-stone-200 px-2 py-2 transition duration-100" @click.prevent="collapseNavigation()">{{ $filters.translate('collapse all') }}</button>
|
||||
<button class="w-1/2 hover:bg-stone-700 hover:border-stone-700 hover:text-stone-50 border-b-2 border-stone-200 px-2 py-2 transition duration-100" @click.prevent="expandNavigation()">{{ $filters.translate('expand all') }}</button>
|
||||
<button class="w-1/2 hover:bg-stone-700 hover:border-stone-700 hover:text-stone-50 border-b-2 border-stone-200 dark:border-stone-600 px-2 py-2 transition duration-100" @click.prevent="collapseNavigation()">{{ $filters.translate('collapse all') }}</button>
|
||||
<button class="w-1/2 hover:bg-stone-700 hover:border-stone-700 hover:text-stone-50 border-b-2 border-stone-200 dark:border-stone-600 px-2 py-2 transition duration-100" @click.prevent="expandNavigation()">{{ $filters.translate('expand all') }}</button>
|
||||
</div>
|
||||
<div class="flex w-full my-px border-y border-stone-200 font-bold">
|
||||
<div class="flex w-full my-px border-y border-stone-200 dark:border-stone-900 font-bold">
|
||||
<div class="border-l-4" :class="getStatusClass(home.status)"></div>
|
||||
<a :href="getUrl(home.urlRelWoF)" class="flex-grow p-1 pl-3 border-l-2 border-stone-50 hover:bg-teal-500 hover:text-stone-50" :class="home.active ? 'text-stone-50 bg-teal-500' : ''">
|
||||
<a :href="getUrl(home.urlRelWoF)" class="flex-grow p-1 pl-3 border-stone-50 hover:bg-teal-500 hover:text-stone-50 dark:hover:bg-stone-200 hover:dark:text-stone-900" :class="home.active ? 'text-stone-50 bg-teal-500' : ''">
|
||||
{{ $filters.translate(home.name) }}
|
||||
</a>
|
||||
</div>
|
||||
@@ -153,9 +153,9 @@ navigation.component('navilevel',{
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<li :class="element.elementType" :id="element.keyPath" :data-url="element.urlRelWoF" :data-active="element.active" :data-hide="element.hide">
|
||||
<div class="flex w-full my-px border-b border-stone-200 relative" :class="element.elementType == 'folder' ? 'font-bold' : ''">
|
||||
<div class="border-l-4" :class="getStatusClass(element.status)"></div>
|
||||
<a :href="getUrl(element.urlRelWoF)" class="flex-grow border-l-2 border-stone-50 p-1 hover:bg-teal-500 hover:text-stone-50" :class="getNaviClass(element.active, element.activeParent, element.keyPathArray)">
|
||||
<div class="flex w-full my-px border-b border-stone-200 dark:border-stone-900 hover:dark:text-stone-900 hover:bg-teal-500 hover:text-stone-50 dark:bg-stone-700 hover:dark:bg-stone-200 hover:dark:text-stone-900 relative transition duration-100" :class="getNaviClass(element.active, element.activeParent, element.elementType)">
|
||||
<div class="border-l-4" :class="getStatusClass(element.status, element.keyPathArray)"></div>
|
||||
<a :href="getUrl(element.urlRelWoF)" class="flex-grow p-1">
|
||||
{{ element.name }}
|
||||
</a>
|
||||
<div v-if="load == element.keyPath" class="p-1 absolute right-0">
|
||||
@@ -248,22 +248,7 @@ navigation.component('navilevel',{
|
||||
},
|
||||
methods:
|
||||
{
|
||||
getStatusClass(status)
|
||||
{
|
||||
if(status == 'published')
|
||||
{
|
||||
return "border-teal-500";
|
||||
}
|
||||
else if(status == 'unpublished')
|
||||
{
|
||||
return "border-rose-500";
|
||||
}
|
||||
else if(status == 'modified')
|
||||
{
|
||||
return "border-yellow-400";
|
||||
}
|
||||
},
|
||||
getNaviClass(active, activeParent, keyPathArray)
|
||||
getStatusClass(status, keyPathArray)
|
||||
{
|
||||
var level = 3;
|
||||
if(keyPathArray.length > 1)
|
||||
@@ -272,16 +257,38 @@ navigation.component('navilevel',{
|
||||
}
|
||||
let naviclass = 'pl-' + level;
|
||||
this.navilevel = naviclass;
|
||||
|
||||
if(status == 'published')
|
||||
{
|
||||
return naviclass += " border-teal-500";
|
||||
}
|
||||
else if(status == 'unpublished')
|
||||
{
|
||||
return naviclass += " border-rose-500";
|
||||
}
|
||||
else if(status == 'modified')
|
||||
{
|
||||
return naviclass += " border-yellow-400";
|
||||
}
|
||||
},
|
||||
getNaviClass(active, activeParent, type)
|
||||
{
|
||||
let fontweight = 'font-normal';
|
||||
if(type == 'folder')
|
||||
{
|
||||
fontweight = 'font-bold'
|
||||
}
|
||||
|
||||
if(activeParent)
|
||||
{
|
||||
naviclass += " activeParent";
|
||||
return fontweight += " activeParent";
|
||||
}
|
||||
else if(active)
|
||||
{
|
||||
naviclass += " text-stone-50 bg-teal-500";
|
||||
return fontweight += " text-stone-50 bg-teal-500 dark:text-stone-900 dark:bg-stone-200";
|
||||
}
|
||||
|
||||
return naviclass;
|
||||
return fontweight;
|
||||
},
|
||||
getNaviInputLevel(keyPathArray)
|
||||
{
|
||||
|
@@ -111,14 +111,9 @@ const app = Vue.createApp({
|
||||
this.formData[this.currentTab][formdata.name] = formdata.value;
|
||||
});
|
||||
|
||||
/*
|
||||
update values that are objects
|
||||
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
|
||||
|
||||
eventBus.$on('forminputobject', formdata => {
|
||||
this.formData[this.currentTab][formdata.name] = Object.assign({}, this.formData[this.currentTab][formdata.name], formdata.value);
|
||||
eventBus.$on('meta', metadata => {
|
||||
this.formData.meta = metadata.meta;
|
||||
});
|
||||
*/
|
||||
},
|
||||
methods: {
|
||||
saveForm: function()
|
||||
|
@@ -2,7 +2,7 @@ const app = Vue.createApp({
|
||||
template: `<Transition name="initial" appear>
|
||||
<div class="w-full">
|
||||
<ul>
|
||||
<li v-for="(plugin,pluginname) in formDefinitions" class="w-full my-8 bg-stone-100 border border-stone-200">
|
||||
<li v-for="(plugin,pluginname) in formDefinitions" class="w-full my-8 bg-stone-100 dark:bg-stone-600 border border-stone-200">
|
||||
<p v-if="versions[pluginname] !== undefined"><a href="https://plugins.typemill.net" class="block p-2 text-center bg-rose-500 text-white">Please update to version {{ versions[pluginname].version }}</a></p>
|
||||
<div class="flex justify-between w-full px-8 py-3 border-b border-white" :class="getActiveClass(pluginname)">
|
||||
<p class="py-2">License: {{ plugin.license }}</p>
|
||||
@@ -137,7 +137,7 @@ const app = Vue.createApp({
|
||||
{
|
||||
if(this.formData[pluginname]['active'])
|
||||
{
|
||||
return 'bg-stone-200';
|
||||
return 'bg-stone-200 dark:bg-stone-900';
|
||||
}
|
||||
},
|
||||
getLinkToLicense()
|
||||
|
@@ -260,6 +260,7 @@ const publisher = Vue.createApp({
|
||||
self.clearPublisher();
|
||||
eventBus.$emit('item', response.data.item);
|
||||
eventBus.$emit('navigation', response.data.navigation);
|
||||
eventBus.$emit('meta', response.data.metadata);
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
|
@@ -2,7 +2,7 @@ const modal = {
|
||||
props: ['labelconfirm', 'labelcancel'],
|
||||
template: `<transition name="initial" appear>
|
||||
<div class="fixed w-full h-100 inset-0 z-50 overflow-hidden flex justify-center items-center bg-stone-700 bg-opacity-90">
|
||||
<div class="border border-teal-500 shadow-lg bg-white w-11/12 md:max-w-md mx-auto shadow-lg z-50 overflow-y-auto">
|
||||
<div class="border border-teal-500 dark:border-stone-200 shadow-lg bg-white dark:bg-stone-600 w-11/12 md:max-w-md mx-auto shadow-lg z-50 overflow-y-auto">
|
||||
<div class="text-left p-6">
|
||||
<div class="text-2xl font-bold">
|
||||
<slot name="header">
|
||||
@@ -71,7 +71,7 @@ function handleErrorMessage(error)
|
||||
const loginform = Vue.createApp({
|
||||
template: `<transition name="initial" appear>
|
||||
<div v-if="show" class="fixed w-full h-100 inset-0 z-50 overflow-hidden flex justify-center items-center bg-stone-700 bg-opacity-90">
|
||||
<div class="border border-teal-500 shadow-lg bg-white w-11/12 md:max-w-md mx-auto shadow-lg z-50 overflow-y-auto">
|
||||
<div class="border border-teal-500 dark:border-stone-200 shadow-lg bg-white dark:bg-stone-600 w-11/12 md:max-w-md mx-auto shadow-lg z-50 overflow-y-auto">
|
||||
<div class="text-left p-6">
|
||||
<div class="text-2xl font-bold"><h2>You are logged out</h2></div>
|
||||
<div class="my-5">
|
||||
|
@@ -27,7 +27,7 @@ const app = Vue.createApp({
|
||||
</div>
|
||||
<div class="my-5">
|
||||
<div :class="messageClass" class="block w-full h-8 px-3 py-1 my-1 text-white transition duration-100">{{ $filters.translate(message) }}</div>
|
||||
<button type="submit" @click.prevent="save()" class="w-full p-3 my-1 bg-stone-700 hover:bg-stone-900 text-white cursor-pointer transition duration-100">{{ $filters.translate('Save') }}</button>
|
||||
<button type="submit" @click.prevent="save()" class="w-full p-3 my-1 bg-stone-700 hover:bg-stone-900 text-white dark:bg-stone-600 hover:dark:bg-stone-900 cursor-pointer transition duration-100">{{ $filters.translate('Save') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="my-5 text-center">
|
||||
|
@@ -3,7 +3,7 @@ const app = Vue.createApp({
|
||||
<div class="w-full">
|
||||
<div class="mt-5 mb-5">
|
||||
<label for="roleselector" class="block mb-1 font-medium">{{ $filters.translate("Select a role") }}</label>
|
||||
<select class="form-select block w-full border border-stone-300 bg-stone-200 px-2 py-3 h-12 transition ease-in-out"
|
||||
<select class="form-select block w-full border border-stone-300 bg-stone-200 text-stone-900 px-2 py-3 h-12 transition ease-in-out"
|
||||
v-model="selectedrole"
|
||||
@change="generateForm()">
|
||||
<option disabled value="">Please select</option>
|
||||
@@ -36,7 +36,7 @@ const app = Vue.createApp({
|
||||
</div>
|
||||
<div class="my-5">
|
||||
<div :class="messageClass" class="block w-full h-8 px-3 py-1 my-1 text-white transition duration-100">{{ $filters.translate(message) }}</div>
|
||||
<button type="submit" @click.prevent="save()" class="w-full p-3 my-1 bg-stone-700 hover:bg-stone-900 text-white cursor-pointer transition duration-100">{{ $filters.translate('Save') }}</button>
|
||||
<button type="submit" @click.prevent="save()" class="w-full p-3 my-1 dark:bg-stone-600 hover:dark:bg-stone-900 bg-stone-700 hover:bg-stone-900 text-white cursor-pointer transition duration-100">{{ $filters.translate('Save') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
@@ -187,10 +187,10 @@ app.component('searchbox', {
|
||||
<select v-if="this.filter == 'userrole'" v-model="searchterm" class="lg:w-3/4 w-full h-12 px-2 py-3 border border-stone-300 bg-stone-200">
|
||||
<option v-for="role in userroles">{{role}}</option>
|
||||
</select>
|
||||
<input v-else type="text" v-model="searchterm" class="lg:w-3/4 w-full h-12 px-2 py-3 border border-stone-300 bg-stone-200">
|
||||
<input v-else type="text" v-model="searchterm" class="lg:w-3/4 w-full h-12 px-2 py-3 border border-stone-300 bg-stone-200 text-stone-900">
|
||||
<div class="lg:w-1/4 lg:mt-0 mt-2 w-full flex justify-around">
|
||||
<button class="p-2 w-1/2 bg-stone-200 hover:bg-stone-100" @click.prevent="clearSearch()">{{ $filters.translate('Clear') }}</button>
|
||||
<button class="p-2 w-1/2 bg-stone-700 hover:bg-stone-900 text-white" @click.prevent="startSearch()">{{ $filters.translate('Search') }}</button>
|
||||
<button class="p-2 w-1/2 bg-stone-200 hover:bg-stone-100 text-stone-900" @click.prevent="clearSearch()">{{ $filters.translate('Clear') }}</button>
|
||||
<button class="p-2 w-1/2 bg-stone-700 hover:bg-stone-900 dark:bg-stone-600 hover:dark:bg-stone-900 text-white" @click.prevent="startSearch()">{{ $filters.translate('Search') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="error" class="error pt1 f6">{{error}}</div>
|
||||
@@ -230,9 +230,9 @@ app.component('searchbox', {
|
||||
{
|
||||
if(this.filter == filter)
|
||||
{
|
||||
return 'border-stone-700 bg-stone-200';
|
||||
return 'border-stone-700 bg-stone-200 dark:text-stone-900';
|
||||
}
|
||||
return 'border-stone-100 bg-stone-100';
|
||||
return 'border-stone-100 bg-stone-100 dark:bg-stone-600 hover:dark:bg-stone-200 hover:dark:text-stone-900 dark:border-stone-700';
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -242,24 +242,24 @@ app.component('usertable', {
|
||||
template: `<table class="w-full mt-8" cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="p-3 bg-stone-200 border-2 border-stone-50">{{ $filters.translate('Username') }}</th>
|
||||
<th class="p-3 bg-stone-200 border-2 border-stone-50">{{ $filters.translate('Userrole') }}</th>
|
||||
<th class="p-3 bg-stone-200 border-2 border-stone-50">{{ $filters.translate('E-Mail') }}</th>
|
||||
<th class="p-3 bg-stone-200 border-2 border-stone-50">{{ $filters.translate('Edit') }}</th>
|
||||
<th class="p-3 bg-stone-200 dark:bg-stone-900 border-2 border-stone-50 dark:border-stone-600">{{ $filters.translate('Username') }}</th>
|
||||
<th class="p-3 bg-stone-200 dark:bg-stone-900 border-2 border-stone-50 dark:border-stone-600">{{ $filters.translate('Userrole') }}</th>
|
||||
<th class="p-3 bg-stone-200 dark:bg-stone-900 border-2 border-stone-50 dark:border-stone-600">{{ $filters.translate('E-Mail') }}</th>
|
||||
<th class="p-3 bg-stone-200 dark:bg-stone-900 border-2 border-stone-50 dark:border-stone-600">{{ $filters.translate('Edit') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="user,index in userdata" key="username">
|
||||
<td class="p-3 bg-stone-100 border-2 border-white">{{ user.username }}</td>
|
||||
<td class="p-3 bg-stone-100 border-2 border-white">{{ user.userrole }}</td>
|
||||
<td class="p-3 bg-stone-100 border-2 border-white">{{ user.email }}</td>
|
||||
<td class="bg-stone-100 border-2 border-white text-center hover:bg-teal-500 hover:text-white pointer transition duration-100"><a :href="getEditLink(user.username)" class="block w-full p-3">{{ $filters.translate('edit') }}</a></td>
|
||||
<td class="p-3 bg-stone-100 dark:bg-stone-700 border-2 border-white dark:border-stone-600">{{ user.username }}</td>
|
||||
<td class="p-3 bg-stone-100 dark:bg-stone-700 border-2 border-white dark:border-stone-600">{{ user.userrole }}</td>
|
||||
<td class="p-3 bg-stone-100 dark:bg-stone-700 border-2 border-white dark:border-stone-600">{{ user.email }}</td>
|
||||
<td class="bg-stone-100 dark:bg-stone-700 border-2 border-white dark:border-stone-600 text-center hover:bg-teal-500 dark:hover:bg-teal-500 hover:text-white pointer transition duration-100"><a :href="getEditLink(user.username)" class="block w-full p-3">{{ $filters.translate('edit') }}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="p-3 bg-stone-100 border-2 border-white"><a class="text-teal-500 hover:underline" :href="getNewUserLink()">{{ $filters.translate('New user') }}</a></td>
|
||||
<td class="p-3 bg-stone-100 border-2 border-white"></td>
|
||||
<td class="p-3 bg-stone-100 border-2 border-white"></td>
|
||||
<td class="bg-stone-100 border-2 border-white text-center text-teal-500 hover:bg-teal-500 hover:text-white transition duration-100"><a class="block w-full p-3" :href="getNewUserLink()">{{ $filters.translate('add') }}</a></td>
|
||||
<td class="p-3 bg-stone-100 dark:bg-stone-700 border-2 border-white dark:border-stone-600"><a class="text-teal-500 hover:underline" :href="getNewUserLink()">{{ $filters.translate('New user') }}</a></td>
|
||||
<td class="p-3 bg-stone-100 dark:bg-stone-700 border-2 border-white dark:border-stone-600"></td>
|
||||
<td class="p-3 bg-stone-100 dark:bg-stone-700 border-2 border-white dark:border-stone-600"></td>
|
||||
<td class="bg-stone-100 dark:bg-stone-700 border-2 border-white dark:border-stone-600 text-center text-teal-500 hover:bg-teal-500 dark:hover:bg-teal-500 hover:text-white transition duration-100"><a class="block w-full p-3" :href="getNewUserLink()">{{ $filters.translate('add') }}</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>`,
|
||||
@@ -275,7 +275,7 @@ app.component('usertable', {
|
||||
|
||||
app.component('pagination', {
|
||||
props: ['page'],
|
||||
template: '<li><button class="p-1 border-2 border-stone-50 hover:bg-stone-200" :class="checkActive()" @click="goto(page)">{{ page }}</button></li>',
|
||||
template: '<li><button class="p-1 dark:bg-stone-700 border-2 border-stone-50 dark:border-stone-600 hover:bg-stone-200" :class="checkActive()" @click="goto(page)">{{ page }}</button></li>',
|
||||
methods: {
|
||||
goto: function(page){
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="{{ settings.darkmode ? 'dark' :'darkmodeoff' }}" >
|
||||
<html lang="en" class="{{ settings.darkmode ? 'dark' : 'darkmodeoff' }}" >
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{% block title %}{% endblock %}</title>
|
||||
@@ -24,11 +24,11 @@
|
||||
{{ assets.renderCSS() }}
|
||||
|
||||
</head>
|
||||
<body class="bg-stone-100">
|
||||
<body class="bg-stone-100 dark:bg-stone-900">
|
||||
|
||||
{% include 'partials/symbols.twig' %}
|
||||
|
||||
<header class="border-b-2 border-stone-200">
|
||||
<header class="border-b-2 border-stone-200 dark:border-stone-600">
|
||||
{% include 'partials/mainNavi.twig' %}
|
||||
</header>
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="{{ settings.darkmode ? 'dark' :'darkmodeoff' }}" >
|
||||
<html lang="en" class="{{ settings.darkmode ? 'dark' : 'darkmodeoff' }}" >
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{% block title %}{% endblock %}</title>
|
||||
@@ -32,8 +32,6 @@
|
||||
{% include 'partials/mainNavi.twig' %}
|
||||
</header>
|
||||
|
||||
{% include 'partials/flash.twig' %}
|
||||
|
||||
<div class="max-w-6xl m-auto mt-7 flex flex-col lg:flex-row justify-between" id="main" data-url="{{ base_url() }}">
|
||||
<aside class="lg:w-1/4">
|
||||
{% include 'partials/systemNavi.twig' %}
|
||||
@@ -54,7 +52,6 @@
|
||||
<script>
|
||||
const tmaxios = axios.create();
|
||||
tmaxios.defaults.baseURL = "{{ base_url() }}";
|
||||
/* header for session authentication in middleware */
|
||||
tmaxios.defaults.headers.common['X-Session-Auth'] = "true";
|
||||
</script>
|
||||
<script src="{{ base_url() }}/system/typemill/author/js/vue.js?v={{ settings.version }}"></script>
|
||||
@@ -63,7 +60,6 @@
|
||||
<script src="{{ base_url() }}/system/typemill/author/js/vue-systemnavi.js?v={{ settings.version }}"></script>
|
||||
<script src="{{ base_url() }}/system/typemill/author/js/vue-medialib.js?v={{ settings.version }}"></script>
|
||||
<script>
|
||||
/* kixote.mount('#kixote'); */
|
||||
|
||||
systemnavi.config.globalProperties.$filters = translatefilter;
|
||||
systemnavi.mount('#systemNavigation');
|
||||
@@ -71,6 +67,8 @@
|
||||
loginform.config.globalProperties.$filters = translatefilter;
|
||||
loginform.mount("#loginform");
|
||||
|
||||
/* kixote.mount('#kixote'); */
|
||||
|
||||
</script>
|
||||
{% block javascript %}{% endblock %}
|
||||
|
||||
|
@@ -24,11 +24,11 @@
|
||||
{{ assets.renderCSS() }}
|
||||
|
||||
</head>
|
||||
<body class="bg-stone-100">
|
||||
<body class="bg-stone-100 dark:bg-stone-900">
|
||||
|
||||
{% include 'partials/symbols.twig' %}
|
||||
|
||||
<header class="border-b-2 border-stone-200">
|
||||
<header class="border-b-2 border-stone-200 dark:border-stone-600">
|
||||
{% include 'partials/mainNavi.twig' %}
|
||||
</header>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<aside class="lg:w-1/4">
|
||||
{% include 'partials/systemNavi.twig' %}
|
||||
</aside>
|
||||
<article class="lg:w-3/4 bg-stone-50 shadow-md p-8">
|
||||
<article class="lg:w-3/4 bg-stone-50 dark:bg-stone-700 dark:text-stone-200 shadow-md p-8">
|
||||
<div id="system" v-cloak></div>
|
||||
</article>
|
||||
</div>
|
||||
|
@@ -53,11 +53,11 @@ fieldsetsystem:
|
||||
label: Google sitemap (readonly)
|
||||
css: lg:w-half
|
||||
disabled: true
|
||||
# darkmode:
|
||||
# type: checkbox
|
||||
# label: Darkmode
|
||||
# checkboxlabel: Switch to darkmode for the authoring area
|
||||
# css: lg:w-half
|
||||
darkmode:
|
||||
type: checkbox
|
||||
label: Darkmode
|
||||
checkboxlabel: Switch to darkmode for the authoring area
|
||||
css: lg:w-half
|
||||
fieldsetmedia:
|
||||
type: fieldset
|
||||
legend: Media
|
||||
|
Reference in New Issue
Block a user