Add basic page editing and saving in control panel
This commit is contained in:
parent
b377e57b5d
commit
aef29f18ab
19
action.php
19
action.php
@ -7,7 +7,6 @@
|
||||
/**
|
||||
* Make things happen when buttons are pressed and forms submitted.
|
||||
*/
|
||||
|
||||
require_once __DIR__ . "/required.php";
|
||||
|
||||
if ($VARS['action'] !== "signout") {
|
||||
@ -32,8 +31,24 @@ function returnToSender($msg, $arg = "") {
|
||||
|
||||
switch ($VARS['action']) {
|
||||
case "saveedits":
|
||||
$page = $VARS['page'];
|
||||
header("Content-Type: application/json");
|
||||
$slug = $VARS['slug'];
|
||||
$site = $VARS['site'];
|
||||
$content = $VARS['content'];
|
||||
if ($database->has("pages", ["AND" => ["slug" => $slug, "siteid" => $site]])) {
|
||||
$pageid = $database->get("pages", "pageid", ["AND" => ["slug" => $slug, "siteid" => $site]]);
|
||||
} else {
|
||||
die(json_encode(["status" => "ERROR", "msg" => "Invalid page or site"]));
|
||||
}
|
||||
foreach ($content as $name => $value) {
|
||||
if ($database->has("components", ["AND" => ["pageid" => $pageid, "name" => $name]])) {
|
||||
$database->update("components", ["content" => $value], ["AND" => ["pageid" => $pageid, "name" => $name]]);
|
||||
} else {
|
||||
$database->insert("components", ["name" => $name, "content" => $value, "pageid" => $pageid]);
|
||||
}
|
||||
}
|
||||
exit(json_encode(["status" => "OK"]));
|
||||
break;
|
||||
case "signout":
|
||||
session_destroy();
|
||||
header('Location: index.php');
|
||||
|
BIN
database.mwb
BIN
database.mwb
Binary file not shown.
@ -28,7 +28,18 @@ define("STRINGS", [
|
||||
"login server error" => "The login server returned an error: {arg}",
|
||||
"login server user data error" => "The login server refused to provide account information. Try again or contact technical support.",
|
||||
"captcha error" => "There was a problem with the CAPTCHA (robot test). Try again.",
|
||||
"actions" => "Actions",
|
||||
"home" => "Home",
|
||||
"more" => "More",
|
||||
"test" => "Test"
|
||||
"sites" => "Sites",
|
||||
"theme" => "Theme",
|
||||
"name" => "Name",
|
||||
"site name" => "Site Name",
|
||||
"url" => "URL",
|
||||
"editing site" => "Editing {site}",
|
||||
"theme type" => "Theme type",
|
||||
"single page" => "Single page",
|
||||
"multiple page" => "Multiple page",
|
||||
"templates" => "Templates",
|
||||
"color styles" => "Color styles"
|
||||
]);
|
@ -59,7 +59,11 @@ function get_page_url($echo = true, $slug = null) {
|
||||
if ($slug == null) {
|
||||
$slug = get_page_slug(false);
|
||||
}
|
||||
$url = get_site_url(false) . "index.php?id=$slug";
|
||||
$edit = "";
|
||||
if (isset($_GET['edit'])) {
|
||||
$edit = "&edit";
|
||||
}
|
||||
$url = get_site_url(false) . "index.php?id=$slug$edit";
|
||||
if ($echo) {
|
||||
echo $url;
|
||||
} else {
|
||||
|
23
pages.php
23
pages.php
@ -11,6 +11,29 @@ define("PAGES", [
|
||||
"navbar" => true,
|
||||
"icon" => "fas fa-home"
|
||||
],
|
||||
"sites" => [
|
||||
"title" => "sites",
|
||||
"navbar" => true,
|
||||
"icon" => "fas fa-sitemap"
|
||||
],
|
||||
"sitesettings" => [
|
||||
"title" => "settings",
|
||||
"styles" => [
|
||||
"static/css/themeselector.css"
|
||||
],
|
||||
"scripts" => [
|
||||
"static/js/sitesettings.js"
|
||||
]
|
||||
],
|
||||
"editor" => [
|
||||
"title" => "editor",
|
||||
"styles" => [
|
||||
"static/css/editorparent.css"
|
||||
],
|
||||
"scripts" => [
|
||||
"static/js/editorparent.js"
|
||||
]
|
||||
],
|
||||
"404" => [
|
||||
"title" => "404 error"
|
||||
]
|
||||
|
71
pages/editor.php
Normal file
71
pages/editor.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
require_once __DIR__ . '/../required.php';
|
||||
|
||||
redirectifnotloggedin();
|
||||
|
||||
if (!is_empty($VARS['siteid'])) {
|
||||
if ($database->has('sites', ['siteid' => $VARS['siteid']])) {
|
||||
$sitedata = $database->get(
|
||||
'sites', [
|
||||
'siteid',
|
||||
'sitename',
|
||||
'url',
|
||||
'theme',
|
||||
'color'
|
||||
], [
|
||||
'siteid' => $VARS['siteid']
|
||||
]);
|
||||
$pagedata = $database->select(
|
||||
'pages', [
|
||||
"pageid",
|
||||
"slug",
|
||||
"title",
|
||||
"template"
|
||||
], ["siteid" => $VARS['siteid']]
|
||||
);
|
||||
$slug = "index";
|
||||
if (isset($VARS['slug']) && $database->has('pages', ["AND" => ['slug' => $VARS['slug'], 'siteid' => $VARS['siteid']]])) {
|
||||
$slug = $VARS['slug'];
|
||||
}
|
||||
} else {
|
||||
header('Location: app.php?page=sites');
|
||||
die();
|
||||
}
|
||||
} else {
|
||||
header('Location: app.php?page=sites');
|
||||
die();
|
||||
}
|
||||
?>
|
||||
<div class="row mb-2">
|
||||
<div class="col-12 col-sm-6 col-md-4">
|
||||
<div class="btn btn-success" id="savebtn">
|
||||
<i class="fas fa-save"></i> <?php lang("save"); ?>
|
||||
</div>
|
||||
</div>
|
||||
<form method="GET" action="app.php" class="col-12 col-sm-6 col-md-4">
|
||||
<input type="hidden" name="page" value="editor" />
|
||||
<input type="hidden" name="siteid" value="<?php echo $VARS['siteid']; ?>" />
|
||||
<div class="input-group">
|
||||
<select name="slug" class="form-control">
|
||||
<?php
|
||||
foreach ($pagedata as $p) {
|
||||
$selected = "";
|
||||
if ($slug == $p['slug']) {
|
||||
$selected = " selected";
|
||||
}
|
||||
echo "<option value=\"" . $p['slug'] . "\"$selected>" . $p['title'] . ' (' . $p['slug'] . ')' . "</option>\n";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<div class="input-group-append">
|
||||
<button type="submit" class="btn btn-primary"><?php lang("edit"); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<iframe id="editorframe" src="public/index.php?id=<?php echo $slug; ?>&edit"></iframe>
|
60
pages/sites.php
Normal file
60
pages/sites.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
require_once __DIR__ . '/../required.php';
|
||||
|
||||
redirectifnotloggedin();
|
||||
?>
|
||||
<div class="btn-group">
|
||||
<a href="app.php?page=addsite" class="btn btn-success"><i class="fas fa-plus"></i> <?php lang("new site"); ?></a>
|
||||
</div>
|
||||
<table id="cattable" class="table table-bordered table-hover table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-priority="0"></th>
|
||||
<th data-priority="1"><?php lang('actions'); ?></th>
|
||||
<th data-priority="1"><i class="fas fa-font d-none d-md-inline"></i> <?php lang('site name'); ?></th>
|
||||
<th data-priority="2"><i class="fas fa-globe d-none d-md-inline"></i> <?php lang('url'); ?></th>
|
||||
<th data-priority="3"><i class="fas fa-paint-brush d-none d-md-inline"></i> <?php lang('theme'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$sites = $database->select('sites', [
|
||||
'siteid',
|
||||
'sitename',
|
||||
'url',
|
||||
'theme',
|
||||
'color'
|
||||
]);
|
||||
foreach ($sites as $site) {
|
||||
$theme = json_decode(file_get_contents("public/themes/".$site['theme']."/theme.json"), true);
|
||||
$themename = $theme["name"];
|
||||
?>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<a class="btn btn-primary btn-sm" href="app.php?page=editor&siteid=<?php echo $site['siteid']; ?>"><i class="fas fa-edit"></i> <?php lang("editor"); ?></a>
|
||||
<a class="btn btn-secondary btn-sm" href="app.php?page=sitesettings&siteid=<?php echo $site['siteid']; ?>"><i class="fas fa-cog"></i> <?php lang("settings"); ?></a>
|
||||
<a class="btn btn-info btn-sm" href="<?php echo $site['url']; ?>" target="_BLANK"><i class="fas fa-eye"></i> <?php lang("view"); ?></a>
|
||||
</td>
|
||||
<td><?php echo $site['sitename']; ?></td>
|
||||
<td><?php echo $site['url']; ?></td>
|
||||
<td><?php echo $themename; ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th data-priority="0"></th>
|
||||
<th data-priority="1"><?php lang('actions'); ?></th>
|
||||
<th data-priority="1"><i class="fas fa-font d-none d-md-inline"></i> <?php lang('site name'); ?></th>
|
||||
<th data-priority="2"><i class="fas fa-globe d-none d-md-inline"></i> <?php lang('url'); ?></th>
|
||||
<th data-priority="3"><i class="fas fa-paint-brush d-none d-md-inline"></i> <?php lang('theme'); ?></th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
97
pages/sitesettings.php
Normal file
97
pages/sitesettings.php
Normal file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
require_once __DIR__ . '/../required.php';
|
||||
|
||||
redirectifnotloggedin();
|
||||
|
||||
if (!is_empty($VARS['siteid'])) {
|
||||
if ($database->has('sites', ['siteid' => $VARS['siteid']])) {
|
||||
$sitedata = $database->select(
|
||||
'sites', [
|
||||
'siteid',
|
||||
'sitename',
|
||||
'url',
|
||||
'theme',
|
||||
'color'
|
||||
], [
|
||||
'siteid' => $VARS['siteid']
|
||||
])[0];
|
||||
} else {
|
||||
header('Location: app.php?page=sites');
|
||||
}
|
||||
} else {
|
||||
header('Location: app.php?page=sites');
|
||||
}
|
||||
?>
|
||||
|
||||
<form role="form" action="action.php" method="POST">
|
||||
<div class="card border-light-blue">
|
||||
<h3 class="card-header text-light-blue">
|
||||
<i class="fas fa-edit"></i> <?php lang2("editing site", ['site' => "<span id=\"name_title\">" . htmlspecialchars($sitedata['sitename']) . "</span>"]); ?>
|
||||
</h3>
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<label for="name"><i class="fas fa-font"></i> <?php lang("name"); ?></label>
|
||||
<input type="text" class="form-control" id="name" name="name" placeholder="Foo Bar" required="required" value="<?php echo htmlspecialchars($sitedata['sitename']); ?>" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="url"><i class="fas fa-globe"></i> <?php lang("url"); ?></label>
|
||||
<input type="text" class="form-control" id="url" name="url" placeholder="https://example.com" required="required" value="<?php echo htmlspecialchars($sitedata['url']); ?>" />
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="form-group">
|
||||
<label for="style"><i class="fas fa-paint-brush"></i> <?php lang('theme'); ?></label>
|
||||
<div class="theme_bin">
|
||||
<?php
|
||||
$themedir = __DIR__ . "/../public/themes/";
|
||||
$themes = array_diff(scandir($themedir), array('..', '.'));
|
||||
foreach ($themes as $t) {
|
||||
if (!file_exists($themedir . "$t/theme.json")) {
|
||||
continue;
|
||||
}
|
||||
$info = json_decode(file_get_contents($themedir . "$t/theme.json"), TRUE);
|
||||
$ts = $sitedata["theme"] == $t ? " checked" : "";
|
||||
?>
|
||||
<label>
|
||||
<input type="radio" name="style" value="<?php echo $t; ?>" <?php echo $ts; ?> />
|
||||
<div class="card theme">
|
||||
<div class="card-body m-0 p-1">
|
||||
<b><?php echo $info['name']; ?></b><br />
|
||||
<?php
|
||||
lang("theme type");
|
||||
echo ": ";
|
||||
if ($info['singlepage'] == true) {
|
||||
lang("single page");
|
||||
} else {
|
||||
lang("multiple page");
|
||||
}
|
||||
?><br />
|
||||
<?php lang("templates");
|
||||
echo ": " . count($info['templates']);
|
||||
?><br />
|
||||
<?php lang("color styles");
|
||||
echo ": " . count($info['colors']);
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="siteid" value="<?php echo htmlspecialchars($VARS['siteid']); ?>" />
|
||||
<input type="hidden" name="action" value="sitesettings" />
|
||||
<input type="hidden" name="source" value="sites" />
|
||||
|
||||
<div class="card-footer d-flex">
|
||||
<button type="submit" class="btn btn-success mr-auto"><i class="fas fa-save"></i> <?php lang("save"); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -19,12 +19,13 @@ include __DIR__ . "/themes/$theme/$template.php";
|
||||
|
||||
if (isset($_GET['edit'])) {
|
||||
?>
|
||||
<link href="<?php echo URL; ?>/static/css/summernote-lite.css" rel="stylesheet" />
|
||||
<style><?php echo str_replace("./font/summernote", "../static/fonts/summernote", file_get_contents(__DIR__ . "/../static/css/summernote-lite.css")); ?></style>
|
||||
<script src="<?php echo URL; ?>/static/js/jquery-3.3.1.min.js"></script>
|
||||
<script src="<?php echo URL; ?>/static/js/summernote-lite.js"></script>
|
||||
<script>
|
||||
var save_url = "<?php echo URL; ?>/action.php";
|
||||
var static_dir = "<?php echo URL; ?>/static";
|
||||
var page_slug = "<?php getpageslug(); ?>";
|
||||
static_dir = "<?php echo URL; ?>/static";
|
||||
page_slug = "<?php echo getpageslug(); ?>";
|
||||
site_id = "<?php echo getsiteid(); ?>";
|
||||
</script>
|
||||
<script src="<?php echo URL; ?>/static/js/editor.js"></script>
|
||||
<?php
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"name": "Bootstrap",
|
||||
"singlepage": false,
|
||||
"templates": {
|
||||
"default": {
|
||||
"title": "Default",
|
||||
|
@ -49,7 +49,7 @@ if ($_SESSION['mobile'] === TRUE) {
|
||||
. "object-src 'none'; "
|
||||
. "img-src * data:; "
|
||||
. "media-src 'self'; "
|
||||
. "frame-src 'none'; "
|
||||
. "frame-src 'self'; "
|
||||
. "font-src 'self'; "
|
||||
. "connect-src *; "
|
||||
. "style-src 'self' 'nonce-$SECURE_NONCE' $captcha_server; "
|
||||
|
@ -4,11 +4,32 @@ License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
.sw-text-input {
|
||||
border: 2px dashed red;
|
||||
input[type="text"].sw-text-input {
|
||||
border: 2px dashed red !important;
|
||||
width: 100%;
|
||||
color: black !important;
|
||||
background: white !important;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.note-editor {
|
||||
border: 2px dashed red !important;
|
||||
}
|
||||
|
||||
button.note-btn, .note-modal button {
|
||||
box-shadow: none;
|
||||
color: #333 !important;
|
||||
}
|
||||
|
||||
.note-modal .close {
|
||||
color: #000 !important;
|
||||
}
|
||||
|
||||
.note-modal .checkbox label input[type="checkbox"] {
|
||||
opacity: 1;
|
||||
margin-right: 1px;
|
||||
appearance: checkbox;
|
||||
-moz-appearance: checkbox;
|
||||
-webkit-appearance: checkbox;
|
||||
-ms-appearance: checkbox;
|
||||
}
|
12
static/css/editorparent.css
Normal file
12
static/css/editorparent.css
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#editorframe {
|
||||
border: 1px solid black;
|
||||
width: 100%;
|
||||
height: 1000px;
|
||||
max-height: calc(100vh - 200px);
|
||||
}
|
25
static/css/themeselector.css
Normal file
25
static/css/themeselector.css
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
.theme_bin {
|
||||
max-height: 300px;
|
||||
overflow-y: scroll;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.theme_bin label input[type=radio] {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.theme_bin label input[type=radio] + .theme {
|
||||
cursor: pointer;
|
||||
border: 3px solid white;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.theme_bin label input[type=radio]:checked + .theme {
|
||||
border: 3px solid rgba(0,0,0,.8);
|
||||
}
|
@ -4,6 +4,25 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
function saveEdits() {
|
||||
var components = {};
|
||||
$(".sw-editable").each(function (e) {
|
||||
components[$(this).data("component")] = $(this).summernote('code');
|
||||
});
|
||||
$(".sw-text-input").each(function (e) {
|
||||
components[$(this).data("component")] = $(this).val();
|
||||
});
|
||||
var output = {
|
||||
slug: page_slug,
|
||||
site: site_id,
|
||||
content: components
|
||||
};
|
||||
//console.log(output);
|
||||
var json = JSON.stringify(output);
|
||||
console.log("editor: sent page content");
|
||||
parent.postMessage('save ' + json, "*");
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
$("body").append("<link href=\"" + static_dir + "/css/editor.css\" rel=\"stylesheet\" />");
|
||||
|
||||
@ -20,7 +39,7 @@ $(document).ready(function () {
|
||||
['fontsize', ['fontsize']],
|
||||
['para', ['ul', 'ol']],
|
||||
['insert', ['link', 'picture']],
|
||||
['misc', ['undo', 'redo', 'fullscreen', 'codeview']]
|
||||
['misc', ['undo', 'redo', 'codeview']]
|
||||
],
|
||||
placeholder: 'Click to edit'
|
||||
});
|
||||
@ -30,21 +49,11 @@ $(document).ready(function () {
|
||||
var component = $(this).data("component");
|
||||
$(this).html("<input type=\"text\" data-component=\"" + component + "\" class=\"sw-text-input\" value=\"" + text + "\" placeholder=\"Click to edit\">");
|
||||
});
|
||||
});
|
||||
|
||||
function saveEdits() {
|
||||
var components = [];
|
||||
$(".sw-editable").each(function (e) {
|
||||
components[$(this).data("component")] = $(this).summernote('code');
|
||||
window.addEventListener('message', function (event) {
|
||||
console.log("editor: received message: " + event.data);
|
||||
if (event.data == "save") {
|
||||
saveEdits();
|
||||
}
|
||||
});
|
||||
$(".sw-text-input").each(function (e) {
|
||||
components[$(this).data("component")] = $(this).val();
|
||||
});
|
||||
var content = JSON.stringify(components);
|
||||
console.log(components);
|
||||
$.post(save_url, {
|
||||
action: "saveedits",
|
||||
page: "",
|
||||
content: content
|
||||
});
|
||||
}
|
||||
});
|
38
static/js/editorparent.js
Normal file
38
static/js/editorparent.js
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
function save(json) {
|
||||
var output = JSON.parse(json);
|
||||
console.log(output);
|
||||
$.post("action.php", {
|
||||
action: "saveedits",
|
||||
source: "editor",
|
||||
slug: output["slug"],
|
||||
site: output["site"],
|
||||
content: output["content"]
|
||||
}, function (data) {
|
||||
if (data.status == "OK") {
|
||||
alert("Saved");
|
||||
} else {
|
||||
alert(data.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('message', function (event) {
|
||||
//console.log("parent: received message: " + event.data);
|
||||
if (event.data.startsWith("save ")) {
|
||||
save(event.data.slice(5));
|
||||
}
|
||||
});
|
||||
|
||||
$("#savebtn").click(function () {
|
||||
triggerSave();
|
||||
});
|
||||
|
||||
function triggerSave() {
|
||||
document.getElementById("editorframe").contentWindow.postMessage("save", "*");
|
||||
}
|
7
static/js/sitesettings.js
Normal file
7
static/js/sitesettings.js
Normal file
@ -0,0 +1,7 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
$('#name').on('input propertychange paste', function () {
|
||||
$('#name_title').text($('#name').val());
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user