Showing
15 changed files
with
210 additions
and
23 deletions
| ... | @@ -164,6 +164,7 @@ class PageController extends Controller | ... | @@ -164,6 +164,7 @@ class PageController extends Controller |
| 164 | $draft = $this->pageRepo->getUserPageDraft($page, $this->currentUser->id); | 164 | $draft = $this->pageRepo->getUserPageDraft($page, $this->currentUser->id); |
| 165 | $page->name = $draft->name; | 165 | $page->name = $draft->name; |
| 166 | $page->html = $draft->html; | 166 | $page->html = $draft->html; |
| 167 | + $page->markdown = $draft->markdown; | ||
| 167 | $page->isDraft = true; | 168 | $page->isDraft = true; |
| 168 | $warnings [] = $this->pageRepo->getUserPageDraftMessage($draft); | 169 | $warnings [] = $this->pageRepo->getUserPageDraftMessage($draft); |
| 169 | } | 170 | } |
| ... | @@ -204,9 +205,9 @@ class PageController extends Controller | ... | @@ -204,9 +205,9 @@ class PageController extends Controller |
| 204 | $page = $this->pageRepo->getById($pageId, true); | 205 | $page = $this->pageRepo->getById($pageId, true); |
| 205 | $this->checkOwnablePermission('page-update', $page); | 206 | $this->checkOwnablePermission('page-update', $page); |
| 206 | if ($page->draft) { | 207 | if ($page->draft) { |
| 207 | - $draft = $this->pageRepo->updateDraftPage($page, $request->only(['name', 'html'])); | 208 | + $draft = $this->pageRepo->updateDraftPage($page, $request->only(['name', 'html', 'markdown'])); |
| 208 | } else { | 209 | } else { |
| 209 | - $draft = $this->pageRepo->saveUpdateDraft($page, $request->only(['name', 'html'])); | 210 | + $draft = $this->pageRepo->saveUpdateDraft($page, $request->only(['name', 'html', 'markdown'])); |
| 210 | } | 211 | } |
| 211 | $updateTime = $draft->updated_at->format('H:i'); | 212 | $updateTime = $draft->updated_at->format('H:i'); |
| 212 | return response()->json(['status' => 'success', 'message' => 'Draft saved at ' . $updateTime]); | 213 | return response()->json(['status' => 'success', 'message' => 'Draft saved at ' . $updateTime]); | ... | ... |
| ... | @@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model; | ... | @@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model; |
| 6 | 6 | ||
| 7 | class Page extends Entity | 7 | class Page extends Entity |
| 8 | { | 8 | { |
| 9 | - protected $fillable = ['name', 'html', 'priority']; | 9 | + protected $fillable = ['name', 'html', 'priority', 'markdown']; |
| 10 | 10 | ||
| 11 | protected $simpleAttributes = ['name', 'id', 'slug']; | 11 | protected $simpleAttributes = ['name', 'id', 'slug']; |
| 12 | 12 | ... | ... |
| ... | @@ -4,7 +4,7 @@ use Illuminate\Database\Eloquent\Model; | ... | @@ -4,7 +4,7 @@ use Illuminate\Database\Eloquent\Model; |
| 4 | 4 | ||
| 5 | class PageRevision extends Model | 5 | class PageRevision extends Model |
| 6 | { | 6 | { |
| 7 | - protected $fillable = ['name', 'html', 'text']; | 7 | + protected $fillable = ['name', 'html', 'text', 'markdown']; |
| 8 | 8 | ||
| 9 | /** | 9 | /** |
| 10 | * Get the user that created the page revision | 10 | * Get the user that created the page revision | ... | ... |
| ... | @@ -5,6 +5,8 @@ return [ | ... | @@ -5,6 +5,8 @@ return [ |
| 5 | 5 | ||
| 6 | 'env' => env('APP_ENV', 'production'), | 6 | 'env' => env('APP_ENV', 'production'), |
| 7 | 7 | ||
| 8 | + 'editor' => env('APP_EDITOR', 'html'), | ||
| 9 | + | ||
| 8 | /* | 10 | /* |
| 9 | |-------------------------------------------------------------------------- | 11 | |-------------------------------------------------------------------------- |
| 10 | | Application Debug Mode | 12 | | Application Debug Mode | ... | ... |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use Illuminate\Database\Schema\Blueprint; | ||
| 4 | +use Illuminate\Database\Migrations\Migration; | ||
| 5 | + | ||
| 6 | +class AddMarkdownSupport extends Migration | ||
| 7 | +{ | ||
| 8 | + /** | ||
| 9 | + * Run the migrations. | ||
| 10 | + * | ||
| 11 | + * @return void | ||
| 12 | + */ | ||
| 13 | + public function up() | ||
| 14 | + { | ||
| 15 | + Schema::table('pages', function (Blueprint $table) { | ||
| 16 | + $table->longText('markdown'); | ||
| 17 | + }); | ||
| 18 | + | ||
| 19 | + Schema::table('page_revisions', function (Blueprint $table) { | ||
| 20 | + $table->longText('markdown'); | ||
| 21 | + }); | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + /** | ||
| 25 | + * Reverse the migrations. | ||
| 26 | + * | ||
| 27 | + * @return void | ||
| 28 | + */ | ||
| 29 | + public function down() | ||
| 30 | + { | ||
| 31 | + Schema::table('pages', function (Blueprint $table) { | ||
| 32 | + $table->dropColumn('markdown'); | ||
| 33 | + }); | ||
| 34 | + | ||
| 35 | + Schema::table('page_revisions', function (Blueprint $table) { | ||
| 36 | + $table->dropColumn('markdown'); | ||
| 37 | + }); | ||
| 38 | + } | ||
| 39 | +} |
| ... | @@ -12,6 +12,7 @@ | ... | @@ -12,6 +12,7 @@ |
| 12 | "bootstrap-sass": "^3.0.0", | 12 | "bootstrap-sass": "^3.0.0", |
| 13 | "dropzone": "^4.0.1", | 13 | "dropzone": "^4.0.1", |
| 14 | "laravel-elixir": "^3.4.0", | 14 | "laravel-elixir": "^3.4.0", |
| 15 | + "marked": "^0.3.5", | ||
| 15 | "zeroclipboard": "^2.2.0" | 16 | "zeroclipboard": "^2.2.0" |
| 16 | } | 17 | } |
| 17 | } | 18 | } | ... | ... |
No preview for this file type
No preview for this file type
| ... | @@ -176,3 +176,4 @@ These are the great projects used to help build BookStack: | ... | @@ -176,3 +176,4 @@ These are the great projects used to help build BookStack: |
| 176 | * [Dropzone.js](http://www.dropzonejs.com/) | 176 | * [Dropzone.js](http://www.dropzonejs.com/) |
| 177 | * [ZeroClipboard](http://zeroclipboard.org/) | 177 | * [ZeroClipboard](http://zeroclipboard.org/) |
| 178 | * [TinyColorPicker](http://www.dematte.at/tinyColorPicker/index.html) | 178 | * [TinyColorPicker](http://www.dematte.at/tinyColorPicker/index.html) |
| 179 | +* [Marked](https://github.com/chjj/marked) | ... | ... |
| ... | @@ -216,16 +216,20 @@ module.exports = function (ngApp, events) { | ... | @@ -216,16 +216,20 @@ module.exports = function (ngApp, events) { |
| 216 | }]); | 216 | }]); |
| 217 | 217 | ||
| 218 | 218 | ||
| 219 | - ngApp.controller('PageEditController', ['$scope', '$http', '$attrs', '$interval', '$timeout', function ($scope, $http, $attrs, $interval, $timeout) { | 219 | + ngApp.controller('PageEditController', ['$scope', '$http', '$attrs', '$interval', '$timeout', '$sce', |
| 220 | + function ($scope, $http, $attrs, $interval, $timeout, $sce) { | ||
| 220 | 221 | ||
| 221 | $scope.editorOptions = require('./pages/page-form'); | 222 | $scope.editorOptions = require('./pages/page-form'); |
| 222 | - $scope.editorHtml = ''; | 223 | + $scope.editContent = ''; |
| 223 | $scope.draftText = ''; | 224 | $scope.draftText = ''; |
| 224 | var pageId = Number($attrs.pageId); | 225 | var pageId = Number($attrs.pageId); |
| 225 | var isEdit = pageId !== 0; | 226 | var isEdit = pageId !== 0; |
| 226 | var autosaveFrequency = 30; // AutoSave interval in seconds. | 227 | var autosaveFrequency = 30; // AutoSave interval in seconds. |
| 228 | + var isMarkdown = $attrs.editorType === 'markdown'; | ||
| 227 | $scope.isUpdateDraft = Number($attrs.pageUpdateDraft) === 1; | 229 | $scope.isUpdateDraft = Number($attrs.pageUpdateDraft) === 1; |
| 228 | $scope.isNewPageDraft = Number($attrs.pageNewDraft) === 1; | 230 | $scope.isNewPageDraft = Number($attrs.pageNewDraft) === 1; |
| 231 | + | ||
| 232 | + // Set inital header draft text | ||
| 229 | if ($scope.isUpdateDraft || $scope.isNewPageDraft) { | 233 | if ($scope.isUpdateDraft || $scope.isNewPageDraft) { |
| 230 | $scope.draftText = 'Editing Draft' | 234 | $scope.draftText = 'Editing Draft' |
| 231 | } else { | 235 | } else { |
| ... | @@ -245,7 +249,14 @@ module.exports = function (ngApp, events) { | ... | @@ -245,7 +249,14 @@ module.exports = function (ngApp, events) { |
| 245 | }, 1000); | 249 | }, 1000); |
| 246 | } | 250 | } |
| 247 | 251 | ||
| 248 | - $scope.editorChange = function () {} | 252 | + // Actions specifically for the markdown editor |
| 253 | + if (isMarkdown) { | ||
| 254 | + $scope.displayContent = ''; | ||
| 255 | + // Editor change event | ||
| 256 | + $scope.editorChange = function (content) { | ||
| 257 | + $scope.displayContent = $sce.trustAsHtml(content); | ||
| 258 | + } | ||
| 259 | + } | ||
| 249 | 260 | ||
| 250 | /** | 261 | /** |
| 251 | * Start the AutoSave loop, Checks for content change | 262 | * Start the AutoSave loop, Checks for content change |
| ... | @@ -253,17 +264,18 @@ module.exports = function (ngApp, events) { | ... | @@ -253,17 +264,18 @@ module.exports = function (ngApp, events) { |
| 253 | */ | 264 | */ |
| 254 | function startAutoSave() { | 265 | function startAutoSave() { |
| 255 | currentContent.title = $('#name').val(); | 266 | currentContent.title = $('#name').val(); |
| 256 | - currentContent.html = $scope.editorHtml; | 267 | + currentContent.html = $scope.editContent; |
| 257 | 268 | ||
| 258 | autoSave = $interval(() => { | 269 | autoSave = $interval(() => { |
| 259 | var newTitle = $('#name').val(); | 270 | var newTitle = $('#name').val(); |
| 260 | - var newHtml = $scope.editorHtml; | 271 | + var newHtml = $scope.editContent; |
| 261 | 272 | ||
| 262 | if (newTitle !== currentContent.title || newHtml !== currentContent.html) { | 273 | if (newTitle !== currentContent.title || newHtml !== currentContent.html) { |
| 263 | currentContent.html = newHtml; | 274 | currentContent.html = newHtml; |
| 264 | currentContent.title = newTitle; | 275 | currentContent.title = newTitle; |
| 265 | - saveDraft(newTitle, newHtml); | 276 | + saveDraft(); |
| 266 | } | 277 | } |
| 278 | + | ||
| 267 | }, 1000 * autosaveFrequency); | 279 | }, 1000 * autosaveFrequency); |
| 268 | } | 280 | } |
| 269 | 281 | ||
| ... | @@ -272,20 +284,24 @@ module.exports = function (ngApp, events) { | ... | @@ -272,20 +284,24 @@ module.exports = function (ngApp, events) { |
| 272 | * @param title | 284 | * @param title |
| 273 | * @param html | 285 | * @param html |
| 274 | */ | 286 | */ |
| 275 | - function saveDraft(title, html) { | 287 | + function saveDraft() { |
| 276 | - $http.put('/ajax/page/' + pageId + '/save-draft', { | 288 | + var data = { |
| 277 | - name: title, | 289 | + name: $('#name').val(), |
| 278 | - html: html | 290 | + html: isMarkdown ? $sce.getTrustedHtml($scope.displayContent) : $scope.editContent |
| 279 | - }).then((responseData) => { | 291 | + }; |
| 292 | + | ||
| 293 | + if (isMarkdown) data.markdown = $scope.editContent; | ||
| 294 | + | ||
| 295 | + console.log(data.markdown); | ||
| 296 | + | ||
| 297 | + $http.put('/ajax/page/' + pageId + '/save-draft', data).then((responseData) => { | ||
| 280 | $scope.draftText = responseData.data.message; | 298 | $scope.draftText = responseData.data.message; |
| 281 | if (!$scope.isNewPageDraft) $scope.isUpdateDraft = true; | 299 | if (!$scope.isNewPageDraft) $scope.isUpdateDraft = true; |
| 282 | }); | 300 | }); |
| 283 | } | 301 | } |
| 284 | 302 | ||
| 285 | $scope.forceDraftSave = function() { | 303 | $scope.forceDraftSave = function() { |
| 286 | - var newTitle = $('#name').val(); | 304 | + saveDraft(); |
| 287 | - var newHtml = $scope.editorHtml; | ||
| 288 | - saveDraft(newTitle, newHtml); | ||
| 289 | }; | 305 | }; |
| 290 | 306 | ||
| 291 | /** | 307 | /** |
| ... | @@ -298,6 +314,7 @@ module.exports = function (ngApp, events) { | ... | @@ -298,6 +314,7 @@ module.exports = function (ngApp, events) { |
| 298 | $scope.draftText = 'Editing Page'; | 314 | $scope.draftText = 'Editing Page'; |
| 299 | $scope.isUpdateDraft = false; | 315 | $scope.isUpdateDraft = false; |
| 300 | $scope.$broadcast('html-update', responseData.data.html); | 316 | $scope.$broadcast('html-update', responseData.data.html); |
| 317 | + $scope.$broadcast('markdown-update', responseData.data.markdown || responseData.data.html); | ||
| 301 | $('#name').val(responseData.data.name); | 318 | $('#name').val(responseData.data.name); |
| 302 | $timeout(() => { | 319 | $timeout(() => { |
| 303 | startAutoSave(); | 320 | startAutoSave(); | ... | ... |
| 1 | "use strict"; | 1 | "use strict"; |
| 2 | var DropZone = require('dropzone'); | 2 | var DropZone = require('dropzone'); |
| 3 | +var markdown = require( "marked" ); | ||
| 3 | 4 | ||
| 4 | var toggleSwitchTemplate = require('./components/toggle-switch.html'); | 5 | var toggleSwitchTemplate = require('./components/toggle-switch.html'); |
| 5 | var imagePickerTemplate = require('./components/image-picker.html'); | 6 | var imagePickerTemplate = require('./components/image-picker.html'); |
| ... | @@ -202,5 +203,36 @@ module.exports = function (ngApp, events) { | ... | @@ -202,5 +203,36 @@ module.exports = function (ngApp, events) { |
| 202 | } | 203 | } |
| 203 | }]) | 204 | }]) |
| 204 | 205 | ||
| 206 | + ngApp.directive('markdownEditor', ['$timeout', function($timeout) { | ||
| 207 | + return { | ||
| 208 | + restrict: 'A', | ||
| 209 | + scope: { | ||
| 210 | + mdModel: '=', | ||
| 211 | + mdChange: '=' | ||
| 212 | + }, | ||
| 213 | + link: function (scope, element, attrs) { | ||
| 214 | + | ||
| 215 | + // Set initial model content | ||
| 216 | + var content = element.val(); | ||
| 217 | + scope.mdModel = content; | ||
| 218 | + scope.mdChange(markdown(content)); | ||
| 219 | + | ||
| 220 | + element.on('change input', (e) => { | ||
| 221 | + content = element.val(); | ||
| 222 | + $timeout(() => { | ||
| 223 | + scope.mdModel = content; | ||
| 224 | + scope.mdChange(markdown(content)); | ||
| 225 | + }); | ||
| 226 | + }); | ||
| 227 | + | ||
| 228 | + scope.$on('markdown-update', (event, value) => { | ||
| 229 | + element.val(value); | ||
| 230 | + scope.mdModel= value; | ||
| 231 | + scope.mdChange(markdown(value)); | ||
| 232 | + }); | ||
| 233 | + | ||
| 234 | + } | ||
| 235 | + } | ||
| 236 | + }]) | ||
| 205 | 237 | ||
| 206 | }; | 238 | }; |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -93,4 +93,15 @@ | ... | @@ -93,4 +93,15 @@ |
| 93 | url('/fonts/roboto-regular-webfont.svg#robotoregular') format('svg'); | 93 | url('/fonts/roboto-regular-webfont.svg#robotoregular') format('svg'); |
| 94 | font-weight: normal; | 94 | font-weight: normal; |
| 95 | font-style: normal; | 95 | font-style: normal; |
| 96 | +} | ||
| 97 | + | ||
| 98 | +/* roboto-mono-regular - latin */ | ||
| 99 | +// https://google-webfonts-helper.herokuapp.com | ||
| 100 | +@font-face { | ||
| 101 | + font-family: 'Roboto Mono'; | ||
| 102 | + font-style: normal; | ||
| 103 | + font-weight: 400; | ||
| 104 | + src: local('Roboto Mono'), local('RobotoMono-Regular'), | ||
| 105 | + url('/fonts/roboto-mono-v4-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ | ||
| 106 | + url('/fonts/roboto-mono-v4-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ | ||
| 96 | } | 107 | } |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -26,6 +26,58 @@ | ... | @@ -26,6 +26,58 @@ |
| 26 | display: none; | 26 | display: none; |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | +#markdown-editor { | ||
| 30 | + position: relative; | ||
| 31 | + z-index: 5; | ||
| 32 | + textarea { | ||
| 33 | + font-family: 'Roboto Mono'; | ||
| 34 | + font-style: normal; | ||
| 35 | + font-weight: 400; | ||
| 36 | + padding: $-xs $-m; | ||
| 37 | + color: #444; | ||
| 38 | + border-radius: 0; | ||
| 39 | + max-height: 100%; | ||
| 40 | + flex: 1; | ||
| 41 | + border: 0; | ||
| 42 | + &:focus { | ||
| 43 | + outline: 0; | ||
| 44 | + } | ||
| 45 | + } | ||
| 46 | + .markdown-display, .markdown-editor-wrap { | ||
| 47 | + flex: 1; | ||
| 48 | + padding-top: 28px; | ||
| 49 | + position: relative; | ||
| 50 | + border: 1px solid #DDD; | ||
| 51 | + &:before { | ||
| 52 | + display: block; | ||
| 53 | + position: absolute; | ||
| 54 | + top: 0; | ||
| 55 | + left: 0; | ||
| 56 | + width: 100%; | ||
| 57 | + padding: $-xs $-m; | ||
| 58 | + font-family: 'Roboto Mono'; | ||
| 59 | + font-size: 11px; | ||
| 60 | + line-height: 1; | ||
| 61 | + border-bottom: 1px solid #DDD; | ||
| 62 | + background-color: #EEE; | ||
| 63 | + } | ||
| 64 | + } | ||
| 65 | + .markdown-editor-wrap { | ||
| 66 | + display: flex; | ||
| 67 | + &:before { | ||
| 68 | + content: 'Editor'; | ||
| 69 | + } | ||
| 70 | + } | ||
| 71 | + .markdown-display { | ||
| 72 | + padding: 0 $-m; | ||
| 73 | + padding-top: 28px; | ||
| 74 | + margin-left: -1px; | ||
| 75 | + &:before { | ||
| 76 | + content: 'Preview'; | ||
| 77 | + } | ||
| 78 | + } | ||
| 79 | +} | ||
| 80 | + | ||
| 29 | label { | 81 | label { |
| 30 | display: block; | 82 | display: block; |
| 31 | line-height: 1.4em; | 83 | line-height: 1.4em; |
| ... | @@ -160,6 +212,10 @@ input:checked + .toggle-switch { | ... | @@ -160,6 +212,10 @@ input:checked + .toggle-switch { |
| 160 | width: 100%; | 212 | width: 100%; |
| 161 | } | 213 | } |
| 162 | 214 | ||
| 215 | +div[editor-type="markdown"] .title-input.page-title input[type="text"] { | ||
| 216 | + max-width: 100%; | ||
| 217 | +} | ||
| 218 | + | ||
| 163 | .search-box { | 219 | .search-box { |
| 164 | max-width: 100%; | 220 | max-width: 100%; |
| 165 | position: relative; | 221 | position: relative; | ... | ... |
| ... | @@ -157,6 +157,12 @@ span.code { | ... | @@ -157,6 +157,12 @@ span.code { |
| 157 | @extend .code-base; | 157 | @extend .code-base; |
| 158 | padding: 1px $-xs; | 158 | padding: 1px $-xs; |
| 159 | } | 159 | } |
| 160 | + | ||
| 161 | +pre code { | ||
| 162 | + background-color: transparent; | ||
| 163 | + border: 0; | ||
| 164 | + font-size: 1em; | ||
| 165 | +} | ||
| 160 | /* | 166 | /* |
| 161 | * Text colors | 167 | * Text colors |
| 162 | */ | 168 | */ | ... | ... |
| 1 | 1 | ||
| 2 | -<div class="page-editor flex-fill flex" ng-controller="PageEditController" page-id="{{ $model->id or 0 }}" page-new-draft="{{ $model->draft or 0 }}" page-update-draft="{{ $model->isDraft or 0 }}"> | 2 | +<div class="page-editor flex-fill flex" ng-controller="PageEditController" editor-type="{{ config('app.editor') }}" page-id="{{ $model->id or 0 }}" page-new-draft="{{ $model->draft or 0 }}" page-update-draft="{{ $model->isDraft or 0 }}"> |
| 3 | 3 | ||
| 4 | {{ csrf_field() }} | 4 | {{ csrf_field() }} |
| 5 | <div class="faded-small toolbar"> | 5 | <div class="faded-small toolbar"> |
| ... | @@ -42,10 +42,31 @@ | ... | @@ -42,10 +42,31 @@ |
| 42 | </div> | 42 | </div> |
| 43 | </div> | 43 | </div> |
| 44 | <div class="edit-area flex-fill flex"> | 44 | <div class="edit-area flex-fill flex"> |
| 45 | - <textarea id="html-editor" tinymce="editorOptions" mce-change="editorChange" mce-model="editorHtml" name="html" rows="5" | 45 | + @if(config('app.editor') === 'html') |
| 46 | - @if($errors->has('html')) class="neg" @endif>@if(isset($model) || old('html')){{htmlspecialchars( old('html') ? old('html') : $model->html)}}@endif</textarea> | 46 | + <textarea id="html-editor" tinymce="editorOptions" mce-change="editorChange" mce-model="editContent" name="html" rows="5" |
| 47 | - @if($errors->has('html')) | 47 | + @if($errors->has('html')) class="neg" @endif>@if(isset($model) || old('html')){{htmlspecialchars( old('html') ? old('html') : $model->html)}}@endif</textarea> |
| 48 | - <div class="text-neg text-small">{{ $errors->first('html') }}</div> | 48 | + @if($errors->has('html')) |
| 49 | + <div class="text-neg text-small">{{ $errors->first('html') }}</div> | ||
| 50 | + @endif | ||
| 51 | + @endif | ||
| 52 | + | ||
| 53 | + @if(config('app.editor') === 'markdown') | ||
| 54 | + <div id="markdown-editor" class="flex-fill flex"> | ||
| 55 | + | ||
| 56 | + <div class="markdown-editor-wrap"> | ||
| 57 | + <textarea markdown-editor md-change="editorChange" md-model="editContent" name="markdown" rows="5" | ||
| 58 | + @if($errors->has('markdown')) class="neg" @endif>@if(isset($model) || old('markdown')){{htmlspecialchars( old('markdown') ? old('markdown') : ($model->markdown === '' ? $model->html : $model->markdown))}}@endif</textarea> | ||
| 59 | + </div> | ||
| 60 | + | ||
| 61 | + <div class="markdown-display page-content" ng-bind-html="displayContent"></div> | ||
| 62 | + </div> | ||
| 63 | + | ||
| 64 | + <input type="hidden" name="html" ng-value="displayContent"> | ||
| 65 | + | ||
| 66 | + @if($errors->has('markdown')) | ||
| 67 | + <div class="text-neg text-small">{{ $errors->first('markdown') }}</div> | ||
| 68 | + @endif | ||
| 69 | + | ||
| 49 | @endif | 70 | @endif |
| 50 | </div> | 71 | </div> |
| 51 | </div> | 72 | </div> |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
-
Please register or sign in to post a comment