From 105680b1bc24ae2b8d243e0ae05f5f681dde9dde Mon Sep 17 00:00:00 2001 From: trendschau Date: Tue, 21 Dec 2021 23:19:51 +0100 Subject: [PATCH] Version 1.5.2: Shortcode component for visual editor --- data/ebookproducts/ebookproducts.yaml | 22 +++ .../Controllers/ControllerAuthorBlockApi.php | 24 ++++ system/Routes/Api.php | 1 + system/Settings.php | 2 +- system/author/js/vue-blox-config.js | 8 ++ system/author/js/vue-blox.js | 126 ++++++++++++++++++ system/author/partials/symbols.twig | 5 +- 7 files changed, 186 insertions(+), 2 deletions(-) create mode 100644 data/ebookproducts/ebookproducts.yaml diff --git a/data/ebookproducts/ebookproducts.yaml b/data/ebookproducts/ebookproducts.yaml new file mode 100644 index 0000000..9e11745 --- /dev/null +++ b/data/ebookproducts/ebookproducts.yaml @@ -0,0 +1,22 @@ +flatfilecms: + title: 'Flat File CMS for simple projects' + cover: media/live/cover-report.png + description: 'Another publication from cmsstash that will uncover the secrets of database-less web publishing. Read about all flat file cms and make an informed choice.' + downloadlabel: '' + downloadurl: '' + firstbuttonlabel: '' + firstbuttonurl: '' + secondbuttonlabel: '' + secondbuttonurl: '' + downloadlabel1: 'Download now' + downloadlabel2: 'Buy on amazon' +enterprisecms: + title: 'Das CMS Drupal: Open Source für Enterprise' + cover: '' + description: '' + downloadlabel: '' + downloadurl: '' + firstbuttonlabel: '' + firstbuttonurl: '' + secondbuttonlabel: '' + secondbuttonurl: '' diff --git a/system/Controllers/ControllerAuthorBlockApi.php b/system/Controllers/ControllerAuthorBlockApi.php index 8ce7faf..35665b4 100644 --- a/system/Controllers/ControllerAuthorBlockApi.php +++ b/system/Controllers/ControllerAuthorBlockApi.php @@ -5,6 +5,7 @@ namespace Typemill\Controllers; use Slim\Http\Request; use Slim\Http\Response; use Typemill\Extensions\ParsedownExtension; +use Typemill\Events\OnShortcodeFound; class ControllerAuthorBlockApi extends ControllerAuthor { @@ -570,4 +571,27 @@ class ControllerAuthorBlockApi extends ControllerAuthor return $response->withJson(array('markdown' => $pageMarkdown, 'toc' => $toc, 'errors' => $errors)); } + + public function getShortcodeData(Request $request, Response $response, $args) + { + /* get params from call */ + $this->params = $request->getParams(); + $this->uri = $request->getUri()->withUserInfo(''); + $errors = false; + + # minimum permission is that user is allowed to update his own content + if(!$this->c->acl->isAllowed($_SESSION['role'], 'mycontent', 'update')) + { + return $response->withJson(array('data' => false, 'errors' => ['message' => 'You are not allowed to delete this content.']), 403); + } + + $shortcodeData = $this->c->dispatcher->dispatch('onShortcodeFound', new OnShortcodeFound(['name' => 'registershortcode', 'data' => []]))->getData(); + + if(empty($shortcodeData['data'])) + { + return $response->withJson(array('shortcodedata' => false)); + } + + return $response->withJson(array('shortcodedata' => $shortcodeData['data'])); + } } \ No newline at end of file diff --git a/system/Routes/Api.php b/system/Routes/Api.php index 7630251..7e08480 100644 --- a/system/Routes/Api.php +++ b/system/Routes/Api.php @@ -36,6 +36,7 @@ $app->post('/api/v1/block', ControllerAuthorBlockApi::class . ':addBlock')->setN $app->put('/api/v1/block', ControllerAuthorBlockApi::class . ':updateBlock')->setName('api.block.update')->add(new RestrictApiAccess($container['router'])); $app->delete('/api/v1/block', ControllerAuthorBlockApi::class . ':deleteBlock')->setName('api.block.delete')->add(new RestrictApiAccess($container['router'])); $app->put('/api/v1/moveblock', ControllerAuthorBlockApi::class . ':moveBlock')->setName('api.block.move')->add(new RestrictApiAccess($container['router'])); +$app->get('/api/v1/shortcodedata', ControllerAuthorBlockApi::class . ':getShortcodeData')->setName('api.shortcodedata.get')->add(new RestrictApiAccess($container['router'])); $app->post('/api/v1/video', ControllerAuthorMediaApi::class . ':saveVideoImage')->setName('api.video.save')->add(new RestrictApiAccess($container['router'])); $app->get('/api/v1/medialib/images', ControllerAuthorMediaApi::class . ':getMediaLibImages')->setName('api.medialibimg.get')->add(new RestrictApiAccess($container['router'])); diff --git a/system/Settings.php b/system/Settings.php index 22eaa1d..1170e8b 100644 --- a/system/Settings.php +++ b/system/Settings.php @@ -82,7 +82,7 @@ class Settings 'userPath' => $rootPath . 'settings' . DIRECTORY_SEPARATOR . 'users', 'authorPath' => __DIR__ . DIRECTORY_SEPARATOR . 'author' . DIRECTORY_SEPARATOR, 'editor' => 'visual', - 'formats' => ['markdown', 'headline', 'ulist', 'olist', 'table', 'quote', 'notice', 'image', 'video', 'file', 'toc', 'hr', 'definition', 'code'], + 'formats' => ['markdown', 'headline', 'ulist', 'olist', 'table', 'quote', 'notice', 'image', 'video', 'file', 'toc', 'hr', 'definition', 'code', 'shortcode'], 'contentFolder' => 'content', 'version' => '1.5.1.1', 'setup' => true, diff --git a/system/author/js/vue-blox-config.js b/system/author/js/vue-blox-config.js index 3fcd1cf..79ea7c0 100644 --- a/system/author/js/vue-blox-config.js +++ b/system/author/js/vue-blox-config.js @@ -63,6 +63,13 @@ let determiner = { } return false; }, + shortcode: function(block,lines,firstChar,secondChar,thirdChar){ + if( firstChar == '[' && secondChar == ':') + { + return "shortcode-component"; + } + return false; + }, notice: function(block,lines,firstChar,secondChar,thirdChar){ if( firstChar == '!' && ( secondChar == '!' || secondChar == ' ') ) { @@ -94,4 +101,5 @@ let bloxFormats = { hr: { label: '', title: 'Horizontal Line', component: 'hr-component' }, definition: { label: '', title: 'Definition List', component: 'definition-component' }, code: { label: '', title: 'Code', component: 'code-component' }, + shortcode: { label: '', title: 'Shortcode', component: 'shortcode-component' }, }; \ No newline at end of file diff --git a/system/author/js/vue-blox.js b/system/author/js/vue-blox.js index 84def27..6c97327 100644 --- a/system/author/js/vue-blox.js +++ b/system/author/js/vue-blox.js @@ -781,6 +781,132 @@ const codeComponent = Vue.component('code-component', { }, }) +const shortcodeComponent = Vue.component('shortcode-component', { + props: ['compmarkdown', 'disabled'], + data: function(){ + return { + shortcodedata: false, + shortcodename: '', + markdown: '', + searchresults: [], + } + }, + template: '
' + + '
' + + '
' + + '' + + '' + + '
' + + '' + + '' + + '
' + + '
' + + '{{item}}' + + '
' + + '
' + + '
' + + '' + + '
', + mounted: function(){ + + var myself = this; + + myaxios.get('/api/v1/shortcodedata',{ + params: { + 'url': document.getElementById("path").value, + 'csrf_name': document.getElementById("csrf_name").value, + 'csrf_value': document.getElementById("csrf_value").value, + } + }) + .then(function (response) { + if(response.data.shortcodedata !== false) + { + myself.shortcodedata = response.data.shortcodedata; + myself.parseshortcode(); + } + }) + .catch(function (error) + { + if(error.response) + { + + } + }); + }, + methods: { + parseshortcode: function() + { + if(this.compmarkdown) + { + var shortcodestring = this.compmarkdown.trim(); + shortcodestring = shortcodestring.slice(2,-2); + this.shortcodename = shortcodestring.substr(0,shortcodestring.indexOf(' ')); + + var regexp = /(\w+)\s*=\s*("[^"]*"|\'[^\']*\'|[^"\'\\s>]*)/g; + var matches = shortcodestring.matchAll(regexp); + matches = Array.from(matches); + matchlength = matches.length; + + if(matchlength > 0) + { + for(var i=0;i -1 && searchitems[item] !== searchterm) + { + this.searchresults.push(searchitems[item]); + if(this.searchresults.length > 4){ break; } + } + } + } + + /* markdown */ + var attributes = ''; + for (var attribute in this.shortcodedata[shortcodename]) + { + if(this.shortcodedata[shortcodename].hasOwnProperty(attribute)) + { + attributes += ' ' + attribute + '="' + this.shortcodedata[shortcodename][attribute].value + '"'; + } + } + + this.markdown = '[:' + shortcodename + attributes + ' :]'; + + this.$emit('updatedMarkdown', this.markdown); + }, + selectsearch: function(item,attribute) + { + /* check if still reactive */ + this.shortcodedata[this.shortcodename][attribute].value = item; + this.createmarkdown(this.shortcodename,attribute); + }, + updatemarkdown: function(event) + { + this.$emit('updatedMarkdown', event.target.value); + }, + }, +}) + const quoteComponent = Vue.component('quote-component', { props: ['compmarkdown', 'disabled'], template: '
' + diff --git a/system/author/partials/symbols.twig b/system/author/partials/symbols.twig index 746761b..0b5d0c6 100644 --- a/system/author/partials/symbols.twig +++ b/system/author/partials/symbols.twig @@ -174,6 +174,9 @@ + + + {{ assets.renderSvg() }} - +