mirror of
https://github.com/typemill/typemill.git
synced 2025-01-17 05:18:19 +01:00
Merge branch 'master' into develop
This commit is contained in:
commit
5a0ad33e19
@ -10,6 +10,7 @@ RewriteEngine On
|
||||
# Protect your system files from prying eyes
|
||||
RewriteRule ^(system\/author\/) - [L]
|
||||
RewriteRule ^(system) - [F,L]
|
||||
RewriteRule ^(data) - [F,L]
|
||||
RewriteRule ^(content) - [F,L]
|
||||
RewriteRule ^(settings) - [F,L]
|
||||
RewriteRule ^(.*)?\.yml$ - [F,L]
|
||||
|
1
cache/index.json
vendored
Normal file
1
cache/index.json
vendored
Normal file
File diff suppressed because one or more lines are too long
36
composer.lock
generated
36
composer.lock
generated
@ -791,16 +791,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.17.1",
|
||||
"version": "v1.18.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
"reference": "2edd75b8b35d62fd3eeabba73b26b8f1f60ce13d"
|
||||
"reference": "1c302646f6efc070cd46856e600e5e0684d6b454"
|
||||
},
|
||||
"dist": {
|
||||
"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": ""
|
||||
},
|
||||
"require": {
|
||||
@ -812,7 +812,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.17-dev"
|
||||
"dev-master": "1.18-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
@ -849,7 +849,7 @@
|
||||
"polyfill",
|
||||
"portable"
|
||||
],
|
||||
"time": "2020-06-06T08:46:27+00:00"
|
||||
"time": "2020-07-14T12:35:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
@ -903,30 +903,30 @@
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v1.42.5",
|
||||
"version": "v1.43.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e"
|
||||
"reference": "597a03e85a60af6feee4f5127f3ef4279a1694c3"
|
||||
},
|
||||
"dist": {
|
||||
"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": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5.0",
|
||||
"php": ">=7.1.3",
|
||||
"symfony/polyfill-ctype": "^1.8"
|
||||
},
|
||||
"require-dev": {
|
||||
"psr/container": "^1.0",
|
||||
"symfony/phpunit-bridge": "^4.4|^5.0"
|
||||
"symfony/phpunit-bridge": "^4.4.9|^5.0.9"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.42-dev"
|
||||
"dev-master": "1.43-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -963,7 +963,7 @@
|
||||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"time": "2020-02-11T05:59:23+00:00"
|
||||
"time": "2020-07-05T13:00:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "vlucas/valitron",
|
||||
@ -971,12 +971,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vlucas/valitron.git",
|
||||
"reference": "4af076d19f3cd4fd61f560cba115316834c7fe81"
|
||||
"reference": "9268adeeb48ba155e35dca861f5990283e14eafb"
|
||||
},
|
||||
"dist": {
|
||||
"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": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1012,7 +1012,7 @@
|
||||
"validation",
|
||||
"validator"
|
||||
],
|
||||
"time": "2020-05-14T14:50:07+00:00"
|
||||
"time": "2020-07-10T08:55:05+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
@ -1,12 +1,12 @@
|
||||
meta:
|
||||
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
|
||||
owner: testauthor
|
||||
author: trendschau
|
||||
manualdate: null
|
||||
modified: '2020-07-09'
|
||||
modified: '2020-06-14'
|
||||
created: '2020-06-11'
|
||||
time: 21-05-02
|
||||
navtitle: 'content elements'
|
||||
|
@ -104,28 +104,23 @@ describe('Typemill Setup', function()
|
||||
{
|
||||
cy.visit('/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')
|
||||
.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()
|
||||
.type('Sebastian')
|
||||
.should('have.value', 'Sebastian')
|
||||
cy.get('input[name="lastname"]')
|
||||
cy.get('input[name="user[lastname]"]')
|
||||
.clear()
|
||||
.type('Schürmanns')
|
||||
.should('have.value', 'Schürmanns')
|
||||
cy.get('input[name="email"]')
|
||||
cy.get('input[name="user[email]"]')
|
||||
.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', '')
|
||||
cy.get('input[name="newpassword"]')
|
||||
cy.get('input[name="user[newpassword]"]')
|
||||
.should('have.value', '')
|
||||
|
||||
cy.get('#userform').submit()
|
||||
|
@ -18,8 +18,8 @@ describe('Typemill Initial Frontend', function()
|
||||
expect($a[4].href).to.match(/welcome\/markdown-test/)
|
||||
expect($a[5].href).to.match(/cyanine-theme/)
|
||||
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/)
|
||||
})
|
||||
})
|
||||
|
@ -270,10 +270,10 @@ class PageController extends Controller
|
||||
protected function getFreshStructure($pathToContent, $cache, $uri)
|
||||
{
|
||||
/* scan the content of the folder */
|
||||
$structure = Folder::scanFolder($pathToContent);
|
||||
$pagetree = Folder::scanFolder($pathToContent);
|
||||
|
||||
/* if there is no content, render an empty page */
|
||||
if(count($structure) == 0)
|
||||
if(count($pagetree) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -282,6 +282,10 @@ class PageController extends Controller
|
||||
$yaml = new writeYaml();
|
||||
$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)
|
||||
{
|
||||
$extended = $this->createExtended($this->pathToContent, $yaml, $structure);
|
||||
@ -289,12 +293,12 @@ class PageController extends Controller
|
||||
if(!empty($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->updateCache('cache', 'structure.txt', 'lastCache.txt', $structure);
|
||||
|
||||
@ -325,7 +329,8 @@ class PageController extends Controller
|
||||
|
||||
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))
|
||||
{
|
||||
|
@ -14,6 +14,27 @@ use Typemill\Events\OnSystemnaviLoaded;
|
||||
|
||||
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 **
|
||||
*********************/
|
||||
@ -26,13 +47,15 @@ class SettingsController extends Controller
|
||||
$copyright = $this->getCopyright();
|
||||
$languages = $this->getLanguages();
|
||||
$locale = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? substr($_SERVER["HTTP_ACCEPT_LANGUAGE"],0,2) : 'en';
|
||||
$users = $user->getUsers();
|
||||
$route = $request->getAttribute('route');
|
||||
$navigation = $this->getNavigation();
|
||||
|
||||
# set navigation active
|
||||
$navigation['System']['active'] = true;
|
||||
|
||||
# set option for registered website
|
||||
$options = ['' => 'all', 'registered' => 'registered users only'];
|
||||
|
||||
return $this->render($response, 'settings/system.twig', array(
|
||||
'settings' => $settings,
|
||||
'acl' => $this->c->acl,
|
||||
@ -41,7 +64,7 @@ class SettingsController extends Controller
|
||||
'languages' => $languages,
|
||||
'locale' => $locale,
|
||||
'formats' => $defaultSettings['formats'],
|
||||
'users' => $users,
|
||||
'access' => $options,
|
||||
'route' => $route->getName()
|
||||
));
|
||||
}
|
||||
@ -68,7 +91,8 @@ class SettingsController extends Controller
|
||||
'year' => $newSettings['year'],
|
||||
'language' => $newSettings['language'],
|
||||
'langattr' => $newSettings['langattr'],
|
||||
'editor' => $newSettings['editor'],
|
||||
'editor' => $newSettings['editor'],
|
||||
'access' => $newSettings['access'],
|
||||
'formats' => $newSettings['formats'],
|
||||
'headlineanchors' => isset($newSettings['headlineanchors']) ? $newSettings['headlineanchors'] : null,
|
||||
);
|
||||
@ -678,7 +702,7 @@ class SettingsController extends Controller
|
||||
$user = new User();
|
||||
$validate = new Validation();
|
||||
$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']]);
|
||||
|
||||
# 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();
|
||||
|
||||
# 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['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
|
||||
|
@ -20,6 +20,12 @@ class accessController
|
||||
|
||||
public function __invoke(Request $request, Response $response, $next)
|
||||
{
|
||||
|
||||
if($this->resource == NULL && $this->privilege == NULL)
|
||||
{
|
||||
return $next($request, $response);
|
||||
}
|
||||
|
||||
if(!isset($_SESSION['login']))
|
||||
{
|
||||
return $response->withRedirect($this->router->pathFor('auth.show'));
|
||||
|
@ -69,7 +69,7 @@ class Folder
|
||||
|
||||
if($fileType == 'md')
|
||||
{
|
||||
$folderContent[] = $item;
|
||||
$folderContent[] = $item;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
else
|
||||
elseif($name)
|
||||
{
|
||||
# do not use files in base folder (only folders are allowed)
|
||||
# if(!isset($keyPath)) continue;
|
||||
|
@ -125,7 +125,6 @@ class User extends WriteYaml
|
||||
{
|
||||
$user['lastlogin'] = time();
|
||||
unset($user['password']);
|
||||
$this->updateUser($user);
|
||||
|
||||
$_SESSION['user'] = $user['username'];
|
||||
$_SESSION['role'] = $user['userrole'];
|
||||
@ -139,6 +138,9 @@ class User extends WriteYaml
|
||||
{
|
||||
$_SESSION['lastname'] = $user['lastname'];
|
||||
}
|
||||
|
||||
# update user last login
|
||||
$this->updateUser($user);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,6 +79,10 @@ if($settings['settings']['setup'])
|
||||
{
|
||||
$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
|
||||
{
|
||||
$app->get('/[{params:.*}]', PageController::class . ':index')->setName('home');
|
||||
|
@ -82,7 +82,7 @@ class Settings
|
||||
'contentFolder' => 'content',
|
||||
'cache' => true,
|
||||
'cachePath' => $rootPath . 'cache',
|
||||
'version' => '1.3.7.2',
|
||||
'version' => '1.3.8',
|
||||
'setup' => true,
|
||||
'welcome' => true,
|
||||
'images' => ['live' => ['width' => 820], 'thumbs' => ['width' => 250, 'height' => 150]],
|
||||
@ -111,7 +111,7 @@ class Settings
|
||||
}
|
||||
|
||||
# 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';
|
||||
|
||||
return $lang;
|
||||
@ -158,6 +158,7 @@ class Settings
|
||||
'startpage' => true,
|
||||
'author' => true,
|
||||
'year' => true,
|
||||
'access' => true,
|
||||
'headlineanchors' => true,
|
||||
'theme' => true,
|
||||
'editor' => true,
|
||||
@ -169,7 +170,7 @@ class Settings
|
||||
'themes' => true,
|
||||
'latestVersion' => true,
|
||||
'logo' => true,
|
||||
'favicon' => true,
|
||||
'favicon' => true
|
||||
];
|
||||
|
||||
# cleanup the existing usersettings
|
||||
@ -212,7 +213,7 @@ class Settings
|
||||
$editor['permissions'] = [ 'mycontent' => ['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)
|
||||
|
@ -7,11 +7,13 @@
|
||||
|
||||
{% if systemcheck %}
|
||||
<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 %}
|
||||
|
||||
<div class="authformWrapper">
|
||||
@ -48,4 +50,4 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
@ -165,7 +165,11 @@ const contentComponent = Vue.component('content-block', {
|
||||
},
|
||||
submitBlock: function(){
|
||||
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"){ }
|
||||
|
||||
/* add new line with markup for these components */
|
||||
else if(this.componentType == "ulist-component" || this.componentType == "olist-component")
|
||||
{
|
||||
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)
|
||||
{
|
||||
var checkempty = this.compmarkdown.replace(/(\r\n|\n|\r|\s)/gm,"");
|
||||
@ -1014,21 +1019,21 @@ const tableComponent = Vue.component('table-component', {
|
||||
'</colgroup>' +
|
||||
'<tbody>' +
|
||||
'<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 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="deletecolumn(value)">{{ \'delete column\'|translate }}</div>' +
|
||||
'</div>' +
|
||||
'</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 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="deleterow(value)">{{ \'delete row\'|translate }}</div>' +
|
||||
'</div>' +
|
||||
'{{ 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 class="actionline" @click="addaboverow(value)">{{ \'add row above\'|translate }}</div>' +
|
||||
'<div class="actionline" @click="addbelowrow(value)">{{ \'add row below\'|translate }}</div>' +
|
||||
@ -1073,6 +1078,10 @@ const tableComponent = Vue.component('table-component', {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
enter: function()
|
||||
{
|
||||
return false;
|
||||
},
|
||||
updatedata: function(event,col,row)
|
||||
{
|
||||
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>' +
|
||||
'<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>' +
|
||||
'<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>' +
|
||||
'</div>' +
|
||||
'</draggable>' +
|
||||
@ -1249,6 +1258,10 @@ const definitionComponent = Vue.component('definition-component', {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
enter: function()
|
||||
{
|
||||
return false;
|
||||
},
|
||||
updateterm: function(event, dindex)
|
||||
{
|
||||
this.definitionList[dindex].term = event.target.value;
|
||||
@ -2162,7 +2175,7 @@ const medialib = Vue.component('medialib', {
|
||||
|
||||
this.$parent.showmedialib = false;
|
||||
|
||||
this.$parent.createmarkdown();
|
||||
this.$parent.createmarkdown(image.src_live);
|
||||
/* this.$parent.updatemarkdown(imgmarkdown, image.src_live); */
|
||||
}
|
||||
if(this.parentcomponent == 'files')
|
||||
@ -2196,7 +2209,7 @@ const medialib = Vue.component('medialib', {
|
||||
|
||||
this.$parent.showmedialib = false;
|
||||
|
||||
this.$parent.createmarkdown();
|
||||
this.$parent.createmarkdown(file.url);
|
||||
/* this.$parent.updatemarkdown(imgmarkdown, file.url);*/
|
||||
}
|
||||
if(this.parentcomponent == 'files')
|
||||
|
@ -64,6 +64,11 @@ Vue.component('component-image', {
|
||||
/* is called from child component medialib */
|
||||
this.update(url);
|
||||
},
|
||||
createmarkdown: function(url)
|
||||
{
|
||||
/* is called from child component medialib */
|
||||
this.update(url);
|
||||
},
|
||||
deleteImage: function()
|
||||
{
|
||||
this.imgpreview = false;
|
||||
|
@ -19,8 +19,8 @@
|
||||
<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/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>
|
||||
<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">
|
||||
@ -74,8 +74,14 @@
|
||||
<footer></footer>
|
||||
</div>
|
||||
<!-- <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>
|
||||
typemillUtilities.start()
|
||||
</script>
|
||||
|
@ -20,7 +20,7 @@
|
||||
<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/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" />
|
||||
</head>
|
||||
<body>
|
||||
@ -56,6 +56,6 @@
|
||||
{% block content %}{% endblock %}
|
||||
|
||||
</div>
|
||||
<script src="{{ base_url }}/system/author/js/auth.js?20200614"></script>
|
||||
<script src="{{ base_url }}/system/author/js/auth.js?20200716"></script>
|
||||
</body>
|
||||
</html>
|
@ -19,7 +19,7 @@
|
||||
<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/style.css?20200614" />
|
||||
<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20200716" />
|
||||
</head>
|
||||
<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">
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
<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/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" />
|
||||
|
||||
{{ assets.renderCSS() }}
|
||||
@ -197,17 +197,17 @@
|
||||
</article>
|
||||
<footer></footer>
|
||||
</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>
|
||||
const myaxios = axios.create();
|
||||
myaxios.defaults.baseURL = "{{ base_url }}";
|
||||
</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>
|
||||
let formatConfig = {{ settings.formats|json_encode() }};
|
||||
let language = {{ settings.language|json_encode() }};
|
||||
@ -217,13 +217,13 @@
|
||||
|
||||
{{ 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() }}
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
<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/style.css?20200614" />
|
||||
<link rel="stylesheet" href="{{ base_url }}/system/author/css/style.css?20200716" />
|
||||
|
||||
{{ assets.renderCSS() }}
|
||||
|
||||
@ -83,16 +83,16 @@
|
||||
</article>
|
||||
<footer></footer>
|
||||
</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>
|
||||
const myaxios = axios.create();
|
||||
myaxios.defaults.baseURL = "{{ base_url }}";
|
||||
</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>
|
||||
let language = {{ settings.language|json_encode() }};
|
||||
@ -102,10 +102,10 @@
|
||||
|
||||
{{ 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() }}
|
||||
|
||||
|
14
system/author/settings/blank.twig
Normal file
14
system/author/settings/blank.twig
Normal file
@ -0,0 +1,14 @@
|
||||
{% extends 'layouts/layout.twig' %}
|
||||
{% block title %}Blank{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="formWrapper">
|
||||
|
||||
<section class="settings">
|
||||
{{ content }}
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
@ -69,6 +69,16 @@
|
||||
</div><div class="medium">
|
||||
<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" />
|
||||
</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>
|
||||
<hr>
|
||||
<header class="headline">
|
||||
|
@ -172,6 +172,13 @@ $path = $uri->getPath();
|
||||
$container['flash'] = 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)
|
||||
{
|
||||
if(substr( $path, 0, strlen($segment) ) === $segment)
|
||||
|
@ -398,6 +398,12 @@ button.play-video::after {
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
.contentnav.collapse .folder > ul{
|
||||
display: none;
|
||||
}
|
||||
.contentnav .folder.active > ul,.contentnav .folder.activeParent > ul{
|
||||
display: block;
|
||||
}
|
||||
.burgerbutton{
|
||||
display: inline-block;
|
||||
font-size: 2em;
|
||||
|
@ -1,5 +1,5 @@
|
||||
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.
|
||||
author: Trendschau
|
||||
homepage: https://trendschau.net
|
||||
@ -211,10 +211,14 @@ forms:
|
||||
type: fieldset
|
||||
legend: Navigations and Chapters
|
||||
fields:
|
||||
collapseNav:
|
||||
type: checkbox
|
||||
label: Collapse navigation
|
||||
checkboxlabel: Collapse and expand navigation?
|
||||
chapnum:
|
||||
type: checkbox
|
||||
label: Show Chapter Numbers
|
||||
checkboxlabel: Count chapters in navigation?
|
||||
label: Chapter Numbers
|
||||
checkboxlabel: Show chapter numbers in navigation?
|
||||
|
||||
fieldsetfooter:
|
||||
type: fieldset
|
||||
|
@ -119,6 +119,30 @@
|
||||
|
||||
<script src="{{ base_url }}/system/author/js/typemillutils.js?20200418"></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() }}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<div class="w-100 mw8 center grid-container">
|
||||
|
||||
<aside class="grid-header ph3 pv3">
|
||||
|
||||
|
||||
<header>
|
||||
|
||||
<div class="logo">
|
||||
@ -22,6 +22,14 @@
|
||||
|
||||
</header>
|
||||
|
||||
{% if widgets %}
|
||||
{% for index,widget in widgets %}
|
||||
<div id="{{ index }}" class="mt4-l mt3">
|
||||
{{ widget }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
</aside>
|
||||
|
||||
<div class="grid-main ph3 ph4-l pv3 lh-copy f4 fw3">
|
||||
@ -105,9 +113,9 @@
|
||||
|
||||
</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 -->
|
||||
<input type="checkbox" id="burger" class="dn">
|
||||
|
@ -15,7 +15,7 @@
|
||||
{% endif %}
|
||||
|
||||
{% 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') %}
|
||||
<ul class="list pa0">
|
||||
{{ macros.loop_over(element.folderContent, chapnum) }}
|
||||
@ -30,6 +30,10 @@
|
||||
|
||||
{% 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 }}">
|
||||
{{ macros.loop_over(navigation, settings.themes.cyanine.chapnum ) }}
|
||||
</ul>
|
Loading…
x
Reference in New Issue
Block a user