Improved content system, Removed trash, Fixed sitemap

Update .gitignore, .htaccess, and 11 more files...
This commit is contained in:
2022-04-15 04:08:46 +02:00
parent de7bb68b49
commit e2adc41bad
13 changed files with 118 additions and 186 deletions

1
.gitignore vendored
View File

@@ -8,6 +8,5 @@ resources/FontAwesomePro/
resources/GoogleFonts/
# Other folders (Will be removed once the content system is finished !)
content/page/
# /files/*/
files/

View File

@@ -49,9 +49,6 @@ Header always set Access-Control-Allow-Origin "*"
Header unset X-Powered-By
Header always set X-Powered-By "Amiga 1200, Kickstart 3.1"
# Removed the condition to prevent silent errors since the module is required for the website
# <IfModule mod_rewrite.c></IfModule>
# Handling all other redirections.
RewriteEngine On
@@ -67,19 +64,6 @@ RewriteRule ^en/(.*)$ /$1 [QSA]
RewriteRule ^fr/(.*)$ /$1 [QSA]
RewriteRule ^lb/(.*)$ /$1 [QSA]
# Content categories. - Should be removed ?
#RewriteRule ^((en|fr|lb)/)?blog/article/(.*)$ /content/page/$1 [QSA]
#RewriteRule ^((en|fr|lb)/)?programming/(applications|tutorials|tools)/(.*)$ /content/page/$1 [QSA]
##RewriteRule ^((en|fr|lb)/)?electronics/ham/(.*)$ /content/page/$1 [QSA]
# Content root pages. - Should be removed ?
#RewriteRule ^((en|fr|lb)/)?programming/(purebasic|python|others)/(.*)$ /content/$1 [QSA]
#RewriteRule ^((en|fr|lb)/)?electronics/(iot|experiments)/(.*)$ /content/$1 [QSA]
# Content pages. (Old regex are taken care of by the "content/index.php" page)
#RewriteRule ^((en|fr|lb)/)?(blog|programming|electronics|projects)/(.*)$ /content/$1 [QSA]
#RewriteRule ^((en|fr|lb)/)?(content)/(.*)$ /content/$1 [QSA]
# Internal redirections for scanning and exploit attempts.
# These rules are here since they're easier to implement in the .htaccess.
#RewriteRule ^.*(install|xmlrpc)\.php.*$ /honeypot/file-php.php [QSA]
@@ -94,4 +78,3 @@ RewriteRule ^lb/(.*)$ /$1 [QSA]
# * //vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
# TODO: Implement bee-movie themed tarpit once I have a rate-limiting solution in place !

View File

@@ -10,7 +10,7 @@ include_once 'langs.php';
// This helper requires PHP 8 or newer !
$SHOW_CONTENT_DEBUG_CARD = true;
$SHOW_CONTENT_DEBUG_CARD = false;
// Defining constants and enums.
abstract class ContentDisplayType {
@@ -27,6 +27,7 @@ $content_error_message = "";
$requested_tags = array();
$raw_additional_tags = "";
$filtered_content_index_data = NULL;
$requested_item_data = NULL;
// Detecting content display type requested.
$content_requested_url_part = explode("?", explode("#", preg_replace("^\/(content)^", "", l10n_url_switch(NULL)))[0])[0];
@@ -91,7 +92,26 @@ if($requested_content_display_type == ContentDisplayType::SEARCH) {
goto content_end;
}
} elseif($requested_content_display_type == ContentDisplayType::CONTENT) {
// Attempting to get the requested ID.
// Sanitizing the requested ID.
if(!ctype_alnum(str_replace("-", "", $content_requested_url_part))) {
$content_has_error = true;
$content_error_message_key = "error.content.id.alphanumeric";
goto content_end;
}
// Loading the content's data.
$content_file_path = realpath($dir_content . "/items/".$content_requested_url_part.".json");
if($content_file_path) {
// FIXME: Handle JSON errors cleanly
$content_json = file_get_contents($content_file_path);
$requested_item_data = json_decode($content_json, true);
unset($content_json);
} else {
$content_has_error = true;
$content_error_message_key = "error.content.data.not.exist";
goto content_end;
}
unset($content_file_path);
}
content_end:
@@ -100,9 +120,9 @@ $content_error_message = localize($content_error_message_key);
// These functions are placed here to prevent the main file from becoming impossible to read.
function startMainCard($iconClasses, $title, $subTitle) {
echo('<div class="card p-0 mx-0"><div class="px-card py-10 border-bottom px-20"><div class="container-fluid">');
echo('<div class="row"><div class="col-4"><h2 class="card-title font-size-18 m-0">');
echo('<div class="row"><div class="col-8"><h2 class="card-title font-size-18 m-0">');
echo('<i class="'.$iconClasses.'"></i>&nbsp;&nbsp;'.localize($title).'</h2></div>');
echo('<div class="col-8 text-right font-italic"><h2 class="card-title font-size-18 m-0 text-super-muted">'.$subTitle.'</h2>');
echo('<div class="col-4 text-right font-italic"><h2 class="card-title font-size-18 m-0 text-super-muted">'.$subTitle.'</h2>');
echo('</div></div></div></div>');
}

View File

@@ -105,11 +105,15 @@
"error.content.tags.length": "The \"tags\" URL parameter is too long.",
"error.content.tags.alphanumeric": "One of the tags given in the \"tags\" URL parameter is not a valid alphanumeric string.",
"error.content.detect.type": "The type of requested content couldn't be determined.",
"error.content.id.alphanumeric": "The requested resource's ID isn't valid.",
"error.content.data.not.exist": "The requested resource's doesn't have an associated item file.",
"error.content.data.no.title": "No title found !",
"content.title.error": "$content.title.error",
"content.title.search": "Projects search",
"content.title.article": "$content.title.article",
"content.title.application": "$content.title.application",
"content.title.error": "Error",
"content.title.content": "Content",
"content.title.search": "Search",
"content.title.search.card.single": "Search result",
"content.title.search.card.multiple": "Search results",
"content.tags.requested": "Requested tags",
"content.search.count.single": "result",
"content.search.count.multiple": "results",
@@ -219,7 +223,7 @@
"error.404.title": "Erreur 404",
"error.404.description": "La ressource demandée est introuvable sur le serveur !",
"error.content.title.generic": "Erreur de contenu",
"error.content.title.generic": "Erreur",
"error.content.title.empty": "Aucun contenu trouvé",
"error.content.none": "Aucune erreur n'a été détectée.",
"error.content.detect.category": "Impossibilité de détecter la catégorie de contenu demandée.",
@@ -230,11 +234,15 @@
"error.content.tags.length": "Le paramètre d'URL \"tags\" est trop long.",
"error.content.tags.alphanumeric": "Un des tags donné dans le paramètre d'URL \"tags\" n'est pas une chaîne de texte alphanumérique valide.",
"error.content.detect.type": "Le type de contenu désiré n'as pas pu être détecté.",
"error.content.id.alphanumeric": "L'ID de la ressource demandée n'est pas valide.",
"error.content.data.not.exist": "La ressource demandée n'a pas de fichier de données associé.",
"error.content.data.no.title": "Aucun titre trouvé !",
"content.title.error": "$content.title.error",
"content.title.search": "Recherche de projets",
"content.title.article": "$content.title.article",
"content.title.application": "$content.title.application",
"content.title.error": "Erreur de contenu",
"content.title.content": "Content",
"content.title.search": "Recherche de contenu",
"content.title.search.card.single": "Résultat de recherche",
"content.title.search.card.multiple": "Résultats de recherche",
"content.tags.requested": "Tags demandés",
"content.search.count.single": "résultat",
"content.search.count.multiple": "résultats",

View File

@@ -1,113 +0,0 @@
<?php if (basename(__FILE__) == basename($_SERVER["SCRIPT_FILENAME"])) { header('HTTP/1.1 403 Forbidden'); die(); } ?>
<div class="content"><?php
function handleError($errorMessage) {
}
function printBlogPreviewCard($id, $title, $previewPreface, $previewText, $previewImageUrl, $previewImageAlt, $tags, $faIcon) {
echo('<div class="card p-0 mx-0"><div class="px-card py-10 border-bottom px-20"><h2 class="card-title font-size-18 m-0 d-inline-block">
<span class="text-left"><i class="'.$faIcon.'"></i>&nbsp;&nbsp;'.$title.'</span><span class="text-right"></span></h2></div>');
echo('<div class="d-flex"><div class="w-100 h-100 m-10 align-self-center"><div class="w-100 h-100 rounded d-flex align-items-center justify-content-center" style="background-color: #5352ed;">
<img src="'.$previewImageUrl.'" class="d-block w-100 h-100 rounded" loading="lazy" alt="'.$previewImageAlt.'"></div></div><div class="flex-grow-1 overflow-y-hidden d-flex align-items-center position-relative h-120">
<div class="p-10 w-full m-auto">');
if(!empty($previewPreface)) {
echo('<p class="font-size-10 text-dark-lm text-light-dm m-0 mb-5 text-truncate font-weight-medium">'.$previewPreface.'</p>');
}
if(!empty($previewText)) {
echo('<p class="font-size-12 mt-5 mb-0">'.$previewText.'<br><span class="text-primary text-smoothing-auto-dm d-inline-block">Click here <i class="fa fa-angle-right" aria-hidden="true"></i></span></p>');
} else {
echo('<p class="font-size-12 mt-5 mb-0"><span class="text-primary text-smoothing-auto-dm d-inline-block">Click here <i class="fa fa-angle-right" aria-hidden="true"></i></span></p>');
}
echo('</div><div class="sponsor-section-card-scroll-block"></div></div></div>');
echo('<div class="px-card py-10 bg-light-lm bg-very-dark-dm rounded-bottom px-20"><p class="font-size-12 m-0"><i class="fad fa-tags"></i>');
foreach($tags as &$tagValue) {
echo('&nbsp;&nbsp;<a href="?c=t&t='.$tagValue.'">#'.$tagValue.'</a>');
}
echo('</p></div></div>');
}
/* Defining globals and constants */
const BLOG_ACTION_NONE = "n";
const BLOG_ACTION_SEARCH_TAGS = "t";
const BLOG_ACTION_SEARCH_AUTHOR = "a";
const BLOG_ACTION_SEARCH_DATE = "d";
//const BLOG_ACTION_ERROR_SEARCH_TYPE_INVALID = "e";
const BLOG_PARAM_ACTION = "c";
const BLOG_PARAM_ARTICLE_PER_PAGE = "c";
const BLOG_PARAM_PAGE = "p";
const BLOG_PARAM_SEARCH_PARAM = "s";
$blog_action = BLOG_ACTION_NONE;
$blog_search_parameter = "";
$current_page = 0;
$article_per_page = 10;
/* Parsing and verifying arguments */
if(count($_GET) > 0) {
if(array_key_exists(BLOG_PARAM_ACTION, $_GET)) {
$blog_action = $_GET[BLOG_PARAM_ACTION];
}
if(array_key_exists(BLOG_PARAM_ARTICLE_PER_PAGE, $_GET)) {
$article_per_page = $_GET[BLOG_PARAM_ARTICLE_PER_PAGE];
}
if(array_key_exists(BLOG_PARAM_PAGE, $_GET)) {
$current_page = $_GET[BLOG_PARAM_PAGE];
}
if(array_key_exists(BLOG_PARAM_SEARCH_PARAM, $_GET)) {
$blog_search_parameter = $_GET[BLOG_PARAM_SEARCH_PARAM];
}
}
if(!($blog_action == BLOG_ACTION_NONE || $blog_action == BLOG_ACTION_SEARCH_TAGS ||
$blog_action == BLOG_ACTION_SEARCH_AUTHOR || $blog_action == BLOG_ACTION_SEARCH_DATE)) {
$blog_action = BLOG_ACTION_NONE;
}
if(!is_numeric($article_per_page)) {
$article_per_page = 10;
}
if(!is_numeric($current_page)) {
$current_page = 0;
}
/* Loading blog entries */
$jsonArticles = null;
try {
$jsonArticles = file_get_contents("articles.json");
$jsonArticles = json_decode($jsonArticles, true);
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
$jsonArticles = null;
}
if($jsonArticles == null) {
exit("An error occured during the JSON parsing process...");
}
/* Printing the articles... */
$currentArticleId = 0;
$articlesLeft = $article_per_page;
//TODO: Max value is not right or checked yet !
for($currentArticleId = ($article_per_page * $current_page); $currentArticleId < count($jsonArticles); $currentArticleId++) {
//echo($jsonArticles[$currentArticleId]["id"]."<br>");
printBlogPreviewCard(
$jsonArticles[$currentArticleId]["id"],
$jsonArticles[$currentArticleId]["title"],
$jsonArticles[$currentArticleId]["preview"]["preface"],
$jsonArticles[$currentArticleId]["preview"]["text"],
$jsonArticles[$currentArticleId]["preview"]["image"],
$jsonArticles[$currentArticleId]["preview"]["imageAlt"],
$jsonArticles[$currentArticleId]["tags"],
$jsonArticles[$currentArticleId]["preview"]["icon"]);
}
?></div>

View File

@@ -41,7 +41,7 @@
},
"image": "/resources/Azias/imgs/lscom-v2-text-01-bkgd-cli.png",
"tags": [
"application", "lscom", "purebasic"
"application", "lscom", "purebasic", "windows"
]
}
]
]

View File

@@ -44,12 +44,35 @@ if($content_has_error) {
<div class="container-fluid">
<div id="page-title-bar" class="card p-0 pl-20 m-0 square-corners bg-very-dark title-bkgd navbar">
<h2 class="content-title font-size-24 mt-20 text-truncate">
<i class="fad fa-mailbox"></i>&nbsp;${TODO}
<i class="fad fa-briefcase"></i>&nbsp;&nbsp;<?php
if($content_has_error) {
if(isset($_SERVER['HTTP_REFERER'])) {
echo('<a href="'.$_SERVER['HTTP_REFERER'].'">'.localize("content.title.content").'</a>');
} else {
//echo('<a class="js-set-previous-url" href="#">'.localize("content.title.content").'</a>');
echo(localize("content.title.content"));
}
echo('<span class="mx-10">❱</span>'.localize("content.title.error"));
} elseif($requested_content_display_type == ContentDisplayType::SEARCH) {
echo(localize("content.title.content").'<span class="mx-10">❱</span>'.localize("content.title.search"));
} elseif($requested_content_display_type == ContentDisplayType::CONTENT) {
echo(localize("content.title.content").'<span class="mx-10">❱</span>$TODO');
}
?>
</h2>
<?php include 'header-lang.php'; ?>
</div>
<div class="content mx-auto w-lg-p90">
<?php
startMainCard("fad fa-construction", "Under construction", "");
echo('<div class="py-20 bg-light-lm rounded-bottom px-0 bg-very-dark title-bkgd">');
echo('<div class="content m-0 mx-20">');
echo('<h3 class="font-size-18 mb-5 font-weight-semi-bold content-search-title">');
echo('<span class="font-weight-bold">15/04/2021</span> - This section is under construction...</h3>');
echo('</div>');
echo('</div>');
endMainCard();
if($SHOW_CONTENT_DEBUG_CARD) {
echo('<div class="card p-0 mx-0">
<div class="px-card py-10 border-bottom px-20">
@@ -74,6 +97,12 @@ if($content_has_error) {
print_r($filtered_content_index_data);
echo('</p>');
echo('<p class="m-0 mb-5">$content_requested_url_part: '.$content_requested_url_part.'</p>');
if($requested_content_display_type == ContentDisplayType::CONTENT) {
echo('<hr class="subtle mb-10 mt-15">');
echo('<p class="m-0 mb-5">$requested_item_data: ');
print_r($requested_item_data);
echo('</p>');
}
echo('</div></div>');
}
@@ -139,10 +168,36 @@ if($content_has_error) {
'</p></div>');
endMainCard();
} elseif($requested_content_display_type == ContentDisplayType::CONTENT) {
startMainCard("fad fa-file-alt", localize("content.title.content"), "subtitle");
endMainCard();
$_title_icon = "fad fa-question";
$_title_text = '<i>' . localize("error.content.data.no.title") . '</i>';
if (array_key_exists("title", $requested_item_data)) {
if (array_key_exists("icon", $requested_item_data["title"])) {
$_title_icon = $requested_item_data["title"]["icon"];
}
if (array_key_exists($user_language, $requested_item_data["title"])) {
$_title_text = $requested_item_data["title"][$user_language];
} elseif (array_key_exists($default_language, $requested_item_data["title"])) {
$_title_text = $requested_item_data["title"][$user_language];
}
}
startMainCard($_title_icon, $_title_text, "");
echo('<div class="py-20 bg-light-lm rounded-bottom px-0 bg-very-dark title-bkgd">');
echo('<div class="content m-0 mx-20">');
echo('<p class="my-0">Text will go here...</p>');
echo('</div>');
echo('</div>');
echo('<div class="px-card py-10 bg-light-lm bg-dark-dm rounded-bottom border-top">' .
'<p class="font-size-12 m-0">' .
'Card footer here.' .
'</p></div>');
endMainCard();
}
content_printing_end:
?>
</div>

View File

@@ -1,9 +1,13 @@
{
"title": {
"icon": "fad fa-terminal",
"en": "PB-ListComPort - CLI COM port enumerator",
"fr": "PB-ListComPort - Enumérateur de port COM pour invité de commande"
},
"tags": [
"programming", "lscom"
]
],
"toggles": {
"downloads": true
}
}

View File

@@ -1,3 +0,0 @@
{
"_": "Is this file used anywhere ? - Referenced as the id in the article index"
}

View File

@@ -1,4 +0,0 @@
* Add bottom margin to the last container in the content container for small screens
* Maybe for big ones too ?
* Does not happen on the privacy one, probably because all of them are shown.
* Small is done !

View File

@@ -3,6 +3,14 @@ document.getElementById('button-sidebar').addEventListener("click", () => {
halfmoon.toggleSidebar();
});
// Adding the last URL to every a element with the 'js-set-previous-url' class.
/*document.querySelectorAll("a.js-set-previous-url").forEach(element => {
element.href = document.referrer;
element.addEventListener('click', function(e) {
window.history.go(-2);
});
});*/
// TOX ID copiers. (Contact page)
if(document.getElementById('button-copy-tox-id-main') != null) {
document.getElementById('button-copy-tox-id-main').addEventListener("click", () => {

View File

@@ -1,41 +1,17 @@
https://nibblepoker.lu/
https://nibblepoker.lu/blog/
https://nibblepoker.lu/programming/
https://nibblepoker.lu/programming/applications/
https://nibblepoker.lu/programming/tutorials/
https://nibblepoker.lu/programming/tools/
https://nibblepoker.lu/programming/purebasic/
https://nibblepoker.lu/programming/python/
https://nibblepoker.lu/programming/docker/
https://nibblepoker.lu/programming/java/
https://nibblepoker.lu/content/
https://nibblepoker.lu/links/
https://nibblepoker.lu/about/
https://nibblepoker.lu/contact/
https://nibblepoker.lu/privacy/
https://nibblepoker.lu/en/
https://nibblepoker.lu/en/blog/
https://nibblepoker.lu/en/programming/
https://nibblepoker.lu/en/programming/applications/
https://nibblepoker.lu/en/programming/tutorials/
https://nibblepoker.lu/en/programming/tools/
https://nibblepoker.lu/en/programming/purebasic/
https://nibblepoker.lu/en/programming/python/
https://nibblepoker.lu/en/programming/docker/
https://nibblepoker.lu/en/programming/java/
https://nibblepoker.lu/en/content/
https://nibblepoker.lu/en/links/
https://nibblepoker.lu/en/about/
https://nibblepoker.lu/en/contact/
https://nibblepoker.lu/en/privacy/
https://nibblepoker.lu/fr/
https://nibblepoker.lu/fr/blog/
https://nibblepoker.lu/fr/programming/
https://nibblepoker.lu/fr/programming/applications/
https://nibblepoker.lu/fr/programming/tutorials/
https://nibblepoker.lu/fr/programming/tools/
https://nibblepoker.lu/fr/programming/purebasic/
https://nibblepoker.lu/fr/programming/python/
https://nibblepoker.lu/fr/programming/docker/
https://nibblepoker.lu/fr/programming/java/
https://nibblepoker.lu/fr/content/
https://nibblepoker.lu/fr/links/
https://nibblepoker.lu/fr/about/
https://nibblepoker.lu/fr/contact/

View File

@@ -1 +0,0 @@
Test123