9 Commits
10 changed files with 280 additions and 112 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ smoother for your content editing experience.
* No Database Required: NeoCMS works without a database, so you don’t have to worry about setup hassles or performance * No Database Required: NeoCMS works without a database, so you don’t have to worry about setup hassles or performance
slowdowns. slowdowns.
* Easy Content Editing: With our intuitive WYSIWYG editor, anyone can update content without writing a single line of * Easy Content Editing: With our intuitive WYSIWYG editor, anyone can update content without writing a single line of
code. code. Adding the additional class *neo-dupe* will allow an element and it's children to be cloned.
* Seamless Integration: Simply add the CMS to any existing static website. Just assign a special class to the elements * Seamless Integration: Simply add the CMS to any existing static website. Just assign a special class to the elements
you want to make editable, and you’re all set. you want to make editable, and you’re all set.
* Consistent Layouts: NeoCMS supports page templates to keep your layouts neat and uniform across all pages. * Consistent Layouts: NeoCMS supports page templates to keep your layouts neat and uniform across all pages.
+13 -4
View File
@@ -12,7 +12,7 @@ body {
.pageContainer .controls { .pageContainer .controls {
flex: 0 1 auto; flex: 0 1 auto;
height: 70px; height: 60px;
background-color: #666666; background-color: #666666;
border-bottom: 1px solid #1a1a1a; border-bottom: 1px solid #1a1a1a;
-webkit-box-shadow: 0 10px 13px -7px #000000, -1px -1px 15px 5px rgba(0, 0, 0, 0); -webkit-box-shadow: 0 10px 13px -7px #000000, -1px -1px 15px 5px rgba(0, 0, 0, 0);
@@ -27,19 +27,19 @@ body {
.controls .logo { .controls .logo {
background-image: url("/cms/img/logo.png"); background-image: url("/cms/img/logo.png");
width: 128px; width: 128px;
height: 70px; height: 60px;
display: block; display: block;
position: absolute; position: absolute;
} }
.controls .buttonContainer { .controls .buttonContainer {
width: 400px; width: 400px;
margin: 18px auto; margin: 12px auto;
} }
.controls .loggedInDetails { .controls .loggedInDetails {
position: absolute; position: absolute;
top: 25px; top: 12px;
right: 10px; right: 10px;
} }
@@ -72,6 +72,11 @@ body {
.blueButton:hover { .blueButton:hover {
background: #415989 linear-gradient(to bottom, #415989 5%, #2e466e 100%); background: #415989 linear-gradient(to bottom, #415989 5%, #2e466e 100%);
color: #ffffff; color: #ffffff;
text-decoration: none;
}
.blueButton:active {
text-decoration: none;
} }
.greenButton { .greenButton {
@@ -92,11 +97,15 @@ body {
.greenButton:hover { .greenButton:hover {
background: #72b352 linear-gradient(to bottom, #72b352 5%, #77b55a 100%); background: #72b352 linear-gradient(to bottom, #72b352 5%, #77b55a 100%);
color: #ffffff; color: #ffffff;
text-decoration: none;
} }
.greenButton:active { .greenButton:active {
position: relative; position: relative;
top: 1px; top: 1px;
text-decoration: none;
} }
-65
View File
@@ -1,65 +0,0 @@
/* General Styles */
body {
margin: 0;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f9f9f9;
color: #333;
}
/* Header Styles */
header {
background-color: #1b6ac9;
padding: 20px;
text-align: center;
}
.logo {
height: 80px;
}
/* Main Content Styles */
main {
text-align: center;
padding: 60px 20px;
}
h1 {
font-size: 2.5em;
color: #1b6ac9;
margin-bottom: 20px;
}
p {
font-size: 1.1em;
line-height: 1.6;
max-width: 700px;
margin: 10px auto;
}
/* Button Styles */
.button {
display: inline-block;
margin-top: 30px;
padding: 15px 30px;
background-color: #1b6ac9;
color: #fff;
text-decoration: none;
font-size: 1em;
border-radius: 5px;
transition: background-color 0.3s ease;
}
.button:hover {
background-color: #155a9c;
}
/* Footer Styles */
footer {
background-color: #333;
color: #fff;
padding: 15px 0;
text-align: center;
position: fixed;
width: 100%;
bottom: 0;
}
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

+1 -1
View File
@@ -44,7 +44,7 @@ require_once "init.php";
?> ?>
</div> </div>
</div> </div>
<iframe id="frameContainer" src="welcome.html" class="frame"></iframe> <iframe id="frameContainer" src="<?php echo $skipWelcomePage ? "/" : "welcome.html"; ?>" class="frame"></iframe>
</div> </div>
<!-- Modal --> <!-- Modal -->
<div id="editModal" class="modal fade" role="dialog"> <div id="editModal" class="modal fade" role="dialog">
+3
View File
@@ -8,6 +8,9 @@ $authentication = [
"editor" => "password", "editor" => "password",
]; ];
// Set to true if you do not want to see the welcome page and want to go straight to your site
$skipWelcomePage = false;
/** /**
* DO NOT CHANGE ANYTHING BENEATH THIS LINE - IT WILL BUGGER STUFF UP * DO NOT CHANGE ANYTHING BENEATH THIS LINE - IT WILL BUGGER STUFF UP
*/ */
+111 -5
View File
@@ -11,9 +11,15 @@ $(document).ready(function () {
// Set up click handler on divs with class 'editable' in the iframe // Set up click handler on divs with class 'editable' in the iframe
$(iframeDoc).find('.editable').css('cursor', 'pointer').click(function (event) { $(iframeDoc).find('.editable').css('cursor', 'pointer').click(function (event) {
editElement(event, $(this));
});
// Edit Element Shared functionality
function editElement(event, element) {
event.preventDefault(); event.preventDefault();
currentDiv = $(this); currentDiv = element;
// Get the content of the div // Get the content of the div
const content = currentDiv.html(); const content = currentDiv.html();
@@ -21,7 +27,7 @@ $(document).ready(function () {
// Set the content in TinyMCE // Set the content in TinyMCE
$('#editor').val(content); $('#editor').val(content);
// Open the modal and init tinyMCE // Open the modal and init TinyMCE
$('#editModal').modal('show') $('#editModal').modal('show')
.on('shown.bs.modal', function () { .on('shown.bs.modal', function () {
tinymce.init({ tinymce.init({
@@ -37,13 +43,65 @@ $(document).ready(function () {
images_upload_credentials: true, images_upload_credentials: true,
force_br_newlines: false, force_br_newlines: false,
force_p_newlines: false, force_p_newlines: false,
forced_root_block: 'aaa',
newline_behavior: 'linebreak' newline_behavior: 'linebreak'
}); });
}); });
}
regenerateButtons();
// Set up event handlers for duplication buttons inside the iframe
$(iframeDoc).on('click', '.duplicate-btn-before', function () {
var parentElement = $(this).closest('.neo-dupe');
var clonedElement = $(parentElement).clone();
// Remove buttons from the cloned element
clonedElement.find('.button-container').remove();
// Add system classes
clonedElement.addClass("neo-dupe");
clonedElement.addClass("editable");
// Insert the cloned element before the original parent element
clonedElement.insertBefore(parentElement);
// Trigger an event on the new duplicated element
clonedElement.trigger('elementDuplicated');
}); });
$(iframeDoc).on('click', '.duplicate-btn-after', function () {
var parentElement = $(this).closest('.neo-dupe');
var clonedElement = $(parentElement).clone();
// Remove buttons from the cloned element
clonedElement.find('.button-container').remove();
// Add system classes
clonedElement.addClass("neo-dupe");
clonedElement.addClass("editable");
// Insert the cloned element after the original parent element
clonedElement.insertAfter(parentElement);
// Trigger an event on the new duplicated element
clonedElement.trigger('elementDuplicated');
}); });
// Handle the custom 'elementDuplicated' event
$(iframeDoc).on('elementDuplicated', '.neo-dupe', function (event) {
// Example action: Animate the new element
$(this).hide().fadeIn('slow');
// Remove buttons if they are there
$(this).find('.button-container').remove();
editElement(event, $(this));
});
// Here for addButtonsForNeoDupe
});
// Save changes made to a div, but not save to the file on the server // Save changes made to a div, but not save to the file on the server
$('#saveBtn').click(function () { $('#saveBtn').click(function () {
// Get the data from TinyMCE // Get the data from TinyMCE
@@ -70,7 +128,16 @@ $(document).ready(function () {
// Handle Saving changes to the page // Handle Saving changes to the page
$('#savePage').click(() => { $('#savePage').click(() => {
frameContainerElement = $('#frameContainer').contents().get(0);
// Remove the buttons container as not to make things awks
$(iframeDoc).find('.button-container').remove();
// Remove pointer cursor, but need to find a proper way of removing the cursor inline style, so we can get rid of any unneeded inline styles
$(iframeDoc).find('.editable, .neo-dupe').css('cursor', 'default');
// Get page content and save it
let frameContainerElement = $('#frameContainer').contents().get(0);
$.post("/cms/controller/", { $.post("/cms/controller/", {
action: "save", action: "save",
uri: frameContainerElement.location.pathname, uri: frameContainerElement.location.pathname,
@@ -81,8 +148,8 @@ $(document).ready(function () {
} else { } else {
showMessage(data.message, "error"); showMessage(data.message, "error");
} }
// alert(data)
}); });
regenerateButtons();
}); });
// Show dialog for page templates // Show dialog for page templates
@@ -192,10 +259,48 @@ $(document).ready(function () {
}); });
}); });
// Add buttons to all existing neo-dupe elements inside the iframe
function regenerateButtons() {
$(iframeDoc).find('.neo-dupe').each(function () {
$(this).find('.buttonContainer').remove();
addButtonsToNeoDupe(this);
});
}
// Function to add buttons to a neo-dupe element inside the iframe
function addButtonsToNeoDupe(element) {
/**
* DANGER WILL ROBINSON: This may break stuff, but is needed for the buttons to be positioned properly
* Since this is alpha, lets see how we go.
*/
if ($(element).css('position') === 'static') {
$(element).css('position', 'relative');
}
var $buttonContainer = $(iframeDoc.createElement('div'));
$buttonContainer.addClass('button-container');
$buttonContainer.css("position", "absolute");
$buttonContainer.css("top", "5px");
$buttonContainer.css("right", "5px");
var $duplicateBeforeButton = $(iframeDoc.createElement('button'));
$duplicateBeforeButton.addClass('duplicate-btn-before').text('◀️').prop('title', 'Clone before');
var $duplicateAfterButton = $(iframeDoc.createElement('button'));
$duplicateAfterButton.addClass('duplicate-btn-after').text('▶️').prop('title', 'Clone after');
// Append buttons to the container
$buttonContainer.append($duplicateBeforeButton, $duplicateAfterButton);
// Prepend the container to the neo-dupe element
$(element).prepend($buttonContainer);
}
}); });
/** /**
* Show A message bar across the top of the screen for a few seconds * Show a message bar across the top of the screen for a few seconds
* @param message - string - message to be shown * @param message - string - message to be shown
* @param type - string "success" or "error" * @param type - string "success" or "error"
*/ */
@@ -232,3 +337,4 @@ function showMessage(message, type) {
messageBar.slideUp(); messageBar.slideUp();
}, 5000); }, 5000);
} }
+142 -27
View File
@@ -1,32 +1,147 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head>
<head> <meta charset="UTF-8" />
<meta charset="UTF-8"> <title>NeoCMS - Super Lightweight CMS</title>
<title>Welcome to NeoCMS</title> <!-- Bootstrap CSS -->
<link href="/cms/css/welcome.style.css" rel="stylesheet"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" />
</head> <!-- Material Design Bootstrap -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.20.0/css/mdb.min.css" />
<!-- Custom Styles -->
<style>
body {
padding-top: 70px;
background-color: #ECEFF1;
}
.feature-icon {
font-size: 50px;
margin-bottom: 20px;
color: #2196F3;
}
.footer {
padding: 20px 0;
background-color: #CFD8DC;
}
.jumbotron {
background-color: #90CAF9;
color: #FFFFFF;
}
h2 {
color: #1976D2;
}
.btn-primary {
background-color: #1976D2;
border: none;
}
.btn-primary:hover {
background-color: #1565C0;
}
</style>
<style type="text/css">/* Chart.js */
@-webkit-keyframes chartjs-render-animation{from{opacity:0.99}to{opacity:1}}@keyframes chartjs-render-animation{from{opacity:0.99}to{opacity:1}}.chartjs-render-monitor{-webkit-animation:chartjs-render-animation 0.001s;animation:chartjs-render-animation 0.001s;}</style><style type="text/css">/* Chart.js */
@-webkit-keyframes chartjs-render-animation{from{opacity:0.99}to{opacity:1}}@keyframes chartjs-render-animation{from{opacity:0.99}to{opacity:1}}.chartjs-render-monitor{-webkit-animation:chartjs-render-animation 0.001s;animation:chartjs-render-animation 0.001s;}</style></head>
<body> <body>
<header>
<img alt="Application Logo" class="logo" src="/cms/img/welcomeLogo.png">
</header>
<main>
<h1>Welcome to NeoCMS</h1>
<p>Introducing a cutting-edge CMS designed to effortlessly integrate with your existing flat-file website—no
database required. Our databaseless WYSIWYG content management system empowers you to create, edit, and manage
content visually, all while maintaining the simplicity and speed of a flat-file setup. Enjoy a seamless
experience that combines the flexibility of a modern CMS with the efficiency of a static website, allowing you
to focus on content without the complexity of database management. Perfect for developers and creators looking
to streamline workflows without sacrificing control or performance.</p>
<p class="editable"> <!-- Header -->
This box is editable! Just click me to edit me!<br/> <header class="jumbotron text-center">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. <h1 class="display-4">Welcome to NeoCMS! 🎉</h1>
Quisque sit amet accumsan tortor. Itaque earum rerum hic tenetur a sapiente delectus. <p class="lead editable" style="cursor: default;">The super lightweight, database-free content management system!</p>
<a href="/" class="btn btn-primary btn-lg waves-effect waves-light" target="_blank">Start Editing your Website</a>
</header>
<!-- Version Section -->
<section class="container my-5">
<h2 class="text-center mb-4">You are running version 2.0! ✨</h2>
<p class="text-center editable" style="cursor: default;">This page is editable for you to familiarise yourself with how Neo works! Any editable blocks will have a hand pointer instead of your usual pointer.</p>
</section>
<!-- Features Section -->
<section class="container my-5">
<h2 class="text-center mb-4">Features 🚀</h2>
<div class="row">
<div class="col-md-6">
<div class="media mb-4">
<div class="feature-icon mr-3">📦</div>
<div class="editable media-body" style="cursor: default;">
<h5 class="mt-0">No Database Required</h5>
<p>NeoCMS works without a database, so you don’t have to worry about setup hassles or performance slowdowns.</p>
</div>
</div>
<div class="media mb-4">
<div class="feature-icon mr-3">✏️</div>
<div class="editable media-body" style="cursor: default;">
<h5 class="mt-0">Easy Content Editing</h5>
<p>With our intuitive WYSIWYG editor, anyone can update content without writing a single line of code. Adding the additional class <code>neo-dupe</code> will allow an element and its children to be cloned.</p>
</div>
</div>
</div>
<div class="col-md-6">
<div class="media mb-4">
<div class="feature-icon mr-3">🔗</div>
<div class="editable media-body" style="cursor: default;">
<h5 class="mt-0">Seamless Integration</h5>
<p>Simply add the CMS to any existing static website. Assign a special class to the elements you want to make editable, and you’re all set.</p>
</div>
</div>
<div class="media mb-4">
<div class="feature-icon mr-3">🖼️</div>
<div class="editable media-body" style="cursor: default;">
<h5 class="mt-0">Consistent Layouts</h5>
<p>NeoCMS supports page templates to keep your layouts neat and uniform across all pages.</p>
</div>
</div>
</div>
</div>
</section>
<!-- Requirements Section -->
<section class="container my-5">
<h2 class="text-center mb-4">Requirements 📝</h2>
<p class="text-center">NeoCMS requires the following:</p>
<ul class="list-group list-group-flush">
<li class="list-group-item">PHP 8 running on a Linux server. (May work on Windows servers, but we don't want to stoop to that level 😉)</li>
</ul>
</section>
<!-- Known Issues Section -->
<section class="container my-5">
<h2 class="text-center mb-4">Known Bugs &amp; Issues 🐞</h2>
<ul class="list-group list-group-flush editable" style="cursor: default;">
<li class="list-group-item"><strong>File Uploads (non-image):</strong> Currently, file uploads are not fully implemented. We're working on it!</li>
<li class="list-group-item"><strong>Testing:</strong> The system is functional, but it hasn’t been fully tested in all scenarios.</li>
</ul>
</section>
<!-- License Section -->
<section class="container my-5">
<h2 class="text-center mb-4">License 📄</h2>
<p class="text-center">NeoCMS is open-source software licensed under the GNU General Public License v3.0 (GPLv3). You are free to use, modify, and distribute this software under the terms of this license.</p>
<p class="text-center">For more information, see the full <a href="#" target="_blank">GPLv3 License</a> found in <code>LICENSE</code>.</p>
</section>
<!-- Bug Report Section -->
<section class="container my-5">
<h2 class="text-center mb-4">Found a Bug? 🐛</h2>
<p class="text-center">If you run into any issues or have feature requests, please submit them on our <a href="https://github.com/andydixon/neoCMS/issues" target="_blank">GitHub issues page</a>. Your feedback helps us improve NeoCMS!</p>
</section>
<!-- Footer -->
<footer class="footer text-center">
<div class="container editable" style="cursor: default;">
<p>© 2024 <a href="https://www.andydixon.com">Andy Dixon</a>. All rights reserved.</p>
<p>
<a href="https://github.com/andydixon/neoCMS/issues" target="_blank">Report an Issue</a>
</p> </p>
<a class="button" href="/">Get Started with your website</a> </div>
</main>
<footer>
<p>&copy; 2024 Andy Dixon</p>
</footer> </footer>
</body>
</html> <!-- Bootstrap JS and dependencies -->
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<!-- Material Design Bootstrap JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.20.0/js/mdb.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<div class="hiddendiv common"></div></body></html>
+1 -1
View File
@@ -6,6 +6,6 @@
<body> <body>
<div class="editable">This is editable content 1.</div> <div class="editable">This is editable content 1.</div>
<div class="editable">This is editable content 2.</div> <div class="editable">This is editable content 2.</div>
<div class="editable">This is editable content 3.</div> <div class="editable neo-dupe">This is editable content 3, and this element can be cloned.</div>
</body> </body>
</html> </html>