From d41cf971c59585699a1e302cacb9d623a6f0abf1 Mon Sep 17 00:00:00 2001 From: trendschau Date: Thu, 30 Mar 2023 14:20:50 +0200 Subject: [PATCH] Finish navigation --- content/02-docs-v2/01-installation.md | 0 data/navigation/navi-draft.txt | 2 +- .../ControllerApiAuthorArticle.php | 112 +++-- .../ControllerApiSystemExtensions.php | 4 +- .../ControllerApiSystemLicense.php | 1 - .../ControllerApiSystemPlugins.php | 2 +- .../ControllerApiSystemSettings.php | 2 +- .../Controllers/ControllerApiSystemThemes.php | 2 +- .../typemill/Controllers/ControllerData.php | 10 +- .../Controllers/ControllerWebAuth.php | 6 +- .../Controllers/ControllerWebAuthor.php | 8 +- .../Controllers/ControllerWebSystem.php | 6 +- .../Extensions/TwigLanguageExtension.php | 2 +- system/typemill/Models/License.php | 4 +- system/typemill/Models/Navigation.php | 99 +++-- system/typemill/Models/ProcessFile.php | 2 + system/typemill/Models/Storage.php | 369 ++++++++++++++--- system/typemill/Models/User.php | 10 +- system/typemill/Static/Helpers.php | 4 +- system/typemill/Static/License.php | 2 +- system/typemill/Static/Settings.php | 2 +- system/typemill/Static/Translations.php | 33 +- system/typemill/author/css/output.css | 284 +++++++------ system/typemill/author/js/vue-contentnavi.js | 387 +++--------------- 24 files changed, 697 insertions(+), 656 deletions(-) delete mode 100644 content/02-docs-v2/01-installation.md diff --git a/content/02-docs-v2/01-installation.md b/content/02-docs-v2/01-installation.md deleted file mode 100644 index e69de29..0000000 diff --git a/data/navigation/navi-draft.txt b/data/navigation/navi-draft.txt index 2484bbd..f46481d 100644 --- a/data/navigation/navi-draft.txt +++ b/data/navigation/navi-draft.txt @@ -1 +1 @@ -a:3:{i:0;O:8:"stdClass":22:{s:12:"originalName";s:10:"00-welcome";s:11:"elementType";s:6:"folder";s:8:"contains";s:5:"pages";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:7:"welcome";s:4:"slug";s:7:"welcome";s:4:"path";s:11:"/00-welcome";s:15:"pathWithoutType";s:17:"/00-welcome/index";s:9:"urlRelWoF";s:8:"/welcome";s:6:"urlRel";s:17:"/typemill/welcome";s:6:"urlAbs";s:33:"http://localhost/typemill/welcome";s:3:"key";i:0;s:7:"keyPath";i:0;s:12:"keyPathArray";a:1:{i:0;s:1:"0";}s:7:"chapter";i:1;s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:13:"folderContent";a:5:{i:0;O:8:"stdClass":20:{s:12:"originalName";s:19:"00-markdown-test.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:13:"markdown test";s:4:"slug";s:13:"markdown-test";s:4:"path";s:31:"/00-welcome/00-markdown-test.md";s:15:"pathWithoutType";s:28:"/00-welcome/00-markdown-test";s:3:"key";i:0;s:7:"keyPath";s:3:"0.0";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"0";}s:7:"chapter";s:3:"1.1";s:9:"urlRelWoF";s:22:"/welcome/markdown-test";s:6:"urlRel";s:31:"/typemill/welcome/markdown-test";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/markdown-test";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:1;O:8:"stdClass":20:{s:12:"originalName";s:19:"01-manage-access.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:13:"manage access";s:4:"slug";s:13:"manage-access";s:4:"path";s:31:"/00-welcome/01-manage-access.md";s:15:"pathWithoutType";s:28:"/00-welcome/01-manage-access";s:3:"key";i:1;s:7:"keyPath";s:3:"0.1";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"1";}s:7:"chapter";s:3:"1.2";s:9:"urlRelWoF";s:22:"/welcome/manage-access";s:6:"urlRel";s:31:"/typemill/welcome/manage-access";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/manage-access";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:2;O:8:"stdClass":20:{s:12:"originalName";s:14:"02-get-help.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"02";s:4:"name";s:8:"get help";s:4:"slug";s:8:"get-help";s:4:"path";s:26:"/00-welcome/02-get-help.md";s:15:"pathWithoutType";s:23:"/00-welcome/02-get-help";s:3:"key";i:2;s:7:"keyPath";s:3:"0.2";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"2";}s:7:"chapter";s:3:"1.3";s:9:"urlRelWoF";s:17:"/welcome/get-help";s:6:"urlRel";s:26:"/typemill/welcome/get-help";s:6:"urlAbs";s:42:"http://localhost/typemill/welcome/get-help";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:3;O:8:"stdClass":20:{s:12:"originalName";s:24:"03-setup-your-website.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"03";s:4:"name";s:18:"setup your website";s:4:"slug";s:18:"setup-your-website";s:4:"path";s:36:"/00-welcome/03-setup-your-website.md";s:15:"pathWithoutType";s:33:"/00-welcome/03-setup-your-website";s:3:"key";i:3;s:7:"keyPath";s:3:"0.3";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"3";}s:7:"chapter";s:3:"1.4";s:9:"urlRelWoF";s:27:"/welcome/setup-your-website";s:6:"urlRel";s:36:"/typemill/welcome/setup-your-website";s:6:"urlAbs";s:52:"http://localhost/typemill/welcome/setup-your-website";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:4;O:8:"stdClass":20:{s:12:"originalName";s:19:"04-write-content.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"04";s:4:"name";s:13:"write content";s:4:"slug";s:13:"write-content";s:4:"path";s:31:"/00-welcome/04-write-content.md";s:15:"pathWithoutType";s:28:"/00-welcome/04-write-content";s:3:"key";i:4;s:7:"keyPath";s:3:"0.4";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"4";}s:7:"chapter";s:3:"1.5";s:9:"urlRelWoF";s:22:"/welcome/write-content";s:6:"urlRel";s:31:"/typemill/welcome/write-content";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/write-content";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}}s:7:"noindex";b:0;}i:1;O:8:"stdClass":22:{s:12:"originalName";s:16:"01-cyanine-theme";s:11:"elementType";s:6:"folder";s:8:"contains";s:5:"pages";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:13:"cyanine theme";s:4:"slug";s:13:"cyanine-theme";s:4:"path";s:17:"/01-cyanine-theme";s:15:"pathWithoutType";s:23:"/01-cyanine-theme/index";s:9:"urlRelWoF";s:14:"/cyanine-theme";s:6:"urlRel";s:23:"/typemill/cyanine-theme";s:6:"urlAbs";s:39:"http://localhost/typemill/cyanine-theme";s:3:"key";i:1;s:7:"keyPath";i:1;s:12:"keyPathArray";a:1:{i:0;s:1:"1";}s:7:"chapter";i:2;s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:13:"folderContent";a:4:{i:0;O:8:"stdClass":20:{s:12:"originalName";s:22:"00-colors-and-fonts.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:16:"colors and fonts";s:4:"slug";s:16:"colors-and-fonts";s:4:"path";s:40:"/01-cyanine-theme/00-colors-and-fonts.md";s:15:"pathWithoutType";s:37:"/01-cyanine-theme/00-colors-and-fonts";s:3:"key";i:0;s:7:"keyPath";s:3:"1.0";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"0";}s:7:"chapter";s:3:"2.1";s:9:"urlRelWoF";s:31:"/cyanine-theme/colors-and-fonts";s:6:"urlRel";s:40:"/typemill/cyanine-theme/colors-and-fonts";s:6:"urlAbs";s:56:"http://localhost/typemill/cyanine-theme/colors-and-fonts";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:1;O:8:"stdClass":20:{s:12:"originalName";s:17:"01-landingpage.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:11:"landingpage";s:4:"slug";s:11:"landingpage";s:4:"path";s:35:"/01-cyanine-theme/01-landingpage.md";s:15:"pathWithoutType";s:32:"/01-cyanine-theme/01-landingpage";s:3:"key";i:1;s:7:"keyPath";s:3:"1.1";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"1";}s:7:"chapter";s:3:"2.2";s:9:"urlRelWoF";s:26:"/cyanine-theme/landingpage";s:6:"urlRel";s:35:"/typemill/cyanine-theme/landingpage";s:6:"urlAbs";s:51:"http://localhost/typemill/cyanine-theme/landingpage";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:2;O:8:"stdClass":20:{s:12:"originalName";s:12:"02-footer.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"02";s:4:"name";s:6:"footer";s:4:"slug";s:6:"footer";s:4:"path";s:30:"/01-cyanine-theme/02-footer.md";s:15:"pathWithoutType";s:27:"/01-cyanine-theme/02-footer";s:3:"key";i:2;s:7:"keyPath";s:3:"1.2";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"2";}s:7:"chapter";s:3:"2.3";s:9:"urlRelWoF";s:21:"/cyanine-theme/footer";s:6:"urlRel";s:30:"/typemill/cyanine-theme/footer";s:6:"urlAbs";s:46:"http://localhost/typemill/cyanine-theme/footer";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:3;O:8:"stdClass":20:{s:12:"originalName";s:22:"03-content-elements.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"03";s:4:"name";s:16:"content elements";s:4:"slug";s:16:"content-elements";s:4:"path";s:40:"/01-cyanine-theme/03-content-elements.md";s:15:"pathWithoutType";s:37:"/01-cyanine-theme/03-content-elements";s:3:"key";i:3;s:7:"keyPath";s:3:"1.3";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"3";}s:7:"chapter";s:3:"2.4";s:9:"urlRelWoF";s:31:"/cyanine-theme/content-elements";s:6:"urlRel";s:40:"/typemill/cyanine-theme/content-elements";s:6:"urlAbs";s:56:"http://localhost/typemill/cyanine-theme/content-elements";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}}s:7:"noindex";b:0;}i:2;O:8:"stdClass":21:{s:12:"originalName";s:10:"02-docs-v2";s:11:"elementType";s:6:"folder";s:8:"contains";s:5:"pages";s:6:"status";s:9:"published";s:8:"fileType";s:0:"";s:5:"order";s:2:"02";s:4:"name";s:7:"docs v2";s:4:"slug";s:7:"docs-v2";s:4:"path";s:11:"/02-docs-v2";s:15:"pathWithoutType";s:17:"/02-docs-v2/index";s:9:"urlRelWoF";s:8:"/docs-v2";s:6:"urlRel";s:17:"/typemill/docs-v2";s:6:"urlAbs";s:33:"http://localhost/typemill/docs-v2";s:3:"key";i:2;s:7:"keyPath";i:2;s:12:"keyPathArray";a:1:{i:0;s:1:"2";}s:7:"chapter";i:3;s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:13:"folderContent";a:1:{i:0;O:8:"stdClass":19:{s:12:"originalName";s:18:"01-installation.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:12:"installation";s:4:"slug";s:12:"installation";s:4:"path";s:30:"/02-docs-v2/01-installation.md";s:15:"pathWithoutType";s:27:"/02-docs-v2/01-installation";s:3:"key";i:0;s:7:"keyPath";s:3:"2.0";s:12:"keyPathArray";a:2:{i:0;s:1:"2";i:1;s:1:"0";}s:7:"chapter";s:3:"3.1";s:9:"urlRelWoF";s:21:"/docs-v2/installation";s:6:"urlRel";s:30:"/typemill/docs-v2/installation";s:6:"urlAbs";s:46:"http://localhost/typemill/docs-v2/installation";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;}}}} \ No newline at end of file +a:2:{i:0;O:8:"stdClass":22:{s:12:"originalName";s:10:"00-welcome";s:11:"elementType";s:6:"folder";s:8:"contains";s:5:"pages";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:7:"welcome";s:4:"slug";s:7:"welcome";s:4:"path";s:11:"/00-welcome";s:15:"pathWithoutType";s:17:"/00-welcome/index";s:9:"urlRelWoF";s:8:"/welcome";s:6:"urlRel";s:17:"/typemill/welcome";s:6:"urlAbs";s:33:"http://localhost/typemill/welcome";s:3:"key";i:0;s:7:"keyPath";i:0;s:12:"keyPathArray";a:1:{i:0;s:1:"0";}s:7:"chapter";i:1;s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:13:"folderContent";a:5:{i:0;O:8:"stdClass":20:{s:12:"originalName";s:19:"00-markdown-test.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:13:"markdown test";s:4:"slug";s:13:"markdown-test";s:4:"path";s:31:"/00-welcome/00-markdown-test.md";s:15:"pathWithoutType";s:28:"/00-welcome/00-markdown-test";s:3:"key";i:0;s:7:"keyPath";s:3:"0.0";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"0";}s:7:"chapter";s:3:"1.1";s:9:"urlRelWoF";s:22:"/welcome/markdown-test";s:6:"urlRel";s:31:"/typemill/welcome/markdown-test";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/markdown-test";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:1;O:8:"stdClass":20:{s:12:"originalName";s:19:"01-manage-access.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:13:"manage access";s:4:"slug";s:13:"manage-access";s:4:"path";s:31:"/00-welcome/01-manage-access.md";s:15:"pathWithoutType";s:28:"/00-welcome/01-manage-access";s:3:"key";i:1;s:7:"keyPath";s:3:"0.1";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"1";}s:7:"chapter";s:3:"1.2";s:9:"urlRelWoF";s:22:"/welcome/manage-access";s:6:"urlRel";s:31:"/typemill/welcome/manage-access";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/manage-access";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:2;O:8:"stdClass":20:{s:12:"originalName";s:14:"02-get-help.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"02";s:4:"name";s:8:"get help";s:4:"slug";s:8:"get-help";s:4:"path";s:26:"/00-welcome/02-get-help.md";s:15:"pathWithoutType";s:23:"/00-welcome/02-get-help";s:3:"key";i:2;s:7:"keyPath";s:3:"0.2";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"2";}s:7:"chapter";s:3:"1.3";s:9:"urlRelWoF";s:17:"/welcome/get-help";s:6:"urlRel";s:26:"/typemill/welcome/get-help";s:6:"urlAbs";s:42:"http://localhost/typemill/welcome/get-help";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:3;O:8:"stdClass":20:{s:12:"originalName";s:24:"03-setup-your-website.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"03";s:4:"name";s:18:"setup your website";s:4:"slug";s:18:"setup-your-website";s:4:"path";s:36:"/00-welcome/03-setup-your-website.md";s:15:"pathWithoutType";s:33:"/00-welcome/03-setup-your-website";s:3:"key";i:3;s:7:"keyPath";s:3:"0.3";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"3";}s:7:"chapter";s:3:"1.4";s:9:"urlRelWoF";s:27:"/welcome/setup-your-website";s:6:"urlRel";s:36:"/typemill/welcome/setup-your-website";s:6:"urlAbs";s:52:"http://localhost/typemill/welcome/setup-your-website";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:4;O:8:"stdClass":20:{s:12:"originalName";s:19:"04-write-content.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"04";s:4:"name";s:13:"write content";s:4:"slug";s:13:"write-content";s:4:"path";s:31:"/00-welcome/04-write-content.md";s:15:"pathWithoutType";s:28:"/00-welcome/04-write-content";s:3:"key";i:4;s:7:"keyPath";s:3:"0.4";s:12:"keyPathArray";a:2:{i:0;s:1:"0";i:1;s:1:"4";}s:7:"chapter";s:3:"1.5";s:9:"urlRelWoF";s:22:"/welcome/write-content";s:6:"urlRel";s:31:"/typemill/welcome/write-content";s:6:"urlAbs";s:47:"http://localhost/typemill/welcome/write-content";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}}s:7:"noindex";b:0;}i:1;O:8:"stdClass":22:{s:12:"originalName";s:16:"01-cyanine-theme";s:11:"elementType";s:6:"folder";s:8:"contains";s:5:"pages";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:13:"cyanine theme";s:4:"slug";s:13:"cyanine-theme";s:4:"path";s:17:"/01-cyanine-theme";s:15:"pathWithoutType";s:23:"/01-cyanine-theme/index";s:9:"urlRelWoF";s:14:"/cyanine-theme";s:6:"urlRel";s:23:"/typemill/cyanine-theme";s:6:"urlAbs";s:39:"http://localhost/typemill/cyanine-theme";s:3:"key";i:1;s:7:"keyPath";i:1;s:12:"keyPathArray";a:1:{i:0;s:1:"1";}s:7:"chapter";i:2;s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:13:"folderContent";a:4:{i:0;O:8:"stdClass":20:{s:12:"originalName";s:22:"00-colors-and-fonts.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"00";s:4:"name";s:16:"colors and fonts";s:4:"slug";s:16:"colors-and-fonts";s:4:"path";s:40:"/01-cyanine-theme/00-colors-and-fonts.md";s:15:"pathWithoutType";s:37:"/01-cyanine-theme/00-colors-and-fonts";s:3:"key";i:0;s:7:"keyPath";s:3:"1.0";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"0";}s:7:"chapter";s:3:"2.1";s:9:"urlRelWoF";s:31:"/cyanine-theme/colors-and-fonts";s:6:"urlRel";s:40:"/typemill/cyanine-theme/colors-and-fonts";s:6:"urlAbs";s:56:"http://localhost/typemill/cyanine-theme/colors-and-fonts";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:1;O:8:"stdClass":20:{s:12:"originalName";s:17:"01-landingpage.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"01";s:4:"name";s:11:"landingpage";s:4:"slug";s:11:"landingpage";s:4:"path";s:35:"/01-cyanine-theme/01-landingpage.md";s:15:"pathWithoutType";s:32:"/01-cyanine-theme/01-landingpage";s:3:"key";i:1;s:7:"keyPath";s:3:"1.1";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"1";}s:7:"chapter";s:3:"2.2";s:9:"urlRelWoF";s:26:"/cyanine-theme/landingpage";s:6:"urlRel";s:35:"/typemill/cyanine-theme/landingpage";s:6:"urlAbs";s:51:"http://localhost/typemill/cyanine-theme/landingpage";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:2;O:8:"stdClass":20:{s:12:"originalName";s:12:"02-footer.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"02";s:4:"name";s:6:"footer";s:4:"slug";s:6:"footer";s:4:"path";s:30:"/01-cyanine-theme/02-footer.md";s:15:"pathWithoutType";s:27:"/01-cyanine-theme/02-footer";s:3:"key";i:2;s:7:"keyPath";s:3:"1.2";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"2";}s:7:"chapter";s:3:"2.3";s:9:"urlRelWoF";s:21:"/cyanine-theme/footer";s:6:"urlRel";s:30:"/typemill/cyanine-theme/footer";s:6:"urlAbs";s:46:"http://localhost/typemill/cyanine-theme/footer";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}i:3;O:8:"stdClass":20:{s:12:"originalName";s:22:"03-content-elements.md";s:11:"elementType";s:4:"file";s:6:"status";s:9:"published";s:8:"fileType";s:2:"md";s:5:"order";s:2:"03";s:4:"name";s:16:"content elements";s:4:"slug";s:16:"content-elements";s:4:"path";s:40:"/01-cyanine-theme/03-content-elements.md";s:15:"pathWithoutType";s:37:"/01-cyanine-theme/03-content-elements";s:3:"key";i:3;s:7:"keyPath";s:3:"1.3";s:12:"keyPathArray";a:2:{i:0;s:1:"1";i:1;s:1:"3";}s:7:"chapter";s:3:"2.4";s:9:"urlRelWoF";s:31:"/cyanine-theme/content-elements";s:6:"urlRel";s:40:"/typemill/cyanine-theme/content-elements";s:6:"urlAbs";s:56:"http://localhost/typemill/cyanine-theme/content-elements";s:6:"active";b:0;s:12:"activeParent";b:0;s:4:"hide";b:0;s:7:"noindex";b:0;}}s:7:"noindex";b:0;}} \ No newline at end of file diff --git a/system/typemill/Controllers/ControllerApiAuthorArticle.php b/system/typemill/Controllers/ControllerApiAuthorArticle.php index 19374a0..a2e776d 100644 --- a/system/typemill/Controllers/ControllerApiAuthorArticle.php +++ b/system/typemill/Controllers/ControllerApiAuthorArticle.php @@ -6,9 +6,10 @@ use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ResponseInterface as Response; use Slim\Routing\RouteContext; -use Typemill\Models\Navigation; -use Typemill\Models\Validation; use Typemill\Models\StorageWrapper; +use Typemill\Models\Validation; +use Typemill\Models\Navigation; +use Typemill\Static\Slug; class ControllerApiAuthorArticle extends Controller { @@ -74,7 +75,7 @@ class ControllerApiAuthorArticle extends Controller } # if an item is moved to the first level - if($parentKeyTo == '') + if($params['parent_id_to'] == '') { # create empty and default values so that the logic below still works $newFolder = new \stdClass(); @@ -91,7 +92,7 @@ class ControllerApiAuthorArticle extends Controller } # if the item has been moved within the same folder - if($parentKeyFrom == $parentKeyTo) + if($params['parent_id_from'] == $params['parent_id_to']) { # no need to ping search engines $ping = false; @@ -127,14 +128,14 @@ class ControllerApiAuthorArticle extends Controller $storage = new StorageWrapper('\Typemill\Models\Storage'); foreach($folderContent as $folderItem) { - if(!$storage->moveFile($folderItem, $newFolder->path, $index)) + if(!$storage->moveContentFile($folderItem, $newFolder->path, $index)) { $writeError = true; } $index++; } if($writeError) - { + { $response->getBody()->write(json_encode([ 'message' => 'Something went wrong. Please refresh the page and check, if all folders and files are writable.', 'navigation' => $draftNavigation, @@ -195,7 +196,7 @@ class ControllerApiAuthorArticle extends Controller # input validation $validate = new Validation(); - $result = $validate->validateNaviItem($params); + $result = $validate->navigationItem($params); if(!$result) { $response->getBody()->write(json_encode([ @@ -208,7 +209,7 @@ class ControllerApiAuthorArticle extends Controller # set variables $urlinfo = $this->c->get('urlinfo'); - $langattr = $this->settings['langattr']; + $langattr = $this->settings['langattr'] ?? 'en'; # get navigation $navigation = new Navigation(); @@ -217,8 +218,8 @@ class ControllerApiAuthorArticle extends Controller if($params['folder_id'] == 'root') { $folderContent = $draftNavigation; - } - else + } + else { # get the ids (key path) for item, old folder and new folder $folderKeyPath = explode('.', $params['folder_id']); @@ -238,30 +239,28 @@ class ControllerApiAuthorArticle extends Controller $folderContent = $folder->folderContent; } + $slug = Slug::createSlug($params['item_name'], $langattr); - - - - - $name = $params['item_name']; - $slug = Folder::createSlug($this->params['item_name'], $this->settings); - - # initialize index - $index = 0; - # iterate through the whole content of the new folder - $writeError = false; - $folderPath = isset($folder) ? $folder->path : ''; + $index = 0; + $writeError = false; + $folderPath = isset($folder) ? $folder->path : ''; + $storage = new StorageWrapper('\Typemill\Models\Storage'); foreach($folderContent as $folderItem) { # check, if the same name as new item, then return an error if($folderItem->slug == $slug) { - return $response->withJson(array('navigation' => $draftNavigation, 'errors' => 'There is already a page with this name. Please choose another name.', 'url' => $url), 404); + $response->getBody()->write(json_encode([ + 'message' => 'There is already a page with this name. Please choose another name.' + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(422); } - if(!$writeYaml->moveElement($folderItem, $folderPath, $index)) + # rename files just in case that index is not in line (because file has been moved before) + if(!$storage->moveContentFile($folderItem, $folderPath, $index)) { $writeError = true; } @@ -270,47 +269,63 @@ class ControllerApiAuthorArticle extends Controller if($writeError) { - return $response->withJson(array('data' => $this->structureDraft, 'errors' => 'Something went wrong. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 404); + $response->getBody()->write(json_encode([ + 'message' => 'Something went wrong. Please refresh the page and check, if all folders and files are writable.' + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(422); } - - - - - # add prefix number to the name $namePath = $index > 9 ? $index . '-' . $slug : '0' . $index . '-' . $slug; - $folderPath = 'content' . $folder->path; # create default content - $content = json_encode(['# ' . $name, 'Content']); + $content = json_encode(['# ' . $params['item_name'], 'Content']); - if($this->params['type'] == 'file') + if($params['type'] == 'file') { - if(!$writeYaml->writeFile($folderPath, $namePath . '.txt', $content)) + if(!$storage->writeFile('contentFolder', $folderPath, $namePath . '.txt', $content)) { - return $response->withJson(array('data' => $this->structureDraft, 'errors' => 'We could not create the file. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 404); + $response->getBody()->write(json_encode([ + 'message' => 'We could not create the file. Please refresh the page and check, if all folders and files are writable.' + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(422); } + $storage->updateYaml('contentFolder', $folderPath, $namePath . '.yaml', ['meta' => ['navtitle' => $params['item_name']]]); } - elseif($this->params['type'] == 'folder') + elseif($params['type'] == 'folder') { - if(!$writeYaml->checkPath($folderPath . DIRECTORY_SEPARATOR . $namePath)) + if(!$storage->checkFolder('contentFolder', $folderPath, $namePath)) { - return $response->withJson(array('data' => $this->structureDraft, 'errors' => 'We could not create the folder. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 404); + $response->getBody()->write(json_encode([ + 'message' => 'We could not create the folder. Please refresh the page and check, if all folders and files are writable.' + ])); + + return $response->withHeader('Content-Type', 'application/json')->withStatus(422); } - $this->writeCache->writeFile($folderPath . DIRECTORY_SEPARATOR . $namePath, 'index.txt', $content); + $storage->writeFile('contentFolder', $folderPath . DIRECTORY_SEPARATOR . $namePath, 'index.txt', $content); + $storage->updateYaml('contentFolder', $folderPath . DIRECTORY_SEPARATOR . $namePath, 'index.yaml', ['meta' => ['navtitle' => $params['item_name']]]); # always redirect to a folder - $url = $this->uri->getBaseUrl() . '/tm/content/' . $this->settings['editor'] . $folder->urlRelWoF . '/' . $slug; - +# $url = $urlinfo['baseurl'] . '/tm/content/' . $this->settings['editor'] . $folder->urlRelWoF . '/' . $slug; } + $navigation->clearNavigation(); + +/* # get extended structure - $extended = $writeYaml->getYaml('cache', 'structure-extended.yaml'); + $extended = $navigation->getExtendedNavigation($urlinfo, $langattr); # create the url for the item - $urlWoF = $folder->urlRelWoF . '/' . $slug; -# $urlWoF = '/' . $slug; + if($params['folder_id'] == 'root') + { + $urlWoF = '/' . $slug; + } + else + { + $urlWoF = $folder->urlRelWoF . '/' . $slug; + } # add the navigation name to the item htmlspecialchars needed for french language $extended[$urlWoF] = ['hide' => false, 'navtitle' => $name]; @@ -331,5 +346,14 @@ class ControllerApiAuthorArticle extends Controller # $url = $this->uri->getBaseUrl() . '/tm/content/' . $this->settings['editor'] . $folder->urlRelWoF . '/' . $slug; return $response->withJson(array('data' => $this->structureDraft, 'errors' => false, 'url' => $url)); +*/ + + $response->getBody()->write(json_encode([ + 'navigation' => $navigation->getDraftNavigation($urlinfo, $langattr), + 'message' => '', + 'url' => false + ])); + + return $response->withHeader('Content-Type', 'application/json'); } } \ No newline at end of file diff --git a/system/typemill/Controllers/ControllerApiSystemExtensions.php b/system/typemill/Controllers/ControllerApiSystemExtensions.php index 7f15cc5..17a33d1 100644 --- a/system/typemill/Controllers/ControllerApiSystemExtensions.php +++ b/system/typemill/Controllers/ControllerApiSystemExtensions.php @@ -42,7 +42,9 @@ class ControllerApiSystemExtensions extends ControllerData if($params['checked'] == true) { - $definitions = $storage->getYaml($params['type'] . DIRECTORY_SEPARATOR . $params['name'], $params['name'] . '.yaml'); + $folder = ( $params['type'] == 'plugins' ) ? 'pluginFolder' : 'themeFolder'; + + $definitions = $storage->getYaml($folder, $params['name'], $params['name'] . '.yaml'); if(isset($definitions['license']) && in_array($definitions['license'], ['MAKER', 'BUSINESS'])) { diff --git a/system/typemill/Controllers/ControllerApiSystemLicense.php b/system/typemill/Controllers/ControllerApiSystemLicense.php index 72055cc..b77912f 100644 --- a/system/typemill/Controllers/ControllerApiSystemLicense.php +++ b/system/typemill/Controllers/ControllerApiSystemLicense.php @@ -5,7 +5,6 @@ namespace Typemill\Controllers; use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ResponseInterface as Response; use Typemill\Models\Validation; -use Typemill\Models\StorageWrapper; use Typemill\Models\License; class ControllerApiSystemLicense extends ControllerData diff --git a/system/typemill/Controllers/ControllerApiSystemPlugins.php b/system/typemill/Controllers/ControllerApiSystemPlugins.php index f250d4c..359d2b4 100644 --- a/system/typemill/Controllers/ControllerApiSystemPlugins.php +++ b/system/typemill/Controllers/ControllerApiSystemPlugins.php @@ -17,7 +17,7 @@ class ControllerApiSystemPlugins extends ControllerData $pluginname = $params['plugin']; $plugininput = $params['settings']; $storage = new StorageWrapper('\Typemill\Models\Storage'); - $formdefinitions = $storage->getYaml('plugins' . DIRECTORY_SEPARATOR . $pluginname, $pluginname . '.yaml'); + $formdefinitions = $storage->getYaml('pluginFolder', $pluginname, $pluginname . '.yaml'); $plugindata = []; # validate input diff --git a/system/typemill/Controllers/ControllerApiSystemSettings.php b/system/typemill/Controllers/ControllerApiSystemSettings.php index a9c4736..0054c75 100644 --- a/system/typemill/Controllers/ControllerApiSystemSettings.php +++ b/system/typemill/Controllers/ControllerApiSystemSettings.php @@ -29,7 +29,7 @@ class ControllerApiSystemSettings extends ControllerData $params = $request->getParsedBody(); $settingsinput = $params['settings']; $storage = new StorageWrapper('\Typemill\Models\Storage'); - $formdefinitions = $storage->getYaml('system/typemill/settings', 'system.yaml'); + $formdefinitions = $storage->getYaml('systemSettings', '', 'system.yaml'); # validate input $validator = new Validation(); diff --git a/system/typemill/Controllers/ControllerApiSystemThemes.php b/system/typemill/Controllers/ControllerApiSystemThemes.php index dcd943e..d3d7132 100644 --- a/system/typemill/Controllers/ControllerApiSystemThemes.php +++ b/system/typemill/Controllers/ControllerApiSystemThemes.php @@ -18,7 +18,7 @@ class ControllerApiSystemThemes extends ControllerData $themename = $params['theme']; $themeinput = $params['settings']; $storage = new StorageWrapper('\Typemill\Models\Storage'); - $formdefinitions = $storage->getYaml('themes' . DIRECTORY_SEPARATOR . $themename, $themename . '.yaml'); + $formdefinitions = $storage->getYaml('themeFolder', $themename, $themename . '.yaml'); $themedata = []; # validate input diff --git a/system/typemill/Controllers/ControllerData.php b/system/typemill/Controllers/ControllerData.php index 5f2d05c..775cf84 100644 --- a/system/typemill/Controllers/ControllerData.php +++ b/system/typemill/Controllers/ControllerData.php @@ -18,7 +18,7 @@ class ControllerData extends Controller { $storage = new StorageWrapper('\Typemill\Models\Storage'); - $mainnavi = $storage->getYaml('system/typemill/settings', 'mainnavi.yaml'); + $mainnavi = $storage->getYaml('systemSettings', '', 'mainnavi.yaml'); $allowedmainnavi = []; @@ -65,7 +65,7 @@ class ControllerData extends Controller { $storage = new StorageWrapper('\Typemill\Models\Storage'); - $systemnavi = $storage->getYaml('system/typemill/settings', 'systemnavi.yaml'); + $systemnavi = $storage->getYaml('systemSettings', '', 'systemnavi.yaml'); $systemnavi = $this->c->get('dispatcher')->dispatch(new OnSystemnaviLoaded($systemnavi), 'onSystemnaviLoaded')->getData(); $allowedsystemnavi = []; @@ -126,7 +126,7 @@ class ControllerData extends Controller { $storage = new StorageWrapper('\Typemill\Models\Storage'); - $themeSettings = $storage->getYaml('themes' . DIRECTORY_SEPARATOR . $themeName, $themeName . '.yaml'); + $themeSettings = $storage->getYaml('themeFolder', $themeName, $themeName . '.yaml'); # add standard-textarea for custom css $themeSettings['forms']['fields']['customcss'] = [ @@ -178,7 +178,7 @@ class ControllerData extends Controller { $storage = new StorageWrapper('\Typemill\Models\Storage'); - $pluginSettings = $storage->getYaml('plugins' . DIRECTORY_SEPARATOR . $pluginName, $pluginName . '.yaml'); + $pluginSettings = $storage->getYaml('pluginFolder', $pluginName, $pluginName . '.yaml'); return $pluginSettings; } @@ -195,7 +195,7 @@ class ControllerData extends Controller $storage = new StorageWrapper('\Typemill\Models\Storage'); - $userfields = $storage->getYaml('system/typemill/settings', 'user.yaml'); + $userfields = $storage->getYaml('systemSettings', '', 'user.yaml'); # if a plugin with a role has been deactivated, then users with the role throw an error, so set them back to member... if(!$this->c->get('acl')->hasRole($userrole)) diff --git a/system/typemill/Controllers/ControllerWebAuth.php b/system/typemill/Controllers/ControllerWebAuth.php index 79b7028..2e639de 100644 --- a/system/typemill/Controllers/ControllerWebAuth.php +++ b/system/typemill/Controllers/ControllerWebAuth.php @@ -27,7 +27,7 @@ class ControllerWebAuth extends Controller $input = $request->getParsedBody(); $validation = new Validation(); - $settings = $this->c->get('settings'); +# $settings = $this->c->get('settings'); if($validation->signin($input)) { @@ -35,7 +35,9 @@ class ControllerWebAuth extends Controller if(!$user->setUserWithPassword($input['username'])) { - # return error + $this->c->get('flash')->addMessage('error', 'Ups, wrong password or username, please try again!!'); + + return $response->withHeader('Location', $this->routeParser->urlFor('auth.show'))->withStatus(302); } $userdata = $user->getUserData(); diff --git a/system/typemill/Controllers/ControllerWebAuthor.php b/system/typemill/Controllers/ControllerWebAuthor.php index 9680017..4077225 100644 --- a/system/typemill/Controllers/ControllerWebAuthor.php +++ b/system/typemill/Controllers/ControllerWebAuthor.php @@ -41,6 +41,8 @@ class ControllerWebAuthor extends Controller $item = $navigation->getItemWithKeyPath($draftNavigation, explode(".", $pageinfo['keyPath'])); + $draftNavigation = $navigation->setActiveNaviItems($draftNavigation, explode(".", $pageinfo['keyPath'])); + $mainNavigation = $navigation->getMainNavigation($request->getAttribute('c_userrole'), $this->c->get('acl'), $urlinfo, $this->settings['editor']); return $this->c->get('view')->render($response, 'content/blox-editor.twig', [ @@ -52,11 +54,7 @@ class ControllerWebAuthor extends Controller 'item' => $item, 'urlinfo' => $urlinfo ] - ]); - - echo '
';
-	    print_r($draftNavigation);
-	    die();
+		]);
 
 
 
diff --git a/system/typemill/Controllers/ControllerWebSystem.php b/system/typemill/Controllers/ControllerWebSystem.php
index 6ad833e..611382a 100644
--- a/system/typemill/Controllers/ControllerWebSystem.php
+++ b/system/typemill/Controllers/ControllerWebSystem.php
@@ -11,7 +11,7 @@ class ControllerWebSystem extends ControllerData
 	public function showSettings($request, $response, $args)
 	{
 		$storage 		= new StorageWrapper('\Typemill\Models\Storage');
-		$systemfields 	= $storage->getYaml('system/typemill/settings', 'system.yaml');
+		$systemfields 	= $storage->getYaml('systemSettings', '', 'system.yaml');
 		$translations 	= $this->c->get('translations');
 
 		# add full url for sitemap to settings
@@ -42,7 +42,7 @@ class ControllerWebSystem extends ControllerData
 		foreach($this->settings['themes'] as $themename => $themeinputs)
 		{
 			$themeSettings[$themename] = $themeinputs;
-			$themeSettings[$themename]['customcss'] = $storage->getFile('cache', $themename . '-custom.css');
+			$themeSettings[$themename]['customcss'] = $storage->getFile('cacheFolder', '', $themename . '-custom.css');
 		}
 
 		$license = [];
@@ -102,7 +102,7 @@ class ControllerWebSystem extends ControllerData
 	{
 		$storage 		= new StorageWrapper('\Typemill\Models\Storage');
 		$license 		= new License();
-		$licensefields 	= $storage->getYaml('system/typemill/settings', 'license.yaml');
+		$licensefields 	= $storage->getYaml('systemSettings', '', 'license.yaml');
 		$translations 	= $this->c->get('translations');
 
 		$licensedata 	= $license->getLicenseData($this->c->get('urlinfo'));
diff --git a/system/typemill/Extensions/TwigLanguageExtension.php b/system/typemill/Extensions/TwigLanguageExtension.php
index d4338b9..58f7ab3 100644
--- a/system/typemill/Extensions/TwigLanguageExtension.php
+++ b/system/typemill/Extensions/TwigLanguageExtension.php
@@ -5,7 +5,7 @@ namespace Typemill\Extensions;
 use Twig\Extension\AbstractExtension;
 use Twig\TwigFilter;
 use Twig\TwigFunction;
-use Typemill\Models\WriteYaml;
+# use Typemill\Models\WriteYaml;
 
 class TwigLanguageExtension extends AbstractExtension
 {
diff --git a/system/typemill/Models/License.php b/system/typemill/Models/License.php
index f2a3708..29c1dbb 100644
--- a/system/typemill/Models/License.php
+++ b/system/typemill/Models/License.php
@@ -74,7 +74,7 @@ class License
 	{
 		$storage = new StorageWrapper('\Typemill\Models\Storage');
 
-		$licensedata = $storage->getYaml('settings', 'license.yaml');
+		$licensedata = $storage->getYaml('basepath', 'settings', 'license.yaml');
 
 		if(!$licensedata)
 		{
@@ -193,7 +193,7 @@ class License
 		$signedLicense['license']['email'] = trim($params['email']);
 		$storage = new StorageWrapper('\Typemill\Models\Storage');
 
-		$storage->updateYaml('settings', 'license.yaml', $signedLicense['license']);
+		$storage->updateYaml('basepath', 'settings', 'license.yaml', $signedLicense['license']);
 
 		return true;
 	}
diff --git a/system/typemill/Models/Navigation.php b/system/typemill/Models/Navigation.php
index 5881ec5..30aa554 100644
--- a/system/typemill/Models/Navigation.php
+++ b/system/typemill/Models/Navigation.php
@@ -5,7 +5,7 @@ namespace Typemill\Models;
 use Typemill\Models\StorageWrapper;
 use Typemill\Models\Folder;
 
-class Navigation
+class Navigation extends Folder
 {
 	private $storage;
 
@@ -27,11 +27,13 @@ class Navigation
 
 	private $basicLiveNavigation = false;
 
+	public $activeNavigation = false;
+
 	public function __construct()
 	{
 		$this->storage 				= new StorageWrapper('\Typemill\Models\Storage');
 
-		$this->naviFolder 			= 'data' . DIRECTORY_SEPARATOR . 'navigation';
+		$this->naviFolder 			= 'navigation';
 
 		$this->liveNaviName 		= 'navi-live.txt';
 
@@ -63,7 +65,7 @@ class Navigation
 
 		foreach($navifiles as $navifile)
 		{
-			$result = $this->storage->deleteFile($this->naviFolder, $navifile);
+			$result = $this->storage->deleteFile('dataFolder', $this->naviFolder, $navifile);
 		}
 
 		return $result;
@@ -71,7 +73,7 @@ class Navigation
 
 	public function getMainNavigation($userrole, $acl, $urlinfo, $editor)
 	{
-		$mainnavi 		= $this->storage->getYaml('system/typemill/settings', 'mainnavi.yaml');
+		$mainnavi 		= $this->storage->getYaml('systemSettings', '', 'mainnavi.yaml');
 
 		$allowedmainnavi = [];
 
@@ -110,7 +112,7 @@ class Navigation
 	{
 		# todo: filter for userrole or username 
 
-		$this->draftNavigation = $this->storage->getFile($this->naviFolder, $this->draftNaviName, 'unserialize');
+		$this->draftNavigation = $this->storage->getFile('dataFolder', $this->naviFolder, $this->draftNaviName, 'unserialize');
 
 		if($this->draftNavigation)
 		{
@@ -127,7 +129,7 @@ class Navigation
 		$draftNavigation = $this->mergeNavigationWithExtended($basicDraftNavigation, $extendedNavigation);
 
 		# cache it
-		$this->storage->writeFile($this->naviFolder, $this->draftNaviName, $draftNavigation, 'serialize');
+		$this->storage->writeFile('dataFolder', $this->naviFolder, $this->draftNaviName, $draftNavigation, 'serialize');
 
 		return $draftNavigation;
 	}
@@ -144,15 +146,13 @@ class Navigation
 	# creates a fresh structure with published and non-published pages for the author
 	public function createBasicDraftNavigation($urlinfo, $language)
 	{
-		$folder = new Folder();
-
 		# scan the content of the folder
-		$draftContentTree = $folder->scanFolder($this->storage->getStorageInfo('contentFolder'), $draft = true);
+		$draftContentTree = $this->scanFolder($this->storage->getFolderPath('contentFolder'), $draft = true);
 
 		# if there is content, then get the content details
 		if(count($draftContentTree) > 0)
 		{
-			$draftNavigation = $folder->getFolderContentDetails($draftContentTree, $language, $urlinfo['baseurl'], $urlinfo['basepath']);
+			$draftNavigation = $this->getFolderContentDetails($draftContentTree, $language, $urlinfo['baseurl'], $urlinfo['basepath']);
 			
 			return $draftNavigation;
 		}
@@ -166,7 +166,7 @@ class Navigation
 		if(!$this->extendedNavigation)
 		{
 			# read the extended navi file
-			$this->extendedNavigation = $this->storage->getYaml($this->naviFolder, $this->extendedNaviName);
+			$this->extendedNavigation = $this->storage->getYaml('dataFolder', $this->naviFolder, $this->extendedNaviName);
 		}
 
 		if(!$this->extendedNavigation)
@@ -176,7 +176,7 @@ class Navigation
 			$this->extendedNavigation = $this->createExtendedNavigation($basicDraftNavigation, $extended = NULL);
 		
 			# cache it
-			$this->storage->updateYaml($this->naviFolder, $this->extendedNaviName, $this->extendedNavigation);
+			$this->storage->updateYaml('dataFolder', $this->naviFolder, $this->extendedNaviName, $this->extendedNavigation);
 		}
 
 		return $this->extendedNavigation;
@@ -190,7 +190,7 @@ class Navigation
 			$extended = [];
 		}
 
-		$contentFolder = $this->storage->getStorageInfo('contentFolder');
+		$contentFolder = $this->storage->getFolderPath('contentFolder');
 
 		foreach ($navigation as $key => $item)
 		{
@@ -200,7 +200,7 @@ class Navigation
 			if(file_exists($contentFolder . $filename))
 			{
 				# read file
-				$meta = $this->storage->getYaml($contentFolder, $filename);
+				$meta = $this->storage->getYaml($contentFolder, '', $filename);
 
 				$extended[$item->urlRelWoF]['navtitle'] 	= isset($meta['meta']['navtitle']) ? $meta['meta']['navtitle'] : '';
 				$extended[$item->urlRelWoF]['hide'] 		= isset($meta['meta']['hide']) ? $meta['meta']['hide'] : false;
@@ -208,6 +208,10 @@ class Navigation
 				$extended[$item->urlRelWoF]['path']			= $item->path;
 				$extended[$item->urlRelWoF]['keyPath']		= $item->keyPath;
 			}
+			else
+			{
+				# should we create the yaml file here if it does not exist?
+			}
 
 			if ($item->elementType == 'folder')
 			{
@@ -250,7 +254,7 @@ class Navigation
 		foreach($searchArray as $key => $itemKey)
 		{
 			$item = isset($navigation[$itemKey]) ? clone($navigation[$itemKey]) : false;
-			
+
 			unset($searchArray[$key]);
 			if(!empty($searchArray) && $item)
 			{
@@ -261,11 +265,60 @@ class Navigation
 		return $item;
 	}
 
+	public function getItemForUrlFrontend($folderContentDetails, $url, $result = NULL)
+	{
+		foreach($folderContentDetails as $key => $item)
+		{
+			# set item active, needed to move item in navigation
+			if($item->urlRelWoF === $url)
+			{
+				$item->active = true;
+				$result = $item;
+			}
+			elseif($item->elementType === "folder")
+			{
+				$result = $this->getItemForUrlFrontend($item->folderContent, $url, $result);
+			}
+		}
+
+		return $result;
+	}	
+
+	public function setActiveNaviItems($navigation, array $searchArray)
+	{
+		foreach($searchArray as $key => $itemKey)
+		{
+			if(isset($navigation[$itemKey]))
+			{
+				unset($searchArray[$key]);
+
+				# active, if there are no more subitems
+				if(empty($searchArray))
+				{
+					$navigation[$itemKey]->active = true;
+				}
+
+				# activeParent, if there are more subitems
+				if(!empty($searchArray) && isset($navigation[$itemKey]->folderContent))
+				{
+					$navigation[$itemKey]->activeParent = true;
+					$navigation[$itemKey]->folderContent = $this->setActiveNaviItems($navigation[$itemKey]->folderContent, $searchArray);
+				}
+				
+				# break to avoid other items with that key are set active
+				break;
+			}
+		}
+		return $navigation;
+	}
+
+
+############################## TODO
 	# reads the cached structure with published pages
 	public function getLiveNavigation()
 	{
 		# get the cached navi
-		$liveNavi = $this->storage->getFile($this->naviFolder, $this->liveNaviName, 'unserialize');
+		$liveNavi = $this->storage->getFile('naviFolder', $this->naviFolder, $this->liveNaviName, 'unserialize');
 
 		# if there is no cached structure
 		if(!$liveNavi)
@@ -276,13 +329,13 @@ class Navigation
 		return $liveNavi;
 	}
 
+
+################################## TODO
 	# creates a fresh structure with published pages
 	private function createNewLiveNavigation($urlinfo, $language)
 	{
-		$folder = new Folder();
-
 		# scan the content of the folder
-		$draftNavi = $folder->scanFolder($this->storage->contentFolder, $draft = false);
+		$draftNavi = $this->scanFolder($this->storage->contentFolder, $draft = false);
 
 		# if there is content, then get the content details
 		if($draftNavi && count($draftNavi) > 0)
@@ -316,7 +369,7 @@ class Navigation
 	{
 		# get the extended structure files with changes like navigation title or hidden pages
 		$yaml = new writeYaml();
-		$extended = $yaml->getYaml('cache', 'structure-extended.yaml');
+		$extended = $yaml->getYaml('cacheFolder', '', 'structure-extended.yaml');
 
 		if(isset($extended[$item->urlRelWoF]))
 		{
@@ -327,7 +380,7 @@ class Navigation
 			unset($extended[$item->urlRelWoF]);
 			
 			$extended[$newUrl] = $entry;
-			$yaml->updateYaml('cache', 'structure-extended.yaml', $extended);
+			$yaml->updateYaml('cacheFolder', '', 'structure-extended.yaml', $extended);
 		}
 
 		return true;
@@ -343,7 +396,7 @@ class Navigation
 		if($this->item->elementType == "file" && isset($extended[$this->item->urlRelWoF]))
 		{
 			unset($extended[$this->item->urlRelWoF]);
-			$yaml->updateYaml('cache', 'structure-extended.yaml', $extended);
+			$yaml->updateYaml('cacheFolder', '', 'structure-extended.yaml', $extended);
 		}
 
 		if($this->item->elementType == "folder")
@@ -362,7 +415,7 @@ class Navigation
 
 			if($changed)
 			{
-				$yaml->updateYaml('cache', 'structure-extended.yaml', $extended);
+				$yaml->updateYaml('cacheFolder', '', 'structure-extended.yaml', $extended);
 			}
 		}
 	}
diff --git a/system/typemill/Models/ProcessFile.php b/system/typemill/Models/ProcessFile.php
index b4d67d6..87ba885 100644
--- a/system/typemill/Models/ProcessFile.php
+++ b/system/typemill/Models/ProcessFile.php
@@ -11,6 +11,7 @@ class Yaml extends StorageWrapper
 	 */
 	public function getYaml($folderName, $yamlFileName)
 	{
+		die('you are useing old class here');
 		$yaml = $this->getFile($folderName, $yamlFileName);
 		
 		if($yaml)
@@ -29,6 +30,7 @@ class Yaml extends StorageWrapper
 	 */	
 	public function updateYaml($folderName, $yamlFileName, $contentArray)
 	{
+		die('you are useing old class here');
 		$yaml = \Symfony\Component\Yaml\Yaml::dump($contentArray,6);
 		if($this->writeFile($folderName, $yamlFileName, $yaml))
 		{
diff --git a/system/typemill/Models/Storage.php b/system/typemill/Models/Storage.php
index 2737343..ea65052 100644
--- a/system/typemill/Models/Storage.php
+++ b/system/typemill/Models/Storage.php
@@ -4,41 +4,69 @@ namespace Typemill\Models;
 
 class Storage
 {
-	public $error 				= false;
+	public $error 					= false;
 
-	protected $basepath 		= false;
+	protected $basepath 			= false;
 
-	protected $tmpFolder 		= false;
+	protected $tmpFolder 			= false;
 
-	protected $originalFolder 	= false;
+	protected $originalFolder 		= false;
 
-	protected $liveFolder 		= false;
+	protected $liveFolder 			= false;
 
-	protected $thumbsFolder 	= false;
+	protected $thumbsFolder 		= false;
 
-	protected $customFolder 	= false;
+	protected $customFolder 		= false;
 
-	protected $fileFolder 		= false;
+	protected $fileFolder 			= false;
 
-	protected $contentFolder 	= false;
+	protected $contentFolder 		= false;
 
+	protected $dataFolder 			= false;
+
+	protected $cacheFolder 			= false;
+
+	protected $settingsFolder 		= false;
+
+	protected $themeFolder 			= false;
+
+	protected $pluginFolder 		= false;
+
+	protected $translationFolder 	= false;
+
+	protected $systemSettings 		= false;
+ 
 	public function __construct()
 	{
-		$this->basepath 		= getcwd() . DIRECTORY_SEPARATOR;
+		$this->basepath 			= getcwd() . DIRECTORY_SEPARATOR;
 
-		$this->tmpFolder 		= $this->basepath . 'media' . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
+		$this->tmpFolder 			= $this->basepath . 'media' . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
 
-		$this->originalFolder 	= $this->basepath . 'media' . DIRECTORY_SEPARATOR . 'original' . DIRECTORY_SEPARATOR;
+		$this->originalFolder 		= $this->basepath . 'media' . DIRECTORY_SEPARATOR . 'original' . DIRECTORY_SEPARATOR;
 
-		$this->liveFolder  		= $this->basepath . 'media' . DIRECTORY_SEPARATOR . 'live' . DIRECTORY_SEPARATOR;
+		$this->liveFolder  			= $this->basepath . 'media' . DIRECTORY_SEPARATOR . 'live' . DIRECTORY_SEPARATOR;
 
-		$this->thumbsFolder		= $this->basepath . 'media' . DIRECTORY_SEPARATOR . 'thumbs' . DIRECTORY_SEPARATOR;
+		$this->thumbsFolder			= $this->basepath . 'media' . DIRECTORY_SEPARATOR . 'thumbs' . DIRECTORY_SEPARATOR;
 
-		$this->customFolder		= $this->basepath . 'media' . DIRECTORY_SEPARATOR . 'custom' . DIRECTORY_SEPARATOR;
+		$this->customFolder			= $this->basepath . 'media' . DIRECTORY_SEPARATOR . 'custom' . DIRECTORY_SEPARATOR;
 
-		$this->fileFolder 		= $this->basepath . 'media' . DIRECTORY_SEPARATOR . 'files' . DIRECTORY_SEPARATOR;
+		$this->fileFolder 			= $this->basepath . 'media' . DIRECTORY_SEPARATOR . 'files' . DIRECTORY_SEPARATOR;
 	
-		$this->contentFolder 	= $this->basepath . 'content';
+		$this->contentFolder 		= $this->basepath . 'content';
+
+		$this->dataFolder  			= $this->basepath . 'data';
+
+		$this->cacheFolder 			= $this->basepath . 'cache';
+
+		$this->settingsFolder 		= $this->basepath . 'settings';
+
+		$this->pluginFolder 		= $this->basepath . 'plugins';
+
+		$this->themeFolder 			= $this->basepath . 'themes';
+
+		$this->translationFolder 	= $this->basepath . 'system' .  DIRECTORY_SEPARATOR . 'typemill' . DIRECTORY_SEPARATOR . 'author' . DIRECTORY_SEPARATOR . 'translations' . DIRECTORY_SEPARATOR;
+	
+		$this->systemSettings 		= $this->basepath . 'system' .  DIRECTORY_SEPARATOR . 'typemill' .  DIRECTORY_SEPARATOR . 'settings';
 	}
 
 	public function getError()
@@ -46,7 +74,251 @@ class Storage
 		return $this->error;
 	}
 
-	public function getStorageInfo($item)
+	public function getFolderPath($location, $folder = NULL)
+	{
+		if(isset($this->$location))
+		{
+			$path = rtrim($this->$location, DIRECTORY_SEPARATOR);
+			$path .= DIRECTORY_SEPARATOR;
+			if($folder && $folder != '')
+			{
+				$folder = trim($folder, DIRECTORY_SEPARATOR);
+				$path .= $folder . DIRECTORY_SEPARATOR; 
+			}
+#			echo '
';
+#			echo $path;
+
+			return $path;
+		}
+
+		$this->error = "We could not find a folderPath for $location";
+		return false;
+	}
+
+	public function checkFolder($location, $folder)
+	{
+		$folderpath = $this->getFolderPath($location, $folder);
+
+		if(!is_dir($folderpath) OR !is_writable($folderpath))
+		{
+			$this->error = "The folder $folderpath does not exist or is not writable.";
+
+			return false;
+		}
+
+		return true;
+	}
+
+	public function createFolder($location, $folder)
+	{
+		$folderpath = $this->getFolderPath($location, $folder);
+
+		if(is_dir($folderpath))
+		{
+			return true;
+		}
+
+		if(!mkdir($folderpath, 0755, true))
+		{
+			$this->error = "Could not create folder $folderpath.";
+
+			return false;
+		}
+
+		return true;
+	}
+
+	public function checkFile($location, $folder, $filename)
+	{
+		$filepath = $this->getFolderPath($location, $folder) . $filename;
+
+		if(!file_exists($filepath))
+		{
+			$this->error = "The file $filepath does not exist.";
+
+			return false;
+		}
+
+		return true;
+	}
+
+	public function getFile($location, $folder, $filename, $method = NULL)
+	{
+		if($this->checkFile($location, $folder, $filename))
+		{
+			$filepath = $this->getFolderPath($location) . $folder . DIRECTORY_SEPARATOR . $filename;
+
+			$fileContent = file_get_contents($filepath);
+		
+			# use unserialise or json_decode
+			if($method && is_callable($method))
+			{
+				$fileContent = $method($fileContent);
+			}
+
+			return $fileContent;
+		}
+
+		return false;
+	}
+
+	public function writeFile($location, $folder, $filename, $data, $method = NULL)
+	{
+		if(!$this->checkFolder($location, $folder))
+		{
+			if(!$this->createFolder($location, $folder))
+			{
+				return false;
+			}
+		}
+
+		$filepath = $this->getFolderPath($location) . $folder . DIRECTORY_SEPARATOR . $filename;
+			
+		$openfile = @fopen($filepath, "w");
+		if(!$openfile)
+		{
+			$this->error = "Could not open and read the file $filepath";
+
+			return false;
+		}
+
+		# serialize, json_decode
+		if($method && is_callable($method))
+		{
+			$data = $method($data);
+		}
+
+		$writefile = fwrite($openfile, $data);
+		if(!$writefile)
+		{
+			$this->error = "Could not write to the file $filepath";
+
+			return false;
+		}
+
+		fclose($openfile);
+
+		return true;
+	}
+
+	public function renameFile($location, $folder, $oldname, $newname)
+	{
+		$oldFilePath = $this->getFolderPath($location) . $folder . DIRECTORY_SEPARATOR . $oldname;
+		$newFilePath = $this->getFolderPath($location) . $folder . DIRECTORY_SEPARATOR . $newname;
+
+		if(!file_exists($oldFilePath))
+		{
+			return false;
+		}
+
+		if(!rename($oldFilePath, $newFilePath))
+		{
+			return false;
+		}
+		
+		return true;
+	}
+
+	public function deleteFile($location, $folder, $filename)
+	{
+		if($this->checkFile($location, $folder, $filename))
+		{
+			$filepath = $this->getFolderPath($location) . $folder . DIRECTORY_SEPARATOR . $filename;
+
+			if(unlink($filepath))
+			{
+				return true;
+			}
+
+			$this->error = "We found the file but could not delete $filepath";
+		}
+
+		return false;
+	}
+
+	# used to sort the navigation / files 
+	public function moveContentFile($item, $folderPath, $index, $date = null)
+	{
+		$filetypes			= array('md', 'txt', 'yaml');
+		
+		# set new order as string
+		$newOrder			= ($index < 10) ? '0' . $index : $index;
+
+		$newPath 			= $this->contentFolder . $folderPath . DIRECTORY_SEPARATOR . $newOrder . '-' . $item->slug;
+
+		if($item->elementType == 'folder')
+		{
+			$oldPath = $this->contentFolder . $item->path;
+
+			if(@rename($oldPath, $newPath))
+			{
+				return true;
+			}
+			return false;
+		}
+		
+		# create old path but without filetype
+		$oldPath		= substr($item->path, 0, strpos($item->path, "."));
+		$oldPath		= $this->contentFolder . $oldPath;
+
+		$result 		= true;
+		
+		foreach($filetypes as $filetype)
+		{
+			$oldFilePath = $oldPath . '.' . $filetype;
+			$newFilePath = $newPath . '.' . $filetype;
+			
+			#check if file with filetype exists and rename
+			if($oldFilePath != $newFilePath && file_exists($oldFilePath))
+			{
+				if(@rename($oldFilePath, $newFilePath))
+				{
+					$result = $result;
+				}
+				else
+				{
+					$result = false;
+				}
+			}
+		}
+
+		return $result;
+	}
+
+	public function getYaml($location, $folder, $filename)
+	{
+		$yaml = $this->getFile($location, $folder, $filename);
+		
+		if($yaml)
+		{
+			return \Symfony\Component\Yaml\Yaml::parse($yaml);
+		}
+
+		return false;
+	}
+
+	public function updateYaml($location, $folder, $filename, $contentArray)
+	{
+		$yaml = \Symfony\Component\Yaml\Yaml::dump($contentArray,6);
+		if($this->writeFile($location, $folder, $filename, $yaml))
+		{
+			return true;
+		}
+
+		return false;
+	}
+
+
+
+
+
+
+
+
+
+
+
+	public function getStorageInfoBREAK($item)
 	{
 		if(isset($this->$item))
 		{
@@ -55,7 +327,7 @@ class Storage
 		return false;
 	}
 
-	public function checkFolder($folder)
+	public function checkFolderBREAK($folder)
 	{
 		$folderpath = $this->basepath . $folder;
 
@@ -69,7 +341,7 @@ class Storage
 		return true;
 	}
 
-	public function createFolder($folder)
+	public function createFolderBREAK($folder)
 	{
 		$folderpath = $this->basepath . $folder;
 
@@ -88,7 +360,7 @@ class Storage
 		return true;
 	}
 
-	public function checkFile($folder, $filename)
+	public function checkFileBREAK($folder, $filename)
 	{
 		if(!file_exists($this->basepath . $folder . DIRECTORY_SEPARATOR . $filename))
 		{
@@ -100,8 +372,12 @@ class Storage
 		return true;
 	}
 
-	public function writeFile($folder, $filename, $data, $method = NULL)
+	public function writeFileBREAK($folder, $filename, $data, $method = NULL)
 	{
+		echo '
';
+		var_dump($folder);
+		die();
+
 		if(!$this->checkFolder($folder))
 		{
 			if(!$this->createFolder($folder))
@@ -139,7 +415,7 @@ class Storage
 		return true;
 	}
 
-	public function getFile($folder, $filename, $method = NULL)
+	public function getFileBREAK($folder, $filename, $method = NULL)
 	{
 		if($this->checkFile($folder, $filename))
 		{
@@ -158,9 +434,8 @@ class Storage
 		return false;
 	}
 
-	public function renameFile($folder, $oldname, $newname)
+	public function renameFileBREAK($folder, $oldname, $newname)
 	{
-
 		$oldFilePath = $this->basepath . $folder . DIRECTORY_SEPARATOR . $oldname;
 		$newFilePath = $this->basepath . $folder . DIRECTORY_SEPARATOR . $newname;
 
@@ -177,7 +452,7 @@ class Storage
 		return true;
 	}
 
-	public function deleteFile($folder, $filename)
+	public function deleteFileBREAK($folder, $filename)
 	{
 		if($this->checkFile($folder, $filename))
 		{
@@ -193,7 +468,7 @@ class Storage
 	}
 
 	# used to sort the navigation / files 
-	public function moveFile($item, $folderPath, $index, $date = null)
+	public function moveContentFileBREAK($item, $folderPath, $index, $date = null)
 	{
 		$filetypes			= array('md', 'txt', 'yaml');
 		
@@ -204,7 +479,8 @@ class Storage
 
 		if($item->elementType == 'folder')
 		{
-			$oldPath = $this->basePath . 'content' . $item->path;
+			$oldPath = $this->contentFolder . $item->path;
+
 			if(@rename($oldPath, $newPath))
 			{
 				return true;
@@ -237,44 +513,9 @@ class Storage
 			}
 		}
 
-		return $result;		
+		return $result;
 	}
 
-	/**
-	 * Get the a yaml file.
-	 * @param string $fileName is the name of the Yaml Folder.
-	 * @param string $yamlFileName is the name of the Yaml File.
-	 */
-	public function getYaml($folderName, $yamlFileName)
-	{
-		$yaml = $this->getFile($folderName, $yamlFileName);
-		
-		if($yaml)
-		{
-			return \Symfony\Component\Yaml\Yaml::parse($yaml);
-		}
-
-		return false;
-	}
-
-	/**
-	 * Writes a yaml file.
-	 * @param string $fileName is the name of the Yaml Folder.
-	 * @param string $yamlFileName is the name of the Yaml File.
-	 * @param array $contentArray is the content as an array.
-	 */	
-	public function updateYaml($folderName, $yamlFileName, $contentArray)
-	{
-		$yaml = \Symfony\Component\Yaml\Yaml::dump($contentArray,6);
-		if($this->writeFile($folderName, $yamlFileName, $yaml))
-		{
-			return true;
-		}
-
-		return false;
-	}
-
-
 
 
 	public function createUniqueImageName($filename, $extension)
diff --git a/system/typemill/Models/User.php b/system/typemill/Models/User.php
index 260b160..6b7de5e 100644
--- a/system/typemill/Models/User.php
+++ b/system/typemill/Models/User.php
@@ -22,7 +22,7 @@ class User
 
 	public function setUser(string $username)
 	{
-		$this->user = $this->storage->getYaml('settings/users', $username . '.yaml');
+		$this->user = $this->storage->getYaml('settingsFolder', 'users', $username . '.yaml');
 	
 		if(!$this->user)
 		{
@@ -39,7 +39,7 @@ class User
 
 	public function setUserWithPassword(string $username)
 	{
-		$this->user = $this->storage->getYaml('settings/users', $username . '.yaml');
+		$this->user = $this->storage->getYaml('settingsFolder', 'users', $username . '.yaml');
 
 		if(!$this->user)
 		{
@@ -103,7 +103,7 @@ class User
 	{
 		$params['password'] = $this->generatePassword($params['password']);
 	
-		if($this->storage->updateYaml('settings/users', $params['username'] . '.yaml', $params))
+		if($this->storage->updateYaml('settingsFolder', 'users', $params['username'] . '.yaml', $params))
 		{
 			$this->deleteUserIndex();
 
@@ -117,7 +117,7 @@ class User
 
 	public function updateUser()
 	{
-		if($this->storage->updateYaml('settings/users', $this->user['username'] . '.yaml', $this->user))
+		if($this->storage->updateYaml('settingsFolder', 'users', $this->user['username'] . '.yaml', $this->user))
 		{
 			$this->deleteUserIndex();
 	
@@ -131,7 +131,7 @@ class User
 
 	public function deleteUser()
 	{
-		if($this->storage->deleteFile('settings/users/', $this->user['username'] . '.yaml'))
+		if($this->storage->deleteFile('settingsFolder', 'users', $this->user['username'] . '.yaml'))
 		{
 			$this->deleteUserIndex();
 
diff --git a/system/typemill/Static/Helpers.php b/system/typemill/Static/Helpers.php
index 3c09bf9..b95cd6f 100644
--- a/system/typemill/Static/Helpers.php
+++ b/system/typemill/Static/Helpers.php
@@ -59,7 +59,7 @@ class Helpers{
 		$line 		.= ';' . $action;
 
 		$storage 	= new StorageWrapper('\Typemill\Models\Storage');
-		$logfile 	= $storage->getFile('cache', 'securitylog.txt');
+		$logfile 	= $storage->getFile('basepath', 'cache', 'securitylog.txt');
 
 		if($logfile)
 		{
@@ -70,7 +70,7 @@ class Helpers{
 			$logfile = $line . PHP_EOL;
 		}
 		
-		$storage->writeFile('cache', 'securitylog.txt', $logfile);
+		$storage->writeFile('basepath', 'cache', 'securitylog.txt', $logfile);
 	}
 
 	public static function array_sort($array, $on, $order=SORT_ASC)
diff --git a/system/typemill/Static/License.php b/system/typemill/Static/License.php
index cd91f9f..2a33492 100644
--- a/system/typemill/Static/License.php
+++ b/system/typemill/Static/License.php
@@ -20,7 +20,7 @@ class License
 	{
 		$storage = new StorageWrapper('\Typemill\Models\Storage');
 
-		$licensedata = $storage->getYaml('settings', 'license.yaml');
+		$licensedata = $storage->getYaml('basepath', 'settings', 'license.yaml');
 
 		if(!$licensedata)
 		{
diff --git a/system/typemill/Static/Settings.php b/system/typemill/Static/Settings.php
index 24fa686..fe7017a 100644
--- a/system/typemill/Static/Settings.php
+++ b/system/typemill/Static/Settings.php
@@ -134,7 +134,7 @@ class Settings
 		
 		$storage 	= new StorageWrapper('\Typemill\Models\Storage');
 		
-		$storage->updateYaml('settings', 'settings.yaml', $settings);
+		$storage->updateYaml('basepath', 'settings', 'settings.yaml', $settings);
 	}
 
 
diff --git a/system/typemill/Static/Translations.php b/system/typemill/Static/Translations.php
index e04ca58..84ca844 100644
--- a/system/typemill/Static/Translations.php
+++ b/system/typemill/Static/Translations.php
@@ -29,21 +29,13 @@ class Translations
 		$plugins_translations 	= [];
 
 		# theme labels selected according to the environment: admin or user
-		$theme_language_folder 	= 'themes' . DIRECTORY_SEPARATOR . $settings['theme'] . DIRECTORY_SEPARATOR . 'languages' . DIRECTORY_SEPARATOR . $environment . DIRECTORY_SEPARATOR;
-		$theme_language_file 	= $language . '.yaml';
-		if (file_exists($theme_language_folder . $theme_language_file))
-		{
-			$theme_translations = $storage->getYaml($theme_language_folder, $theme_language_file);
-		}
+		$theme_language_folder 	= DIRECTORY_SEPARATOR . $settings['theme'] . DIRECTORY_SEPARATOR . 'languages' . DIRECTORY_SEPARATOR . $environment . DIRECTORY_SEPARATOR;
+		$theme_translations 	= $storage->getYaml('themeFolder', $theme_language_folder, $language . '.yaml') ?? [];
 
 		if($environment == 'admin')
 		{
-			$system_language_folder = 'system' . DIRECTORY_SEPARATOR . 'typemill' . DIRECTORY_SEPARATOR . 'author' . DIRECTORY_SEPARATOR . 'translations' . DIRECTORY_SEPARATOR;
-			$system_language_file 	= $language . '.yaml';
-			if(file_exists($system_language_folder . $system_language_file))
-			{
-				$system_translations = $storage->getYaml($system_language_folder, $system_language_file);
-			}
+			$system_language_folder 	= DIRECTORY_SEPARATOR . 'typemill' . DIRECTORY_SEPARATOR . 'author' . DIRECTORY_SEPARATOR . 'translations' . DIRECTORY_SEPARATOR;
+			$system_translations 		= $storage->getYaml('translationFolder', $system_language_folder, $language . '.yaml');
 
 			# Next change, to provide labels for the admin and user environments.
 			# There may be plugins that only work in the user environment, only in the admin environment, or in both environments.
@@ -54,12 +46,8 @@ class Translations
 			  	{
 					if(isset($config['active']) && $config['active'])
 					{
-				  		$plugin_language_folder = 'plugins' . DIRECTORY_SEPARATOR . $plugin . DIRECTORY_SEPARATOR . 'languages' . DIRECTORY_SEPARATOR;
-				  		$plugin_language_file = $language . '.yaml';
-				  		if (file_exists($plugin_language_folder . $plugin_language_file))
-				  		{
-							$plugins_translations[$plugin] = $storage->getYaml($plugin_language_folder, $plugin_language_file);
-				  		}
+				  		$plugin_language_folder 		= DIRECTORY_SEPARATOR . $plugin . DIRECTORY_SEPARATOR . 'languages' . DIRECTORY_SEPARATOR;
+						$plugins_translations[$plugin] 	= $storage->getYaml('pluginFolder', $plugin_language_folder, $language . '.yaml');
 					}
 			  	}
 
@@ -69,24 +57,23 @@ class Translations
 					{
 	  					$plugins_translations = array_merge($plugins_translations, $value);
 					}
-  				}	
+  				}
 	  		}
 		}
 
 		$translations = [];
-		if(!empty($plugins_translations))
+		if(is_array($plugins_translations) && !empty($plugins_translations))
 		{
 	  		$translations = array_merge($translations, $plugins_translations);
 		}
-		if(!empty($system_translations))
+		if(is_array($system_translations) && !empty($system_translations))
 		{
 	  		$translations = array_merge($translations, $system_translations);
 		}
-		if(!empty($theme_translations))
+		if(is_array($theme_translations) && !empty($theme_translations))
 		{
 	  		$translations = array_merge($translations, $theme_translations);
 		}
-
 		return $translations;
 	}
 
diff --git a/system/typemill/author/css/output.css b/system/typemill/author/css/output.css
index c601452..093ff07 100644
--- a/system/typemill/author/css/output.css
+++ b/system/typemill/author/css/output.css
@@ -661,14 +661,14 @@ video {
   bottom: 0px;
 }
 
-.left-0 {
-  left: 0px;
-}
-
 .right-0 {
   right: 0px;
 }
 
+.left-0 {
+  left: 0px;
+}
+
 .top-0 {
   top: 0px;
 }
@@ -701,15 +701,16 @@ video {
   margin: auto;
 }
 
-.m-1 {
-  margin: 0.25rem;
-}
-
 .my-2 {
   margin-top: 0.5rem;
   margin-bottom: 0.5rem;
 }
 
+.my-px {
+  margin-top: 1px;
+  margin-bottom: 1px;
+}
+
 .my-8 {
   margin-top: 2rem;
   margin-bottom: 2rem;
@@ -740,11 +741,6 @@ video {
   margin-bottom: 0.75rem;
 }
 
-.mx-1 {
-  margin-left: 0.25rem;
-  margin-right: 0.25rem;
-}
-
 .mt-6 {
   margin-top: 1.5rem;
 }
@@ -757,16 +753,16 @@ video {
   margin-right: 0.75rem;
 }
 
-.mb-1 {
-  margin-bottom: 0.25rem;
+.ml-1 {
+  margin-left: 0.25rem;
 }
 
 .mr-1 {
   margin-right: 0.25rem;
 }
 
-.mr-4 {
-  margin-right: 1rem;
+.mb-1 {
+  margin-bottom: 0.25rem;
 }
 
 .mt-3 {
@@ -813,18 +809,14 @@ video {
   margin-top: 1.75rem;
 }
 
+.mr-4 {
+  margin-right: 1rem;
+}
+
 .mr-2 {
   margin-right: 0.5rem;
 }
 
-.ml-1 {
-  margin-left: 0.25rem;
-}
-
-.-ml-1 {
-  margin-left: -0.25rem;
-}
-
 .block {
   display: block;
 }
@@ -861,6 +853,10 @@ video {
   display: none;
 }
 
+.h-5 {
+  height: 1.25rem;
+}
+
 .h-8 {
   height: 2rem;
 }
@@ -877,10 +873,6 @@ video {
   height: 3rem;
 }
 
-.h-5 {
-  height: 1.25rem;
-}
-
 .h-80 {
   height: 20rem;
 }
@@ -905,6 +897,10 @@ video {
   width: 100%;
 }
 
+.w-5 {
+  width: 1.25rem;
+}
+
 .w-1\/4 {
   width: 25%;
 }
@@ -929,10 +925,6 @@ video {
   width: 0px;
 }
 
-.w-5 {
-  width: 1.25rem;
-}
-
 .w-2\/3 {
   width: 66.666667%;
 }
@@ -1026,10 +1018,6 @@ video {
   resize: both;
 }
 
-.list-none {
-  list-style-type: none;
-}
-
 .flex-col {
   flex-direction: column;
 }
@@ -1106,6 +1094,11 @@ video {
   border-width: 2px;
 }
 
+.border-y {
+  border-top-width: 1px;
+  border-bottom-width: 1px;
+}
+
 .border-x-8 {
   border-left-width: 8px;
   border-right-width: 8px;
@@ -1152,14 +1145,24 @@ video {
   border-color: rgb(209 213 219 / var(--tw-border-opacity));
 }
 
+.border-stone-200 {
+  --tw-border-opacity: 1;
+  border-color: rgb(231 229 228 / var(--tw-border-opacity));
+}
+
 .border-teal-500 {
   --tw-border-opacity: 1;
   border-color: rgb(20 184 166 / var(--tw-border-opacity));
 }
 
-.border-stone-200 {
+.border-stone-100 {
   --tw-border-opacity: 1;
-  border-color: rgb(231 229 228 / var(--tw-border-opacity));
+  border-color: rgb(245 245 244 / var(--tw-border-opacity));
+}
+
+.border-stone-50 {
+  --tw-border-opacity: 1;
+  border-color: rgb(250 250 249 / var(--tw-border-opacity));
 }
 
 .border-white {
@@ -1187,16 +1190,6 @@ video {
   border-color: rgb(255 228 230 / var(--tw-border-opacity));
 }
 
-.border-stone-100 {
-  --tw-border-opacity: 1;
-  border-color: rgb(245 245 244 / var(--tw-border-opacity));
-}
-
-.border-stone-50 {
-  --tw-border-opacity: 1;
-  border-color: rgb(250 250 249 / var(--tw-border-opacity));
-}
-
 .border-cyan-500 {
   --tw-border-opacity: 1;
   border-color: rgb(6 182 212 / var(--tw-border-opacity));
@@ -1232,6 +1225,20 @@ video {
   background-color: rgb(255 255 255 / var(--tw-bg-opacity));
 }
 
+.bg-transparent {
+  background-color: transparent;
+}
+
+.bg-teal-500 {
+  --tw-bg-opacity: 1;
+  background-color: rgb(20 184 166 / var(--tw-bg-opacity));
+}
+
+.bg-rose-500 {
+  --tw-bg-opacity: 1;
+  background-color: rgb(244 63 94 / var(--tw-bg-opacity));
+}
+
 .bg-stone-100 {
   --tw-bg-opacity: 1;
   background-color: rgb(245 245 244 / var(--tw-bg-opacity));
@@ -1247,16 +1254,6 @@ video {
   background-color: rgb(231 229 228 / var(--tw-bg-opacity));
 }
 
-.bg-rose-500 {
-  --tw-bg-opacity: 1;
-  background-color: rgb(244 63 94 / var(--tw-bg-opacity));
-}
-
-.bg-teal-500 {
-  --tw-bg-opacity: 1;
-  background-color: rgb(20 184 166 / var(--tw-bg-opacity));
-}
-
 .bg-red-100 {
   --tw-bg-opacity: 1;
   background-color: rgb(254 226 226 / var(--tw-bg-opacity));
@@ -1272,10 +1269,6 @@ video {
   background-color: rgb(250 250 249 / var(--tw-bg-opacity));
 }
 
-.bg-transparent {
-  background-color: transparent;
-}
-
 .bg-opacity-90 {
   --tw-bg-opacity: 0.9;
 }
@@ -1337,6 +1330,11 @@ video {
   padding-bottom: 0.75rem;
 }
 
+.px-2 {
+  padding-left: 0.5rem;
+  padding-right: 0.5rem;
+}
+
 .px-8 {
   padding-left: 2rem;
   padding-right: 2rem;
@@ -1357,28 +1355,43 @@ video {
   padding-right: 1rem;
 }
 
-.px-2 {
-  padding-left: 0.5rem;
-  padding-right: 0.5rem;
-}
-
 .px-1 {
   padding-left: 0.25rem;
   padding-right: 0.25rem;
 }
 
-.pl-2 {
-  padding-left: 0.5rem;
-}
-
 .pl-3 {
   padding-left: 0.75rem;
 }
 
+.pl-2 {
+  padding-left: 0.5rem;
+}
+
+.pl-4 {
+  padding-left: 1rem;
+}
+
+.pl-6 {
+  padding-left: 1.5rem;
+}
+
+.pl-8 {
+  padding-left: 2rem;
+}
+
+.pl-9 {
+  padding-left: 2.25rem;
+}
+
 .pl-10 {
   padding-left: 2.5rem;
 }
 
+.pl-12 {
+  padding-left: 3rem;
+}
+
 .pr-2 {
   padding-right: 0.5rem;
 }
@@ -1411,18 +1424,6 @@ video {
   padding-bottom: 0.75rem;
 }
 
-.pl-4 {
-  padding-left: 1rem;
-}
-
-.pl-8 {
-  padding-left: 2rem;
-}
-
-.pl-12 {
-  padding-left: 3rem;
-}
-
 .text-left {
   text-align: left;
 }
@@ -1463,11 +1464,6 @@ video {
   line-height: 2.25rem;
 }
 
-.text-sm {
-  font-size: 0.875rem;
-  line-height: 1.25rem;
-}
-
 .text-lg {
   font-size: 1.125rem;
   line-height: 1.75rem;
@@ -1478,6 +1474,11 @@ video {
   line-height: 1.75rem;
 }
 
+.text-sm {
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+}
+
 .text-2xl {
   font-size: 1.5rem;
   line-height: 2rem;
@@ -1526,6 +1527,21 @@ video {
   color: rgb(225 29 72 / var(--tw-text-opacity));
 }
 
+.text-stone-50 {
+  --tw-text-opacity: 1;
+  color: rgb(250 250 249 / var(--tw-text-opacity));
+}
+
+.text-stone-700 {
+  --tw-text-opacity: 1;
+  color: rgb(68 64 60 / var(--tw-text-opacity));
+}
+
+.text-stone-500 {
+  --tw-text-opacity: 1;
+  color: rgb(120 113 108 / var(--tw-text-opacity));
+}
+
 .text-teal-500 {
   --tw-text-opacity: 1;
   color: rgb(20 184 166 / var(--tw-text-opacity));
@@ -1561,21 +1577,6 @@ video {
   color: rgb(6 182 212 / var(--tw-text-opacity));
 }
 
-.text-stone-700 {
-  --tw-text-opacity: 1;
-  color: rgb(68 64 60 / var(--tw-text-opacity));
-}
-
-.text-stone-200 {
-  --tw-text-opacity: 1;
-  color: rgb(231 229 228 / var(--tw-text-opacity));
-}
-
-.text-stone-500 {
-  --tw-text-opacity: 1;
-  color: rgb(120 113 108 / var(--tw-text-opacity));
-}
-
 .underline {
   -webkit-text-decoration-line: underline;
           text-decoration-line: underline;
@@ -1585,10 +1586,6 @@ video {
   accent-color: #fff;
 }
 
-.opacity-0 {
-  opacity: 0;
-}
-
 .opacity-25 {
   opacity: 0.25;
 }
@@ -1597,6 +1594,10 @@ video {
   opacity: 0.75;
 }
 
+.opacity-0 {
+  opacity: 0;
+}
+
 .shadow-lg {
   --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
   --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
@@ -1659,6 +1660,11 @@ video {
   border-bottom-width: 4px;
 }
 
+.hover\:border-stone-200:hover {
+  --tw-border-opacity: 1;
+  border-color: rgb(231 229 228 / var(--tw-border-opacity));
+}
+
 .hover\:border-stone-700:hover {
   --tw-border-opacity: 1;
   border-color: rgb(68 64 60 / var(--tw-border-opacity));
@@ -1674,19 +1680,24 @@ video {
   border-color: rgb(20 184 166 / var(--tw-border-opacity));
 }
 
-.hover\:border-stone-50:hover {
-  --tw-border-opacity: 1;
-  border-color: rgb(250 250 249 / var(--tw-border-opacity));
-}
-
 .hover\:bg-gray-200:hover {
   --tw-bg-opacity: 1;
   background-color: rgb(229 231 235 / var(--tw-bg-opacity));
 }
 
-.hover\:bg-stone-50:hover {
+.hover\:bg-stone-700:hover {
   --tw-bg-opacity: 1;
-  background-color: rgb(250 250 249 / var(--tw-bg-opacity));
+  background-color: rgb(68 64 60 / var(--tw-bg-opacity));
+}
+
+.hover\:bg-teal-500:hover {
+  --tw-bg-opacity: 1;
+  background-color: rgb(20 184 166 / var(--tw-bg-opacity));
+}
+
+.hover\:bg-stone-200:hover {
+  --tw-bg-opacity: 1;
+  background-color: rgb(231 229 228 / var(--tw-bg-opacity));
 }
 
 .hover\:bg-stone-900:hover {
@@ -1714,11 +1725,6 @@ video {
   background-color: rgb(214 211 209 / var(--tw-bg-opacity));
 }
 
-.hover\:bg-stone-200:hover {
-  --tw-bg-opacity: 1;
-  background-color: rgb(231 229 228 / var(--tw-bg-opacity));
-}
-
 .hover\:bg-rose-700:hover {
   --tw-bg-opacity: 1;
   background-color: rgb(190 18 60 / var(--tw-bg-opacity));
@@ -1734,24 +1740,9 @@ video {
   background-color: rgb(6 182 212 / var(--tw-bg-opacity));
 }
 
-.hover\:bg-stone-700:hover {
+.hover\:bg-stone-50:hover {
   --tw-bg-opacity: 1;
-  background-color: rgb(68 64 60 / var(--tw-bg-opacity));
-}
-
-.hover\:bg-stone-500:hover {
-  --tw-bg-opacity: 1;
-  background-color: rgb(120 113 108 / var(--tw-bg-opacity));
-}
-
-.hover\:bg-teal-500:hover {
-  --tw-bg-opacity: 1;
-  background-color: rgb(20 184 166 / var(--tw-bg-opacity));
-}
-
-.hover\:text-white:hover {
-  --tw-text-opacity: 1;
-  color: rgb(255 255 255 / var(--tw-text-opacity));
+  background-color: rgb(250 250 249 / var(--tw-bg-opacity));
 }
 
 .hover\:text-stone-50:hover {
@@ -1764,6 +1755,11 @@ video {
   color: rgb(245 245 244 / var(--tw-text-opacity));
 }
 
+.hover\:text-white:hover {
+  --tw-text-opacity: 1;
+  color: rgb(255 255 255 / var(--tw-text-opacity));
+}
+
 .hover\:underline:hover {
   -webkit-text-decoration-line: underline;
           text-decoration-line: underline;
@@ -1774,9 +1770,9 @@ video {
   border-color: rgb(37 99 235 / var(--tw-border-opacity));
 }
 
-.focus\:border-stone-100:focus {
+.focus\:border-stone-200:focus {
   --tw-border-opacity: 1;
-  border-color: rgb(245 245 244 / var(--tw-border-opacity));
+  border-color: rgb(231 229 228 / var(--tw-border-opacity));
 }
 
 .focus\:bg-white:focus {
@@ -1784,16 +1780,16 @@ video {
   background-color: rgb(255 255 255 / var(--tw-bg-opacity));
 }
 
+.focus\:bg-stone-200:focus {
+  --tw-bg-opacity: 1;
+  background-color: rgb(231 229 228 / var(--tw-bg-opacity));
+}
+
 .focus\:bg-stone-50:focus {
   --tw-bg-opacity: 1;
   background-color: rgb(250 250 249 / var(--tw-bg-opacity));
 }
 
-.focus\:bg-stone-100:focus {
-  --tw-bg-opacity: 1;
-  background-color: rgb(245 245 244 / var(--tw-bg-opacity));
-}
-
 .focus\:text-gray-700:focus {
   --tw-text-opacity: 1;
   color: rgb(55 65 81 / var(--tw-text-opacity));
diff --git a/system/typemill/author/js/vue-contentnavi.js b/system/typemill/author/js/vue-contentnavi.js
index 4df60df..a825925 100644
--- a/system/typemill/author/js/vue-contentnavi.js
+++ b/system/typemill/author/js/vue-contentnavi.js
@@ -5,12 +5,12 @@ const navigation = Vue.createApp({
 					
 					
 				
-				
+
- Home + Home
-
- +
+
`, data: function () { return { @@ -59,12 +59,28 @@ const navigation = Vue.createApp({ expandNavigation() { this.expanded = this.getFolderNames(this.navigation, []); - localStorage.setItem("expanded", this.expanded.toString()); + localStorage.setItem("expanded", this.expanded.toString()); }, collapseNavigation() { - this.expanded = []; - localStorage.removeItem('expanded'); + this.expanded = this.getActiveNames(this.navigation, []); + localStorage.setItem("expanded", this.expanded.toString()); + }, + getActiveNames(navigation, expanded) + { + for (const item of navigation) + { + if(item.activeParent || item.active) + { + expanded.push(item.name); + } + + if (item.elementType == 'folder') + { + this.getActiveNames(item.folderContent, expanded); + } + } + return expanded; }, getFolderNames(navigation, result) { @@ -97,10 +113,11 @@ navigation.component('navilevel',{ :component-data="{ id: parentId ? parentId : false }" + :expanded="expanded" >