Skip to content

Commit

Permalink
Editor: Add default JS markdown editor.
Browse files Browse the repository at this point in the history
  • Loading branch information
janbarasek committed Sep 16, 2021
1 parent a6b2926 commit b6f3108
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 4 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"baraja-core/path-resolvers": "^1.0",
"baraja-core/phone-number": "^1.0",
"baraja-core/network": "^1.0",
"baraja-core/markdown-latte-filter": "^3.0",
"nette/di": "^3.0",
"latte/latte": "^2.5",
"nette/security": "^3.1",
Expand Down
12 changes: 12 additions & 0 deletions src/Api/CmsEndpoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Baraja\Cms\User\Entity\UserResetPasswordRequest;
use Baraja\Cms\User\UserManager;
use Baraja\Doctrine\EntityManager;
use Baraja\Markdown\CommonMarkRenderer;
use Baraja\StructuredApi\Attributes\PublicEndpoint;
use Baraja\StructuredApi\BaseEndpoint;
use Baraja\Url\Url;
Expand All @@ -34,6 +35,7 @@ public function __construct(
private Settings $settings,
private EntityManager $entityManager,
private ContextAccessor $contextAccessor,
private CommonMarkRenderer $commonMarkRenderer,
) {
}

Expand Down Expand Up @@ -259,4 +261,14 @@ public function postSetUserPassword(string $locale, int $userId, string $passwor
$this->entityManager->flush();
$this->sendOk();
}


public function postRenderEditorPreview(string $haystack): void
{
$this->sendJson(
[
'html' => $this->commonMarkRenderer->render($haystack),
]
);
}
}
4 changes: 4 additions & 0 deletions src/CmsExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Baraja\Cms\Plugin\ErrorPlugin;
use Baraja\Cms\Plugin\HomepagePlugin;
use Baraja\Cms\Plugin\UserPlugin;
use Baraja\Cms\Proxy\GlobalAsset\CmsEditorAsset;
use Baraja\Cms\Proxy\GlobalAsset\CmsSimpleStaticAsset;
use Baraja\Cms\Proxy\GlobalAsset\CustomGlobalAssetManager;
use Baraja\Cms\Proxy\GlobalAsset\CustomGlobalAssetManagerAccessor;
Expand Down Expand Up @@ -343,5 +344,8 @@ private function registerGlobalAssets(ServiceDefinition $globalAssetManager, arr
$url,
]);
}
$globalAssetManager->addSetup('?->addAsset(new ' . CmsEditorAsset::class . ')', [
'@self',
]);
}
}
22 changes: 22 additions & 0 deletions src/Proxy/GlobalAsset/CmsEditorAsset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Baraja\Cms\Proxy\GlobalAsset;


use Baraja\Cms\Proxy\Proxy;

final class CmsEditorAsset implements CmsAsset
{
public function getFormat(): string
{
return 'js';
}


public function getUrl(): string
{
return Proxy::getUrl('cms-editor.js');
}
}
10 changes: 6 additions & 4 deletions template/@layout.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,23 @@ namespace Baraja\Cms;


use Baraja\Cms\Proxy\GlobalAsset\CmsAsset;
use Baraja\Cms\Proxy\Proxy;

/**
* @var string $basePath
* @var CmsAsset[] $staticAssets
* @var mixed[] $globalSettings
* @var string|null $title
* @var string $content
* @var string $locale
* @var mixed[] $menu
* @var bool $isDebug
* @var array<string, mixed> $settings
*/

?>
<!DOCTYPE html>
<html lang="cs">
<html lang="<?= Helpers::escapeHtmlAttr($locale) ?>">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
Expand All @@ -30,13 +32,13 @@ use Baraja\Cms\Proxy\GlobalAsset\CmsAsset;
<title><?= $title ? htmlspecialchars((string) $title) . ' | ' : '' ?>Admin</title>
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap@4.6.0/dist/css/bootstrap.min.css">
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue@2.21.2/dist/bootstrap-vue.min.css">
<link type="text/css" rel="stylesheet" href="<?= Helpers::escapeHtmlAttr($basePath . '/admin/assets/core.css') ?>">
<link type="text/css" rel="stylesheet" href="<?= Helpers::escapeHtmlAttr(Proxy::getUrl('core.css')) ?>">
<?php
if (($settings['user']['theme'] ?? '') !== '' && ($settings['user']['theme'] ?? '') !== 'light') {
echo '<link type="text/css" rel="stylesheet" href="' . Helpers::escapeHtmlAttr($basePath . '/admin/assets/core-' . $settings['user']['theme']. '.css') . '">';
echo '<link type="text/css" rel="stylesheet" href="' . Helpers::escapeHtmlAttr(Proxy::getUrl('core-' . $settings['user']['theme'] . '.css')) . '">';
}
?>
<link rel="shortcut icon" type="image/x-icon" href="<?= Helpers::escapeHtmlAttr($basePath . '/admin/assets/favicon.ico') ?>">
<link rel="shortcut icon" type="image/x-icon" href="<?= Helpers::escapeHtmlAttr(Proxy::getUrl('favicon.ico')) ?>">
<div id="app-header"></div>
<?php
foreach ($staticAssets as $staticAsset) {
Expand Down
85 changes: 85 additions & 0 deletions template/assets/cms-editor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
Vue.component('cms-editor', {
model: {
prop: 'value',
},
props: ['value', 'rows', 'label'],
template: `<div>
<label :for="labelId">{{ label }}</label>
<b-card no-body>
<b-tabs card>
<b-tab title="Editor" lazy active class="p-0">
<textarea v-model="content" :id="labelId" class="form-control" :rows="rows ? rows : 5" style="border:0 !important"></textarea>
</b-tab>
<b-tab title="Preview" lazy @click="renderPreview" class="p-0">
<div v-if="!content" class="p-3"><i>Empty preview.</i></div>
<div v-else class="p-3">
<div v-if="isLoading" class="text-center my-5"><b-spinner></b-spinner></div>
<div v-else v-html="preview"></div>
</div>
</b-tab>
</b-tabs>
</b-card>
<div class="card" style="border-bottom:0 !important">
<div class="card-header px-2 py-1">
<a href="https://brj.cz/markdown" target="_blank">
<svg aria-hidden="true" width="16" height="16" viewBox="0 0 16 16" version="1.1">
<path fill-rule="evenodd" d="M14.85 3H1.15C.52 3 0 3.52 0 4.15v7.69C0 12.48.52 13 1.15 13h13.69c.64 0 1.15-.52 1.15-1.15v-7.7C16 3.52 15.48 3 14.85 3zM9 11H7V8L5.5 9.92 4 8v3H2V5h2l1.5 2L7 5h2v6zm2.99.5L9.5 8H11V5h2v3h1.5l-2.51 3.5z"></path>
</svg>
Styling with Markdown is supported
</a>
</div>
</div>
</div>`,
data() {
return {
hash: '',
preview: '',
isLoading: false
};
},
mounted() {
this.hash = this.computeHash(this.label);
},
computed: {
labelId: function () {
return 'cme-editor--' + this.hash;
},
content: {
get() {
return this.value;
},
set(val) {
this.$emit('input', val);
}
}
},
methods: {
computeHash(haystack) {
let hash = 0, i, chr;
if (haystack.length === 0) return hash;
for (i = 0; i < haystack.length; i++) {
chr = haystack.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0;
}
return hash;
},
renderPreview() {
if (!this.content) {
return;
}
this.isLoading = true;
fetch(baseApiPath + '/cms/render-editor-preview', {
method: 'POST',
body: JSON.stringify({
haystack: this.content
})
})
.then(data => data.json())
.then(data => {
this.isLoading = false;
this.preview = data.html;
});
}
}
});

0 comments on commit b6f3108

Please sign in to comment.