浏览代码

Merge branch 'master' into develop

trendschau 5 年之前
父节点
当前提交
5a0ad33e19

+ 1 - 0
.htaccess

@@ -10,6 +10,7 @@ RewriteEngine On
 # Protect your system files from prying eyes
 # Protect your system files from prying eyes
 RewriteRule ^(system\/author\/) - [L]
 RewriteRule ^(system\/author\/) - [L]
 RewriteRule ^(system) - [F,L]
 RewriteRule ^(system) - [F,L]
+RewriteRule ^(data) - [F,L]
 RewriteRule ^(content) - [F,L]
 RewriteRule ^(content) - [F,L]
 RewriteRule ^(settings) - [F,L]
 RewriteRule ^(settings) - [F,L]
 RewriteRule ^(.*)?\.yml$ - [F,L]
 RewriteRule ^(.*)?\.yml$ - [F,L]

文件差异内容过多而无法显示
+ 0 - 0
cache/index.json


+ 18 - 18
composer.lock

@@ -791,16 +791,16 @@
         },
         },
         {
         {
             "name": "symfony/polyfill-ctype",
             "name": "symfony/polyfill-ctype",
-            "version": "v1.17.1",
+            "version": "v1.18.0",
             "source": {
             "source": {
                 "type": "git",
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-ctype.git",
                 "url": "https://github.com/symfony/polyfill-ctype.git",
-                "reference": "2edd75b8b35d62fd3eeabba73b26b8f1f60ce13d"
+                "reference": "1c302646f6efc070cd46856e600e5e0684d6b454"
             },
             },
             "dist": {
             "dist": {
                 "type": "zip",
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/2edd75b8b35d62fd3eeabba73b26b8f1f60ce13d",
-                "reference": "2edd75b8b35d62fd3eeabba73b26b8f1f60ce13d",
+                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1c302646f6efc070cd46856e600e5e0684d6b454",
+                "reference": "1c302646f6efc070cd46856e600e5e0684d6b454",
                 "shasum": ""
                 "shasum": ""
             },
             },
             "require": {
             "require": {
@@ -812,7 +812,7 @@
             "type": "library",
             "type": "library",
             "extra": {
             "extra": {
                 "branch-alias": {
                 "branch-alias": {
-                    "dev-master": "1.17-dev"
+                    "dev-master": "1.18-dev"
                 },
                 },
                 "thanks": {
                 "thanks": {
                     "name": "symfony/polyfill",
                     "name": "symfony/polyfill",
@@ -849,7 +849,7 @@
                 "polyfill",
                 "polyfill",
                 "portable"
                 "portable"
             ],
             ],
-            "time": "2020-06-06T08:46:27+00:00"
+            "time": "2020-07-14T12:35:20+00:00"
         },
         },
         {
         {
             "name": "symfony/yaml",
             "name": "symfony/yaml",
@@ -903,30 +903,30 @@
         },
         },
         {
         {
             "name": "twig/twig",
             "name": "twig/twig",
-            "version": "v1.42.5",
+            "version": "v1.43.0",
             "source": {
             "source": {
                 "type": "git",
                 "type": "git",
                 "url": "https://github.com/twigphp/Twig.git",
                 "url": "https://github.com/twigphp/Twig.git",
-                "reference": "87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e"
+                "reference": "597a03e85a60af6feee4f5127f3ef4279a1694c3"
             },
             },
             "dist": {
             "dist": {
                 "type": "zip",
                 "type": "zip",
-                "url": "https://api.github.com/repos/twigphp/Twig/zipball/87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e",
-                "reference": "87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e",
+                "url": "https://api.github.com/repos/twigphp/Twig/zipball/597a03e85a60af6feee4f5127f3ef4279a1694c3",
+                "reference": "597a03e85a60af6feee4f5127f3ef4279a1694c3",
                 "shasum": ""
                 "shasum": ""
             },
             },
             "require": {
             "require": {
-                "php": ">=5.5.0",
+                "php": ">=7.1.3",
                 "symfony/polyfill-ctype": "^1.8"
                 "symfony/polyfill-ctype": "^1.8"
             },
             },
             "require-dev": {
             "require-dev": {
                 "psr/container": "^1.0",
                 "psr/container": "^1.0",
-                "symfony/phpunit-bridge": "^4.4|^5.0"
+                "symfony/phpunit-bridge": "^4.4.9|^5.0.9"
             },
             },
             "type": "library",
             "type": "library",
             "extra": {
             "extra": {
                 "branch-alias": {
                 "branch-alias": {
-                    "dev-master": "1.42-dev"
+                    "dev-master": "1.43-dev"
                 }
                 }
             },
             },
             "autoload": {
             "autoload": {
@@ -963,7 +963,7 @@
             "keywords": [
             "keywords": [
                 "templating"
                 "templating"
             ],
             ],
-            "time": "2020-02-11T05:59:23+00:00"
+            "time": "2020-07-05T13:00:49+00:00"
         },
         },
         {
         {
             "name": "vlucas/valitron",
             "name": "vlucas/valitron",
@@ -971,12 +971,12 @@
             "source": {
             "source": {
                 "type": "git",
                 "type": "git",
                 "url": "https://github.com/vlucas/valitron.git",
                 "url": "https://github.com/vlucas/valitron.git",
-                "reference": "4af076d19f3cd4fd61f560cba115316834c7fe81"
+                "reference": "9268adeeb48ba155e35dca861f5990283e14eafb"
             },
             },
             "dist": {
             "dist": {
                 "type": "zip",
                 "type": "zip",
-                "url": "https://api.github.com/repos/vlucas/valitron/zipball/4af076d19f3cd4fd61f560cba115316834c7fe81",
-                "reference": "4af076d19f3cd4fd61f560cba115316834c7fe81",
+                "url": "https://api.github.com/repos/vlucas/valitron/zipball/9268adeeb48ba155e35dca861f5990283e14eafb",
+                "reference": "9268adeeb48ba155e35dca861f5990283e14eafb",
                 "shasum": ""
                 "shasum": ""
             },
             },
             "require": {
             "require": {
@@ -1012,7 +1012,7 @@
                 "validation",
                 "validation",
                 "validator"
                 "validator"
             ],
             ],
-            "time": "2020-05-14T14:50:07+00:00"
+            "time": "2020-07-10T08:55:05+00:00"
         }
         }
     ],
     ],
     "packages-dev": [],
     "packages-dev": [],

+ 3 - 3
content/01-cyanine-theme/03-content-elements.yaml

@@ -1,12 +1,12 @@
 meta:
 meta:
     title: 'Content Elements'
     title: 'Content Elements'
-    description: "There are a lot of other settings for your content area. For example:  \nAdd an edit-button for github, gitlab or other plattforms.\nShow the author.\nShow the publish date.\nShow the chapter numbers in the navigation.\n"
-    heroimage: null
+    description: "There are a lot of other settings for your content area. For example:  \n"
+    heroimage: ''
     heroimagealt: null
     heroimagealt: null
     owner: testauthor
     owner: testauthor
     author: trendschau
     author: trendschau
     manualdate: null
     manualdate: null
-    modified: '2020-07-09'
+    modified: '2020-06-14'
     created: '2020-06-11'
     created: '2020-06-11'
     time: 21-05-02
     time: 21-05-02
     navtitle: 'content elements'
     navtitle: 'content elements'

+ 8 - 13
cypress/test01-system-setup.spec.js

@@ -104,28 +104,23 @@ describe('Typemill Setup', function()
     {
     {
       cy.visit('/tm/user/trendschau')
       cy.visit('/tm/user/trendschau')
       cy.url().should('include', '/tm/user/trendschau')
       cy.url().should('include', '/tm/user/trendschau')
-    
-      cy.get('input[name="showusername"]')
+      cy.get('input[name="user[username]"]')
         .should('have.value', 'trendschau')
         .should('have.value', 'trendschau')
-        .and('have.attr','disabled')
-      cy.get('input[name="username"]')
-        .should('have.value', 'trendschau')
-      cy.get('input[name="firstname"]')
+      cy.get('input[name="user[firstname]"]')
         .clear()
         .clear()
         .type('Sebastian')
         .type('Sebastian')
         .should('have.value', 'Sebastian')
         .should('have.value', 'Sebastian')
-      cy.get('input[name="lastname"]')
+      cy.get('input[name="user[lastname]"]')
         .clear()
         .clear()
         .type('Schürmanns')
         .type('Schürmanns')
         .should('have.value', 'Schürmanns')
         .should('have.value', 'Schürmanns')
-      cy.get('input[name="email"]')
+      cy.get('input[name="user[email]"]')
         .should('have.value', 'trendschau@gmail.com')
         .should('have.value', 'trendschau@gmail.com')
-        .and('have.attr','required')
-      cy.get('select[name="userrole"]')
-        .should('have.attr','required')
-      cy.get('input[name="password"]')
+      cy.get('select[name="user[userrole]"]')
+        .should('have.value','administrator')
+      cy.get('input[name="user[password]"]')
         .should('have.value', '')
         .should('have.value', '')
-      cy.get('input[name="newpassword"]')
+      cy.get('input[name="user[newpassword]"]')
         .should('have.value', '')
         .should('have.value', '')
 
 
       cy.get('#userform').submit()
       cy.get('#userform').submit()

+ 2 - 2
cypress/test02-initial-frontend.spec.js

@@ -18,8 +18,8 @@ describe('Typemill Initial Frontend', function()
         expect($a[4].href).to.match(/welcome\/markdown-test/)
         expect($a[4].href).to.match(/welcome\/markdown-test/)
         expect($a[5].href).to.match(/cyanine-theme/)
         expect($a[5].href).to.match(/cyanine-theme/)
         expect($a[6].href).to.match(/cyanine-theme\/landingpage/)
         expect($a[6].href).to.match(/cyanine-theme\/landingpage/)
-        expect($a[7].href).to.match(/cyanine-theme\/footer/)
-        expect($a[8].href).to.match(/cyanine-theme\/colors-and-fonts/)
+        expect($a[7].href).to.match(/cyanine-theme\/colors-and-fonts/)
+        expect($a[8].href).to.match(/cyanine-theme\/footer/)
         expect($a[9].href).to.match(/cyanine-theme\/content-elements/)
         expect($a[9].href).to.match(/cyanine-theme\/content-elements/)
       })      
       })      
     })
     })

+ 12 - 7
system/Controllers/PageController.php

@@ -270,10 +270,10 @@ class PageController extends Controller
 	protected function getFreshStructure($pathToContent, $cache, $uri)
 	protected function getFreshStructure($pathToContent, $cache, $uri)
 	{
 	{
 		/* scan the content of the folder */
 		/* scan the content of the folder */
-		$structure = Folder::scanFolder($pathToContent);
+		$pagetree = Folder::scanFolder($pathToContent);
 
 
 		/* if there is no content, render an empty page */
 		/* if there is no content, render an empty page */
-		if(count($structure) == 0)
+		if(count($pagetree) == 0)
 		{
 		{
 			return false;
 			return false;
 		}
 		}
@@ -282,6 +282,10 @@ class PageController extends Controller
 		$yaml = new writeYaml();
 		$yaml = new writeYaml();
 		$extended = $yaml->getYaml('cache', 'structure-extended.yaml');
 		$extended = $yaml->getYaml('cache', 'structure-extended.yaml');
 
 
+		# create an array of object with the whole content of the folder
+		$structure = Folder::getFolderContentDetails($pagetree, $extended, $uri->getBaseUrl(), $uri->getBasePath());
+
+		# now update the extended structure
 		if(!$extended)
 		if(!$extended)
 		{
 		{
 			$extended = $this->createExtended($this->pathToContent, $yaml, $structure);
 			$extended = $this->createExtended($this->pathToContent, $yaml, $structure);
@@ -289,12 +293,12 @@ class PageController extends Controller
 			if(!empty($extended))
 			if(!empty($extended))
 			{
 			{
 				$yaml->updateYaml('cache', 'structure-extended.yaml', $extended);
 				$yaml->updateYaml('cache', 'structure-extended.yaml', $extended);
+
+				# we have to update the structure with extended again
+				$structure = Folder::getFolderContentDetails($pagetree, $extended, $uri->getBaseUrl(), $uri->getBasePath());
 			}
 			}
 		}
 		}
-
-		# create an array of object with the whole content of the folder
-		$structure = Folder::getFolderContentDetails($structure, $extended, $uri->getBaseUrl(), $uri->getBasePath());
-
+		
 		# cache structure
 		# cache structure
 		$cache->updateCache('cache', 'structure.txt', 'lastCache.txt', $structure);
 		$cache->updateCache('cache', 'structure.txt', 'lastCache.txt', $structure);
 
 
@@ -325,7 +329,8 @@ class PageController extends Controller
 
 
 		foreach ($structure as $key => $item)
 		foreach ($structure as $key => $item)
 		{
 		{
-			$filename = ($item->elementType == 'folder') ? DIRECTORY_SEPARATOR . 'index.yaml' : $item->pathWithoutType . '.yaml';
+			# $filename = ($item->elementType == 'folder') ? DIRECTORY_SEPARATOR . 'index.yaml' : $item->pathWithoutType . '.yaml';
+			$filename = $item->pathWithoutType . '.yaml';
 
 
 			if(file_exists($contentPath . $filename))
 			if(file_exists($contentPath . $filename))
 			{				
 			{				

+ 32 - 6
system/Controllers/SettingsController.php

@@ -14,6 +14,27 @@ use Typemill\Events\OnSystemnaviLoaded;
 
 
 class SettingsController extends Controller
 class SettingsController extends Controller
 {	
 {	
+
+	public function showBlank($request, $response, $args)
+	{
+		$user				= new User();
+		$settings 			= $this->c->get('settings');
+#		$users				= $user->getUsers();
+		$route 				= $request->getAttribute('route');
+		$navigation 		= $this->getNavigation();
+
+		$content 			= '<h1>Hello</h1>';
+
+		return $this->render($response, 'settings/blank.twig', array(
+			'settings' 		=> $settings,
+			'acl' 			=> $this->c->acl, 
+			'navigation'	=> $navigation,
+			'content' 		=> $content,
+#			'users' 		=> $users, 
+			'route' 		=> $route->getName() 
+		));
+	}
+
 	/*********************
 	/*********************
 	**	BASIC SETTINGS	**
 	**	BASIC SETTINGS	**
 	*********************/
 	*********************/
@@ -26,13 +47,15 @@ class SettingsController extends Controller
 		$copyright			= $this->getCopyright();
 		$copyright			= $this->getCopyright();
 		$languages			= $this->getLanguages();
 		$languages			= $this->getLanguages();
 		$locale				= isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? substr($_SERVER["HTTP_ACCEPT_LANGUAGE"],0,2) : 'en';
 		$locale				= isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? substr($_SERVER["HTTP_ACCEPT_LANGUAGE"],0,2) : 'en';
-		$users				= $user->getUsers();
 		$route 				= $request->getAttribute('route');
 		$route 				= $request->getAttribute('route');
 		$navigation 		= $this->getNavigation();
 		$navigation 		= $this->getNavigation();
 
 
 		# set navigation active
 		# set navigation active
 		$navigation['System']['active'] = true;
 		$navigation['System']['active'] = true;
 
 
+		# set option for registered website
+		$options = ['' => 'all', 'registered' => 'registered users only'];
+
 		return $this->render($response, 'settings/system.twig', array(
 		return $this->render($response, 'settings/system.twig', array(
 			'settings' 		=> $settings,
 			'settings' 		=> $settings,
 			'acl' 			=> $this->c->acl, 
 			'acl' 			=> $this->c->acl, 
@@ -41,7 +64,7 @@ class SettingsController extends Controller
 			'languages' 	=> $languages, 
 			'languages' 	=> $languages, 
 			'locale' 		=> $locale, 
 			'locale' 		=> $locale, 
 			'formats' 		=> $defaultSettings['formats'],
 			'formats' 		=> $defaultSettings['formats'],
-			'users' 		=> $users, 
+			'access'		=> $options,
 			'route' 		=> $route->getName() 
 			'route' 		=> $route->getName() 
 		));
 		));
 	}
 	}
@@ -68,7 +91,8 @@ class SettingsController extends Controller
 					'year'				=> $newSettings['year'],
 					'year'				=> $newSettings['year'],
 					'language'			=> $newSettings['language'],
 					'language'			=> $newSettings['language'],
 					'langattr'			=> $newSettings['langattr'],
 					'langattr'			=> $newSettings['langattr'],
-					'editor' 			=> $newSettings['editor'], 
+					'editor' 			=> $newSettings['editor'],
+					'access'			=> $newSettings['access'], 
 					'formats'			=> $newSettings['formats'],
 					'formats'			=> $newSettings['formats'],
 					'headlineanchors'	=> isset($newSettings['headlineanchors']) ? $newSettings['headlineanchors'] : null,
 					'headlineanchors'	=> isset($newSettings['headlineanchors']) ? $newSettings['headlineanchors'] : null,
 				);
 				);
@@ -678,7 +702,7 @@ class SettingsController extends Controller
 			$user 			= new User();
 			$user 			= new User();
 			$validate		= new Validation();
 			$validate		= new Validation();
 			$userroles 		= $this->c->acl->getRoles();
 			$userroles 		= $this->c->acl->getRoles();
-			
+
 			$redirectRoute	= ($userdata['username'] == $_SESSION['user']) ? $this->c->router->pathFor('user.account') : $this->c->router->pathFor('user.show', ['username' => $userdata['username']]);
 			$redirectRoute	= ($userdata['username'] == $_SESSION['user']) ? $this->c->router->pathFor('user.account') : $this->c->router->pathFor('user.show', ['username' => $userdata['username']]);
 
 
 			# check if user is allowed to view (edit) userlist and other users
 			# check if user is allowed to view (edit) userlist and other users
@@ -809,11 +833,13 @@ class SettingsController extends Controller
 		$fields = $this->c->dispatcher->dispatch('onUserfieldsLoaded', new OnUserfieldsLoaded($fields))->getData();
 		$fields = $this->c->dispatcher->dispatch('onUserfieldsLoaded', new OnUserfieldsLoaded($fields))->getData();
 
 
 		# only roles who can edit content need profile image and description
 		# only roles who can edit content need profile image and description
-		if($this->c->acl->isAllowed($role, 'content', 'create'))
+		if($this->c->acl->isAllowed($role, 'mycontent', 'create'))
 		{
 		{
 			$newfield['image'] 			= ['label' => 'Profile-Image', 'type' => 'image'];
 			$newfield['image'] 			= ['label' => 'Profile-Image', 'type' => 'image'];
 			$newfield['description'] 	= ['label' => 'Author-Description (Markdown)', 'type' => 'textarea'];			
 			$newfield['description'] 	= ['label' => 'Author-Description (Markdown)', 'type' => 'textarea'];			
-			array_splice($fields,1,0,$newfield);
+			
+			$fields = array_slice($fields, 0, 1, true) + $newfield + array_slice($fields, 1, NULL, true);
+			# array_splice($fields,1,0,$newfield);
 		}
 		}
 
 
 		# Only admin can change userroles
 		# Only admin can change userroles

+ 6 - 0
system/Middleware/accessController.php

@@ -20,6 +20,12 @@ class accessController
 
 
 	public function __invoke(Request $request, Response $response, $next)
 	public function __invoke(Request $request, Response $response, $next)
 	{
 	{
+
+		if($this->resource == NULL && $this->privilege == NULL)
+		{
+			return $next($request, $response);
+		}
+
 		if(!isset($_SESSION['login']))
 		if(!isset($_SESSION['login']))
 		{
 		{
 			return $response->withRedirect($this->router->pathFor('auth.show'));
 			return $response->withRedirect($this->router->pathFor('auth.show'));

+ 2 - 2
system/Models/Folder.php

@@ -69,7 +69,7 @@ class Folder
 					
 					
 					if($fileType == 'md')
 					if($fileType == 'md')
 					{
 					{
-						$folderContent[] 			= $item;						
+						$folderContent[] 			= $item;					
 					}
 					}
 					
 					
 					if($draft === true && $fileType == 'txt')
 					if($draft === true && $fileType == 'txt')
@@ -166,7 +166,7 @@ class Folder
 
 
 				$item->folderContent = self::getFolderContentDetails($name, $extended, $baseUrl, $item->urlRel, $item->urlRelWoF, $item->path, $item->keyPath, $item->chapter);
 				$item->folderContent = self::getFolderContentDetails($name, $extended, $baseUrl, $item->urlRel, $item->urlRelWoF, $item->path, $item->keyPath, $item->chapter);
 			}
 			}
-			else
+			elseif($name)
 			{
 			{
 				# do not use files in base folder (only folders are allowed)
 				# do not use files in base folder (only folders are allowed)
 				# if(!isset($keyPath)) continue;
 				# if(!isset($keyPath)) continue;

+ 3 - 1
system/Models/User.php

@@ -125,7 +125,6 @@ class User extends WriteYaml
 		{
 		{
 			$user['lastlogin'] = time();
 			$user['lastlogin'] = time();
 			unset($user['password']);
 			unset($user['password']);
-			$this->updateUser($user);
 
 
 			$_SESSION['user'] 	= $user['username'];
 			$_SESSION['user'] 	= $user['username'];
 			$_SESSION['role'] 	= $user['userrole'];
 			$_SESSION['role'] 	= $user['userrole'];
@@ -139,6 +138,9 @@ class User extends WriteYaml
 			{
 			{
 				$_SESSION['lastname'] = $user['lastname'];
 				$_SESSION['lastname'] = $user['lastname'];
 			}
 			}
+			
+			# update user last login
+			$this->updateUser($user);
 		}
 		}
 	}
 	}
 	
 	

+ 4 - 0
system/Routes/Web.php

@@ -79,6 +79,10 @@ if($settings['settings']['setup'])
 {
 {
 	$app->get('/[{params:.*}]', SetupController::class . ':redirect');	
 	$app->get('/[{params:.*}]', SetupController::class . ':redirect');	
 }
 }
+elseif(isset($settings['settings']['access']) && $settings['settings']['access'] != '')
+{
+	$app->get('/[{params:.*}]', PageController::class . ':index')->setName('home')->add(new accessController($container['router'], $container['acl'], 'user', 'view'));
+}
 else
 else
 {
 {
 	$app->get('/[{params:.*}]', PageController::class . ':index')->setName('home');
 	$app->get('/[{params:.*}]', PageController::class . ':index')->setName('home');

+ 5 - 4
system/Settings.php

@@ -82,7 +82,7 @@ class Settings
 			'contentFolder'							=> 'content',
 			'contentFolder'							=> 'content',
 			'cache'									=> true,
 			'cache'									=> true,
 			'cachePath'								=> $rootPath . 'cache',
 			'cachePath'								=> $rootPath . 'cache',
-			'version'								=> '1.3.7.2',
+			'version'								=> '1.3.8',
 			'setup'									=> true,
 			'setup'									=> true,
 			'welcome'								=> true,
 			'welcome'								=> true,
 			'images'								=> ['live' => ['width' => 820], 'thumbs' => ['width' => 250, 'height' => 150]],
 			'images'								=> ['live' => ['width' => 820], 'thumbs' => ['width' => 250, 'height' => 150]],
@@ -111,7 +111,7 @@ class Settings
     	}
     	}
     
     
     	# Detect browser language
     	# Detect browser language
-    	$accept_lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
+    	$accept_lang = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2) : false;
     	$lang = in_array($accept_lang, $langs) ? $accept_lang : 'en';
     	$lang = in_array($accept_lang, $langs) ? $accept_lang : 'en';
 
 
     	return $lang;
     	return $lang;
@@ -158,6 +158,7 @@ class Settings
 									'startpage' => true,
 									'startpage' => true,
 									'author' => true,
 									'author' => true,
 									'year' => true,
 									'year' => true,
+									'access' => true,
 									'headlineanchors' => true,
 									'headlineanchors' => true,
 									'theme' => true,
 									'theme' => true,
 									'editor' => true,
 									'editor' => true,
@@ -169,7 +170,7 @@ class Settings
 									'themes' => true,
 									'themes' => true,
 									'latestVersion' => true,
 									'latestVersion' => true,
 									'logo' => true,
 									'logo' => true,
-									'favicon' => true, 
+									'favicon' => true 
 								];
 								];
 
 
 			# cleanup the existing usersettings
 			# cleanup the existing usersettings
@@ -212,7 +213,7 @@ class Settings
 		$editor['permissions']	= [ 'mycontent' => ['delete', 'publish', 'unpublish'],
 		$editor['permissions']	= [ 'mycontent' => ['delete', 'publish', 'unpublish'],
 									'content' => ['create', 'update', 'delete', 'publish', 'unpublish']];
 									'content' => ['create', 'update', 'delete', 'publish', 'unpublish']];
 
 
-		return [$member, $author, $editor];
+		return ['member' => $member,'author' => $author, 'editor' => $editor];
 	}
 	}
 
 
 	public static function createAcl($roles, $resources)
 	public static function createAcl($roles, $resources)

+ 8 - 6
system/author/auth/setup.twig

@@ -7,11 +7,13 @@
 
 
 		{% if systemcheck %}
 		{% if systemcheck %}
 			<h2>Missing Requirements</h2>
 			<h2>Missing Requirements</h2>
-			<ul style="color:red;padding: 0 14px">
-				{% for systemerror in systemcheck %}
-					<li style="margin: 5px 0">{{ systemerror }}</li>
-				{% endfor %}
-			</ul>
+			{% if systemcheck.error %}
+				<ul style="color:red;padding: 0 14px">
+					{% for systemerror in systemcheck.error %}
+						<li style="margin: 5px 0">{{ systemerror }}</li>
+					{% endfor %}
+				</ul>
+			{% endif %}
 		{% endif %}
 		{% endif %}
 
 
 		<div class="authformWrapper">
 		<div class="authformWrapper">
@@ -48,4 +50,4 @@
 		</div>		
 		</div>		
 	</div>
 	</div>
 	
 	
-{% endblock %}
+{% endblock %}

+ 19 - 6
system/author/js/vue-blox.js

@@ -165,7 +165,11 @@ const contentComponent = Vue.component('content-block', {
 		},
 		},
  		submitBlock: function(){
  		submitBlock: function(){
 			var emptyline = /^\s*$(?:\r\n?|\n)/gm;
 			var emptyline = /^\s*$(?:\r\n?|\n)/gm;
+			
+			/* allow empty lines for these components */
 			if(this.componentType == "code-component" || this.componentType == "math-component" || this.componentType == "notice-component"){ }
 			if(this.componentType == "code-component" || this.componentType == "math-component" || this.componentType == "notice-component"){ }
+			
+			/* add new line with markup for these components */
 			else if(this.componentType == "ulist-component" || this.componentType == "olist-component")
 			else if(this.componentType == "ulist-component" || this.componentType == "olist-component")
 			{
 			{
 				var listend = (this.componentType == "ulist-component") ? '* \n' : '1. \n';
 				var listend = (this.componentType == "ulist-component") ? '* \n' : '1. \n';
@@ -194,6 +198,7 @@ const contentComponent = Vue.component('content-block', {
 					}
 					}
 				}
 				}
 			}
 			}
+			/* save or close for all other components */
 			else if(this.compmarkdown.search(emptyline) > -1)
 			else if(this.compmarkdown.search(emptyline) > -1)
 			{
 			{
 				var checkempty = this.compmarkdown.replace(/(\r\n|\n|\r|\s)/gm,"");
 				var checkempty = this.compmarkdown.replace(/(\r\n|\n|\r|\s)/gm,"");
@@ -1014,21 +1019,21 @@ const tableComponent = Vue.component('table-component', {
 					'</colgroup>' +
 					'</colgroup>' +
 					'<tbody>' +
 					'<tbody>' +
 						'<tr v-for="(row, rowindex) in table">' +
 						'<tr v-for="(row, rowindex) in table">' +
-							'<td v-if="rowindex === 0" v-for="(value,colindex) in row" contenteditable="false" class="noteditable" @click="switchcolumnbar(value)">{{value}} ' +
+							'<td v-if="rowindex === 0" v-for="(value,colindex) in row" contenteditable="false" class="noteditable" @click="switchcolumnbar(value)"  @keydown.13.prevent="enter">{{value}} ' +
 							  '<div v-if="columnbar === value" class="columnaction">' + 
 							  '<div v-if="columnbar === value" class="columnaction">' + 
 							     '<div class="actionline" @click="addrightcolumn(value)">{{ \'add right column\'|translate }}</div>' +
 							     '<div class="actionline" @click="addrightcolumn(value)">{{ \'add right column\'|translate }}</div>' +
 								 '<div class="actionline" @click="addleftcolumn(value)">{{ \'add left column\'|translate }}</div>' +
 								 '<div class="actionline" @click="addleftcolumn(value)">{{ \'add left column\'|translate }}</div>' +
 								 '<div class="actionline" @click="deletecolumn(value)">{{ \'delete column\'|translate }}</div>' +							
 								 '<div class="actionline" @click="deletecolumn(value)">{{ \'delete column\'|translate }}</div>' +							
 							  '</div>' +
 							  '</div>' +
 							'</td>' +
 							'</td>' +
-							'<th v-if="rowindex === 1" v-for="(value,colindex) in row" :contenteditable="colindex !== 0 ? true : false" @click="switchrowbar(value)" @blur="updatedata($event,colindex,rowindex)" :class="colindex !== 0 ? editable : noteditable">' + 
+							'<th v-if="rowindex === 1" v-for="(value,colindex) in row" :contenteditable="colindex !== 0 ? true : false" @click="switchrowbar(value)" @keydown.13.prevent="enter" @blur="updatedata($event,colindex,rowindex)" :class="colindex !== 0 ? editable : noteditable">' + 
 							 '<div v-if="colindex === 0 && rowbar === value" class="rowaction">' + 
 							 '<div v-if="colindex === 0 && rowbar === value" class="rowaction">' + 
  								 '<div class="actionline" @click="addaboverow(value)">{{ \'add row above\'|translate }}</div>' +
  								 '<div class="actionline" @click="addaboverow(value)">{{ \'add row above\'|translate }}</div>' +
 								 '<div class="actionline" @click="addbelowrow(value)">{{ \'add row below\'|translate }}</div>' +
 								 '<div class="actionline" @click="addbelowrow(value)">{{ \'add row below\'|translate }}</div>' +
 								 '<div class="actionline" @click="deleterow(value)">{{ \'delete row\'|translate }}</div>' +						
 								 '<div class="actionline" @click="deleterow(value)">{{ \'delete row\'|translate }}</div>' +						
 							  '</div>' + 
 							  '</div>' + 
 							'{{ value }}</th>' +
 							'{{ value }}</th>' +
-							'<td v-if="rowindex > 1" v-for="(value,colindex) in row" :contenteditable="colindex !== 0 ? true : false" @click="switchrowbar(value)" @blur="updatedata($event,colindex,rowindex)" :class="colindex !== 0 ? editable : noteditable">' + 
+							'<td v-if="rowindex > 1" v-for="(value,colindex) in row" :contenteditable="colindex !== 0 ? true : false" @click="switchrowbar(value)" @keydown.13.prevent="enter" @blur="updatedata($event,colindex,rowindex)" :class="colindex !== 0 ? editable : noteditable">' + 
 							 '<div v-if="colindex === 0 && rowbar === value" class="rowaction">' + 
 							 '<div v-if="colindex === 0 && rowbar === value" class="rowaction">' + 
   								 '<div class="actionline" @click="addaboverow(value)">{{ \'add row above\'|translate }}</div>' +
   								 '<div class="actionline" @click="addaboverow(value)">{{ \'add row above\'|translate }}</div>' +
 								 '<div class="actionline" @click="addbelowrow(value)">{{ \'add row below\'|translate }}</div>' +
 								 '<div class="actionline" @click="addbelowrow(value)">{{ \'add row below\'|translate }}</div>' +
@@ -1073,6 +1078,10 @@ const tableComponent = Vue.component('table-component', {
 		}
 		}
 	},
 	},
 	methods: {
 	methods: {
+		enter: function()
+		{
+			return false;
+		},
 		updatedata: function(event,col,row)
 		updatedata: function(event,col,row)
 		{
 		{
 			this.table[row][col] = event.target.innerText;			
 			this.table[row][col] = event.target.innerText;			
@@ -1215,7 +1224,7 @@ const definitionComponent = Vue.component('definition-component', {
 						'<svg class="icon icon-arrows-v"><use xlink:href="#icon-arrows-v"></use></svg>' +
 						'<svg class="icon icon-arrows-v"><use xlink:href="#icon-arrows-v"></use></svg>' +
 						'<input type="text" class="definitionTerm" v-bind:placeholder="\'term\'|translate" :value="definition.term" :disabled="disabled" @input="updateterm($event,dindex)" @blur="updateMarkdown">' +
 						'<input type="text" class="definitionTerm" v-bind:placeholder="\'term\'|translate" :value="definition.term" :disabled="disabled" @input="updateterm($event,dindex)" @blur="updateMarkdown">' +
 		  		  '<svg class="icon icon-dots-two-vertical"><use xlink:href="#icon-dots-two-vertical"></use></svg>' + 
 		  		  '<svg class="icon icon-dots-two-vertical"><use xlink:href="#icon-dots-two-vertical"></use></svg>' + 
-	  			  '<textarea class="definitionDescription" v-bind:placeholder="\'description\'|translate" v-html="definition.description" :disabled="disabled" @input="updatedescription($event, dindex)" @blur="updateMarkdown"></textarea>' +
+	  			  '<textarea class="definitionDescription" v-bind:placeholder="\'description\'|translate" v-html="definition.description" :disabled="disabled" @input="updatedescription($event, dindex)" @keydown.13.prevent="enter" @blur="updateMarkdown"></textarea>' +
 					  '<button class="delDL" @click.prevent="deleteDefinition(dindex)"><svg class="icon icon-minus"><use xlink:href="#icon-minus"></use></svg></button>' +
 					  '<button class="delDL" @click.prevent="deleteDefinition(dindex)"><svg class="icon icon-minus"><use xlink:href="#icon-minus"></use></svg></button>' +
 				  '</div>' +
 				  '</div>' +
 				'</draggable>' +
 				'</draggable>' +
@@ -1249,6 +1258,10 @@ const definitionComponent = Vue.component('definition-component', {
 		}
 		}
 	},
 	},
 	methods: {
 	methods: {
+		enter: function()
+		{
+			return false;
+		},
 		updateterm: function(event, dindex)
 		updateterm: function(event, dindex)
 		{
 		{
 			this.definitionList[dindex].term = event.target.value;
 			this.definitionList[dindex].term = event.target.value;
@@ -2162,7 +2175,7 @@ const medialib = Vue.component('medialib', {
 
 
 				this.$parent.showmedialib = false;
 				this.$parent.showmedialib = false;
 
 
-				this.$parent.createmarkdown();
+				this.$parent.createmarkdown(image.src_live);
 /*				this.$parent.updatemarkdown(imgmarkdown, image.src_live); */
 /*				this.$parent.updatemarkdown(imgmarkdown, image.src_live); */
 			}
 			}
 			if(this.parentcomponent == 'files')
 			if(this.parentcomponent == 'files')
@@ -2196,7 +2209,7 @@ const medialib = Vue.component('medialib', {
 
 
 				this.$parent.showmedialib = false;
 				this.$parent.showmedialib = false;
 
 
-				this.$parent.createmarkdown();
+				this.$parent.createmarkdown(file.url);
 /*				this.$parent.updatemarkdown(imgmarkdown, file.url);*/
 /*				this.$parent.updatemarkdown(imgmarkdown, file.url);*/
 			}
 			}
 			if(this.parentcomponent == 'files')
 			if(this.parentcomponent == 'files')

+ 5 - 0
system/author/js/vue-shared.js

@@ -64,6 +64,11 @@ Vue.component('component-image', {
 			/* is called from child component medialib */
 			/* is called from child component medialib */
 			this.update(url);
 			this.update(url);
 		},
 		},
+		createmarkdown: function(url)
+		{
+			/* is called from child component medialib */
+			this.update(url);
+		},
 		deleteImage: function()
 		deleteImage: function()
 		{
 		{
 			this.imgpreview = false;
 			this.imgpreview = false;

+ 10 - 4
system/author/layouts/layout.twig

@@ -19,8 +19,8 @@
 		<link rel="apple-touch-icon" sizes="180x180" href="{{ base_url }}/system/author/img/favicon-180.png" />
 		<link rel="apple-touch-icon" sizes="180x180" href="{{ base_url }}/system/author/img/favicon-180.png" />
 		
 		
 		<link rel="stylesheet" href="{{ base_url }}/system/author/css/normalize.css" />
 		<link rel="stylesheet" href="{{ base_url }}/system/author/css/normalize.css" />
-		<link rel="stylesheet" href="{{ base_url }}/system/author/css/tachyons.min.css?20200614" />
-		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20200614" />
+		<link rel="stylesheet" href="{{ base_url }}/system/author/css/tachyons.min.css?20200716" />
+		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20200716" />
 	</head>
 	</head>
 	<body>
 	<body>
 		<svg style="position: absolute; width: 0; height: 0; overflow: hidden" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 		<svg style="position: absolute; width: 0; height: 0; overflow: hidden" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
@@ -74,8 +74,14 @@
 			<footer></footer>
 			<footer></footer>
 		</div>
 		</div>
 <!--		<script src="{{ base_url }}/system/author/js/color-picker.min.js?20200505"></script> -->
 <!--		<script src="{{ base_url }}/system/author/js/color-picker.min.js?20200505"></script> -->
-		<script src="{{ base_url }}/system/author/js/author.js?20200614"></script>
-		<script src="{{ base_url }}/system/author/js/typemillutils.js?20200614"></script>
+		<script src="{{ base_url }}/system/author/js/axios.min.js?20200716"></script>
+		<script>
+			const myaxios = axios.create();
+			myaxios.defaults.baseURL =  "{{ base_url }}";
+		</script>
+		<script src="{{ base_url }}/system/author/js/vue.min.js?20200716"></script>
+		<script src="{{ base_url }}/system/author/js/author.js?20200716"></script>
+		<script src="{{ base_url }}/system/author/js/typemillutils.js?20200716"></script>
 		<script>
 		<script>
 			typemillUtilities.start()
 			typemillUtilities.start()
 		</script>
 		</script>

+ 2 - 2
system/author/layouts/layoutAuth.twig

@@ -20,7 +20,7 @@
 		<link rel="apple-touch-icon" sizes="180x180" href="{{ base_url }}/system/author/img/favicon-180.png" />
 		<link rel="apple-touch-icon" sizes="180x180" href="{{ base_url }}/system/author/img/favicon-180.png" />
 				
 				
 		<link rel="stylesheet" href="{{ base_url }}/system/author/css/normalize.css" />
 		<link rel="stylesheet" href="{{ base_url }}/system/author/css/normalize.css" />
-		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20200614" />
+		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20200716" />
 		<link rel="stylesheet" href="{{ base_url }}/system/author/css/color-picker.min.css" />
 		<link rel="stylesheet" href="{{ base_url }}/system/author/css/color-picker.min.css" />
 	</head>
 	</head>
 	<body>
 	<body>
@@ -56,6 +56,6 @@
 			{% block content %}{% endblock %}
 			{% block content %}{% endblock %}
 
 
 		</div>
 		</div>
-		<script src="{{ base_url }}/system/author/js/auth.js?20200614"></script>
+		<script src="{{ base_url }}/system/author/js/auth.js?20200716"></script>
 	</body>
 	</body>
 </html>
 </html>

+ 1 - 1
system/author/layouts/layoutBlank.twig

@@ -19,7 +19,7 @@
 		<link rel="apple-touch-icon" sizes="180x180" href="{{ base_url }}/system/author/img/favicon-180.png" />
 		<link rel="apple-touch-icon" sizes="180x180" href="{{ base_url }}/system/author/img/favicon-180.png" />
 
 
 		<link rel="stylesheet" href="{{ base_url }}/system/author/css/normalize.css" />
 		<link rel="stylesheet" href="{{ base_url }}/system/author/css/normalize.css" />
-		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20200614" />
+		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20200716" />
 	</head>
 	</head>
 	<body>
 	<body>
 		<svg style="position: absolute; width: 0; height: 0; overflow: hidden" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 		<svg style="position: absolute; width: 0; height: 0; overflow: hidden" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

+ 15 - 15
system/author/layouts/layoutBlox.twig

@@ -20,7 +20,7 @@
 		
 		
 		<link rel="stylesheet" href="{{ base_url }}/system/author/css/normalize.css" />
 		<link rel="stylesheet" href="{{ base_url }}/system/author/css/normalize.css" />
 		<link rel="stylesheet" href="{{ base_url }}/system/author/css/tachyons.min.css" />
 		<link rel="stylesheet" href="{{ base_url }}/system/author/css/tachyons.min.css" />
-		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20200614" />
+		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20200716" />
 		<link rel="stylesheet" href="{{ base_url }}/system/author/css/color-picker.min.css" />
 		<link rel="stylesheet" href="{{ base_url }}/system/author/css/color-picker.min.css" />
 
 
 		{{ assets.renderCSS() }}
 		{{ assets.renderCSS() }}
@@ -197,17 +197,17 @@
 			</article>
 			</article>
 			<footer></footer>
 			<footer></footer>
 		</div>
 		</div>
-		<script src="{{ base_url }}/system/author/js/axios.min.js?20200226"></script>
+		<script src="{{ base_url }}/system/author/js/axios.min.js?20200716"></script>
 		<script>
 		<script>
 			const myaxios = axios.create();
 			const myaxios = axios.create();
 			myaxios.defaults.baseURL =  "{{ base_url }}";
 			myaxios.defaults.baseURL =  "{{ base_url }}";
 		</script>
 		</script>
-		<script src="{{ base_url }}/system/author/js/typemillutils.js?20200614"></script>
-		<script src="{{ base_url }}/system/author/js/vue.min.js?20200614"></script>
-		<script src="{{ base_url }}/system/author/js/autosize.min.js?20200614"></script>
-		<script src="{{ base_url }}/system/author/js/author.js?20200614"></script>
-		<script src="{{ base_url }}/system/author/js/vue-publishcontroller.js?20200614"></script>
-		<script src="{{ base_url }}/system/author/js/vue-blox-config.js?20200614"></script>
+		<script src="{{ base_url }}/system/author/js/typemillutils.js?20200716"></script>
+		<script src="{{ base_url }}/system/author/js/vue.min.js?20200716"></script>
+		<script src="{{ base_url }}/system/author/js/autosize.min.js?20200716"></script>
+		<script src="{{ base_url }}/system/author/js/author.js?20200716"></script>
+		<script src="{{ base_url }}/system/author/js/vue-publishcontroller.js?20200716"></script>
+		<script src="{{ base_url }}/system/author/js/vue-blox-config.js?20200716"></script>
 		<script>
 		<script>
 			let formatConfig = {{ settings.formats|json_encode() }};
 			let formatConfig = {{ settings.formats|json_encode() }};
       		let language = {{ settings.language|json_encode() }};
       		let language = {{ settings.language|json_encode() }};
@@ -217,13 +217,13 @@
 
 
 		{{ assets.renderEditorJS() }}
 		{{ assets.renderEditorJS() }}
 
 
-		<script src="{{ base_url }}/system/author/js/vue-blox.js?20200614"></script>
-		<script src="{{ base_url }}/system/author/js/vue-posts.js?20200614"></script>
-		<script src="{{ base_url }}/system/author/js/sortable.min.js?20200614"></script>
-		<script src="{{ base_url }}/system/author/js/vuedraggable.umd.min.js?20200614"></script>
-		<script src="{{ base_url }}/system/author/js/vue-navi.js?20200614"></script>
-		<script src="{{ base_url }}/system/author/js/vue-shared.js?20200614"></script>
-		<script src="{{ base_url }}/system/author/js/vue-meta.js?20200614"></script>
+		<script src="{{ base_url }}/system/author/js/vue-blox.js?20200716"></script>
+		<script src="{{ base_url }}/system/author/js/vue-posts.js?20200716"></script>
+		<script src="{{ base_url }}/system/author/js/sortable.min.js?20200716"></script>
+		<script src="{{ base_url }}/system/author/js/vuedraggable.umd.min.js?20200716"></script>
+		<script src="{{ base_url }}/system/author/js/vue-navi.js?20200716"></script>
+		<script src="{{ base_url }}/system/author/js/vue-shared.js?20200716"></script>
+		<script src="{{ base_url }}/system/author/js/vue-meta.js?20200716"></script>
 
 
 		{{ assets.renderJS() }}
 		{{ assets.renderJS() }}
 
 

+ 11 - 11
system/author/layouts/layoutEditor.twig

@@ -19,7 +19,7 @@
 		<link rel="apple-touch-icon" sizes="180x180" href="{{ base_url }}/system/author/img/favicon-180.png" />
 		<link rel="apple-touch-icon" sizes="180x180" href="{{ base_url }}/system/author/img/favicon-180.png" />
 		
 		
 		<link rel="stylesheet" href="{{ base_url }}/system/author/css/normalize.css" />
 		<link rel="stylesheet" href="{{ base_url }}/system/author/css/normalize.css" />
-		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20200614" />
+		<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20200716" />
 
 
 		{{ assets.renderCSS() }}
 		{{ assets.renderCSS() }}
 
 
@@ -83,16 +83,16 @@
 			</article>
 			</article>
 			<footer></footer>
 			<footer></footer>
 		</div>
 		</div>
-		<script src="{{ base_url }}/system/author/js/axios.min.js?20200614"></script>
+		<script src="{{ base_url }}/system/author/js/axios.min.js?20200716"></script>
 		<script>
 		<script>
 			const myaxios = axios.create();
 			const myaxios = axios.create();
 			myaxios.defaults.baseURL =  "{{ base_url }}";
 			myaxios.defaults.baseURL =  "{{ base_url }}";
 		</script>		
 		</script>		
-		<script src="{{ base_url }}/system/author/js/vue.min.js?20200614"></script>
-		<script src="{{ base_url }}/system/author/js/autosize.min.js?20200614"></script>
-		<script src="{{ base_url }}/system/author/js/sortable.min.js?20200614"></script>
-		<script src="{{ base_url }}/system/author/js/vuedraggable.umd.min.js?20200614"></script>
-		<script src="{{ base_url }}/system/author/js/author.js?20200614"></script>
+		<script src="{{ base_url }}/system/author/js/vue.min.js?20200716"></script>
+		<script src="{{ base_url }}/system/author/js/autosize.min.js?20200716"></script>
+		<script src="{{ base_url }}/system/author/js/sortable.min.js?20200716"></script>
+		<script src="{{ base_url }}/system/author/js/vuedraggable.umd.min.js?20200716"></script>
+		<script src="{{ base_url }}/system/author/js/author.js?20200716"></script>
 
 
 	    <script>
 	    <script>
     	  	let language = {{ settings.language|json_encode() }};
     	  	let language = {{ settings.language|json_encode() }};
@@ -102,10 +102,10 @@
     
     
 		{{ assets.renderEditorJS() }}		
 		{{ assets.renderEditorJS() }}		
 		
 		
-		<script src="{{ base_url }}/system/author/js/vue-publishcontroller.js?20200614"></script>		
-		<script src="{{ base_url }}/system/author/js/vue-editor.js?20200614"></script>
-		<script src="{{ base_url }}/system/author/js/vue-meta.js?20200614"></script>		
-		<script src="{{ base_url }}/system/author/js/vue-navi.js?20200614"></script>
+		<script src="{{ base_url }}/system/author/js/vue-publishcontroller.js?20200716"></script>
+		<script src="{{ base_url }}/system/author/js/vue-editor.js?20200716"></script>
+		<script src="{{ base_url }}/system/author/js/vue-meta.js?20200716"></script>		
+		<script src="{{ base_url }}/system/author/js/vue-navi.js?20200716"></script>
 
 
 		{{ assets.renderJS() }}
 		{{ assets.renderJS() }}
 		
 		

+ 14 - 0
system/author/settings/blank.twig

@@ -0,0 +1,14 @@
+{% extends 'layouts/layout.twig' %}
+{% block title %}Blank{% endblock %}
+
+{% block content %}
+	
+	<div class="formWrapper">
+
+		<section class="settings">
+			{{ content }}
+		</section>
+	
+	</div>
+
+{% endblock %}

+ 10 - 0
system/author/settings/system.twig

@@ -69,6 +69,16 @@
 					</div><div class="medium">
 					</div><div class="medium">
 						<label for="settings[sitemap]">{{ __('Google Sitemap') }} <small>({{ __('Readonly') }})</small></label>
 						<label for="settings[sitemap]">{{ __('Google Sitemap') }} <small>({{ __('Readonly') }})</small></label>
 						<input type="text" name="settings[sitemap]" id="sitemap" readonly value="{{ base_url }}/cache/sitemap.xml" />
 						<input type="text" name="settings[sitemap]" id="sitemap" readonly value="{{ base_url }}/cache/sitemap.xml" />
+					</div><div class="medium{{ errors.settings.access ? ' error' : '' }}">
+						<label for="settings[access]">{{ __('Website visible for') }}</label>
+						<select name="settings[access]" id="access">
+							{% for key,option in access %}
+								<option value="{{ key }}"{% if (key == old.settings.access or key == settings.access) %} selected{% endif %}>{{ __(option) }}</option>
+							{% endfor %}
+						</select>
+						{% if errors.settings.access %}
+							<span class="error">{{ errors.settings.access | first }}</span>
+						{% endif %}
 					</div>
 					</div>
 					<hr>
 					<hr>
 					<header class="headline">
 					<header class="headline">

+ 7 - 0
system/system.php

@@ -172,6 +172,13 @@ $path 				= $uri->getPath();
 $container['flash']	= false;
 $container['flash']	= false;
 $container['csrf'] 	= false;
 $container['csrf'] 	= false;
 
 
+# if website is restricted to registered user
+if(isset($settings['settings']['access']) && $settings['settings']['access'] == 'registered')
+{
+	# activate session for all routes
+	$session_segments = [$path];
+}
+
 foreach($session_segments as $segment)
 foreach($session_segments as $segment)
 {
 {
 	if(substr( $path, 0, strlen($segment) ) === $segment)
 	if(substr( $path, 0, strlen($segment) ) === $segment)

+ 6 - 0
themes/cyanine/css/style.css

@@ -398,6 +398,12 @@ button.play-video::after {
 	right: 0;
 	right: 0;
 	top: 0;
 	top: 0;
 }
 }
+.contentnav.collapse .folder > ul{
+	display: none;
+}
+.contentnav .folder.active > ul,.contentnav .folder.activeParent > ul{
+	display: block;
+}
 .burgerbutton{
 .burgerbutton{
 	display: inline-block;
 	display: inline-block;
 	font-size: 2em;
 	font-size: 2em;

+ 7 - 3
themes/cyanine/cyanine.yaml

@@ -1,5 +1,5 @@
 name: Cyanine Theme
 name: Cyanine Theme
-version: 1.0.0
+version: 1.0.1
 description: Cyanine is a modern and flexible multi-purpose theme and the standard theme for typemill. 
 description: Cyanine is a modern and flexible multi-purpose theme and the standard theme for typemill. 
 author: Trendschau
 author: Trendschau
 homepage: https://trendschau.net
 homepage: https://trendschau.net
@@ -211,10 +211,14 @@ forms:
       type: fieldset
       type: fieldset
       legend: Navigations and Chapters
       legend: Navigations and Chapters
       fields:
       fields:
+        collapseNav:
+          type: checkbox
+          label: Collapse navigation
+          checkboxlabel: Collapse and expand navigation?
         chapnum:
         chapnum:
           type: checkbox
           type: checkbox
-          label: Show Chapter Numbers
-          checkboxlabel: Count chapters in navigation?
+          label: Chapter Numbers
+          checkboxlabel: Show chapter numbers in navigation?
 
 
     fieldsetfooter:
     fieldsetfooter:
       type: fieldset
       type: fieldset

+ 24 - 0
themes/cyanine/layout.twig

@@ -119,6 +119,30 @@
 
 
 			<script src="{{ base_url }}/system/author/js/typemillutils.js?20200418"></script>
 			<script src="{{ base_url }}/system/author/js/typemillutils.js?20200418"></script>
 			<script>typemillUtilities.start();</script>
 			<script>typemillUtilities.start();</script>
+			
+			{% if settings.themes.cyanine.collapseNav %}
+				<script>
+					var expandButton = document.getElementById("expander");
+					if(expandButton)
+					{
+						expandButton.addEventListener('click', function(e)
+						{
+							var contentnav = document.getElementById("contentnav");
+							
+							contentnav.classList.toggle("collapse");
+
+							if(contentnav.classList.contains("collapse"))
+							{
+								expandButton.innerHTML = "expand navigation";
+							}
+							else
+							{
+								expandButton.innerHTML = "collapse navigation";
+							}
+						});
+					}
+				</script>
+			{% endif %}
 
 
 			{{ assets.renderJS() }}
 			{{ assets.renderJS() }}
 		
 		

+ 11 - 3
themes/cyanine/page.twig

@@ -5,7 +5,7 @@
 	<div class="w-100 mw8 center grid-container">
 	<div class="w-100 mw8 center grid-container">
 
 
 		<aside class="grid-header ph3 pv3">
 		<aside class="grid-header ph3 pv3">
-					
+
 			<header>
 			<header>
 						
 						
 				<div class="logo">
 				<div class="logo">
@@ -22,6 +22,14 @@
 					
 					
 			</header>
 			</header>
 
 
+			{% if widgets %}
+				{% for index,widget in widgets %}
+					<div id="{{ index }}" class="mt4-l mt3">
+						{{ widget }}					
+					</div>
+				{% endfor %}
+			{% endif %}
+
 		</aside>
 		</aside>
 
 
 		<div class="grid-main ph3 ph4-l pv3 lh-copy f4 fw3">
 		<div class="grid-main ph3 ph4-l pv3 lh-copy f4 fw3">
@@ -105,9 +113,9 @@
 
 
 		</div>
 		</div>
 
 
-		<aside class="grid-sidebar ph3 pv4">
+		<aside class="grid-sidebar ph3 pv3">
 
 
-			<nav class="contentnav" aria-label="Menu">
+			<nav id="contentnav" class="contentnav{{ settings.themes.cyanine.collapseNav ? ' collapse' : '' }}" aria-label="Menu">
 
 
 				<!-- burger menu controlled by invisible checkbox -->
 				<!-- burger menu controlled by invisible checkbox -->
 	  			<input type="checkbox" id="burger" class="dn">
 	  			<input type="checkbox" id="burger" class="dn">

+ 5 - 1
themes/cyanine/partials/navigation.twig

@@ -15,7 +15,7 @@
 		{% endif %}
 		{% endif %}
         
         
         {% if (element.elementType == 'folder') %}
         {% if (element.elementType == 'folder') %}
-				<a class="link dib w-100 relative fw9 pv2 pr2 indent-l-{{depth}} margin-bottom-1 arrow-after hover-bg-primary f-primary hover-f-secondary" href="{{ element.urlAbs }}">{% if chapnum %}{{ element.chapter }}. {% endif %}{{ element.name }}</a>
+				<a class="link dib w-100 relative fw7 pv2 pr2 indent-l-{{depth}} margin-bottom-1 arrow-after hover-bg-primary f-primary hover-f-secondary" href="{{ element.urlAbs }}">{% if chapnum %}{{ element.chapter }}. {% endif %}{{ element.name }}</a>
 		{% if (element.folderContent|length > 0) and (element.contains == 'pages') %}	
 		{% if (element.folderContent|length > 0) and (element.contains == 'pages') %}	
                 <ul class="list pa0">
                 <ul class="list pa0">
                     {{ macros.loop_over(element.folderContent, chapnum) }}
                     {{ macros.loop_over(element.folderContent, chapnum) }}
@@ -30,6 +30,10 @@
 
 
 {% import _self as macros %}
 {% import _self as macros %}
 
 
+{% if settings.themes.cyanine.collapseNav %}
+    <button id="expander" class=" dn db-l link pointer w-100 bg-secondary ba b--tertiary pa2 mb1 f7">expand navigation</button>
+{% endif %}
+
 <ul class="list pa0 menu {{ settings.themes.cyanine.fontnavi }}">
 <ul class="list pa0 menu {{ settings.themes.cyanine.fontnavi }}">
     {{ macros.loop_over(navigation, settings.themes.cyanine.chapnum ) }}
     {{ macros.loop_over(navigation, settings.themes.cyanine.chapnum ) }}
 </ul>
 </ul>

部分文件因为文件数量过多而无法显示