mirror of
https://github.com/typemill/typemill.git
synced 2025-08-03 20:57:38 +02:00
Version 1.2.3 Reorder Pages
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,6 +5,7 @@ plugins/disqus
|
||||
plugins/download
|
||||
plugins/finalwords
|
||||
plugins/version
|
||||
plugins/textadds
|
||||
settings/settings.yaml
|
||||
settings/users
|
||||
system/vendor
|
||||
|
2
cache/lastCache.txt
vendored
2
cache/lastCache.txt
vendored
@@ -1 +1 @@
|
||||
1532595582
|
||||
1536861417
|
@@ -1,3 +1,5 @@
|
||||
# Typemill
|
||||
|
||||
TYPEMILL is a small flat file cms designed for **writers**. It creates websites based on markdown files and is a perfect solution for text-works like studies, manuals or documentations. TYPEMILL is simple, lightweight and open source. Just download and start.
|
||||
Modern Web Publishing For Writers.
|
||||
|
||||
Typemill is a user-friendly and lightweight open source CMS for publishing text-works like prosa, lyrics, manuals, documentations, studies and more. Just download and start.
|
@@ -4,6 +4,8 @@ namespace Typemill\Controllers;
|
||||
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
use Typemill\Models\Folder;
|
||||
use Typemill\Models\Write;
|
||||
use Typemill\Extensions\ParsedownExtension;
|
||||
|
||||
class ContentApiController extends ContentController
|
||||
@@ -180,6 +182,103 @@ class ContentApiController extends ContentController
|
||||
}
|
||||
}
|
||||
|
||||
public function sortArticle(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri();
|
||||
|
||||
# url is only needed, if an active page is moved
|
||||
$url = false;
|
||||
|
||||
# set structure
|
||||
if(!$this->setStructure($draft = true)){ return $response->withJson(array('data' => false, 'errors' => $this->errors, 'url' => $url), 404); }
|
||||
|
||||
# validate input
|
||||
if(!$this->validateNavigationSort()){ return $response->withJson(array('data' => $this->structure, 'errors' => 'Data not valid. Please refresh the page and try again.', 'url' => $url), 422); }
|
||||
|
||||
# get the ids (key path) for item, old folder and new folder
|
||||
$itemKeyPath = explode('.', $this->params['item_id']);
|
||||
$parentKeyFrom = explode('.', $this->params['parent_id_from']);
|
||||
$parentKeyTo = explode('.', $this->params['parent_id_to']);
|
||||
|
||||
# get the item from structure
|
||||
$item = Folder::getItemWithKeyPath($this->structure, $itemKeyPath);
|
||||
|
||||
if(!$item){ return $response->withJson(array('data' => $this->structure, 'errors' => 'We could not find this page. Please refresh and try again.', 'url' => $url), 404); }
|
||||
|
||||
# if a folder is moved on the first level
|
||||
if($this->params['parent_id_from'] == 'navi')
|
||||
{
|
||||
# create empty and default values so that the logic below still works
|
||||
$newFolder = new \stdClass();
|
||||
$newFolder->path = '';
|
||||
$folderContent = $this->structure;
|
||||
}
|
||||
else
|
||||
{
|
||||
# get the target folder from structure
|
||||
$newFolder = Folder::getItemWithKeyPath($this->structure, $parentKeyTo);
|
||||
|
||||
# get the content of the target folder
|
||||
$folderContent = $newFolder->folderContent;
|
||||
}
|
||||
|
||||
# if the item has been moved within the same folder
|
||||
if($this->params['parent_id_from'] == $this->params['parent_id_to'])
|
||||
{
|
||||
# get key of item
|
||||
$itemKey = end($itemKeyPath);
|
||||
reset($itemKeyPath);
|
||||
|
||||
# delete item from folderContent
|
||||
unset($folderContent[$itemKey]);
|
||||
}
|
||||
elseif($this->params['active'] == 'active')
|
||||
{
|
||||
# an active file has been moved to another folder
|
||||
$url = $this->uri->getBaseUrl() . '/tm/content' . $newFolder->urlRelWoF . '/' . $item->slug;
|
||||
}
|
||||
|
||||
# add item to newFolder
|
||||
array_splice($folderContent, $this->params['index_new'], 0, array($item));
|
||||
|
||||
# initialize index
|
||||
$index = 0;
|
||||
|
||||
# initialise write object
|
||||
$write = new Write();
|
||||
|
||||
# iterate through the whole content of the new folder
|
||||
$writeError = false;
|
||||
foreach($folderContent as $folderItem)
|
||||
{
|
||||
if(!$write->moveElement($folderItem, $newFolder->path, $index))
|
||||
{
|
||||
$writeError = true;
|
||||
}
|
||||
$index++;
|
||||
}
|
||||
if($writeError){ return $response->withJson(array('data' => $this->structure, 'errors' => 'Something went wrong. Please refresh the page and check, if all folders and files are writable.', 'url' => $url), 404); }
|
||||
|
||||
# update the structure for editor
|
||||
$this->setStructure($draft = true, $cache = false);
|
||||
|
||||
# get item for url and set it active again
|
||||
if(isset($this->params['url']))
|
||||
{
|
||||
$activeItem = Folder::getItemForUrl($this->structure, $this->params['url']);
|
||||
}
|
||||
|
||||
# keep the internal structure for response
|
||||
$internalStructure = $this->structure;
|
||||
|
||||
# update the structure for website
|
||||
$this->setStructure($draft = false, $cache = false);
|
||||
|
||||
return $response->withJson(array('data' => $internalStructure, 'errors' => false, 'url' => $url));
|
||||
}
|
||||
|
||||
public function createBlock(Request $request, Response $response, $args)
|
||||
{
|
||||
|
||||
|
@@ -5,6 +5,7 @@ namespace Typemill\Controllers;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
use Slim\Views\Twig;
|
||||
use Typemill\Models\Folder;
|
||||
use Typemill\Extensions\ParsedownExtension;
|
||||
|
||||
class ContentBackendController extends ContentController
|
||||
@@ -29,6 +30,9 @@ class ContentBackendController extends ContentController
|
||||
# set item
|
||||
if(!$this->setItem()){ return $this->render404($response, array( 'navigation' => $this->structure, 'settings' => $this->settings, 'content' => $this->errors )); }
|
||||
|
||||
# get the breadcrumb (here we need it only to mark the actual item active in navigation)
|
||||
$breadcrumb = isset($this->item->keyPathArray) ? Folder::getBreadcrumb($this->structure, $this->item->keyPathArray) : false;
|
||||
|
||||
# set the status for published and drafted
|
||||
$this->setPublishStatus();
|
||||
|
||||
@@ -68,6 +72,6 @@ class ContentBackendController extends ContentController
|
||||
}
|
||||
}
|
||||
|
||||
return $this->render($response, 'content/content.twig', array('navigation' => $this->structure, 'title' => $title, 'content' => $content, 'item' => $this->item, 'settings' => $this->settings ));
|
||||
return $this->render($response, 'editor/editor.twig', array('navigation' => $this->structure, 'title' => $title, 'content' => $content, 'item' => $this->item, 'settings' => $this->settings ));
|
||||
}
|
||||
}
|
@@ -39,6 +39,9 @@ abstract class ContentController
|
||||
# hold the page-item as an object
|
||||
protected $item;
|
||||
|
||||
# hold the breadcrumb as an object
|
||||
protected $breadcrumb;
|
||||
|
||||
# holds the path to the requested file
|
||||
protected $path = false;
|
||||
|
||||
@@ -91,6 +94,19 @@ abstract class ContentController
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function validateNavigationSort()
|
||||
{
|
||||
$validate = new Validation();
|
||||
$vResult = $validate->navigationSort($this->params);
|
||||
|
||||
if(is_array($vResult))
|
||||
{
|
||||
$this->errors = ['errors' => $vResult];
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function setStructure($draft = false, $cache = true)
|
||||
{
|
||||
# set initial structure to false
|
||||
@@ -176,7 +192,7 @@ abstract class ContentController
|
||||
{
|
||||
$this->path = $this->item->pathWithoutType . '.' . $fileType;
|
||||
}
|
||||
|
||||
|
||||
protected function setPublishStatus()
|
||||
{
|
||||
$this->item->published = false;
|
||||
|
@@ -6,6 +6,34 @@ use \URLify;
|
||||
|
||||
class Folder
|
||||
{
|
||||
|
||||
/*
|
||||
* scans content of a folder (without recursion)
|
||||
* vars: folder path as string
|
||||
* returns: one-dimensional array with names of folders and files
|
||||
*/
|
||||
public static function scanFolderFlat($folderPath)
|
||||
{
|
||||
$folderItems = scandir($folderPath);
|
||||
$folderContent = array();
|
||||
|
||||
foreach ($folderItems as $key => $item)
|
||||
{
|
||||
if (!in_array($item, array(".","..")))
|
||||
{
|
||||
$nameParts = self::getStringParts($item);
|
||||
$fileType = array_pop($nameParts);
|
||||
|
||||
if($fileType == 'md' OR $fileType == 'txt' )
|
||||
{
|
||||
$folderContent[] = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $folderContent;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* scans content of a folder recursively
|
||||
* vars: folder path as string
|
||||
@@ -88,6 +116,8 @@ class Folder
|
||||
$item->keyPath = isset($keyPath) ? $keyPath . '.' . $iteration : $iteration;
|
||||
$item->keyPathArray = explode('.', $item->keyPath);
|
||||
$item->chapter = $chapter ? $chapter . '.' . $chapternr : $chapternr;
|
||||
$item->active = false;
|
||||
$item->activeParent = false;
|
||||
|
||||
$item->folderContent = self::getFolderContentDetails($name, $baseUrl, $item->urlRel, $item->urlRelWoF, $item->path, $item->keyPath, $item->chapter);
|
||||
}
|
||||
@@ -115,6 +145,8 @@ class Folder
|
||||
$item->urlRelWoF = $fullSlugWithoutFolder . '/' . $item->slug;
|
||||
$item->urlRel = $fullSlugWithFolder . '/' . $item->slug;
|
||||
$item->urlAbs = $baseUrl . $fullSlugWithoutFolder . '/' . $item->slug;
|
||||
$item->active = false;
|
||||
$item->activeParent = false;
|
||||
}
|
||||
$iteration++;
|
||||
$chapternr++;
|
||||
@@ -213,7 +245,14 @@ class Folder
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Gets a copy of an item with a key
|
||||
* @param array $content with the full structure of the content as multidimensional array
|
||||
* @param array $searchArray with the key as a one-dimensional array like array(0,3,4)
|
||||
* @return array $item
|
||||
*/
|
||||
|
||||
public static function getItemWithKeyPath($content, array $searchArray)
|
||||
{
|
||||
$item = false;
|
||||
@@ -231,6 +270,51 @@ class Folder
|
||||
return $item;
|
||||
}
|
||||
|
||||
# https://www.quora.com/Learning-PHP-Is-there-a-way-to-get-the-value-of-multi-dimensional-array-by-specifying-the-key-with-a-variable
|
||||
# NOT IN USE
|
||||
public static function getItemWithKeyPathNew($array, array $keys)
|
||||
{
|
||||
$item = $array;
|
||||
|
||||
foreach ($keys as $key)
|
||||
{
|
||||
$item = isset($item[$key]->folderContent) ? $item[$key]->folderContent : $item[$key];
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extracts an item with a key https://stackoverflow.com/questions/52097092/php-delete-value-of-array-with-dynamic-key
|
||||
* @param array $content with the full structure of the content as multidimensional array
|
||||
* @param array $searchArray with the key as a one-dimensional array like array(0,3,4)
|
||||
* @return array $item
|
||||
* NOT IN USE ??
|
||||
*/
|
||||
|
||||
public static function extractItemWithKeyPath($structure, array $keys)
|
||||
{
|
||||
$result = &$structure;
|
||||
$last = array_pop($keys);
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if(isset($result[$key]->folderContent))
|
||||
{
|
||||
$result = &$result[$key]->folderContent;
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = &$result[$key];
|
||||
}
|
||||
}
|
||||
|
||||
$item = $result[$last];
|
||||
unset($result[$last]);
|
||||
|
||||
return array('structure' => $structure, 'item' => $item);
|
||||
}
|
||||
|
||||
|
||||
/* get breadcrumb as copied array, set elements active in original and mark parent element in original */
|
||||
public static function getBreadcrumb($content, $searchArray, $i = NULL, $breadcrumb = NULL)
|
||||
{
|
||||
@@ -280,7 +364,7 @@ class Folder
|
||||
}
|
||||
return $lastItem;
|
||||
}
|
||||
|
||||
|
||||
public static function getStringParts($name)
|
||||
{
|
||||
return preg_split('/[\-\.\_\=\+\?\!\*\#\(\)\/ ]/',$name);
|
||||
|
@@ -214,6 +214,33 @@ class Validation
|
||||
return $v->errors();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* validation for resort navigation
|
||||
*
|
||||
* @param array $params with form data.
|
||||
* @return true or $v->errors with array of errors to use in json-response
|
||||
*/
|
||||
|
||||
public function navigationSort(array $params)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
|
||||
$v->rule('required', ['item_id', 'parent_id_from', 'parent_id_to']);
|
||||
$v->rule('regex', 'item_id', '/^[0-9.]+$/i');
|
||||
$v->rule('regex', 'parent_id_from', '/^[a-zA-Z0-9.]+$/i');
|
||||
$v->rule('regex', 'parent_id_to', '/^[a-zA-Z0-9.]+$/i');
|
||||
$v->rule('integer', 'index_new');
|
||||
|
||||
if($v->validate())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $v->errors();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* validation for dynamic fields ( settings for themes and plugins)
|
||||
|
@@ -79,4 +79,50 @@ class Write
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function moveElement($item, $folderPath, $index)
|
||||
{
|
||||
$result = false;
|
||||
|
||||
$newOrder = ($index < 10) ? '0' . $index : $index;
|
||||
|
||||
if($item->elementType == 'folder')
|
||||
{
|
||||
$newName = $newOrder . '-' . $item->name;
|
||||
}
|
||||
else
|
||||
{
|
||||
$newName = $newOrder . '-' . $item->name . '.' . $item->fileType;
|
||||
}
|
||||
|
||||
$oldPath = $this->basePath . 'content' . $item->path;
|
||||
$newPath = $this->basePath . 'content' . $folderPath . DIRECTORY_SEPARATOR . $newName;
|
||||
|
||||
if(@rename($oldPath, $newPath))
|
||||
{
|
||||
$result = true;
|
||||
}
|
||||
|
||||
# if it is a txt file, check, if there is a corresponding .md file and move it
|
||||
if($result && $item->elementType == 'file' && $item->fileType == 'txt')
|
||||
{
|
||||
$result = false;
|
||||
|
||||
$oldPath = substr($item->path, 0, strpos($item->path, "."));
|
||||
$oldPath = $this->basePath . 'content' . $oldPath . '.md';
|
||||
|
||||
if(file_exists($oldPath))
|
||||
{
|
||||
$newName = $newOrder . '-' . $item->name . '.md';
|
||||
$newPath = $this->basePath . 'content' . $folderPath . DIRECTORY_SEPARATOR . $newName;
|
||||
|
||||
if(@rename($oldPath, $newPath))
|
||||
{
|
||||
$result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
@@ -10,4 +10,5 @@ $app->post('/api/v1/article/publish', ContentApiController::class . ':publishArt
|
||||
$app->delete('/api/v1/article/unpublish', ContentApiController::class . ':unpublishArticle')->setName('api.article.unpublish')->add(new RestrictApiAccess($container['router']));
|
||||
$app->put('/api/v1/article', ContentApiController::class . ':updateArticle')->setName('api.article.update')->add(new RestrictApiAccess($container['router']));
|
||||
$app->delete('/api/v1/article', ContentApiController::class . ':deleteArticle')->setName('api.article.delete')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/block', ContentBackendController::class . ':createBlock')->setName('api.block.create')->add(new RestrictApiAccess($container['router']));
|
||||
$app->post('/api/v1/article/sort', ContentApiController::class . ':sortArticle')->setName('api.article.sort')->add(new RestrictApiAccess($container['router']));
|
||||
// $app->post('/api/v1/block', ContentBackendController::class . ':createBlock')->setName('api.block.create')->add(new RestrictApiAccess($container['router']));
|
||||
|
@@ -10,12 +10,3 @@ Font license info
|
||||
Homepage: http://fortawesome.github.com/Font-Awesome/
|
||||
|
||||
|
||||
## Web Symbols
|
||||
|
||||
Copyright (c) 2011 by Just Be Nice studio. All rights reserved.
|
||||
|
||||
Author: Just Be Nice studio
|
||||
License: SIL (http://scripts.sil.org/OFL)
|
||||
Homepage: http://www.justbenicestudio.com/
|
||||
|
||||
|
||||
|
@@ -7,27 +7,33 @@
|
||||
"ascent": 850,
|
||||
"glyphs": [
|
||||
{
|
||||
"uid": "8b9e6a8dd8f67f7c003ed8e7e5ee0857",
|
||||
"css": "off",
|
||||
"code": 59393,
|
||||
"uid": "5408be43f7c42bccee419c6be53fdef5",
|
||||
"css": "doc-text",
|
||||
"code": 61686,
|
||||
"src": "fontawesome"
|
||||
},
|
||||
{
|
||||
"uid": "c5fd349cbd3d23e4ade333789c29c729",
|
||||
"css": "eye",
|
||||
"code": 59394,
|
||||
"uid": "b091a8bd0fdade174951f17d936f51e4",
|
||||
"css": "folder-empty",
|
||||
"code": 61716,
|
||||
"src": "fontawesome"
|
||||
},
|
||||
{
|
||||
"uid": "6533bdc16ab201eb3f3b27ce989cab33",
|
||||
"css": "folder-open-empty",
|
||||
"code": 61717,
|
||||
"src": "fontawesome"
|
||||
},
|
||||
{
|
||||
"uid": "e99461abfef3923546da8d745372c995",
|
||||
"css": "cog",
|
||||
"code": 59396,
|
||||
"code": 59392,
|
||||
"src": "fontawesome"
|
||||
},
|
||||
{
|
||||
"uid": "5408be43f7c42bccee419c6be53fdef5",
|
||||
"css": "doc-text",
|
||||
"code": 61686,
|
||||
"uid": "381da2c2f7fd51f8de877c044d7f439d",
|
||||
"css": "picture",
|
||||
"code": 59393,
|
||||
"src": "fontawesome"
|
||||
},
|
||||
{
|
||||
@@ -37,16 +43,22 @@
|
||||
"src": "fontawesome"
|
||||
},
|
||||
{
|
||||
"uid": "381da2c2f7fd51f8de877c044d7f439d",
|
||||
"css": "picture",
|
||||
"code": 59392,
|
||||
"uid": "b013f6403e5ab0326614e68d1850fd6b",
|
||||
"css": "resize-full-alt",
|
||||
"code": 61618,
|
||||
"src": "fontawesome"
|
||||
},
|
||||
{
|
||||
"uid": "8da3ac534210aae9c0f0e13804c1df97",
|
||||
"css": "cancel",
|
||||
"uid": "8b9e6a8dd8f67f7c003ed8e7e5ee0857",
|
||||
"css": "off",
|
||||
"code": 59394,
|
||||
"src": "fontawesome"
|
||||
},
|
||||
{
|
||||
"uid": "d7271d490b71df4311e32cdacae8b331",
|
||||
"css": "home",
|
||||
"code": 59395,
|
||||
"src": "websymbols"
|
||||
"src": "fontawesome"
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,8 +1,10 @@
|
||||
|
||||
.icon-picture:before { content: '\e800'; } /* '' */
|
||||
.icon-off:before { content: '\e801'; } /* '' */
|
||||
.icon-eye:before { content: '\e802'; } /* '' */
|
||||
.icon-cancel:before { content: '\e803'; } /* '' */
|
||||
.icon-cog:before { content: '\e804'; } /* '' */
|
||||
.icon-cog:before { content: '\e800'; } /* '' */
|
||||
.icon-picture:before { content: '\e801'; } /* '' */
|
||||
.icon-off:before { content: '\e802'; } /* '' */
|
||||
.icon-home:before { content: '\e803'; } /* '' */
|
||||
.icon-link-ext:before { content: '\f08e'; } /* '' */
|
||||
.icon-doc-text:before { content: '\f0f6'; } /* '' */
|
||||
.icon-resize-full-alt:before { content: '\f0b2'; } /* '' */
|
||||
.icon-doc-text:before { content: '\f0f6'; } /* '' */
|
||||
.icon-folder-empty:before { content: '\f114'; } /* '' */
|
||||
.icon-folder-open-empty:before { content: '\f115'; } /* '' */
|
File diff suppressed because one or more lines are too long
@@ -1,8 +1,10 @@
|
||||
|
||||
.icon-picture { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-off { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-eye { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-cancel { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-cog { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-cog { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-picture { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-off { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-home { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-link-ext { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-doc-text { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-resize-full-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-doc-text { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-folder-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-folder-open-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
14
system/author/css/fontello/css/fontello-ie7.css
vendored
14
system/author/css/fontello/css/fontello-ie7.css
vendored
@@ -10,10 +10,12 @@
|
||||
/* font-size: 120%; */
|
||||
}
|
||||
|
||||
.icon-picture { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-off { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-eye { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-cancel { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-cog { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-cog { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-picture { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-off { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-home { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-link-ext { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-doc-text { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-resize-full-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-doc-text { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-folder-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-folder-open-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
28
system/author/css/fontello/css/fontello.css
vendored
28
system/author/css/fontello/css/fontello.css
vendored
@@ -1,11 +1,11 @@
|
||||
@font-face {
|
||||
font-family: 'fontello';
|
||||
src: url('../font/fontello.eot?88351620');
|
||||
src: url('../font/fontello.eot?88351620#iefix') format('embedded-opentype'),
|
||||
url('../font/fontello.woff2?88351620') format('woff2'),
|
||||
url('../font/fontello.woff?88351620') format('woff'),
|
||||
url('../font/fontello.ttf?88351620') format('truetype'),
|
||||
url('../font/fontello.svg?88351620#fontello') format('svg');
|
||||
src: url('../font/fontello.eot?55717473');
|
||||
src: url('../font/fontello.eot?55717473#iefix') format('embedded-opentype'),
|
||||
url('../font/fontello.woff2?55717473') format('woff2'),
|
||||
url('../font/fontello.woff?55717473') format('woff'),
|
||||
url('../font/fontello.ttf?55717473') format('truetype'),
|
||||
url('../font/fontello.svg?55717473#fontello') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||
@font-face {
|
||||
font-family: 'fontello';
|
||||
src: url('../font/fontello.svg?88351620#fontello') format('svg');
|
||||
src: url('../font/fontello.svg?55717473#fontello') format('svg');
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -55,10 +55,12 @@
|
||||
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
|
||||
}
|
||||
|
||||
.icon-picture:before { content: '\e800'; } /* '' */
|
||||
.icon-off:before { content: '\e801'; } /* '' */
|
||||
.icon-eye:before { content: '\e802'; } /* '' */
|
||||
.icon-cancel:before { content: '\e803'; } /* '' */
|
||||
.icon-cog:before { content: '\e804'; } /* '' */
|
||||
.icon-cog:before { content: '\e800'; } /* '' */
|
||||
.icon-picture:before { content: '\e801'; } /* '' */
|
||||
.icon-off:before { content: '\e802'; } /* '' */
|
||||
.icon-home:before { content: '\e803'; } /* '' */
|
||||
.icon-link-ext:before { content: '\f08e'; } /* '' */
|
||||
.icon-doc-text:before { content: '\f0f6'; } /* '' */
|
||||
.icon-resize-full-alt:before { content: '\f0b2'; } /* '' */
|
||||
.icon-doc-text:before { content: '\f0f6'; } /* '' */
|
||||
.icon-folder-empty:before { content: '\f114'; } /* '' */
|
||||
.icon-folder-open-empty:before { content: '\f115'; } /* '' */
|
@@ -229,11 +229,11 @@ body {
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'fontello';
|
||||
src: url('./font/fontello.eot?8909408');
|
||||
src: url('./font/fontello.eot?8909408#iefix') format('embedded-opentype'),
|
||||
url('./font/fontello.woff?8909408') format('woff'),
|
||||
url('./font/fontello.ttf?8909408') format('truetype'),
|
||||
url('./font/fontello.svg?8909408#fontello') format('svg');
|
||||
src: url('./font/fontello.eot?16979120');
|
||||
src: url('./font/fontello.eot?16979120#iefix') format('embedded-opentype'),
|
||||
url('./font/fontello.woff?16979120') format('woff'),
|
||||
url('./font/fontello.ttf?16979120') format('truetype'),
|
||||
url('./font/fontello.svg?16979120#fontello') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
@@ -298,15 +298,19 @@ body {
|
||||
</div>
|
||||
<div class="container" id="icons">
|
||||
<div class="row">
|
||||
<div class="the-icons span3" title="Code: 0xe800"><i class="demo-icon icon-picture"></i> <span class="i-name">icon-picture</span><span class="i-code">0xe800</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe801"><i class="demo-icon icon-off"></i> <span class="i-name">icon-off</span><span class="i-code">0xe801</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe802"><i class="demo-icon icon-eye"></i> <span class="i-name">icon-eye</span><span class="i-code">0xe802</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe803"><i class="demo-icon icon-cancel"></i> <span class="i-name">icon-cancel</span><span class="i-code">0xe803</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe800"><i class="demo-icon icon-cog"></i> <span class="i-name">icon-cog</span><span class="i-code">0xe800</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe801"><i class="demo-icon icon-picture"></i> <span class="i-name">icon-picture</span><span class="i-code">0xe801</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe802"><i class="demo-icon icon-off"></i> <span class="i-name">icon-off</span><span class="i-code">0xe802</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe803"><i class="demo-icon icon-home"></i> <span class="i-name">icon-home</span><span class="i-code">0xe803</span></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="the-icons span3" title="Code: 0xe804"><i class="demo-icon icon-cog"></i> <span class="i-name">icon-cog</span><span class="i-code">0xe804</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xf08e"><i class="demo-icon icon-link-ext"></i> <span class="i-name">icon-link-ext</span><span class="i-code">0xf08e</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xf0b2"><i class="demo-icon icon-resize-full-alt"></i> <span class="i-name">icon-resize-full-alt</span><span class="i-code">0xf0b2</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xf0f6"><i class="demo-icon icon-doc-text"></i> <span class="i-name">icon-doc-text</span><span class="i-code">0xf0f6</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xf114"><i class="demo-icon icon-folder-empty"></i> <span class="i-name">icon-folder-empty</span><span class="i-code">0xf114</span></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="the-icons span3" title="Code: 0xf115"><i class="demo-icon icon-folder-open-empty"></i> <span class="i-name">icon-folder-open-empty</span><span class="i-code">0xf115</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container footer">Generated by <a href="http://fontello.com">fontello.com</a></div>
|
||||
|
Binary file not shown.
@@ -6,19 +6,23 @@
|
||||
<font id="fontello" horiz-adv-x="1000" >
|
||||
<font-face font-family="fontello" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
|
||||
<missing-glyph horiz-adv-x="1000" />
|
||||
<glyph glyph-name="picture" unicode="" d="M357 529q0-45-31-76t-76-32-76 32-31 76 31 76 76 31 76-31 31-76z m572-215v-250h-786v107l178 179 90-89 285 285z m53 393h-893q-7 0-12-5t-6-13v-678q0-7 6-13t12-5h893q7 0 13 5t5 13v678q0 8-5 13t-13 5z m89-18v-678q0-37-26-63t-63-27h-893q-36 0-63 27t-26 63v678q0 37 26 63t63 27h893q37 0 63-27t26-63z" horiz-adv-x="1071.4" />
|
||||
<glyph glyph-name="cog" unicode="" d="M571 350q0 59-41 101t-101 42-101-42-42-101 42-101 101-42 101 42 41 101z m286 61v-124q0-7-4-13t-11-7l-104-16q-10-30-21-51 19-27 59-77 6-6 6-13t-5-13q-15-21-55-61t-53-39q-7 0-14 5l-77 60q-25-13-51-21-9-76-16-104-4-16-20-16h-124q-8 0-14 5t-6 12l-16 103q-27 9-50 21l-79-60q-6-5-14-5-8 0-14 6-70 64-92 94-4 5-4 13 0 6 5 12 8 12 28 37t30 40q-15 28-23 55l-102 15q-7 1-11 7t-5 13v124q0 7 5 13t10 7l104 16q8 25 22 51-23 32-60 77-6 7-6 14 0 5 5 12 15 20 55 60t53 40q7 0 15-5l77-60q24 13 50 21 9 76 17 104 3 16 20 16h124q7 0 13-5t7-12l15-103q28-9 51-20l79 59q5 5 13 5 7 0 14-5 72-67 92-95 4-5 4-12 0-7-4-13-9-12-29-37t-30-40q15-28 23-54l102-16q7-1 12-7t4-13z" horiz-adv-x="857.1" />
|
||||
|
||||
<glyph glyph-name="off" unicode="" d="M857 350q0-87-34-166t-91-137-137-92-166-34-167 34-136 92-92 137-34 166q0 102 45 191t126 151q24 18 54 14t46-28q18-23 14-53t-28-47q-54-41-84-101t-30-127q0-58 23-111t61-91 91-61 111-23 110 23 92 61 61 91 22 111q0 68-30 127t-84 101q-23 18-28 47t14 53q17 24 47 28t53-14q81-61 126-151t45-191z m-357 429v-358q0-29-21-50t-50-21-51 21-21 50v358q0 29 21 50t51 21 50-21 21-50z" horiz-adv-x="857.1" />
|
||||
<glyph glyph-name="picture" unicode="" d="M357 529q0-45-31-76t-76-32-76 32-31 76 31 76 76 31 76-31 31-76z m572-215v-250h-786v107l178 179 90-89 285 285z m53 393h-893q-7 0-12-5t-6-13v-678q0-7 6-13t12-5h893q7 0 13 5t5 13v678q0 8-5 13t-13 5z m89-18v-678q0-37-26-63t-63-27h-893q-36 0-63 27t-26 63v678q0 37 26 63t63 27h893q37 0 63-27t26-63z" horiz-adv-x="1071.4" />
|
||||
|
||||
<glyph glyph-name="eye" unicode="" d="M929 314q-85 132-213 197 34-58 34-125 0-103-73-177t-177-73-177 73-73 177q0 67 34 125-128-65-213-197 75-114 187-182t242-68 243 68 186 182z m-402 215q0 11-8 19t-19 7q-70 0-120-50t-50-119q0-11 8-19t19-8 19 8 8 19q0 48 34 82t82 34q11 0 19 8t8 19z m473-215q0-19-11-38-78-129-210-206t-279-77-279 77-210 206q-11 19-11 38t11 39q78 128 210 205t279 78 279-78 210-205q11-20 11-39z" horiz-adv-x="1000" />
|
||||
<glyph glyph-name="off" unicode="" d="M857 350q0-87-34-166t-91-137-137-92-166-34-167 34-136 92-92 137-34 166q0 102 45 191t126 151q24 18 54 14t46-28q18-23 14-53t-28-47q-54-41-84-101t-30-127q0-58 23-111t61-91 91-61 111-23 110 23 92 61 61 91 22 111q0 68-30 127t-84 101q-23 18-28 47t14 53q17 24 47 28t53-14q81-61 126-151t45-191z m-357 429v-358q0-29-21-50t-50-21-51 21-21 50v358q0 29 21 50t51 21 50-21 21-50z" horiz-adv-x="857.1" />
|
||||
|
||||
<glyph glyph-name="cancel" unicode="" d="M654 349l346-346-154-154-346 346-346-346-154 154 346 346-346 346 154 154 346-346 346 346 154-154z" horiz-adv-x="1000" />
|
||||
|
||||
<glyph glyph-name="cog" unicode="" d="M571 350q0 59-41 101t-101 42-101-42-42-101 42-101 101-42 101 42 41 101z m286 61v-124q0-7-4-13t-11-7l-104-16q-10-30-21-51 19-27 59-77 6-6 6-13t-5-13q-15-21-55-61t-53-39q-7 0-14 5l-77 60q-25-13-51-21-9-76-16-104-4-16-20-16h-124q-8 0-14 5t-6 12l-16 103q-27 9-50 21l-79-60q-6-5-14-5-8 0-14 6-70 64-92 94-4 5-4 13 0 6 5 12 8 12 28 37t30 40q-15 28-23 55l-102 15q-7 1-11 7t-5 13v124q0 7 5 13t10 7l104 16q8 25 22 51-23 32-60 77-6 7-6 14 0 5 5 12 15 20 55 60t53 40q7 0 15-5l77-60q24 13 50 21 9 76 17 104 3 16 20 16h124q7 0 13-5t7-12l15-103q28-9 51-20l79 59q5 5 13 5 7 0 14-5 72-67 92-95 4-5 4-12 0-7-4-13-9-12-29-37t-30-40q15-28 23-54l102-16q7-1 12-7t4-13z" horiz-adv-x="857.1" />
|
||||
<glyph glyph-name="home" unicode="" d="M786 296v-267q0-15-11-25t-25-11h-214v214h-143v-214h-214q-15 0-25 11t-11 25v267q0 1 0 2t0 2l321 264 321-264q1-1 1-4z m124 39l-34-41q-5-5-12-6h-2q-7 0-12 3l-386 322-386-322q-7-4-13-3-7 1-12 6l-35 41q-4 6-3 13t6 12l401 334q18 15 42 15t43-15l136-113v108q0 8 5 13t13 5h107q8 0 13-5t5-13v-227l122-102q6-4 6-12t-4-13z" horiz-adv-x="928.6" />
|
||||
|
||||
<glyph glyph-name="link-ext" unicode="" d="M786 332v-178q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h393q7 0 12-5t5-13v-36q0-8-5-13t-12-5h-393q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63v178q0 8 5 13t13 5h36q8 0 13-5t5-13z m214 482v-285q0-15-11-25t-25-11-25 11l-98 98-364-364q-5-6-13-6t-12 6l-64 64q-6 5-6 12t6 13l364 364-98 98q-11 11-11 25t11 25 25 11h285q15 0 25-11t11-25z" horiz-adv-x="1000" />
|
||||
|
||||
<glyph glyph-name="resize-full-alt" unicode="" d="M716 548l-198-198 198-198 80 80q17 18 39 8 22-9 22-33v-250q0-14-10-25t-26-11h-250q-23 0-32 23-10 21 7 38l81 81-198 198-198-198 80-81q17-17 8-38-10-23-33-23h-250q-15 0-25 11t-11 25v250q0 24 22 33 22 10 39-8l80-80 198 198-198 198-80-80q-11-11-25-11-7 0-14 3-22 9-22 33v250q0 14 11 25t25 11h250q23 0 33-23 9-21-8-38l-80-81 198-198 198 198-81 81q-17 17-7 38 9 23 32 23h250q15 0 26-11t10-25v-250q0-24-22-33-7-3-14-3-14 0-25 11z" horiz-adv-x="857.1" />
|
||||
|
||||
<glyph glyph-name="doc-text" unicode="" d="M819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 17-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 16t-16 37v233h-429v-858h715z m-572 483q0 7 5 12t13 5h393q8 0 13-5t5-12v-36q0-8-5-13t-13-5h-393q-8 0-13 5t-5 13v36z m411-125q8 0 13-5t5-13v-36q0-8-5-13t-13-5h-393q-8 0-13 5t-5 13v36q0 8 5 13t13 5h393z m0-143q8 0 13-5t5-13v-36q0-8-5-13t-13-5h-393q-8 0-13 5t-5 13v36q0 8 5 13t13 5h393z" horiz-adv-x="857.1" />
|
||||
|
||||
<glyph glyph-name="folder-empty" unicode="" d="M857 118v393q0 22-15 38t-38 15h-393q-23 0-38 16t-16 38v36q0 22-15 38t-38 15h-179q-22 0-38-15t-16-38v-536q0-22 16-38t38-16h679q22 0 38 16t15 38z m72 393v-393q0-51-37-88t-88-37h-679q-51 0-88 37t-37 88v536q0 51 37 88t88 37h179q51 0 88-37t37-88v-18h375q51 0 88-37t37-88z" horiz-adv-x="928.6" />
|
||||
|
||||
<glyph glyph-name="folder-open-empty" unicode="" d="M994 331q0 19-30 19h-607q-22 0-48-12t-39-29l-164-203q-11-13-11-22 0-20 30-20h607q23 0 48 13t40 29l164 203q10 12 10 22z m-637 90h429v90q0 22-16 38t-38 15h-321q-23 0-38 16t-16 38v36q0 22-15 38t-38 15h-179q-22 0-38-15t-16-38v-476l143 175q25 30 65 49t78 19z m708-90q0-35-25-67l-165-203q-24-30-65-49t-78-19h-607q-51 0-88 37t-37 88v536q0 51 37 88t88 37h179q51 0 88-37t37-88v-18h303q52 0 88-37t37-88v-90h107q30 0 56-13t37-40q8-17 8-37z" horiz-adv-x="1071.4" />
|
||||
</font>
|
||||
</defs>
|
||||
</svg>
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 4.7 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -9,7 +9,13 @@ a, a:link, a:visited, a:focus, a:hover, a:active, button, .button, input, .contr
|
||||
-ms-transition: all 0.2s ease;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.navi-item a, .navi-item.folder a i, .navi-item.file a i{
|
||||
-webkit-transition: all 0.1s ease;
|
||||
-moz-transition: all 0.1s ease;
|
||||
-o-transition: all 0.1s ease;
|
||||
-ms-transition: all 0.1s ease;
|
||||
transition: all 0.1s ease;
|
||||
}
|
||||
/********************
|
||||
* COMMONS *
|
||||
********************/
|
||||
@@ -153,7 +159,7 @@ aside.sidebar{
|
||||
}
|
||||
ul.menu-list{
|
||||
list-style: none;
|
||||
margin:5px 0 30px;
|
||||
margin: 5px 0 30px;
|
||||
padding:0;
|
||||
}
|
||||
li.menu-item{
|
||||
@@ -176,6 +182,75 @@ li.menu-item{
|
||||
background: #e0474c;
|
||||
}
|
||||
|
||||
/********************
|
||||
* CONTENT-NAVI *
|
||||
********************/
|
||||
.infoline{
|
||||
display: none;
|
||||
}
|
||||
.content-navi{
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
}
|
||||
.navi-list{
|
||||
padding: 0px;
|
||||
}
|
||||
.navi-item{
|
||||
list-style: none;
|
||||
padding: 0px;
|
||||
position: relative;
|
||||
}
|
||||
.navi-item i.icon-doc-text, .navi-item i.icon-folder-empty, .navi-item i.icon-home{
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
background: #fff;
|
||||
color: #ccc;
|
||||
padding: 7px 2px 7px;
|
||||
}
|
||||
.navi-item i.icon-resize-full-alt{
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 7px;
|
||||
color: #fff;
|
||||
}
|
||||
.navi-item a{
|
||||
display: block;
|
||||
padding: 7px 0;
|
||||
width: 100%;
|
||||
margin-bottom: 2px;
|
||||
box-shadow: 0 0 1px #ddd;
|
||||
text-decoration: none;
|
||||
color: #444;
|
||||
background: #fff;
|
||||
}
|
||||
.navi-item.folder a{
|
||||
font-weight: 700;
|
||||
}
|
||||
.navi-item.file a{
|
||||
font-weight: 300;
|
||||
}
|
||||
.navi-item a:hover, .navi-item a:hover i{
|
||||
background: #66b0a3;
|
||||
color: #f9f8f6;
|
||||
}
|
||||
.navi-item a.active, .navi-item a.active i{
|
||||
background: #e0474c;
|
||||
color: #f9f8f6;
|
||||
}
|
||||
[class^="level-"]{
|
||||
padding-left: 80px;
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
span.level-1{ padding-left: 30px; }
|
||||
span.level-2{ padding-left: 40px; }
|
||||
span.level-3{ padding-left: 50px; }
|
||||
span.level-4{ padding-left: 60px; }
|
||||
span.level-5{ padding-left: 70px; }
|
||||
|
||||
/********************
|
||||
* CONTENT *
|
||||
********************/
|
||||
@@ -275,6 +350,7 @@ h1 .version-number{
|
||||
}
|
||||
.modal.show{
|
||||
display: block;
|
||||
z-index: 99999;
|
||||
}
|
||||
.modalInner{
|
||||
position: relative;
|
||||
@@ -285,6 +361,12 @@ h1 .version-number{
|
||||
border-radius: 3px;
|
||||
box-shadow: 0px 0px 10px rgba(0,0,0,0.2);
|
||||
}
|
||||
.modalInner h2{
|
||||
margin-top: 0px;
|
||||
}
|
||||
.modalInner.wide{
|
||||
max-width: 500px;
|
||||
}
|
||||
.closeModal{
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
@@ -1055,8 +1137,6 @@ label .help, .label .help{
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/********************
|
||||
* EDITOR *
|
||||
********************/
|
||||
@@ -1138,7 +1218,6 @@ label .help, .label .help{
|
||||
color: #444;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.buttonset .secondary{
|
||||
display: inline-block;
|
||||
float: right;
|
||||
@@ -1206,10 +1285,13 @@ label .help, .label .help{
|
||||
.editor button{
|
||||
min-width: 150px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
}
|
||||
|
||||
/* load design editor button */
|
||||
.editor button.load:after,
|
||||
.editor button.success:after,
|
||||
.editor button.fail:after{
|
||||
.editor button.fail:after
|
||||
{
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 6px;
|
||||
@@ -1238,6 +1320,23 @@ label .help, .label .help{
|
||||
.editor button.fail:after{
|
||||
background: #e0474c;
|
||||
}
|
||||
|
||||
/* load design navi buttons */
|
||||
.navi-item.load:after
|
||||
{
|
||||
position: absolute;
|
||||
right: 6px;
|
||||
top: 6px;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
content: '';
|
||||
border: 8px solid #eee; /* background */
|
||||
border-top: 8px solid #ccc; /* moving border */
|
||||
background: #ccc; /* dot in the middle */
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
|
||||
.buttonset .secondary--block{
|
||||
display: inline-block;
|
||||
}
|
||||
@@ -1256,7 +1355,36 @@ label .help, .label .help{
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 800px) {
|
||||
@media only screen and (min-width: 900px) {
|
||||
.main{
|
||||
margin: 30px auto;
|
||||
padding: 20px 30px;
|
||||
}
|
||||
.infoline{
|
||||
min-height: 30px;
|
||||
width: 100%;
|
||||
display: block;
|
||||
color: #bbb;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
.infoline .help{
|
||||
float: right;
|
||||
text-align: center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
border-radius: 50%;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
span.level-1{ padding-left: 5px; }
|
||||
span.level-2{ padding-left: 20px; }
|
||||
span.level-3{ padding-left: 35px; }
|
||||
span.level-4{ padding-left: 50px; }
|
||||
span.level-5{ padding-left: 65px; }
|
||||
.navi-item i.icon-doc-text, .navi-item i.icon-folder-empty, .navi-item i.icon-home{
|
||||
left: -27px;
|
||||
}
|
||||
fieldset.plugin{
|
||||
width: 49.5%;
|
||||
}
|
||||
@@ -1268,15 +1396,9 @@ label .help, .label .help{
|
||||
width: 33.3%;
|
||||
display: inline-block;
|
||||
}
|
||||
.navi-items span{
|
||||
display: inline;
|
||||
}
|
||||
.header-navi ul{
|
||||
font-size: 1em;
|
||||
}
|
||||
.main{
|
||||
margin: 30px auto;
|
||||
}
|
||||
article{
|
||||
width: 80%;
|
||||
display: inline-block;
|
||||
@@ -1290,8 +1412,8 @@ label .help, .label .help{
|
||||
}
|
||||
.sidebar-menu, .sidebar-menu--content{
|
||||
max-height: 2000px;
|
||||
padding: 0px 20px 0 0;
|
||||
overflow: hidden;
|
||||
padding: 0 0 0 0;
|
||||
overflow: visible;
|
||||
box-sizing: border-box;
|
||||
font-size: 1em;
|
||||
text-align: left;
|
||||
@@ -1306,10 +1428,13 @@ label .help, .label .help{
|
||||
display: none;
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
}
|
||||
}
|
||||
ul.menu-list{
|
||||
margin: 5px 0 0 20px;
|
||||
}
|
||||
.navi-items span{
|
||||
display: inline;
|
||||
}
|
||||
.level-1 > ul.menu-list{
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
{% extends 'layouts/layoutContent.twig' %}
|
||||
{% extends 'layouts/layoutEditor.twig' %}
|
||||
{% block title %}Content{% endblock %}
|
||||
|
||||
{% block content %}
|
2
system/author/js/sortable.min.js
vendored
Normal file
2
system/author/js/sortable.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
let app = new Vue({
|
||||
let editor = new Vue({
|
||||
delimiters: ['${', '}'],
|
||||
el: '#editor',
|
||||
data: {
|
||||
@@ -8,7 +8,7 @@ let app = new Vue({
|
||||
content: this.title = document.getElementById("content").value,
|
||||
url: document.getElementById("path").value,
|
||||
csrf_name: document.getElementById("csrf_name").value,
|
||||
csrf_value: document.getElementById("csrf_value").value,
|
||||
csrf_value: document.getElementById("csrf_value").value,
|
||||
},
|
||||
errors:{
|
||||
title: false,
|
||||
@@ -171,4 +171,4 @@ let app = new Vue({
|
||||
this.modalWindow = "modal";
|
||||
},
|
||||
}
|
||||
})
|
||||
});
|
137
system/author/js/vue-navi.js
Normal file
137
system/author/js/vue-navi.js
Normal file
@@ -0,0 +1,137 @@
|
||||
const navcomponent = Vue.component('navigation', {
|
||||
template: '#navigation-template',
|
||||
props: ['name', 'parent', 'active', 'filetype', 'element', 'folder', 'level', 'url', 'root', 'freeze'],
|
||||
methods: {
|
||||
checkMove : function(evt)
|
||||
{
|
||||
if(evt.dragged.classList.contains('folder') && evt.from.parentNode.id != evt.to.parentNode.id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
onStart(evt)
|
||||
{
|
||||
/* delete error messages if exist */
|
||||
var errorMessages = document.getElementById("navi-errors");
|
||||
if(errorMessages)
|
||||
{
|
||||
errorMessages.parentNode.removeChild(errorMessages);
|
||||
}
|
||||
},
|
||||
onEnd(evt)
|
||||
{
|
||||
var locator = {
|
||||
'item_id': evt.item.id,
|
||||
'parent_id_from': evt.from.parentNode.id,
|
||||
'parent_id_to': evt.to.parentNode.id,
|
||||
'index_old': evt.oldIndex,
|
||||
'index_new': evt.newIndex,
|
||||
'active': evt.item.firstChild.className,
|
||||
'url': document.getElementById("path").value,
|
||||
'csrf_name': document.getElementById("csrf_name").value,
|
||||
'csrf_value': document.getElementById("csrf_value").value,
|
||||
};
|
||||
|
||||
if(locator.parent_id_from == locator.parent_id_to && locator.index_old == locator.index_new)
|
||||
{
|
||||
return
|
||||
}
|
||||
|
||||
evt.item.classList.add("load");
|
||||
|
||||
var self = this;
|
||||
|
||||
self.$root.$data.freeze = true;
|
||||
self.errors = {title: false, content: false, message: false};
|
||||
|
||||
var url = this.root + '/api/v1/article/sort';
|
||||
var method = 'POST';
|
||||
|
||||
sendJson(function(response, httpStatus)
|
||||
{
|
||||
if(response)
|
||||
{
|
||||
self.$root.$data.freeze = false;
|
||||
var result = JSON.parse(response);
|
||||
|
||||
if(result.errors)
|
||||
{
|
||||
var publishController = document.getElementById("publishController");
|
||||
var errorMessage = document.createElement("div");
|
||||
errorMessage.id = "navi-errors";
|
||||
errorMessage.className = "message error";
|
||||
errorMessage.innerHTML = result.errors;
|
||||
publishController.insertBefore(errorMessage, publishController.childNodes[0]);
|
||||
}
|
||||
if(result.url)
|
||||
{
|
||||
window.location.replace(result.url);
|
||||
}
|
||||
if(result.data)
|
||||
{
|
||||
evt.item.classList.remove("load");
|
||||
self.$root.$data.items = result.data;
|
||||
}
|
||||
}
|
||||
}, method, url, locator );
|
||||
},
|
||||
getUrl : function(root, url)
|
||||
{
|
||||
return root + '/tm/content' + url
|
||||
},
|
||||
getLevel : function(level)
|
||||
{
|
||||
level = level.toString();
|
||||
level = level.split('.').length;
|
||||
return 'level-' + level;
|
||||
},
|
||||
getIcon : function(filetype)
|
||||
{
|
||||
if(filetype == 'file')
|
||||
{
|
||||
return 'icon-doc-text'
|
||||
}
|
||||
if(filetype == 'folder')
|
||||
{
|
||||
return 'icon-folder-empty'
|
||||
}
|
||||
},
|
||||
checkActive : function(active,parent)
|
||||
{
|
||||
if(active && !parent)
|
||||
{
|
||||
return 'active';
|
||||
}
|
||||
return 'inactive';
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
let navi = new Vue({
|
||||
el: "#navi",
|
||||
components: {
|
||||
navcomponent
|
||||
},
|
||||
data: {
|
||||
title: "Navigation",
|
||||
items: JSON.parse(document.getElementById("data-navi").dataset.navi),
|
||||
root: document.getElementById("main").dataset.url,
|
||||
freeze: false,
|
||||
modalWindow: "modal hide",
|
||||
},
|
||||
methods:{
|
||||
onStart(evt){
|
||||
this.$refs.draggit[0].onStart(evt);
|
||||
},
|
||||
onEnd(evt){
|
||||
this.$refs.draggit[0].save(evt);
|
||||
},
|
||||
showModal: function(e){
|
||||
this.modalWindow = "modal show";
|
||||
},
|
||||
hideModal: function(e){
|
||||
this.modalWindow = "modal";
|
||||
},
|
||||
}
|
||||
})
|
1
system/author/js/vuedraggable.min.js
vendored
Normal file
1
system/author/js/vuedraggable.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -26,8 +26,8 @@
|
||||
</header>
|
||||
{% include 'partials/flash.twig' %}
|
||||
<div class="main" id="main" data-url="{{ base_url }}">
|
||||
<aside class="sidebar">
|
||||
{% include 'partials/contentNavi.twig' %}
|
||||
<aside class="sidebar">
|
||||
{% include 'partials/editorNavi.twig' %}
|
||||
</aside>
|
||||
<article>
|
||||
{% block content %}{% endblock %}
|
||||
@@ -36,7 +36,10 @@
|
||||
</div>
|
||||
<script src="{{ base_url }}/system/author/js/vue.min.js"></script>
|
||||
<script src="{{ base_url }}/system/author/js/autosize.min.js"></script>
|
||||
<script src="{{ base_url }}/system/author/js/sortable.min.js"></script>
|
||||
<script src="{{ base_url }}/system/author/js/vuedraggable.min.js"></script>
|
||||
<script src="{{ base_url }}/system/author/js/author.js?20180724"></script>
|
||||
<script src="{{ base_url }}/system/author/js/vue-editor.js?20180724"></script>
|
||||
<script src="{{ base_url }}/system/author/js/vue-navi.js"></script>
|
||||
</body>
|
||||
</html>
|
@@ -1,41 +0,0 @@
|
||||
{% macro loop_over(navigation, base_url) %}
|
||||
|
||||
{% import _self as macros %}
|
||||
|
||||
{% for element in navigation %}
|
||||
|
||||
{% set depth = element.keyPathArray|length %}
|
||||
|
||||
{% if element.activeParent %}
|
||||
<li class="menu-item {{ element.elementType }} level-{{ depth }} active parent">
|
||||
{% elseif element.active %}
|
||||
<li class="menu-item {{ element.elementType }} level-{{ depth }} active">
|
||||
{% else %}
|
||||
<li class="menu-item {{ element.elementType }} level-{{ depth }}">
|
||||
{% endif %}
|
||||
{% if element.activeParent %}
|
||||
<a class="parent active" href="{{base_url}}/tm/content{{ element.urlRelWoF }}">{{ element.name|title }}</a>
|
||||
{% elseif element.active %}
|
||||
<a class="active" href="{{base_url}}/tm/content{{ element.urlRelWoF }}">{{ element.name|title }}</a>
|
||||
{% else %}
|
||||
<a href="{{base_url}}/tm/content{{ element.urlRelWoF }}">{{ element.name|title }}</a>
|
||||
{% endif %}
|
||||
|
||||
{% if (element.elementType == 'folder') %}
|
||||
<ul class="menu-list">
|
||||
{{ macros.loop_over(element.folderContent, base_url) }}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
|
||||
{% import _self as macros %}
|
||||
|
||||
<nav id="sidebar-menu" class="sidebar-menu--content">
|
||||
<div id="mobile-menu" class="menu-action">Menu <span class="button-arrow"></span></div>
|
||||
<ul class="menu-list">
|
||||
<li class="menu-item folder level-0"><a {% if current_url == 'tm/content' %}class="active"{% endif %} href="{{base_url}}/tm/content">Startpage</a></li>
|
||||
{{ macros.loop_over(navigation, base_url) }}
|
||||
</ul>
|
||||
</nav>
|
42
system/author/partials/editorNavi.twig
Normal file
42
system/author/partials/editorNavi.twig
Normal file
@@ -0,0 +1,42 @@
|
||||
<nav id="sidebar-menu" class="sidebar-menu--content">
|
||||
<div id="data-navi" data-navi='{{ navigation|json_encode() }}'></div>
|
||||
<div id="mobile-menu" class="menu-action">Menu <span class="button-arrow"></span></div>
|
||||
<div id="navi" class="content-navi" v-model="freeze" v-cloak>
|
||||
<div class="infoline">Reorder navi with drag&drop<div class="help" @click="showModal">?</div></div>
|
||||
<div class="navi-list">
|
||||
<div class="navi-item folder">
|
||||
<a href="{{ base_url }}/tm/content"><i class="icon-home"></i><span class="level-1">Homepage</span></a>
|
||||
</div>
|
||||
</div>
|
||||
<draggable :element="'ul'" class="navi-list" :list="items" @start="onStart" @start="onEnd" :options="{group:{ name:'folder'}, animation: 150, 'disabled': freeze }">
|
||||
<navigation ref="draggit" v-for="item in items" :freeze="freeze" :name="item.name" :active="item.active" :parent="item.activeParent" :level="item.keyPath" :root="root" :url="item.urlRelWoF" v-bind:id="item.keyPath" :key="item.keyPath" :filetype="item.elementType" :folder="item.folderContent"></navigation>
|
||||
</draggable>
|
||||
|
||||
<div id="modalWindow" :class="modalWindow">
|
||||
<div class="modalInner wide">
|
||||
<div @click="hideModal" id="closeModal" class="closeModal">X</div>
|
||||
<h2>Reorder The Navigation</h2>
|
||||
<p>You can reorder the navigation with simple drag&drop. However, there are some rules and limitations:</p>
|
||||
<ul>
|
||||
<li>You can move <strong>files</strong> to any other <strong>folder</strong>.</li>
|
||||
<li>Only <strong>folders</strong> are allowed at the <strong>first level</strong>.</li>
|
||||
<li><strong>Folders</strong> can be reordered within the <strong>same level</strong>.</li>
|
||||
<li>But a <strong>folder</strong> can not be moved to another folder or <strong>another level</strong>.</li>
|
||||
</ul>
|
||||
<p>Here is the reason for the last restriction: If you move a folder to another folder, then the adress (url) will change for the whole folder and all its content (pages). It is a nightmare for your readers and for google.</p>
|
||||
<p>If you really want to move the whole folder content, then create a new folder in the desired place and move all files manually to the new folder.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{% verbatim %}
|
||||
<template id="navigation-template">
|
||||
<li class="navi-item" :class="filetype"><a v-bind:href="getUrl(root, url)" :class="checkActive(active,parent)"><i :class="getIcon(filetype)"></i><span :class="getLevel(level)">{{ name }}</span><i class="icon-resize-full-alt"></i></a>
|
||||
<draggable v-if="folder" :element="'ul'" class="navi-list" :list="folder" :move="checkMove" @start="onStart" @end="onEnd" :options="{group:{ name:'file'}, animation: 150, 'disabled': freeze }">
|
||||
<navigation ref="draggit" v-for="item in folder" :freeze="freeze" :name="item.name" :active="item.active" :parent="item.activeParent" :level="item.keyPath" :url="item.urlRelWoF" :root="root" v-bind:id="item.keyPath" :key="item.keyPath" :filetype="item.elementType" :folder="item.folderContent"></navigation>
|
||||
</draggable>
|
||||
<!-- <div v-if="folder">+ add</div> -->
|
||||
</li>
|
||||
</template>
|
||||
{% endverbatim %}
|
@@ -3,11 +3,11 @@
|
||||
<a href="{{ path_for('content.show') }}">Typemill</a>
|
||||
</div>
|
||||
<ul class="navi-items">
|
||||
<li><a href="{{ path_for('content.show') }}"{{ navigation ? 'class="active"' : '' }}><i class="icon-doc-text"></i><span class="nav-label"> Content</span></a></li><li>
|
||||
<li><a href="{{ path_for('content.show') }}"{{ navigation ? ' class="active"' : '' }}><i class="icon-doc-text"></i><span class="nav-label"> Content</span></a></li><li>
|
||||
{% if is_role('administrator') %}
|
||||
<a href="{{ path_for('settings.show') }}"{{ users ? 'class="active"' : '' }}><i class="icon-cog"></i><span class="nav-label"> Settings</span></a></li><li>
|
||||
<a href="{{ path_for('settings.show') }}"{{ users ? ' class="active"' : '' }}><i class="icon-cog"></i><span class="nav-label"> Settings</span></a></li><li>
|
||||
{% else %}
|
||||
<a href="{{ path_for('user.show', {'username' : get_username() }) }}"{{ users ? 'class="active"' : '' }}><i class="icon-cog"></i><span class="nav-label"> Account</span></a></li><li>
|
||||
<a href="{{ path_for('user.show', {'username' : get_username() }) }}"{{ users ? ' class="active"' : '' }}><i class="icon-cog"></i><span class="nav-label"> Account</span></a></li><li>
|
||||
{% endif %}
|
||||
<a href="{{ base_url }}"><i class="icon-link-ext"></i><span class="nav-label"> View Site</span></a></li><li>
|
||||
<a href="{{ path_for('auth.logout') }}"><i class="icon-off"></i><span class="nav-label"> Logout</span></a></li>
|
||||
|
Reference in New Issue
Block a user