implemented preview of article markdown via AJAX
This commit is contained in:
+25
-23
@@ -2,56 +2,58 @@
|
||||
|
||||
<footer>
|
||||
<?php
|
||||
function get_args_from_url()
|
||||
{
|
||||
function get_args_from_url()
|
||||
{
|
||||
$args = [];
|
||||
$arr = explode('&', $_SERVER['QUERY_STRING']);
|
||||
|
||||
foreach ($arr as $a) {
|
||||
$tmp = explode('=', $a);
|
||||
$key = $tmp[0];
|
||||
$value = $tmp[1];
|
||||
$tmp = explode('=', $a);
|
||||
$key = $tmp[0];
|
||||
$value = $tmp[1];
|
||||
|
||||
$args[$key] = $value;
|
||||
$args[$key] = $value;
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
}
|
||||
|
||||
if ($_SERVER['SCRIPT_NAME'] == '/user.php') {
|
||||
if ($_SERVER['SCRIPT_NAME'] == '/user.php') {
|
||||
$args = get_args_from_url();
|
||||
|
||||
if (isset($args['action'])) {
|
||||
if ($args['action'] == 'signup') {
|
||||
echo '
|
||||
if ($args['action'] == 'signup') {
|
||||
echo '
|
||||
<script src="js/profile_picture_cropper_modal.js"></script>
|
||||
<script src="js/upload.js"></script>
|
||||
';
|
||||
} else if ($args['action'] == 'view') {
|
||||
echo '
|
||||
';
|
||||
} else if ($args['action'] == 'view') {
|
||||
echo '
|
||||
<script src="js/user_actions_modal.js"></script>
|
||||
<script src="js/profile_picture_cropper_modal.js"></script>
|
||||
<script src="js/upload.js"></script>
|
||||
';
|
||||
}
|
||||
';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($_SERVER['SCRIPT_NAME'] == '/admin.php') {
|
||||
} else if ($_SERVER['SCRIPT_NAME'] == '/admin.php') {
|
||||
echo '
|
||||
<script src="js/clickable_rows.js"></script>
|
||||
';
|
||||
$args = get_args_from_url();
|
||||
|
||||
if (isset($args['view'])) {
|
||||
if ($args['view'] == 'users') {
|
||||
echo '
|
||||
if ($args['view'] == 'users') {
|
||||
echo '
|
||||
<script src="js/upload.js"></script>
|
||||
';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
} else if ($_SERVER['SCRIPT_NAME'] == '/compose.php') {
|
||||
echo '
|
||||
<script src="js/md_preview.js"></script>
|
||||
';
|
||||
}
|
||||
?>
|
||||
</footer>
|
||||
|
||||
</html>
|
||||
|
||||
+60
-38
@@ -4,77 +4,87 @@ require_once 'functions/functions.php';
|
||||
include_once 'functions/article_functions.php';
|
||||
|
||||
if (!empty($_POST)) {
|
||||
if (isset($_POST['article_id'])) {
|
||||
$tags = [];
|
||||
for ($i = 0; $i < count($_POST['tags']); $i++)
|
||||
$tags[] = $_POST['tags'][$i];
|
||||
if (isset($_POST['article_id'])) {
|
||||
$tags = [];
|
||||
for ($i = 0; $i < count($_POST['tags']); $i++)
|
||||
$tags[] = $_POST['tags'][$i];
|
||||
|
||||
update_article($_POST['article_id'], $_POST['title'], $_POST['excerpt'], $tags, $_POST['markdown']);
|
||||
header('Location: articles.php?article_id=' . $_POST['article_id']);
|
||||
} else {
|
||||
$id = create_article($_COOKIE['user_id'], $_POST['title'], $_POST['excerpt'], (isset($_POST['tags']) ? $_POST['tags'] : []), $_POST['markdown']);
|
||||
header('Location: articles.php?article_id=' . $id);
|
||||
}
|
||||
update_article($_POST['article_id'], $_POST['title'], $_POST['excerpt'], $tags, $_POST['markdown']);
|
||||
header('Location: articles.php?article_id=' . $_POST['article_id']);
|
||||
} else {
|
||||
$id = create_article($_COOKIE['user_id'], $_POST['title'], $_POST['excerpt'], (isset($_POST['tags']) ? $_POST['tags'] : []), $_POST['markdown']);
|
||||
header('Location: articles.php?article_id=' . $id);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($_COOKIE['role_id']) || $_COOKIE['role_id'] == 4)
|
||||
header('Location: articles.php');
|
||||
header('Location: articles.php');
|
||||
|
||||
include_once 'components/head.php';
|
||||
|
||||
if (isset($_GET['article_id'])) {
|
||||
$article_id = $_GET['article_id'];
|
||||
$article_id = $_GET['article_id'];
|
||||
|
||||
$conn = get_connection();
|
||||
$stmt = $conn->prepare('SELECT * FROM article WHERE article_id = ?');
|
||||
$stmt->bind_param('i', $article_id);
|
||||
$stmt->execute();
|
||||
$article = $stmt->get_result()->fetch_assoc();
|
||||
$conn = get_connection();
|
||||
$stmt = $conn->prepare('SELECT * FROM article WHERE article_id = ?');
|
||||
$stmt->bind_param('i', $article_id);
|
||||
$stmt->execute();
|
||||
$article = $stmt->get_result()->fetch_assoc();
|
||||
|
||||
$stmt = $conn->prepare('SELECT tag_id FROM article_tags WHERE article_id = ?');
|
||||
$stmt->bind_param('i', $article_id);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
$tags = [];
|
||||
while ($row = $result->fetch_assoc())
|
||||
$tags[] = $row['tag_id'];
|
||||
$stmt = $conn->prepare('SELECT tag_id FROM article_tags WHERE article_id = ?');
|
||||
$stmt->bind_param('i', $article_id);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
$tags = [];
|
||||
while ($row = $result->fetch_assoc())
|
||||
$tags[] = $row['tag_id'];
|
||||
|
||||
$title = $article['title'];
|
||||
$excerpt = $article['excerpt'];
|
||||
$existing_markdown = read_file_one_string($_ENV['ARTICLES_FQ_PATH'] . $article_id . '/article.md');
|
||||
$title = $article['title'];
|
||||
$excerpt = $article['excerpt'];
|
||||
$existing_markdown = read_file_one_string($_ENV['ARTICLES_FQ_PATH'] . $article_id . '/article.md');
|
||||
}
|
||||
|
||||
echo '
|
||||
<div class="grid-2x1">
|
||||
';
|
||||
if (!empty($existing_markdown)) {
|
||||
echo form($article_id, $title, $excerpt, $existing_markdown, $tags);
|
||||
echo form($article_id, $title, $excerpt, $existing_markdown, $tags);
|
||||
} else {
|
||||
echo form();
|
||||
echo form();
|
||||
}
|
||||
|
||||
echo preview();
|
||||
|
||||
echo '
|
||||
</div>
|
||||
';
|
||||
|
||||
include_once 'components/foot.php';
|
||||
|
||||
function form($article_id = null, $title = null, $excerpt = null, $existing_markdown = null, $tags = null)
|
||||
{
|
||||
$raw_tags = article_tags();
|
||||
$tags_boxes = '
|
||||
$raw_tags = article_tags();
|
||||
$tags_boxes = '
|
||||
<div class="checkboxes">
|
||||
<label>Tags</label>
|
||||
';
|
||||
|
||||
foreach ($raw_tags as $row) {
|
||||
$tags_boxes .= '
|
||||
foreach ($raw_tags as $row) {
|
||||
$tags_boxes .= '
|
||||
<label class="form_checkbox_container">' . $row['tag'] . '
|
||||
<input name="tags[]" value="' . $row['tag_id'] . '" type="checkbox"' . (isset($tags) && in_array($row['tag_id'], $tags) ? ' checked' : '') . '>
|
||||
<span class="checkmark"></span>
|
||||
</label>
|
||||
';
|
||||
}
|
||||
}
|
||||
|
||||
$tags_boxes .= '
|
||||
$tags_boxes .= '
|
||||
</div>
|
||||
';
|
||||
|
||||
$form = '
|
||||
<div class="form_card">
|
||||
$form = '
|
||||
<div class="full-height">
|
||||
<div class="form_card" id="composer">
|
||||
<form method="post">
|
||||
' . (isset($article_id) ? '<input type="hidden" name="article_id" value="' . $article_id . '">' : '') . '
|
||||
|
||||
@@ -90,8 +100,20 @@ function form($article_id = null, $title = null, $excerpt = null, $existing_mark
|
||||
<input class="button" type="submit" value="' . (isset($article_id) ? 'Update Article' : 'Create Article') . '">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
return $form;
|
||||
function preview()
|
||||
{
|
||||
$preview = '
|
||||
<div class="full-height">
|
||||
<div class="form_card" id="md_preview">
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
|
||||
return $preview;
|
||||
}
|
||||
|
||||
+58
-2
@@ -168,6 +168,7 @@ code {
|
||||
.view_card {
|
||||
margin: 0 auto;
|
||||
margin-top: 50px;
|
||||
margin-bottom: 50px;
|
||||
width: 70%;
|
||||
padding: 18px;
|
||||
height: max-content;
|
||||
@@ -335,6 +336,7 @@ textarea {
|
||||
margin: 15px 15px 15px 0px;
|
||||
box-sizing: border-box;
|
||||
transition-duration: 500ms;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
input:focus,
|
||||
@@ -348,10 +350,12 @@ textarea:hover {
|
||||
|
||||
textarea {
|
||||
border-radius: 18px;
|
||||
height: 500px;
|
||||
height: 70%;
|
||||
}
|
||||
|
||||
.checkboxes {}
|
||||
.checkboxes {
|
||||
height: max-content;
|
||||
}
|
||||
|
||||
input[type="radio"] {
|
||||
display: none;
|
||||
@@ -639,6 +643,58 @@ input[type="file"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
::selection {
|
||||
color: black;
|
||||
background: orange;
|
||||
}
|
||||
|
||||
.grid-2x1 {
|
||||
margin: 0 auto;
|
||||
width: 90%;
|
||||
display: grid;
|
||||
grid-template-columns: 50% 50%;
|
||||
|
||||
}
|
||||
|
||||
.grid-2x1 .form_card,
|
||||
.grid-2x1 #md_preview {
|
||||
width: 80%;
|
||||
height: 90%;
|
||||
overflow-y: scroll;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.grid-2x1 #composer {
|
||||
padding-top: 150px;
|
||||
}
|
||||
|
||||
#md_preview {
|
||||
border: none;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.full-height {
|
||||
height: 700px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
background-color: black;
|
||||
border-radius: 18px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
display: none;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: orange;
|
||||
border-radius: 9px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 992px) {
|
||||
h1 {
|
||||
font-size: 10vw;
|
||||
|
||||
@@ -92,12 +92,6 @@ function article_page_from_markdown($article_id)
|
||||
$parsedown = new Parsedown();
|
||||
$parsedown->setSafeMode(true);
|
||||
$article_content = $parsedown->text($markdown);
|
||||
$article_toc = '';
|
||||
|
||||
$lines = preg_split("/\r\n|\n|\r/", $article_content);
|
||||
foreach ($lines as $line)
|
||||
if (str_contains($line, '<h4>'))
|
||||
$article_toc .= '<p>' . extract_content_from_tag($line, '<h4>', '</h4>') . '</p><br>';
|
||||
|
||||
$html = '
|
||||
<div class="article">
|
||||
@@ -116,14 +110,9 @@ function article_page_from_markdown($article_id)
|
||||
</div>
|
||||
</div>
|
||||
<div class="line" style="margin-bottom: 15px;"></div>
|
||||
<div class="article_grid">
|
||||
<div class="article_toc">
|
||||
' . $article_toc . '
|
||||
</div>
|
||||
<div class="article_content">
|
||||
' . $article_content . '
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
require_once 'vendor/autoload.php';
|
||||
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
|
||||
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/..');
|
||||
$dotenv->safeLoad();
|
||||
|
||||
// Use environment variables for the database password and IP address.
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
session_start();
|
||||
header("Content-Security-Policy: default-src 'self'; font-src 'self' https://www.nerdfonts.com/assets/fonts/Symbols-2048-em%20Nerd%20Font%20Complete.woff2; style-src 'self' 'unsafe-inline' https://nerdfonts.com/assets/css/webfont.css https://www.nerdfonts.com/assets/css/webfont.css; script-src 'self'; img-src 'self';");
|
||||
require_once '../vendor/autoload.php';
|
||||
|
||||
$markdown = urldecode($_POST['markdown']);
|
||||
|
||||
$parsedown = new Parsedown();
|
||||
$parsedown->setSafeMode(true);
|
||||
$article_content = $parsedown->text($markdown);
|
||||
|
||||
echo $article_content;
|
||||
@@ -1,18 +1,15 @@
|
||||
<?php
|
||||
// Initializes environment variables and other stuff.
|
||||
// if (!isset($_SESSION['initialized']))
|
||||
require_once 'functions/init.php';
|
||||
require_once 'functions/functions.php';
|
||||
include_once 'components/head.php';
|
||||
|
||||
|
||||
echo home_content();
|
||||
|
||||
include_once 'components/foot.php';
|
||||
|
||||
function home_content()
|
||||
{
|
||||
$content = '
|
||||
$content = '
|
||||
<div class="article">
|
||||
<h1>Vintage Coding</h1>
|
||||
<h3>Intentional Craftsmanship Over Ephemeral Trends</h3>
|
||||
@@ -34,5 +31,5 @@ function home_content()
|
||||
</div>
|
||||
';
|
||||
|
||||
return $content;
|
||||
return $content;
|
||||
}
|
||||
|
||||
+3
-4
@@ -1,9 +1,8 @@
|
||||
// Optional: Real-time preview using JavaScript
|
||||
const textarea = document.querySelector('textarea');
|
||||
const preview = document.getElementById('preview');
|
||||
const preview = document.getElementById('md_preview');
|
||||
|
||||
textarea.addEventListener('input', function() {
|
||||
fetch('preview.php', { // Create a separate preview.php file for real-time updates
|
||||
fetch('functions/preview.php', { // Create a separate preview.php file for real-time updates
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
@@ -12,6 +11,6 @@ textarea.addEventListener('input', function() {
|
||||
})
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
preview.innerHTML = data;
|
||||
preview.innerHTML = decodeURIComponent(data);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user