improves in editor area

This commit is contained in:
Diego Najar 2018-10-17 22:35:30 +02:00
parent 6a3609098f
commit 8e7a2f93b9
18 changed files with 874 additions and 764 deletions

3
.gitignore vendored
View File

@ -5,8 +5,11 @@ bl-plugins/timemachine
bl-plugins/timemachine-x bl-plugins/timemachine-x
bl-plugins/discovery bl-plugins/discovery
bl-plugins/updater bl-plugins/updater
bl-plugins/medium-editor
bl-kernel/bludit.pro.php bl-kernel/bludit.pro.php
bl-themes/docs bl-themes/docs
bl-themes/docsx bl-themes/docsx
bl-themes/editorial bl-themes/editorial
bl-themes/mediumish bl-themes/mediumish
bl-themes/clean-blog
bl-themes/grayscale

View File

@ -51,6 +51,12 @@ a:hover {
border-color: #4a90e2; border-color: #4a90e2;
} }
.btn-light {
color: #212529;
background-color: #f3f3f3;
border-color: #ced4d9;
}
.btn-form { .btn-form {
background-color: #F3F3F3; background-color: #F3F3F3;
border-color: #DDD; border-color: #DDD;
@ -237,4 +243,16 @@ div.sidebar .nav-item span.oi {
td.child { td.child {
padding-left: 30px; padding-left: 30px;
} }
/*
Manage > New Content
*/
#jseditor {
background: #fff;
border: 1px solid #ced4da;
padding: 10px 5% !important;
font-size: 16px;
line-height: 1.5em;
}

View File

@ -25,7 +25,7 @@ if (!empty($listOfFilesByPage[0])) {
$numberOfPages = count($listOfFilesByPage); $numberOfPages = count($listOfFilesByPage);
?> ?>
<div id="jsbluditMediaModal" class="modal fade" tabindex="-1" role="dialog"> <div id="jsmediaManagerModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg"> <div class="modal-dialog modal-lg">
<div class="modal-content"> <div class="modal-content">
<div class="container-fluid"> <div class="container-fluid">
@ -85,40 +85,47 @@ echo 'var preLoadFiles = '.json_encode($preLoadFiles).';';
?> ?>
function openMediaManager() { function openMediaManager() {
$('#jsbluditMediaModal').modal('show'); $('#jsmediaManagerModal').modal('show');
} }
function closeMediaManager() { function closeMediaManager() {
$('#jsbluditMediaModal').modal('hide'); $('#jsmediaManagerModal').modal('hide');
} }
// Remove all files from the table // Remove all files from the table
function cleanFiles() { function cleanTable() {
$('#jsbluditMediaTable').empty(); $('#jsbluditMediaTable').empty();
} }
// Show the files in the table // Show the files in the table
function displayFiles(files) { function displayFiles(files) {
// Clean table // Clean table
cleanFiles(); cleanTable();
// Regenerate the table
$.each(files, function(key, filename) {
var thumbnail = "<?php echo $thumbnailURL; ?>"+filename;
var image = "<?php echo $imagesURL; ?>"+filename;
tableRow = '<tr id="js'+filename+'">'+ // Regenerate the table
'<td style="width:80px"><img class="img-thumbnail" alt="200x200" src="'+thumbnail+'" style="width: 50px; height: 50px;"><\/td>'+ if (files.length > 0) {
'<td class="information">'+ $.each(files, function(key, filename) {
'<div class="pb-2">'+filename+'<\/div>'+ var thumbnail = "<?php echo $thumbnailURL; ?>"+filename;
'<div>'+ var image = "<?php echo $imagesURL; ?>"+filename;
'<button type="button" class="btn btn-primary btn-sm mr-2" onClick="editorInsertMedia(\''+image+'\'); closeMediaManager();"><?php $L->p('Insert') ?><\/button>'+
'<button type="button" class="btn btn-primary btn-sm" onClick="setCoverImage(\''+filename+'\'); closeMediaManager();"><?php $L->p('Set as cover image') ?><\/button>'+ tableRow = '<tr id="js'+filename+'">'+
'<button type="button" class="btn btn-secondary btn-sm float-right" onClick="deleteMedia(\''+filename+'\')"><?php $L->p('Delete') ?><\/button>'+ '<td style="width:80px"><img class="img-thumbnail" alt="200x200" src="'+thumbnail+'" style="width: 50px; height: 50px;"><\/td>'+
'<\/div>'+ '<td class="information">'+
'<\/td>'+ '<div class="pb-2">'+filename+'<\/div>'+
'<\/tr>'; '<div>'+
$('#jsbluditMediaTable').append(tableRow); '<button type="button" class="btn btn-primary btn-sm mr-2" onClick="editorInsertMedia(\''+image+'\'); closeMediaManager();"><?php $L->p('Insert') ?><\/button>'+
}); '<button type="button" class="btn btn-primary btn-sm" onClick="setCoverImage(\''+filename+'\'); closeMediaManager();"><?php $L->p('Set as cover image') ?><\/button>'+
'<button type="button" class="btn btn-secondary btn-sm float-right" onClick="deleteMedia(\''+filename+'\')"><?php $L->p('Delete') ?><\/button>'+
'<\/div>'+
'<\/td>'+
'<\/tr>';
$('#jsbluditMediaTable').append(tableRow);
});
}
if (files.length == 0) {
$('#jsbluditMediaTable').html("<p><?php (IMAGE_RESTRICT ? $L->p('There are no images for the page') : $L->p('There are no images')) ?></p>");
}
} }
// Get the list of files via AJAX, filter by the page number // Get the list of files via AJAX, filter by the page number

View File

@ -35,7 +35,7 @@
<?php Theme::plugins('adminHead') ?> <?php Theme::plugins('adminHead') ?>
</head> </head>
<body> <body class="h-100">
<!-- Plugins --> <!-- Plugins -->
<?php Theme::plugins('adminBodyBegin') ?> <?php Theme::plugins('adminBodyBegin') ?>
@ -57,9 +57,9 @@
<!-- Navbar, only for small devices --> <!-- Navbar, only for small devices -->
<?php include('html/navbar.php'); ?> <?php include('html/navbar.php'); ?>
<div class="container"> <div class="container h-100">
<!-- 25%/75% split on large devices, small, medium devices hide --> <!-- 25%/75% split on large devices, small, medium devices hide -->
<div class="row"> <div class="row h-100">
<!-- LEFT SIDEBAR - Display only on large devices --> <!-- LEFT SIDEBAR - Display only on large devices -->
<div class="sidebar col-lg-2 d-none d-lg-block"> <div class="sidebar col-lg-2 d-none d-lg-block">
@ -67,7 +67,7 @@
</div> </div>
<!-- RIGHT MAIN --> <!-- RIGHT MAIN -->
<div class="col-lg-10 pt-3"> <div class="col-lg-10 pt-3 h-100">
<?php <?php
if (Sanitize::pathFile(PATH_ADMIN_VIEWS, $layout['view'].'.php')) { if (Sanitize::pathFile(PATH_ADMIN_VIEWS, $layout['view'].'.php')) {
include(PATH_ADMIN_VIEWS.$layout['view'].'.php'); include(PATH_ADMIN_VIEWS.$layout['view'].'.php');
@ -87,4 +87,4 @@
<?php Theme::plugins('adminBodyEnd') ?> <?php Theme::plugins('adminBodyEnd') ?>
</body> </body>
</html> </html>

View File

@ -68,9 +68,10 @@ EOF;
$enctype = empty($args['enctype'])?'':'enctype="'.$args['enctype'].'"'; $enctype = empty($args['enctype'])?'':'enctype="'.$args['enctype'].'"';
$action = empty($args['action'])?'action=""':'action="'.$args['action'].'"'; $action = empty($args['action'])?'action=""':'action="'.$args['action'].'"';
$method = empty($args['method'])?'method="post"':'method="'.$args['method'].'"'; $method = empty($args['method'])?'method="post"':'method="'.$args['method'].'"';
$style = empty($args['style'])?'':'style="'.$args['style'].'"';
return <<<EOF return <<<EOF
<form $class $enctype $id $method $action autocomplete="off"> <form $class $enctype $id $method $action $style autocomplete="off">
EOF; EOF;
} }

View File

@ -1,311 +1,173 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?> <?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<!-- TABS --> <?php
<ul class="nav nav-tabs" id="dynamicTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="content-tab" data-toggle="tab" href="#content" role="tab" aria-controls="content" aria-selected="true"><?php $L->p('Editor') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" id="images-tab" data-toggle="tab" href="#images" role="tab" aria-controls="images" aria-selected="false"><?php $L->p('Cover image') ?></a>
</li>
<li class="nav-item">
<a class="nav-link " id="options-tab" data-toggle="tab" href="#options" role="tab" aria-controls="options" aria-selected="false"><?php $L->p('Options') ?></a>
</li>
</ul>
<?php
echo Bootstrap::formOpen(array(
'id'=>'jsform',
'class'=>'tab-content mt-1'
));
// Token CSRF // FORM START
echo Bootstrap::formInputHidden(array( echo Bootstrap::formOpen(array(
'name'=>'tokenCSRF', 'id'=>'jsform',
'value'=>$security->getTokenCSRF() 'class'=>'d-flex flex-column h-100'
)); ));
// Parent // Token CSRF
echo Bootstrap::formInputHidden(array( echo Bootstrap::formInputHidden(array(
'name'=>'parent', 'name'=>'tokenCSRF',
'value'=>$page->parent() 'value'=>$security->getTokenCSRF()
));
// UUID
echo Bootstrap::formInputHidden(array(
'name'=>'uuid',
'value'=>$page->uuid()
));
// Status = published, draft, sticky, static
echo Bootstrap::formInputHidden(array(
'name'=>'type',
'value'=>$page->type()
));
// Page current key
echo Bootstrap::formInputHidden(array(
'name'=>'key',
'value'=>$page->key()
));
// Cover image
echo Bootstrap::formInputHidden(array(
'name'=>'coverImage',
'value'=>$page->coverImage(false)
));
// Content
echo Bootstrap::formInputHidden(array(
'name'=>'content',
'value'=>''
));
?>
<!-- TABS CONTENT -->
<div class="tab-pane show active" id="content" role="tabpanel" aria-labelledby="content-tab">
<div class="form-group m-0">
<input value="<?php echo $page->title() ?>" class="form-control form-control-lg rounded-0 " id="jstitle" name="title" placeholder="<?php $L->p('Enter title') ?>" type="text">
</div>
<div class="form-group m-0 mt-1">
<button id="jsmediaManagerButton" type="button" class="btn btn-form btn-sm" data-toggle="modal" data-target="#jsbluditMediaModal"><span class="oi oi-image"></span> <?php $L->p('Images') ?></button>
<button id="jscategoryButton" type="button" class="btn btn-form btn-sm" data-toggle="modal" data-target="#jscategoryModal"><span class="oi oi-tag"></span> <?php $L->p('Category') ?>: <span class="option">-</span></button>
<button id="jsdescriptionButton" type="button" class="btn btn-form btn-sm" data-toggle="modal" data-target="#jsdescriptionModal"><span class="oi oi-tag"></span> <?php $L->p('Description') ?>: <span class="option">-</span></button>
</div>
<div class="form-group mt-1">
<textarea id="jseditor" style="display:none;"><?php echo $page->contentRaw(false) ?></textarea>
</div>
<?php if($page->draft()): ?>
<div class="alert alert-primary mt-2 mb-2"><?php $L->p('the-content-is-saved-as-a-draft-to-publish-it') ?></div>
<?php endif; ?>
<div class="form-group mt-2">
<button type="button" class="jsbuttonSave btn btn-primary"><?php echo ($page->draft()?$L->g('Publish'):$L->g('Save')) ?></button>
<button type="button" class="jsbuttonDraft btn btn-secondary"><?php $L->p('Save as draft') ?></button>
<a href="<?php echo HTML_PATH_ADMIN_ROOT ?>dashboard" class="btn btn-secondary"><?php $L->p('Cancel') ?></a>
<?php
if (count($page->children())===0) {
echo '<button type="button" class="btn btn-secondary" data-toggle="modal" data-target="#jsdeletePageModal">'.$L->g('Delete').'</button>';
}
?>
</div>
</div>
<!-- TABS IMAGES -->
<div class="tab-pane" id="images" role="tabpanel" aria-labelledby="images-tab">
<div>
<div class="float-right">
<button type="button" class="jsbuttonSave btn btn-primary btn-sm"><?php echo ($page->draft()?$L->g('Publish'):$L->g('Save')) ?></button>
<button type="button" class="jsbuttonDraft btn btn-secondary btn-sm"><?php $L->p('Save as draft') ?></button>
</div>
<h4 class="mt-4 mb-4 font-weight-normal"><?php $L->p('Cover image') ?></h4>
</div>
<?php
$coverImage = $page->coverImage(false);
$externalCoverImage = '';
if (filter_var($coverImage, FILTER_VALIDATE_URL)) {
$coverImage = '';
$externalCoverImage = $page->coverImage(false);
}
?>
<img id="jscoverImagePreview" style="width: 350px; height: 200px;" class="img-thumbnail" alt="coverImagePreview" src="<?php echo (empty($coverImage) ? HTML_PATH_ADMIN_THEME_IMG.'default.svg' : $page->coverImage() ) ?>" />
<div class="mt-2">
<button type="button" id="jsbuttonRemoveCoverImage" class="btn btn-primary btn-sm"><?php echo $L->g('Remove cover image') ?></button>
</div>
<?php
echo Bootstrap::formTitle(array('title'=>$L->g('External Cover image')));
echo Bootstrap::formInputTextBlock(array(
'name'=>'externalCoverImage',
'placeholder'=>'https://',
'value'=>$externalCoverImage,
'tip'=>$L->g('Set a cover image from external URL, such as a CDN or some server dedicated for images.')
));
?>
</div>
<!-- TABS OPTIONS -->
<div class="tab-pane" id="options" role="tabpanel" aria-labelledby="options-tab">
<div>
<div class="float-right">
<button type="button" class="jsbuttonSave btn btn-primary btn-sm"><?php echo ($page->draft()?$L->g('Publish'):$L->g('Save')) ?></button>
<button type="button" class="jsbuttonDraft btn btn-secondary btn-sm"><?php $L->p('Save as draft') ?></button>
</div>
<h4 class="mt-4 mb-4 font-weight-normal"><?php $L->p('General') ?></h4>
</div>
<?php
// Username
echo Bootstrap::formInputText(array(
'name'=>'',
'label'=>$L->g('User'),
'placeholder'=>'',
'value'=>$page->username(),
'tip'=>'',
'disabled'=>true
));
// Date
echo Bootstrap::formInputText(array(
'name'=>'date',
'label'=>$L->g('Date'),
'placeholder'=>'',
'value'=>$page->dateRaw(),
'tip'=>$L->g('date-format-format')
));
// Type
echo Bootstrap::formSelect(array(
'name'=>'typeTMP',
'label'=>$L->g('Type'),
'selected'=>$page->type(),
'options'=>array(
'published'=>'- '.$L->g('Default').' -',
'sticky'=>$L->g('Sticky'),
'static'=>$L->g('Static')
),
'tip'=>''
));
// Parent
try {
$parentKey = $page->parent();
$parent = new Page($parentKey);
$parentOption = $parent->title();
} catch (Exception $e) {
$parentOption = '';
}
echo Bootstrap::formInputText(array(
'name'=>'parentTMP',
'label'=>$L->g('Parent'),
'placeholder'=>'',
'tip'=>$L->g('Start typing a page title to see a list of suggestions.'),
'value'=>$parentOption
));
// Position
echo Bootstrap::formInputText(array(
'name'=>'position',
'label'=>$L->g('Position'),
'tip'=>$L->g('Field used when ordering content by position'),
'value'=>$page->position()
));
// Template
echo Bootstrap::formInputText(array(
'name'=>'template',
'label'=>$L->g('Template'),
'placeholder'=>'',
'value'=>$page->template(),
'tip'=>$L->g('Write a template name to filter the page in the theme and change the style of the page.')
));
// Tags
echo Bootstrap::formInputText(array(
'name'=>'tags',
'label'=>$L->g('Tags'),
'placeholder'=>'',
'value'=>$page->tags(),
'tip'=>$L->g('Write the tags separated by comma')
));
echo Bootstrap::formTitle(array('title'=>'SEO'));
// Friendly URL
echo Bootstrap::formInputText(array(
'name'=>'slug',
'tip'=>$L->g('URL associated with the content'),
'label'=>$L->g('Friendly URL'),
'placeholder'=>$L->g('Leave empty for autocomplete by Bludit.'),
'value'=>$page->slug()
));
echo Bootstrap::formCheckbox(array(
'name'=>'noindex',
'label'=>'Robots',
'labelForCheckbox'=>$L->g('apply-code-noindex-code-to-this-page'),
'placeholder'=>'',
'class'=>'mt-4',
'checked'=>$page->noindex(),
'tip'=>$L->g('This tells search engines not to show this page in their search results.')
));
echo Bootstrap::formCheckbox(array(
'name'=>'nofollow',
'label'=>'',
'labelForCheckbox'=>$L->g('apply-code-nofollow-code-to-this-page'),
'placeholder'=>'',
'checked'=>$page->nofollow(),
'tip'=>$L->g('This tells search engines not to follow links on this page.')
));
echo Bootstrap::formCheckbox(array(
'name'=>'noarchive',
'label'=>'',
'labelForCheckbox'=>$L->g('apply-code-noarchive-code-to-this-page'),
'placeholder'=>'',
'checked'=>$page->noarchive(),
'tip'=>$L->g('This tells search engines not to save a cached copy of this page.')
));
?>
</div>
<!-- Modal for delete page -->
<?php echo Bootstrap::modal(array(
'buttonPrimary'=>$L->g('Delete'),
'buttonPrimaryClass'=>'jsbuttonDeleteAccept',
'buttonSecondary'=>$L->g('Cancel'),
'buttonSecondaryClass'=>'',
'modalTitle'=>$L->g('Delete content'),
'modalText'=>$L->g('Are you sure you want to delete this page'),
'modalId'=>'jsdeletePageModal'
)); ));
?>
// Parent
echo Bootstrap::formInputHidden(array(
'name'=>'parent',
'value'=>$page->parent()
));
// UUID
// The UUID is generated in the controller
echo Bootstrap::formInputHidden(array(
'name'=>'uuid',
'value'=>$uuid
));
// Type = published, draft, sticky, static
echo Bootstrap::formInputHidden(array(
'name'=>'type',
'value'=>$page->type()
));
// Cover image
echo Bootstrap::formInputHidden(array(
'name'=>'coverImage',
'value'=>$page->coverImage(false)
));
// Content
echo Bootstrap::formInputHidden(array(
'name'=>'content',
'value'=>''
));
// Current page key
echo Bootstrap::formInputHidden(array(
'name'=>'key',
'value'=>$page->key()
));
?>
<!-- TOOLBAR -->
<div>
<div class="btn-group btn-group-sm" role="group" aria-label="Basic example">
<button type="button" class="btn btn-light" id="jsmediaManagerOpenModal" data-toggle="modal" data-target="#jsmediaManagerModal"><?php $L->p('Images') ?></button>
<button type="button" class="btn btn-light" id="jscoverImageOpenModal" data-toggle="modal" data-target="#jscoverImageModal"><?php $L->p('Cover image') ?></button>
<button type="button" class="btn btn-light" id="jscategoryOpenModal" data-toggle="modal" data-target="#jscategoryModal"><?php $L->p('Category') ?><span class="option"></span></button>
<button type="button" class="btn btn-light" id="jsdescriptionOpenModal" data-toggle="modal" data-target="#jsdescriptionModal"><?php $L->p('Description') ?><span class="option"></span></button>
<button type="button" class="btn btn-light" id="jsoptionsOpenModal" data-toggle="modal" data-target="#jsoptionsModal"><?php $L->p('More options') ?></button>
</div>
<div class="btn-group btn-group-sm float-right" role="group" aria-label="Basic example">
<button type="button" class="btn btn-primary" id="jsbuttonSave"><?php echo ($page->draft()?$L->g('Publish'):$L->g('Save')) ?></button>
<?php if(!$page->draft()): ?>
<button type="button" class="btn btn-secondary" id="jsbuttonDraft"><?php $L->p('Save as draft') ?></button>
<?php endif; ?>
<?php if (count($page->children())===0): ?>
<button type="button" class="btn btn-danger" id="jsbuttonDelete" data-toggle="modal" data-target="#jsdeletePageModal"><?php $L->p('Delete') ?></button>
<?php endif; ?>
<a href="<?php echo HTML_PATH_ADMIN_ROOT ?>dashboard" class="btn btn-secondary"><?php $L->p('Cancel') ?></a>
</div>
</div>
<!-- Title -->
<div class="form-group mt-1 mb-1">
<input id="jstitle" name="title" type="text" class="form-control form-control-lg rounded-0" value="<?php echo $page->title() ?>" placeholder="<?php $L->p('Enter title') ?>">
</div>
<!-- Editor -->
<div id="jseditor" class="editable h-100" style=""><?php echo $page->contentRaw(false) ?></div>
<!-- Modal for Cover Image -->
<div id="jscoverImageModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><?php $L->p('Cover Image') ?></h5>
</div>
<div class="modal-body">
<?php
$coverImage = $page->coverImage(false);
$externalCoverImage = '';
if (filter_var($coverImage, FILTER_VALIDATE_URL)) {
$coverImage = '';
$externalCoverImage = $page->coverImage(false);
}
?>
<div>
<img id="jscoverImagePreview" style="width: 350px; height: 200px;" class="mx-auto d-block" alt="Cover image preview" src="<?php echo (empty($coverImage) ? HTML_PATH_ADMIN_THEME_IMG.'default.svg' : $page->coverImage() ) ?>" />
</div>
<div class="mt-2 text-center">
<button type="button" id="jsbuttonSelectCoverImage" class="btn btn-primary btn-sm"><?php echo $L->g('Select cover image') ?></button>
<button type="button" id="jsbuttonRemoveCoverImage" class="btn btn-secondary btn-sm"><?php echo $L->g('Remove cover image') ?></button>
</div>
<hr>
<?php
echo Bootstrap::formTitle(array('title'=>$L->g('External Cover Image')));
echo Bootstrap::formInputTextBlock(array(
'name'=>'externalCoverImage',
'placeholder'=>"https://",
'value'=>$externalCoverImage,
'tip'=>$L->g('Set a cover image from external URL, such as a CDN or some server dedicated for images.')
));
?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal"><?php $L->p('Done') ?></button>
</div>
</div>
</div>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
// Delete content $("#jsexternalCoverImage").change(function() {
$(".jsbuttonDeleteAccept").on("click", function() { $("#jscoverImage").val( $(this).val() );
$("#jstype").val("delete"); });
$("#jscontent").val("");
$("#jsform").submit(); $("#jscoverImagePreview").on("click", function() {
openMediaManager();
});
$("#jsbuttonSelectCoverImage").on("click", function() {
openMediaManager();
});
$("#jsbuttonRemoveCoverImage").on("click", function() {
$("#jscoverImage").val('');
$("#jscoverImagePreview").attr('src', HTML_PATH_ADMIN_THEME_IMG+'default.svg');
}); });
}); });
</script> </script>
</div>
<!-- Modal for Categories --> <!-- Modal for Categories -->
<div id="jscategoryModal" class="modal fade" tabindex="-1" role="dialog"> <div id="jscategoryModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title"><?php $L->p('Category') ?></h5> <h5 class="modal-title"><?php $L->p('Category') ?></h5>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<?php <?php
echo Bootstrap::formSelectBlock(array( echo Bootstrap::formSelectBlock(array(
'name'=>'category', 'name'=>'category',
'label'=>'', 'label'=>'',
'selected'=>$page->categoryKey(), 'selected'=>$page->categoryKey(),
'class'=>'', 'class'=>'',
'emptyOption'=>'- '.$L->g('Uncategorized').' -', 'emptyOption'=>'- '.$L->g('Uncategorized').' -',
'options'=>$categories->getKeyNameArray() 'options'=>$categories->getKeyNameArray()
)); ));
?> ?>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal"><?php $L->p('Done') ?></button> <button type="button" class="btn btn-primary" data-dismiss="modal"><?php $L->p('Done') ?></button>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -315,9 +177,9 @@
var selected = $("#jscategory option:selected"); var selected = $("#jscategory option:selected");
var value = selected.val().trim(); var value = selected.val().trim();
if (value) { if (value) {
$("#jscategoryButton").find("span.option").html(selected.text()); $("#jscategoryOpenModal").find("span.option").html(": "+selected.text());
} else { } else {
$("#jscategoryButton").find("span.option").html("-"); $("#jscategoryOpenModal").find("span.option").html("");
} }
} }
@ -330,30 +192,30 @@
}); });
}); });
</script> </script>
</div>
<!-- Modal for Description --> <!-- Modal for Description -->
<div id="jsdescriptionModal" class="modal fade" tabindex="-1" role="dialog"> <div id="jsdescriptionModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title"><?php $L->p('Description') ?></h5> <h5 class="modal-title"><?php $L->p('Description') ?></h5>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<?php <?php
echo Bootstrap::formTextareaBlock(array( echo Bootstrap::formTextareaBlock(array(
'name'=>'description', 'name'=>'description',
'label'=>'', 'label'=>'',
'selected'=>'', 'selected'=>'',
'class'=>'', 'class'=>'',
'value'=>$page->description(), 'value'=>$page->description(),
'rows'=>3, 'rows'=>3,
'placeholder'=>$L->get('this-field-can-help-describe-the-content') 'placeholder'=>$L->get('this-field-can-help-describe-the-content')
)); ));
?> ?>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal"><?php $L->p('Done') ?></button> <button type="button" class="btn btn-primary" data-dismiss="modal"><?php $L->p('Done') ?></button>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -361,12 +223,10 @@
$(document).ready(function() { $(document).ready(function() {
function setDescriptionBox(value) { function setDescriptionBox(value) {
var value = $("#jsdescription").val(); var value = $("#jsdescription").val();
if (!value) { if (value) {
value = '-'; value = ": "+$.trim(value).substring(0, 30).split(" ").slice(0, -1).join(" ") + "...";
} else {
value = jQuery.trim(value).substring(0, 60).split(" ").slice(0, -1).join(" ") + "...";
} }
$("#jsdescriptionButton").find("span.option").html(value); $("#jsdescriptionOpenModal").find("span.option").html(value);
} }
// Set the current description // Set the current description
@ -378,95 +238,252 @@
}); });
}); });
</script> </script>
</div>
<!-- Modal for More options -->
<div id="jsoptionsModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><?php $L->p('More options') ?></h5>
</div>
<div class="modal-body">
<?php
// Username
echo Bootstrap::formInputText(array(
'name'=>'',
'label'=>$L->g('Author'),
'placeholder'=>'',
'value'=>$page->username(),
'tip'=>'',
'disabled'=>true
));
// Date
echo Bootstrap::formInputText(array(
'name'=>'date',
'label'=>$L->g('Date'),
'placeholder'=>'',
'value'=>$page->dateRaw(),
'tip'=>$L->g('date-format-format')
));
// Type
echo Bootstrap::formSelect(array(
'name'=>'typeTMP',
'label'=>$L->g('Type'),
'selected'=>$page->type(),
'options'=>array(
'published'=>'- '.$L->g('Default').' -',
'sticky'=>$L->g('Sticky'),
'static'=>$L->g('Static')
),
'tip'=>''
));
// Parent
try {
$parentKey = $page->parent();
$parent = new Page($parentKey);
$parentValue = $parent->title();
} catch (Exception $e) {
$parentValue = '';
}
echo Bootstrap::formInputText(array(
'name'=>'parentTMP',
'label'=>$L->g('Parent'),
'placeholder'=>'',
'tip'=>$L->g('Start typing a page title to see a list of suggestions.'),
'value'=>$parentValue
));
// Position
echo Bootstrap::formInputText(array(
'name'=>'position',
'label'=>$L->g('Position'),
'tip'=>$L->g('Field used when ordering content by position'),
'value'=>$page->position()
));
// Template
echo Bootstrap::formInputText(array(
'name'=>'template',
'label'=>$L->g('Template'),
'placeholder'=>'',
'tip'=>$L->g('Write a template name to filter the page in the theme and change the style of the page.'),
'value'=>$page->template()
));
// Tags
echo Bootstrap::formInputText(array(
'name'=>'tags',
'label'=>$L->g('Tags'),
'placeholder'=>'',
'tip'=>$L->g('Write the tags separated by comma'),
'value'=>$page->tags()
));
echo Bootstrap::formTitle(array('title'=>$L->g('SEO')));
// Friendly URL
echo Bootstrap::formInputText(array(
'name'=>'slug',
'tip'=>$L->g('URL associated with the content'),
'label'=>$L->g('Friendly URL'),
'placeholder'=>$L->g('Leave empty for autocomplete by Bludit.'),
'value'=>$page->slug()
));
echo Bootstrap::formCheckbox(array(
'name'=>'noindex',
'label'=>'Robots',
'labelForCheckbox'=>$L->g('apply-code-noindex-code-to-this-page'),
'placeholder'=>'',
'class'=>'mt-4',
'checked'=>$page->noindex(),
'tip'=>$L->g('This tells search engines not to show this page in their search results.')
));
echo Bootstrap::formCheckbox(array(
'name'=>'nofollow',
'label'=>'',
'labelForCheckbox'=>$L->g('apply-code-nofollow-code-to-this-page'),
'placeholder'=>'',
'checked'=>$page->nofollow(),
'tip'=>$L->g('This tells search engines not to follow links on this page.')
));
echo Bootstrap::formCheckbox(array(
'name'=>'noarchive',
'label'=>'',
'labelForCheckbox'=>$L->g('apply-code-noarchive-code-to-this-page'),
'placeholder'=>'',
'checked'=>$page->noarchive(),
'tip'=>$L->g('This tells search engines not to save a cached copy of this page.')
));
?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal"><?php $L->p('Done') ?></button>
</div>
</div>
</div>
<script>
$(document).ready(function() {
// Generate slug when the user type the title
$("#jstitle").keyup(function() {
var text = $(this).val();
var parent = $("#jsparent").val();
var currentKey = "";
var ajax = new bluditAjax();
var callBack = $("#jsslug");
ajax.generateSlug(text, parent, currentKey, callBack);
});
// Datepicker
$("#jsdate").datetimepicker({format:DB_DATE_FORMAT});
// Parent autocomplete
var parentsXHR;
var parentsList; // Keep the parent list returned to get the key by the title page
$("#jsparentTMP").autoComplete({
minChars: 1,
source: function(term, response) {
// Prevent call inmediatly another ajax request
try { parentsXHR.abort(); } catch(e){}
// Get the list of parent pages by title (term)
parentsXHR = $.getJSON(HTML_PATH_ADMIN_ROOT+"ajax/get-parents", {query: term},
function(data) {
parentsList = data;
term = term.toLowerCase();
var matches = [];
for (var title in data) {
if (~title.toLowerCase().indexOf(term))
matches.push(title);
}
response(matches);
});
},
onSelect: function(event, term, item) {
// parentsList = array( pageTitle => pageKey )
var parentKey = parentsList[term];
$("#jsparent").attr("value", parentKey);
}
});
});
</script>
</div>
</form> </form>
<!-- Modal for Delete page -->
<div id="jsdeletePageModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><?php $L->p('Delete content') ?></h5>
</div>
<div class="modal-body">
<?php $L->p('Are you sure you want to delete this page') ?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal"><?php $L->p('Cancel') ?></button>
<button type="button" class="btn btn-danger" data-dismiss="modal" id="jsbuttonDeleteAccept"><?php $L->p('Delete') ?></button>
</div>
</div>
</div>
<script>
$(document).ready(function() {
$("#jsbuttonDeleteAccept").on("click", function() {
$("#jstype").val("delete");
$("#jscontent").val("");
$("#jsform").submit();
});
});
</script>
</div>
<!-- Modal for Media Manager --> <!-- Modal for Media Manager -->
<?php include(PATH_ADMIN_THEMES.'booty/html/media.php'); ?> <?php include(PATH_ADMIN_THEMES.'booty/html/media.php'); ?>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
// Datepicker // Button Publish or Save
$("#jsdate").datetimepicker({format:DB_DATE_FORMAT}); $("#jsbuttonSave").on("click", function() {
// Get the type
// Button Save
$(".jsbuttonSave").on("click", function() {
var type = $("#jstypeTMP option:selected").val(); var type = $("#jstypeTMP option:selected").val();
$("#jstype").val(type); $("#jstype").val(type);
// Get the content
$("#jscontent").val( editorGetContent() ); $("#jscontent").val( editorGetContent() );
// Submit the form
$("#jsform").submit(); $("#jsform").submit();
}); });
// Button Save as draft // Button Save as draft
$(".jsbuttonDraft").on("click", function() { $("#jsbuttonDraft").on("click", function() {
// Set the type as draft
$("#jstype").val("draft"); $("#jstype").val("draft");
// Get the content
$("#jscontent").val( editorGetContent() ); $("#jscontent").val( editorGetContent() );
// Submit the form
$("#jsform").submit(); $("#jsform").submit();
}); });
// External cover image
$("#jsexternalCoverImage").change(function() {
$("#jscoverImage").val( $(this).val() );
});
$("#jsbuttonRemoveCoverImage").on("click", function() {
$("#jscoverImage").val('');
$("#jscoverImagePreview").attr('src', HTML_PATH_ADMIN_THEME_IMG+'default.svg');
});
// Autosave interval // Autosave interval
// Autosave works when the content of the page is bigger than 100 characters // Autosave works when the content of the page is bigger than 100 characters
var currentContent = editorGetContent();
setInterval(function() { setInterval(function() {
var uuid = $("#jsuuid").val(); var uuid = $("#jsuuid").val();
var title = $("#jstitle").val(); var title = $("#jstitle").val();
var content = editorGetContent(); var content = editorGetContent();
var ajax = new bluditAjax(); var ajax = new bluditAjax();
if (currentContent!=content) { // showAlert is the function to display an alert defined in alert.php
// showAlert is the function to display an alert defined in alert.php ajax.autosave(uuid, title, content, showAlert);
ajax.autosave(uuid, title, content, showAlert);
}
},1000*60*AUTOSAVE_INTERVAL); },1000*60*AUTOSAVE_INTERVAL);
// Template autocomplete
$('input[name="template"]').autoComplete({
minChars: 2,
source: function(term, suggest){
term = term.toLowerCase();
var choices = ['ActionScript', 'Acti', 'Asp'];
var matches = [];
for (i=0; i<choices.length; i++)
if (~choices[i].toLowerCase().indexOf(term)) matches.push(choices[i]);
suggest(matches);
}
});
// Parent autocomplete
var parentsXHR;
var parentsList; // Keep the parent list returned to get the key by the title page
$("#jsparentTMP").autoComplete({
minChars: 1,
source: function(term, response) {
// Prevent call inmediatly another ajax request
try { parentsXHR.abort(); } catch(e){}
parentsXHR = $.getJSON(HTML_PATH_ADMIN_ROOT+"ajax/get-parents", {query: term},
function(data) {
parentsList = data;
term = term.toLowerCase();
var matches = [];
for (var title in data) {
if (~title.toLowerCase().indexOf(term))
matches.push(title);
}
response(matches);
});
},
onSelect: function(e, term, item) {
// parentsList = array( pageTitle => pageKey )
var parentKey = parentsList[term];
$("#jsparent").attr("value", parentKey);
}
});
}); });
</script> </script>

View File

@ -1,255 +1,153 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?> <?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<!-- TABS --> <?php
<ul class="nav nav-tabs" id="dynamicTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="content-tab" data-toggle="tab" href="#content" role="tab" aria-controls="content" aria-selected="true"><?php $L->p('Editor') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" id="images-tab" data-toggle="tab" href="#images" role="tab" aria-controls="images" aria-selected="false"><?php $L->p('Cover image') ?></a>
</li>
<li class="nav-item">
<a class="nav-link " id="options-tab" data-toggle="tab" href="#options" role="tab" aria-controls="options" aria-selected="false"><?php $L->p('Options') ?></a>
</li>
</ul>
<?php
echo Bootstrap::formOpen(array(
'id'=>'jsform',
'class'=>'tab-content mt-1'
));
// Token CSRF // FORM START
echo Bootstrap::formInputHidden(array( echo Bootstrap::formOpen(array(
'name'=>'tokenCSRF', 'id'=>'jsform',
'value'=>$security->getTokenCSRF() 'class'=>'d-flex flex-column h-100'
)); ));
// Parent // Token CSRF
echo Bootstrap::formInputHidden(array( echo Bootstrap::formInputHidden(array(
'name'=>'parent', 'name'=>'tokenCSRF',
'value'=>'' 'value'=>$security->getTokenCSRF()
)); ));
// UUID // Parent
echo Bootstrap::formInputHidden(array( echo Bootstrap::formInputHidden(array(
'name'=>'uuid', 'name'=>'parent',
'value'=>$uuid 'value'=>''
)); ));
// Status = published, draft, sticky, static // UUID
echo Bootstrap::formInputHidden(array( // The UUID is generated in the controller
'name'=>'type', echo Bootstrap::formInputHidden(array(
'value'=>'published' 'name'=>'uuid',
)); 'value'=>$uuid
));
// Cover image // Type = published, draft, sticky, static
echo Bootstrap::formInputHidden(array( echo Bootstrap::formInputHidden(array(
'name'=>'coverImage', 'name'=>'type',
'value'=>'' 'value'=>'published'
)); ));
// Content // Cover image
echo Bootstrap::formInputHidden(array( echo Bootstrap::formInputHidden(array(
'name'=>'content', 'name'=>'coverImage',
'value'=>'' 'value'=>''
)); ));
?>
<!-- TABS CONTENT --> // Content
<div class="tab-pane show active" id="content" role="tabpanel" aria-labelledby="content-tab"> echo Bootstrap::formInputHidden(array(
'name'=>'content',
<div class="form-group m-0"> 'value'=>''
<input value="" class="form-control form-control-lg rounded-0 " id="jstitle" name="title" placeholder="<?php $L->p('Enter title') ?>" type="text"> ));
</div> ?>
<div class="form-group m-0">
<button id="jsmediaManagerButton" type="button" class="mt-1 btn btn-form btn-sm d-block d-sm-inline d-sm-none" data-toggle="modal" data-target="#jsbluditMediaModal"><span class="oi oi-image"></span> <?php $L->p('Images') ?></button>
<button id="jscategoryButton" type="button" class="mt-1 btn btn-form btn-sm" data-toggle="modal" data-target="#jscategoryModal"><span class="oi oi-tag"></span> <?php $L->p('Category') ?>: <span class="option">-</span></button>
<button id="jsdescriptionButton" type="button" class="mt-1 btn btn-form btn-sm" data-toggle="modal" data-target="#jsdescriptionModal"><span class="oi oi-tag"></span> <?php $L->p('Description') ?>: <span class="option">-</span></button>
</div>
<div class="form-group mt-1">
<textarea id="jseditor" style="display:none;"></textarea>
</div>
<div class="form-group mt-2">
<button type="button" class="jsbuttonSave btn btn-primary"><?php echo $L->g('Publish') ?></button>
<button type="button" class="jsbuttonDraft btn btn-secondary"><?php echo $L->g('Save as draft') ?></button>
<a href="<?php echo HTML_PATH_ADMIN_ROOT ?>dashboard" class="btn btn-secondary"><?php echo $L->g('Cancel') ?></a>
</div>
<!-- TOOLBAR -->
<div>
<div class="btn-group btn-group-sm" role="group" aria-label="Basic example">
<button type="button" class="btn btn-light" id="jsmediaManagerOpenModal" data-toggle="modal" data-target="#jsmediaManagerModal"><?php $L->p('Images') ?></button>
<button type="button" class="btn btn-light" id="jscoverImageOpenModal" data-toggle="modal" data-target="#jscoverImageModal"><?php $L->p('Cover image') ?></button>
<button type="button" class="btn btn-light" id="jscategoryOpenModal" data-toggle="modal" data-target="#jscategoryModal"><?php $L->p('Category') ?><span class="option"></span></button>
<button type="button" class="btn btn-light" id="jsdescriptionOpenModal" data-toggle="modal" data-target="#jsdescriptionModal"><?php $L->p('Description') ?><span class="option"></span></button>
<button type="button" class="btn btn-light" id="jsoptionsOpenModal" data-toggle="modal" data-target="#jsoptionsModal"><?php $L->p('More options') ?></button>
</div> </div>
<!-- TABS IMAGES --> <div class="btn-group btn-group-sm float-right" role="group" aria-label="Basic example">
<div class="tab-pane" id="images" role="tabpanel" aria-labelledby="images-tab"> <button type="button" class="btn btn-primary" id="jsbuttonSave"><?php $L->p('Publish') ?></button>
<button type="button" class="btn btn-secondary" id="jsbuttonDraft"><?php $L->p('Save as draft') ?></button>
<a href="<?php echo HTML_PATH_ADMIN_ROOT ?>dashboard" class="btn btn-secondary"><?php $L->p('Cancel') ?></a>
</div>
</div>
<div> <!-- Title -->
<div class="float-right"> <div class="form-group mt-1 mb-1">
<button type="button" class="jsbuttonSave btn btn-primary btn-sm"><?php echo $L->g('Publish') ?></button> <input id="jstitle" name="title" type="text" class="form-control form-control-lg rounded-0" value="" placeholder="<?php $L->p('Enter title') ?>">
<button type="button" class="jsbuttonDraft btn btn-secondary btn-sm"><?php echo $L->g('Save as draft') ?></button> </div>
<!-- Editor -->
<div id="jseditor" class="editable h-100" style=""></div>
<!-- Modal for Cover Image -->
<div id="jscoverImageModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><?php $L->p('Cover Image') ?></h5>
</div> </div>
<h4 class="mt-4 mb-4 font-weight-normal"><?php $L->p('Cover image') ?></h4> <div class="modal-body">
</div> <div>
<img id="jscoverImagePreview" style="width: 350px; height: 200px;" class="mx-auto d-block" alt="Cover image preview" src="<?php echo HTML_PATH_ADMIN_THEME_IMG ?>default.svg" />
</div>
<div class="mt-2 text-center">
<button type="button" id="jsbuttonSelectCoverImage" class="btn btn-primary btn-sm"><?php echo $L->g('Select cover image') ?></button>
<button type="button" id="jsbuttonRemoveCoverImage" class="btn btn-secondary btn-sm"><?php echo $L->g('Remove cover image') ?></button>
</div>
<img id="jscoverImagePreview" style="width: 350px; height: 200px;" class="img-thumbnail" alt="coverImagePreview" src="<?php echo HTML_PATH_ADMIN_THEME_IMG ?>default.svg" /> <hr>
<div class="mt-2">
<button type="button" id="jsbuttonRemoveCoverImage" class="btn btn-primary btn-sm"><?php echo $L->g('Remove cover image') ?></button>
</div>
<?php <?php
echo Bootstrap::formTitle(array('title'=>$L->g('External Cover Image'))); echo Bootstrap::formTitle(array('title'=>$L->g('External Cover Image')));
echo Bootstrap::formInputTextBlock(array( echo Bootstrap::formInputTextBlock(array(
'name'=>'externalCoverImage', 'name'=>'externalCoverImage',
'placeholder'=>"https://", 'placeholder'=>"https://",
'value'=>'', 'value'=>'',
'tip'=>$L->g('Set a cover image from external URL, such as a CDN or some server dedicated for images.') 'tip'=>$L->g('Set a cover image from external URL, such as a CDN or some server dedicated for images.')
)); ));
?> ?>
</div>
</div> <div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal"><?php $L->p('Done') ?></button>
<!-- TABS OPTIONS -->
<div class="tab-pane" id="options" role="tabpanel" aria-labelledby="options-tab">
<div>
<div class="float-right">
<button type="button" class="jsbuttonSave btn btn-primary btn-sm"><?php echo $L->g('Publish') ?></button>
<button type="button" class="jsbuttonDraft btn btn-secondary btn-sm"><?php echo $L->g('Save as draft') ?></button>
</div> </div>
<h4 class="mt-4 mb-4 font-weight-normal"><?php $L->p('Advanced') ?></h4>
</div> </div>
<?php
// Username
echo Bootstrap::formInputText(array(
'name'=>'',
'label'=>$L->g('User'),
'placeholder'=>'',
'value'=>$login->username(),
'tip'=>'',
'disabled'=>true
));
// Date
echo Bootstrap::formInputText(array(
'name'=>'date',
'label'=>$L->g('Date'),
'placeholder'=>'',
'value'=>Date::current(DB_DATE_FORMAT),
'tip'=>$L->g('date-format-format')
));
// Type
echo Bootstrap::formSelect(array(
'name'=>'typeTMP',
'label'=>$L->g('Type'),
'selected'=>'',
'options'=>array(
'published'=>'- '.$L->g('Default').' -',
'sticky'=>$L->g('Sticky'),
'static'=>$L->g('Static')
),
'tip'=>''
));
// Parent
echo Bootstrap::formInputText(array(
'name'=>'parentTMP',
'label'=>$L->g('Parent'),
'placeholder'=>'',
'tip'=>$L->g('Start typing a page title to see a list of suggestions.'),
'value'=>''
));
// Position
echo Bootstrap::formInputText(array(
'name'=>'position',
'label'=>$L->g('Position'),
'tip'=>$L->g('Field used when ordering content by position'),
'value'=>$pages->nextPositionNumber()
));
// Template
echo Bootstrap::formInputText(array(
'name'=>'template',
'label'=>$L->g('Template'),
'placeholder'=>'',
'value'=>'',
'tip'=>$L->g('Write a template name to filter the page in the theme and change the style of the page.')
));
// Tags
echo Bootstrap::formInputText(array(
'name'=>'tags',
'label'=>$L->g('Tags'),
'placeholder'=>'',
'tip'=>$L->g('Write the tags separated by comma')
));
echo Bootstrap::formTitle(array('title'=>$L->g('SEO')));
// Friendly URL
echo Bootstrap::formInputText(array(
'name'=>'slug',
'tip'=>$L->g('URL associated with the content'),
'label'=>$L->g('Friendly URL'),
'placeholder'=>$L->g('Leave empty for autocomplete by Bludit.')
));
echo Bootstrap::formCheckbox(array(
'name'=>'noindex',
'label'=>'Robots',
'labelForCheckbox'=>$L->g('apply-code-noindex-code-to-this-page'),
'placeholder'=>'',
'class'=>'mt-4',
'checked'=>false,
'tip'=>$L->g('This tells search engines not to show this page in their search results.')
));
echo Bootstrap::formCheckbox(array(
'name'=>'nofollow',
'label'=>'',
'labelForCheckbox'=>$L->g('apply-code-nofollow-code-to-this-page'),
'placeholder'=>'',
'checked'=>false,
'tip'=>$L->g('This tells search engines not to follow links on this page.')
));
echo Bootstrap::formCheckbox(array(
'name'=>'noarchive',
'label'=>'',
'labelForCheckbox'=>$L->g('apply-code-noarchive-code-to-this-page'),
'placeholder'=>'',
'checked'=>false,
'tip'=>$L->g('This tells search engines not to save a cached copy of this page.')
));
?>
</div> </div>
<script>
$(document).ready(function() {
$("#jsexternalCoverImage").change(function() {
$("#jscoverImage").val( $(this).val() );
});
<!-- Modal for Categories --> $("#jscoverImagePreview").on("click", function() {
<div id="jscategoryModal" class="modal fade" tabindex="-1" role="dialog"> openMediaManager();
<div class="modal-dialog"> });
<div class="modal-content">
<div class="modal-header"> $("#jsbuttonSelectCoverImage").on("click", function() {
<h5 class="modal-title"><?php $L->p('Category') ?></h5> openMediaManager();
</div> });
<div class="modal-body">
<?php $("#jsbuttonRemoveCoverImage").on("click", function() {
echo Bootstrap::formSelectBlock(array( $("#jscoverImage").val('');
'name'=>'category', $("#jscoverImagePreview").attr('src', HTML_PATH_ADMIN_THEME_IMG+'default.svg');
'label'=>'', });
'selected'=>'', });
'class'=>'', </script>
'emptyOption'=>'- '.$L->g('Uncategorized').' -', </div>
'options'=>$categories->getKeyNameArray()
)); <!-- Modal for Categories -->
?> <div id="jscategoryModal" class="modal" tabindex="-1" role="dialog">
</div> <div class="modal-dialog">
<div class="modal-footer"> <div class="modal-content">
<button type="button" class="btn btn-primary" data-dismiss="modal"><?php $L->p('Done') ?></button> <div class="modal-header">
</div> <h5 class="modal-title"><?php $L->p('Category') ?></h5>
</div>
<div class="modal-body">
<?php
echo Bootstrap::formSelectBlock(array(
'name'=>'category',
'label'=>'',
'selected'=>'',
'class'=>'',
'emptyOption'=>'- '.$L->g('Uncategorized').' -',
'options'=>$categories->getKeyNameArray()
));
?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal"><?php $L->p('Done') ?></button>
</div> </div>
</div> </div>
</div> </div>
@ -259,9 +157,9 @@
var selected = $("#jscategory option:selected"); var selected = $("#jscategory option:selected");
var value = selected.val().trim(); var value = selected.val().trim();
if (value) { if (value) {
$("#jscategoryButton").find("span.option").html(selected.text()); $("#jscategoryOpenModal").find("span.option").html(": "+selected.text());
} else { } else {
$("#jscategoryButton").find("span.option").html("-"); $("#jscategoryOpenModal").find("span.option").html("");
} }
} }
@ -274,30 +172,30 @@
}); });
}); });
</script> </script>
</div>
<!-- Modal for Description --> <!-- Modal for Description -->
<div id="jsdescriptionModal" class="modal fade" tabindex="-1" role="dialog"> <div id="jsdescriptionModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title"><?php $L->p('Description') ?></h5> <h5 class="modal-title"><?php $L->p('Description') ?></h5>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<?php <?php
echo Bootstrap::formTextareaBlock(array( echo Bootstrap::formTextareaBlock(array(
'name'=>'description', 'name'=>'description',
'label'=>'', 'label'=>'',
'selected'=>'', 'selected'=>'',
'class'=>'', 'class'=>'',
'value'=>'', 'value'=>'',
'rows'=>3, 'rows'=>3,
'placeholder'=>$L->get('this-field-can-help-describe-the-content') 'placeholder'=>$L->get('this-field-can-help-describe-the-content')
)); ));
?> ?>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal"><?php $L->p('Done') ?></button> <button type="button" class="btn btn-primary" data-dismiss="modal"><?php $L->p('Done') ?></button>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -305,12 +203,10 @@
$(document).ready(function() { $(document).ready(function() {
function setDescriptionBox(value) { function setDescriptionBox(value) {
var value = $("#jsdescription").val(); var value = $("#jsdescription").val();
if (!value) { if (value) {
value = '-'; value = ": "+$.trim(value).substring(0, 30).split(" ").slice(0, -1).join(" ") + "...";
} else {
value = jQuery.trim(value).substring(0, 60).split(" ").slice(0, -1).join(" ") + "...";
} }
$("#jsdescriptionButton").find("span.option").html(value); $("#jsdescriptionOpenModal").find("span.option").html(value);
} }
// Set the current description // Set the current description
@ -322,6 +218,173 @@
}); });
}); });
</script> </script>
</div>
<!-- Modal for More options -->
<div id="jsoptionsModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><?php $L->p('More options') ?></h5>
</div>
<div class="modal-body">
<?php
// Username
echo Bootstrap::formInputText(array(
'name'=>'',
'label'=>$L->g('Author'),
'placeholder'=>'',
'value'=>$login->username(),
'tip'=>'',
'disabled'=>true
));
// Date
echo Bootstrap::formInputText(array(
'name'=>'date',
'label'=>$L->g('Date'),
'placeholder'=>'',
'value'=>Date::current(DB_DATE_FORMAT),
'tip'=>$L->g('date-format-format')
));
// Type
echo Bootstrap::formSelect(array(
'name'=>'typeTMP',
'label'=>$L->g('Type'),
'selected'=>'',
'options'=>array(
'published'=>'- '.$L->g('Default').' -',
'sticky'=>$L->g('Sticky'),
'static'=>$L->g('Static')
),
'tip'=>''
));
// Parent
echo Bootstrap::formInputText(array(
'name'=>'parentTMP',
'label'=>$L->g('Parent'),
'placeholder'=>'',
'tip'=>$L->g('Start typing a page title to see a list of suggestions.'),
'value'=>''
));
// Position
echo Bootstrap::formInputText(array(
'name'=>'position',
'label'=>$L->g('Position'),
'tip'=>$L->g('Field used when ordering content by position'),
'value'=>$pages->nextPositionNumber()
));
// Template
echo Bootstrap::formInputText(array(
'name'=>'template',
'label'=>$L->g('Template'),
'placeholder'=>'',
'value'=>'',
'tip'=>$L->g('Write a template name to filter the page in the theme and change the style of the page.')
));
// Tags
echo Bootstrap::formInputText(array(
'name'=>'tags',
'label'=>$L->g('Tags'),
'placeholder'=>'',
'tip'=>$L->g('Write the tags separated by comma')
));
echo Bootstrap::formTitle(array('title'=>$L->g('SEO')));
// Friendly URL
echo Bootstrap::formInputText(array(
'name'=>'slug',
'tip'=>$L->g('URL associated with the content'),
'label'=>$L->g('Friendly URL'),
'placeholder'=>$L->g('Leave empty for autocomplete by Bludit.')
));
echo Bootstrap::formCheckbox(array(
'name'=>'noindex',
'label'=>'Robots',
'labelForCheckbox'=>$L->g('apply-code-noindex-code-to-this-page'),
'placeholder'=>'',
'class'=>'mt-4',
'checked'=>false,
'tip'=>$L->g('This tells search engines not to show this page in their search results.')
));
echo Bootstrap::formCheckbox(array(
'name'=>'nofollow',
'label'=>'',
'labelForCheckbox'=>$L->g('apply-code-nofollow-code-to-this-page'),
'placeholder'=>'',
'checked'=>false,
'tip'=>$L->g('This tells search engines not to follow links on this page.')
));
echo Bootstrap::formCheckbox(array(
'name'=>'noarchive',
'label'=>'',
'labelForCheckbox'=>$L->g('apply-code-noarchive-code-to-this-page'),
'placeholder'=>'',
'checked'=>false,
'tip'=>$L->g('This tells search engines not to save a cached copy of this page.')
));
?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal"><?php $L->p('Done') ?></button>
</div>
</div>
</div>
<script>
$(document).ready(function() {
// Generate slug when the user type the title
$("#jstitle").keyup(function() {
var text = $(this).val();
var parent = $("#jsparent").val();
var currentKey = "";
var ajax = new bluditAjax();
var callBack = $("#jsslug");
ajax.generateSlug(text, parent, currentKey, callBack);
});
// Datepicker
$("#jsdate").datetimepicker({format:DB_DATE_FORMAT});
// Parent autocomplete
var parentsXHR;
var parentsList; // Keep the parent list returned to get the key by the title page
$("#jsparentTMP").autoComplete({
minChars: 1,
source: function(term, response) {
// Prevent call inmediatly another ajax request
try { parentsXHR.abort(); } catch(e){}
// Get the list of parent pages by title (term)
parentsXHR = $.getJSON(HTML_PATH_ADMIN_ROOT+"ajax/get-parents", {query: term},
function(data) {
parentsList = data;
term = term.toLowerCase();
var matches = [];
for (var title in data) {
if (~title.toLowerCase().indexOf(term))
matches.push(title);
}
response(matches);
});
},
onSelect: function(event, term, item) {
// parentsList = array( pageTitle => pageKey )
var parentKey = parentsList[term];
$("#jsparent").attr("value", parentKey);
}
});
});
</script>
</div>
</form> </form>
<!-- Modal for Media Manager --> <!-- Modal for Media Manager -->
@ -330,43 +393,31 @@
<script> <script>
$(document).ready(function() { $(document).ready(function() {
// Datepicker // Button Publish or Save
$("#jsdate").datetimepicker({format:DB_DATE_FORMAT}); $("#jsbuttonSave").on("click", function() {
// Get the type
// Button Save
$(".jsbuttonSave").on("click", function() {
var type = $("#jstypeTMP option:selected").val(); var type = $("#jstypeTMP option:selected").val();
$("#jstype").val(type); $("#jstype").val(type);
// Get the content
$("#jscontent").val( editorGetContent() ); $("#jscontent").val( editorGetContent() );
// Submit the form
$("#jsform").submit(); $("#jsform").submit();
}); });
// Button Save as draft // Button Save as draft
$(".jsbuttonDraft").on("click", function() { $("#jsbuttonDraft").on("click", function() {
// Set the type as draft
$("#jstype").val("draft"); $("#jstype").val("draft");
// Get the content
$("#jscontent").val( editorGetContent() ); $("#jscontent").val( editorGetContent() );
// Submit the form
$("#jsform").submit(); $("#jsform").submit();
}); });
// External cover image
$("#jsexternalCoverImage").change(function() {
$("#jscoverImage").val( $(this).val() );
});
$("#jsbuttonRemoveCoverImage").on("click", function() {
$("#jscoverImage").val('');
$("#jscoverImagePreview").attr('src', HTML_PATH_ADMIN_THEME_IMG+'default.svg');
});
// Generate slug when the user type the title
$("#jstitle").keyup(function() {
var text = $(this).val();
var parent = $("#jsparent").val();
var currentKey = "";
var ajax = new bluditAjax();
ajax.generateSlug(text, parent, currentKey, $("#jsslug"));
});
// Autosave interval // Autosave interval
// Autosave works when the content of the page is bigger than 100 characters // Autosave works when the content of the page is bigger than 100 characters
setInterval(function() { setInterval(function() {
@ -378,45 +429,5 @@ $(document).ready(function() {
ajax.autosave(uuid, title, content, showAlert); ajax.autosave(uuid, title, content, showAlert);
},1000*60*AUTOSAVE_INTERVAL); },1000*60*AUTOSAVE_INTERVAL);
// Template autocomplete
$('input[name="template"]').autoComplete({
minChars: 2,
source: function(term, suggest){
term = term.toLowerCase();
var choices = ['ActionScript', 'Acti', 'Asp'];
var matches = [];
for (i=0; i<choices.length; i++)
if (~choices[i].toLowerCase().indexOf(term)) matches.push(choices[i]);
suggest(matches);
}
});
// Parent autocomplete
var parentsXHR;
var parentsList; // Keep the parent list returned to get the key by the title page
$("#jsparentTMP").autoComplete({
minChars: 1,
source: function(term, response) {
// Prevent call inmediatly another ajax request
try { parentsXHR.abort(); } catch(e){}
parentsXHR = $.getJSON(HTML_PATH_ADMIN_ROOT+"ajax/get-parents", {query: term},
function(data) {
parentsList = data;
term = term.toLowerCase();
var matches = [];
for (var title in data) {
if (~title.toLowerCase().indexOf(term))
matches.push(title);
}
response(matches);
});
},
onSelect: function(e, term, item) {
// parentsList = array( pageTitle => pageKey )
var parentKey = parentsList[term];
$("#jsparent").attr("value", parentKey);
}
});
}); });
</script> </script>

View File

@ -179,7 +179,7 @@ define('HTML_PATH_UPLOADS_THUMBNAILS', HTML_PATH_UPLOADS.'thumbnails/');
define('HTML_PATH_PLUGINS', HTML_PATH_ROOT.'bl-plugins/'); define('HTML_PATH_PLUGINS', HTML_PATH_ROOT.'bl-plugins/');
// --- Objects with dependency --- // --- Objects with dependency ---
$language = $Language = new Language( $site->language() ); $language = $language = new Language( $site->language() );
$url->checkFilters( $site->uriFilters() ); $url->checkFilters( $site->uriFilters() );
// --- CONSTANTS with dependency --- // --- CONSTANTS with dependency ---

View File

@ -146,7 +146,7 @@ class Paginator {
*/ */
public static function bootstrap_html($textPrevPage=false, $textNextPage=false, $showPageNumber=false){ public static function bootstrap_html($textPrevPage=false, $textNextPage=false, $showPageNumber=false){
global $Language; global $language;
$total_pages = self::numberOfPages(); $total_pages = self::numberOfPages();
$howMany = 2; $howMany = 2;
@ -160,12 +160,12 @@ class Paginator {
$html .= '<ul class="pagination">'; $html .= '<ul class="pagination">';
if ($currentPage > 3 || $currentPage === $total_pages){ if ($currentPage > 3 || $currentPage === $total_pages){
$html .= '<li class="page-item">'; $html .= '<li class="page-item">';
$html .= '<a class="page-link" href="'.self::firstPageUrl().'" aria-label="First"><span aria-hidden="true">&laquo;</span> '.$Language->get('First').'</a>'; $html .= '<a class="page-link" href="'.self::firstPageUrl().'" aria-label="First"><span aria-hidden="true">&laquo;</span> '.$language->get('First').'</a>';
$html .= '</li>'; $html .= '</li>';
} }
if ($currentPage > 1){ if ($currentPage > 1){
$html .= '<li class="page-item'.$show_previois.'">'; $html .= '<li class="page-item'.$show_previois.'">';
$html .= '<a class="page-link" href="'.self::prevPageUrl().'" aria-label="Previous"><span aria-hidden="true">&laquo;</span> '.$Language->get('Previous').'</a>'; $html .= '<a class="page-link" href="'.self::prevPageUrl().'" aria-label="Previous"><span aria-hidden="true">&laquo;</span> '.$language->get('Previous').'</a>';
$html .= '</li>'; $html .= '</li>';
} }
if ($currentPage > $howMany + 1){ if ($currentPage > $howMany + 1){
@ -184,9 +184,9 @@ class Paginator {
} }
if ($currentPage < $total_pages){ if ($currentPage < $total_pages){
$html .= '<li class="page-item'.$show_next.'">'; $html .= '<li class="page-item'.$show_next.'">';
$html .= '<a class="page-link" href="'.self::nextPageUrl().'" aria-label="Next">'.$Language->get('Next').' <span aria-hidden="true">&raquo;</span></a>'; $html .= '<a class="page-link" href="'.self::nextPageUrl().'" aria-label="Next">'.$language->get('Next').' <span aria-hidden="true">&raquo;</span></a>';
$html .= '</li>'; $html .= '</li>';
$html .= '<li><a href="'.$last_page.'">'.$Language->get('Last').'</a></li>'; $html .= '<li><a href="'.$last_page.'">'.$language->get('Last').'</a></li>';
} }
$html .= '</ul>'; $html .= '</ul>';
$html .= '</nav>'; $html .= '</nav>';

View File

@ -26,6 +26,12 @@ class Theme {
return $site->footer(); return $site->footer();
} }
public static function lang()
{
global $language;
return $language->currentLanguageShortVersion();
}
public static function rssUrl() public static function rssUrl()
{ {
if (pluginActivated('pluginRSS')) { if (pluginActivated('pluginRSS')) {

View File

@ -95,4 +95,5 @@ class bluditAjax {
console.log("Bludit AJAX: generateSlug(): always handler"); console.log("Bludit AJAX: generateSlug(): always handler");
}); });
} }
} }

View File

@ -360,5 +360,7 @@
"good-morning": "Good morning", "good-morning": "Good morning",
"good-afternoon": "Good afternoon", "good-afternoon": "Good afternoon",
"good-evening": "Good evening", "good-evening": "Good evening",
"hello": "Hello" "hello": "Hello",
"there-are-no-images-for-the-page": "There are no images for the page.",
"select-cover-image": "Select cover image"
} }

View File

@ -16,11 +16,11 @@ class pluginRemoteContent extends Plugin {
public function form() public function form()
{ {
global $Language; global $language;
if (extension_loaded('zip')===false) { if (extension_loaded('zip')===false) {
$this->formButtons = false; $this->formButtons = false;
return '<div class="alert alert-success">'.$Language->get('the-extension-zip-is-not-installed').'</div>'; return '<div class="alert alert-success">'.$language->get('the-extension-zip-is-not-installed').'</div>';
} }
$html = '<div class="alert alert-primary" role="alert">'; $html = '<div class="alert alert-primary" role="alert">';
@ -28,15 +28,15 @@ class pluginRemoteContent extends Plugin {
$html .= '</div>'; $html .= '</div>';
$html .= '<div>'; $html .= '<div>';
$html .= '<label>'.$Language->get('Webhook').'</label>'; $html .= '<label>'.$language->get('Webhook').'</label>';
$html .= '<input id="jswebhook" name="webhook" type="text" value="'.$this->getValue('webhook').'">'; $html .= '<input id="jswebhook" name="webhook" type="text" value="'.$this->getValue('webhook').'">';
$html .= '<span class="tip">'.DOMAIN_BASE.$this->getValue('webhook').'</span>'; $html .= '<span class="tip">'.DOMAIN_BASE.$this->getValue('webhook').'</span>';
$html .= '</div>'; $html .= '</div>';
$html .= '<div>'; $html .= '<div>';
$html .= '<label>'.$Language->get('Source').'</label>'; $html .= '<label>'.$language->get('Source').'</label>';
$html .= '<input id="jssource" name="source" type="text" value="'.$this->getValue('source').'" placeholder="https://">'; $html .= '<input id="jssource" name="source" type="text" value="'.$this->getValue('source').'" placeholder="https://">';
$html .= '<span class="tip">'.$Language->get('Complete URL of the zip file').'</span>'; $html .= '<span class="tip">'.$language->get('Complete URL of the zip file').'</span>';
$html .= '</div>'; $html .= '</div>';
return $html; return $html;

View File

@ -90,6 +90,7 @@ class pluginsimpleMDE extends Plugin {
$html .= '$(document).ready(function() { '.PHP_EOL; $html .= '$(document).ready(function() { '.PHP_EOL;
$html .= ' $html .= '
$( "#jseditor" ).replaceWith( "<textarea id=\"jseditor\"></textarea>" );
simplemde = new SimpleMDE({ simplemde = new SimpleMDE({
element: document.getElementById("jseditor"), element: document.getElementById("jseditor"),
status: false, status: false,

View File

@ -12,7 +12,7 @@ class pluginTinymce extends Plugin {
$this->dbFields = array( $this->dbFields = array(
'toolbar1'=>'formatselect bold italic bullist numlist | blockquote alignleft aligncenter alignright | link unlink pagebreak image removeformat code', 'toolbar1'=>'formatselect bold italic bullist numlist | blockquote alignleft aligncenter alignright | link unlink pagebreak image removeformat code',
'toolbar2'=>'', 'toolbar2'=>'',
'plugins'=>'code autolink image link pagebreak advlist lists textcolor colorpicker textpattern' 'plugins'=>'code autolink image link pagebreak advlist lists textcolor colorpicker textpattern autoheight'
); );
} }
@ -57,7 +57,7 @@ class pluginTinymce extends Plugin {
$toolbar1 = $this->getValue('toolbar1'); $toolbar1 = $this->getValue('toolbar1');
$toolbar2 = $this->getValue('toolbar2'); $toolbar2 = $this->getValue('toolbar2');
$min_height = '500'; $min_height = '760';
$content_css = $this->htmlPath().'css/bludit.css'; $content_css = $this->htmlPath().'css/bludit.css';
$plugins = $this->getValue('plugins'); $plugins = $this->getValue('plugins');
@ -89,16 +89,16 @@ function editorGetContent() {
return tinymce.get('jseditor').getContent(); return tinymce.get('jseditor').getContent();
} }
$("#jseditor").show(); function resizeEditor() {
var editor = tinymce.activeEditor;
editor.theme.resizeTo("100%", "500px");
}
tinymce.init({ tinymce.init({
selector: "#jseditor", selector: "#jseditor",
auto_focus: "jseditor",
theme: "modern", theme: "modern",
skin: "bludit", skin: "bludit",
min_height: $min_height,
autoresize_min_height: $min_height,
autoresize_bottom_margin: 10,
max_height: 1000,
element_format : "html", element_format : "html",
entity_encoding : "raw", entity_encoding : "raw",
schema: "html5", schema: "html5",
@ -116,7 +116,8 @@ tinymce.init({
toolbar1: "$toolbar1", toolbar1: "$toolbar1",
toolbar2: "$toolbar2", toolbar2: "$toolbar2",
language: "$lang", language: "$lang",
content_css : "$content_css" content_css : "$content_css",
height: 200
}); });
</script> </script>

View File

@ -0,0 +1,41 @@
tinymce.PluginManager.add('autoheight', function(editor) {
var editor_container;
var bars_height = 0;
function resizeEditor(e) {
if (typeof(editor_container) === 'undefined') return;
try {
var element_height = parseInt(window.getComputedStyle(editor_container).height);
/*calculate bar height only once*/
if (bars_height === 0) {
var toolbars = editor_container.querySelectorAll('.mce-toolbar, .mce-statusbar, .mce-menubar');
/*IE11 FIX*/
var toolbarsLength = toolbars.length;
for (var i = 0; i < toolbarsLength; i++) {
var toolbar = toolbars[i];
/*skip sidebar*/
if (!toolbar.classList.contains('mce-sidebar-toolbar')) {
var bar_height = parseInt(window.getComputedStyle(toolbar).height);
bars_height += bar_height;
}
}
}
/*the extra 8 is for margin added between the toolbars*/
new_height = element_height - bars_height - 8;
editor.theme.resizeTo('100%', new_height);
} catch (err) {
console.log(err);
}
}
editor.on('ResizeWindow', resizeEditor);
editor.on("init", function() {
try {
editor_container = editor.getContainer().parentNode;
} catch (e) {}
setTimeout(function() {
resizeEditor();
}, 10);
});
});

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
<svg aria-labelledby="simpleicons-rss-icon" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title id="simpleicons-rss-icon">RSS icon</title><path d="M19.199 24C19.199 13.467 10.533 4.8 0 4.8V0c13.165 0 24 10.835 24 24h-4.801zM3.291 17.415c1.814 0 3.293 1.479 3.293 3.295 0 1.813-1.485 3.29-3.301 3.29C1.47 24 0 22.526 0 20.71s1.475-3.294 3.291-3.295zM15.909 24h-4.665c0-6.169-5.075-11.245-11.244-11.245V8.09c8.727 0 15.909 7.184 15.909 15.91z"/></svg>

After

Width:  |  Height:  |  Size: 470 B