diff --git a/.gitignore b/.gitignore
index 0f521b3..e731746 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+
/vendor/
+.docker_vols
sftp.json
\ No newline at end of file
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000..e69de29
diff --git a/docker_dev/Dockerfile b/docker_dev/Dockerfile
index 6440854..2060d63 100644
--- a/docker_dev/Dockerfile
+++ b/docker_dev/Dockerfile
@@ -2,7 +2,7 @@ FROM composer
WORKDIR /app
COPY www/composer.* .
-RUN composer install
+COPY www/vendor/* vendor/
FROM php:apache
WORKDIR /var/www/html
diff --git a/docker_dev/compose.yaml b/docker_dev/compose.yaml
index 1b9493d..5a25529 100644
--- a/docker_dev/compose.yaml
+++ b/docker_dev/compose.yaml
@@ -24,7 +24,7 @@ services:
- ../.git
- mysql_schema.sql
volumes:
- - website_datavolume:/var/www/html/raw
+ - ../.docker_vols/web:/var/www/html/raw
mysql:
build:
@@ -42,7 +42,4 @@ services:
- path: mysql_schema.sql
action: rebuild
volumes:
- - sqlvolume:/var/lib/mysql
-volumes:
- sqlvolume: {}
- website_datavolume: {}
+ - ../.docker_vols/sql:/var/lib/mysql
diff --git a/docker_dev/mysql_schema.sql b/docker_dev/mysql_schema.sql
index baf0a58..97645e6 100644
--- a/docker_dev/mysql_schema.sql
+++ b/docker_dev/mysql_schema.sql
@@ -3,35 +3,59 @@ CREATE DATABASE dragon_fire;
USE dragon_fire;
+-- DROP TABLE posts;
+-- DROP TABLE path_access_counts;
+-- DROP TABLE path_errcodes;
+-- DROP TABLE feed_cache;
+
CREATE TABLE posts (
post_id INTEGER AUTO_INCREMENT,
host VARCHAR(64) NOT NULL,
+
post_path VARCHAR(255) NOT NULL,
post_path_depth INTEGER NOT NULL DEFAULT 0,
- post_create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
- post_update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ post_created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ post_updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
- post_access_count INTEGER DEFAULT 0,
+ post_view_count INTEGER DEFAULT 0,
- post_metadata JSON NOT NULL,
+ post_title VARCHAR(1024),
+ post_tags VARCHAR(1024),
+ post_brief TEXT(2048),
+
+ post_metadata JSON DEFAULT NULL,
post_settings_cache JSON DEFAULT NULL,
- post_content MEDIUMTEXT,
-
PRIMARY KEY(post_id),
CONSTRAINT unique_post UNIQUE (host, post_path),
INDEX(host, post_path),
- INDEX(post_path_depth, post_path),
- INDEX(post_create_time),
- INDEX(post_update_time)
+ INDEX(host, post_path_depth, post_path),
+
+ INDEX(host, post_created_at),
+ INDEX(host, post_updated_at),
+
+ FULLTEXT(post_tags)
+);
+
+CREATE TABLE post_markdown (
+ post_id INTEGER,
+
+ post_markdown TEXT,
+
+ PRIMARY KEY(post_id),
+ FOREIGN KEY(post_id) REFERENCES posts(post_id)
+ ON DELETE CASCADE,
+
+ FULLTEXT(post_markdown)
);
CREATE TABLE path_access_counts (
access_time DATETIME NOT NULL,
host VARCHAR(64) NOT NULL,
+
post_path VARCHAR(255),
agent VARCHAR(255),
referrer VARCHAR(255),
@@ -42,6 +66,17 @@ CREATE TABLE path_access_counts (
PRIMARY KEY(access_time, host, post_path, agent, referrer)
);
+CREATE TABLE path_errcodes (
+ access_timestamp DATETIME NOT NULL,
+
+ host VARCHAR(64) NOT NULL,
+
+ post_path VARCHAR(255),
+ agent VARCHAR(255),
+ referrer VARCHAR(255),
+ error VARCHAR(1024),
+);
+
CREATE TABLE feed_cache (
host VARCHAR(64) NOT NULL,
search_path VARCHAR(255),
diff --git a/www/.htaccess b/www/.htaccess
index eb86f63..d17abcd 100644
--- a/www/.htaccess
+++ b/www/.htaccess
@@ -14,21 +14,20 @@ RewriteRule ^.*\.(flv|gif|ico|jpg|jpeg|mp4|mpeg|png|svg|swf|webp)$ raw/%{HTTP_HO
RewriteRule ^/?raw/(.*)$ raw/%{HTTP_HOST}/$1 [L,END]
-RewriteEngine On
-RewriteCond %{HTTPS} !on
-RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,END]
+# RewriteCond %{HTTPS} !on
+# RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,END]
-RewriteCond %{REQUEST_URI} !^/?(static|raw|robots\.txt).*
-RewriteRule (.*) router.php
+RewriteCond %{REQUEST_URI} !^/?(src/dbtest\.php|static|raw|robots\.txt).*
+RewriteRule (.*) src/router.php
Allow from all
Options +Indexes
- Header set Cache-Control "max-age=315360, public"
+ Header set Cache-Control "max-age=60, public"
- Header set Cache-Control "max-age=315360, public"
+ Header set Cache-Control "max-age=60, public"
\ No newline at end of file
diff --git a/www/composer.lock b/www/composer.lock
index c157e3a..d41c77f 100644
--- a/www/composer.lock
+++ b/www/composer.lock
@@ -8,16 +8,16 @@
"packages": [
{
"name": "dflydev/dot-access-data",
- "version": "v3.0.2",
+ "version": "v3.0.3",
"source": {
"type": "git",
"url": "https://github.com/dflydev/dflydev-dot-access-data.git",
- "reference": "f41715465d65213d644d3141a6a93081be5d3549"
+ "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/f41715465d65213d644d3141a6a93081be5d3549",
- "reference": "f41715465d65213d644d3141a6a93081be5d3549",
+ "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/a23a2bf4f31d3518f3ecb38660c95715dfead60f",
+ "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f",
"shasum": ""
},
"require": {
@@ -77,9 +77,9 @@
],
"support": {
"issues": "https://github.com/dflydev/dflydev-dot-access-data/issues",
- "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.2"
+ "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.3"
},
- "time": "2022-10-27T11:44:00+00:00"
+ "time": "2024-07-08T12:26:09+00:00"
},
{
"name": "erusev/parsedown",
@@ -519,16 +519,16 @@
},
{
"name": "league/commonmark",
- "version": "2.4.1",
+ "version": "2.5.1",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark.git",
- "reference": "3669d6d5f7a47a93c08ddff335e6d945481a1dd5"
+ "reference": "ac815920de0eff6de947eac0a6a94e5ed0fb147c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/3669d6d5f7a47a93c08ddff335e6d945481a1dd5",
- "reference": "3669d6d5f7a47a93c08ddff335e6d945481a1dd5",
+ "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/ac815920de0eff6de947eac0a6a94e5ed0fb147c",
+ "reference": "ac815920de0eff6de947eac0a6a94e5ed0fb147c",
"shasum": ""
},
"require": {
@@ -541,8 +541,8 @@
},
"require-dev": {
"cebe/markdown": "^1.0",
- "commonmark/cmark": "0.30.0",
- "commonmark/commonmark.js": "0.30.0",
+ "commonmark/cmark": "0.31.0",
+ "commonmark/commonmark.js": "0.31.0",
"composer/package-versions-deprecated": "^1.8",
"embed/embed": "^4.4",
"erusev/parsedown": "^1.0",
@@ -551,10 +551,10 @@
"michelf/php-markdown": "^1.4 || ^2.0",
"nyholm/psr7": "^1.5",
"phpstan/phpstan": "^1.8.2",
- "phpunit/phpunit": "^9.5.21",
+ "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0",
"scrutinizer/ocular": "^1.8.1",
- "symfony/finder": "^5.3 | ^6.0",
- "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0",
+ "symfony/finder": "^5.3 | ^6.0 || ^7.0",
+ "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 || ^7.0",
"unleashedtech/php-coding-standard": "^3.1.1",
"vimeo/psalm": "^4.24.0 || ^5.0.0"
},
@@ -564,7 +564,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "2.5-dev"
+ "dev-main": "2.6-dev"
}
},
"autoload": {
@@ -621,7 +621,7 @@
"type": "tidelift"
}
],
- "time": "2023-08-30T16:55:00+00:00"
+ "time": "2024-07-24T12:52:09+00:00"
},
{
"name": "league/config",
@@ -707,31 +707,31 @@
},
{
"name": "nette/schema",
- "version": "v1.2.5",
+ "version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/nette/schema.git",
- "reference": "0462f0166e823aad657c9224d0f849ecac1ba10a"
+ "reference": "a6d3a6d1f545f01ef38e60f375d1cf1f4de98188"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nette/schema/zipball/0462f0166e823aad657c9224d0f849ecac1ba10a",
- "reference": "0462f0166e823aad657c9224d0f849ecac1ba10a",
+ "url": "https://api.github.com/repos/nette/schema/zipball/a6d3a6d1f545f01ef38e60f375d1cf1f4de98188",
+ "reference": "a6d3a6d1f545f01ef38e60f375d1cf1f4de98188",
"shasum": ""
},
"require": {
- "nette/utils": "^2.5.7 || ^3.1.5 || ^4.0",
- "php": "7.1 - 8.3"
+ "nette/utils": "^4.0",
+ "php": "8.1 - 8.3"
},
"require-dev": {
- "nette/tester": "^2.3 || ^2.4",
+ "nette/tester": "^2.4",
"phpstan/phpstan-nette": "^1.0",
- "tracy/tracy": "^2.7"
+ "tracy/tracy": "^2.8"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.2-dev"
+ "dev-master": "1.3-dev"
}
},
"autoload": {
@@ -763,26 +763,26 @@
],
"support": {
"issues": "https://github.com/nette/schema/issues",
- "source": "https://github.com/nette/schema/tree/v1.2.5"
+ "source": "https://github.com/nette/schema/tree/v1.3.0"
},
- "time": "2023-10-05T20:37:59+00:00"
+ "time": "2023-12-11T11:54:22+00:00"
},
{
"name": "nette/utils",
- "version": "v4.0.3",
+ "version": "v4.0.5",
"source": {
"type": "git",
"url": "https://github.com/nette/utils.git",
- "reference": "a9d127dd6a203ce6d255b2e2db49759f7506e015"
+ "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nette/utils/zipball/a9d127dd6a203ce6d255b2e2db49759f7506e015",
- "reference": "a9d127dd6a203ce6d255b2e2db49759f7506e015",
+ "url": "https://api.github.com/repos/nette/utils/zipball/736c567e257dbe0fcf6ce81b4d6dbe05c6899f96",
+ "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96",
"shasum": ""
},
"require": {
- "php": ">=8.0 <8.4"
+ "php": "8.0 - 8.4"
},
"conflict": {
"nette/finder": "<3",
@@ -849,9 +849,9 @@
],
"support": {
"issues": "https://github.com/nette/utils/issues",
- "source": "https://github.com/nette/utils/tree/v4.0.3"
+ "source": "https://github.com/nette/utils/tree/v4.0.5"
},
- "time": "2023-10-29T21:02:13+00:00"
+ "time": "2024-08-07T15:39:19+00:00"
},
{
"name": "psr/event-dispatcher",
@@ -983,16 +983,16 @@
},
{
"name": "spatie/yaml-front-matter",
- "version": "2.0.8",
+ "version": "2.0.9",
"source": {
"type": "git",
"url": "https://github.com/spatie/yaml-front-matter.git",
- "reference": "f2f1f749a405fafc9d6337067c92c062d51a581c"
+ "reference": "cbe67e1cdd0a29a96d74ccab9400fe663e078392"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/spatie/yaml-front-matter/zipball/f2f1f749a405fafc9d6337067c92c062d51a581c",
- "reference": "f2f1f749a405fafc9d6337067c92c062d51a581c",
+ "url": "https://api.github.com/repos/spatie/yaml-front-matter/zipball/cbe67e1cdd0a29a96d74ccab9400fe663e078392",
+ "reference": "cbe67e1cdd0a29a96d74ccab9400fe663e078392",
"shasum": ""
},
"require": {
@@ -1029,7 +1029,7 @@
"yaml"
],
"support": {
- "source": "https://github.com/spatie/yaml-front-matter/tree/2.0.8"
+ "source": "https://github.com/spatie/yaml-front-matter/tree/2.0.9"
},
"funding": [
{
@@ -1041,20 +1041,20 @@
"type": "github"
}
],
- "time": "2023-12-04T10:02:52+00:00"
+ "time": "2024-06-13T10:20:51+00:00"
},
{
"name": "symfony/deprecation-contracts",
- "version": "v3.4.0",
+ "version": "v3.5.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
- "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf"
+ "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf",
- "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf",
+ "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
+ "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
"shasum": ""
},
"require": {
@@ -1063,7 +1063,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "3.4-dev"
+ "dev-main": "3.5-dev"
},
"thanks": {
"name": "symfony/contracts",
@@ -1092,7 +1092,7 @@
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0"
+ "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0"
},
"funding": [
{
@@ -1108,20 +1108,20 @@
"type": "tidelift"
}
],
- "time": "2023-05-23T14:45:45+00:00"
+ "time": "2024-04-18T09:32:20+00:00"
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.28.0",
+ "version": "v1.30.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb"
+ "reference": "0424dff1c58f028c451efff2045f5d92410bd540"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
- "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540",
+ "reference": "0424dff1c58f028c451efff2045f5d92410bd540",
"shasum": ""
},
"require": {
@@ -1135,9 +1135,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -1174,7 +1171,7 @@
"portable"
],
"support": {
- "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.30.0"
},
"funding": [
{
@@ -1190,20 +1187,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-05-31T15:07:36+00:00"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.28.0",
+ "version": "v1.30.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "42292d99c55abe617799667f454222c54c60e229"
+ "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229",
- "reference": "42292d99c55abe617799667f454222c54c60e229",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c",
+ "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c",
"shasum": ""
},
"require": {
@@ -1217,9 +1214,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -1257,7 +1251,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0"
},
"funding": [
{
@@ -1273,20 +1267,20 @@
"type": "tidelift"
}
],
- "time": "2023-07-28T09:04:16+00:00"
+ "time": "2024-06-19T12:30:46+00:00"
},
{
"name": "symfony/polyfill-php80",
- "version": "v1.28.0",
+ "version": "v1.30.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
- "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5"
+ "reference": "77fa7995ac1b21ab60769b7323d600a991a90433"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
- "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/77fa7995ac1b21ab60769b7323d600a991a90433",
+ "reference": "77fa7995ac1b21ab60769b7323d600a991a90433",
"shasum": ""
},
"require": {
@@ -1294,9 +1288,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -1340,7 +1331,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-php80/tree/v1.30.0"
},
"funding": [
{
@@ -1356,20 +1347,96 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-05-31T15:07:36+00:00"
},
{
- "name": "symfony/yaml",
- "version": "v7.0.0",
+ "name": "symfony/polyfill-php81",
+ "version": "v1.30.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/yaml.git",
- "reference": "0055b230c408428b9b5cde7c55659555be5c0278"
+ "url": "https://github.com/symfony/polyfill-php81.git",
+ "reference": "3fb075789fb91f9ad9af537c4012d523085bd5af"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/0055b230c408428b9b5cde7c55659555be5c0278",
- "reference": "0055b230c408428b9b5cde7c55659555be5c0278",
+ "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/3fb075789fb91f9ad9af537c4012d523085bd5af",
+ "reference": "3fb075789fb91f9ad9af537c4012d523085bd5af",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Php81\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php81/tree/v1.30.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-06-19T12:30:46+00:00"
+ },
+ {
+ "name": "symfony/yaml",
+ "version": "v7.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/yaml.git",
+ "reference": "fa34c77015aa6720469db7003567b9f772492bf2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/fa34c77015aa6720469db7003567b9f772492bf2",
+ "reference": "fa34c77015aa6720469db7003567b9f772492bf2",
"shasum": ""
},
"require": {
@@ -1411,7 +1478,7 @@
"description": "Loads and dumps YAML files",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/yaml/tree/v7.0.0"
+ "source": "https://github.com/symfony/yaml/tree/v7.1.1"
},
"funding": [
{
@@ -1427,24 +1494,25 @@
"type": "tidelift"
}
],
- "time": "2023-11-07T10:26:03+00:00"
+ "time": "2024-05-31T14:57:53+00:00"
},
{
"name": "twig/markdown-extra",
- "version": "v3.8.0",
+ "version": "v3.11.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/markdown-extra.git",
- "reference": "b6e4954ab60030233df5d293886b5404558daac8"
+ "reference": "504557d60d80478260ebd2221a2b3332a480865d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/markdown-extra/zipball/b6e4954ab60030233df5d293886b5404558daac8",
- "reference": "b6e4954ab60030233df5d293886b5404558daac8",
+ "url": "https://api.github.com/repos/twigphp/markdown-extra/zipball/504557d60d80478260ebd2221a2b3332a480865d",
+ "reference": "504557d60d80478260ebd2221a2b3332a480865d",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
+ "symfony/deprecation-contracts": "^2.5|^3",
"twig/twig": "^3.0"
},
"require-dev": {
@@ -1456,6 +1524,9 @@
},
"type": "library",
"autoload": {
+ "files": [
+ "Resources/functions.php"
+ ],
"psr-4": {
"Twig\\Extra\\Markdown\\": ""
},
@@ -1483,7 +1554,7 @@
"twig"
],
"support": {
- "source": "https://github.com/twigphp/markdown-extra/tree/v3.8.0"
+ "source": "https://github.com/twigphp/markdown-extra/tree/v3.11.0"
},
"funding": [
{
@@ -1495,34 +1566,42 @@
"type": "tidelift"
}
],
- "time": "2023-11-21T14:02:01+00:00"
+ "time": "2024-08-07T17:34:09+00:00"
},
{
"name": "twig/twig",
- "version": "v3.8.0",
+ "version": "v3.11.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
- "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d"
+ "reference": "e80fb8ebba85c7341a97a9ebf825d7fd4b77708d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/9d15f0ac07f44dc4217883ec6ae02fd555c6f71d",
- "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/e80fb8ebba85c7341a97a9ebf825d7fd4b77708d",
+ "reference": "e80fb8ebba85c7341a97a9ebf825d7fd4b77708d",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
+ "symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-ctype": "^1.8",
"symfony/polyfill-mbstring": "^1.3",
- "symfony/polyfill-php80": "^1.22"
+ "symfony/polyfill-php80": "^1.22",
+ "symfony/polyfill-php81": "^1.29"
},
"require-dev": {
"psr/container": "^1.0|^2.0",
- "symfony/phpunit-bridge": "^5.4.9|^6.3|^7.0"
+ "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0"
},
"type": "library",
"autoload": {
+ "files": [
+ "src/Resources/core.php",
+ "src/Resources/debug.php",
+ "src/Resources/escaper.php",
+ "src/Resources/string_loader.php"
+ ],
"psr-4": {
"Twig\\": "src/"
}
@@ -1555,7 +1634,7 @@
],
"support": {
"issues": "https://github.com/twigphp/Twig/issues",
- "source": "https://github.com/twigphp/Twig/tree/v3.8.0"
+ "source": "https://github.com/twigphp/Twig/tree/v3.11.0"
},
"funding": [
{
@@ -1567,7 +1646,7 @@
"type": "tidelift"
}
],
- "time": "2023-11-21T18:54:41+00:00"
+ "time": "2024-08-08T16:15:16+00:00"
}
],
"packages-dev": [],
diff --git a/www/post.php b/www/post.php
deleted file mode 100644
index 872b75f..0000000
--- a/www/post.php
+++ /dev/null
@@ -1,200 +0,0 @@
-
- -1,
- 'post_path' => '/404.md',
- 'post_title' => '404 Page',
- 'post_metadata' => [
- 'type' => '404'
- ]
- ];
- }
-
- public static function _deduce_type($path) {
- $ext = pathinfo($path, PATHINFO_EXTENSION);
-
- if(preg_match("/\.(\w+)\.md$/", $path, $ext_match)) {
- $ext = $ext_match[1];
- }
-
- $ext_mapping = [
- '' => 'directory',
- 'md' => 'text/markdown',
- 'png' => 'image',
- 'jpg' => 'image',
- 'jpeg' => 'image'
- ];
-
- return $ext_mapping[$ext] ?? '?';
- }
-
- public static function _deduce_icon($type) {
- $icon_mapping = [
- '' => 'question',
- 'text/markdown' => 'markdown',
- 'blog' => 'markdown',
- 'blog_list' => 'rectangle-list',
- 'directory' => 'folder',
- 'gallery' => 'images',
- 'image' => 'image'
- ];
-
- return $icon_mapping[$type] ?? 'unknown';
- }
-
- function __construct($post_handler, $sql_row) {
- $this->handler = $post_handler;
-
- $this->content_html = null;
- $this->content_markdown = null;
-
- $sql_meta = null;
-
- if(!isset($sql_row) or !$sql_row['found']) {
- $sql_row = $this->_generate_404($sql_row);
- $sql_meta = $sql_row['post_metadata'];
- }
-
- $sql_meta = $sql_row['post_metadata'];
- if(is_string($sql_meta)) {
- $sql_meta = json_decode($sql_meta, true);
- }
-
- unset($sql_meta['settings']);
-
- $this->sql_row = $sql_row;
- $this->sql_meta = $sql_meta ?? [];
-
- $sql_settings = json_decode($sql_row['post_settings_cache'], true)
- ?? $this->handler->get_settings_for_path($sql_row['post_path']);
-
- $data = [
- 'id' => $sql_row['post_id'],
- 'path' => $sql_row['post_path'],
- 'url' => 'https://' . $sql_row['host'] . $sql_row['post_path'],
- 'created_at' => $sql_row['post_create_time'] ?? '',
- 'updated_at' => $sql_row['post_update_time'] ?? '',
- 'view_count' => $sql_row['post_access_count'] ?? 0
- ];
-
- $data['title'] = $sql_meta['title'] ?? $sql_row['title'];
- unset($sql_meta['title']);
-
- $data['tags'] = $sql_meta['tags'] ?? [];
- unset($sql_meta['tags']);
-
- $data['type'] = $sql_meta['type']
- ?? self::_deduce_type($sql_row['post_path']);
- unset($sql_meta['type']);
-
- $data['icon'] = $sql_meta['icon']
- ?? self::_deduce_icon($data['type']);
- unset($sql_meta['icon']);
-
- if(isset($sql_meta['media_url'])) {
- $data['media_url'] = $sql_meta['media_url'];
- $data['thumb_url'] = $sql_meta['thumb_url'] ?? $data['media_url'];
-
- unset($sql_meta['media_url']);
- unset($sql_meta['thumb_url']);
- }
-
- $data['banners'] = $sql_meta['banners']
- ?? $sql_settings['banners']
- ?? self::$default_banners;
-
- unset($sql_meta['banners']);
- unset($sql_settings['banners']);
-
- $data['preview_image'] = $sql_meta['preview_image'] ?? $data['banners'][0]['src'] ?? null;
- unset($sql_meta['preview_image']);
-
- $data['brief'] = $sql_meta['brief']
- ?? $data['title'];
- unset($sql_meta['brief']);
-
- $data['excerpt'] = $sql_meta['excerpt']
- ?? substr($sql_row['post_content'], 0, 256);
-
- $data['metadata'] = $sql_meta;
- $data['settings'] = $sql_settings;
-
- $this->data = $data;
- }
-
- public function __get($name) {
- if($name == 'html') {
- return $this->get_html();
- }
- if($name == 'markdown') {
- return $this->get_markdown();
- }
- if($name == 'json') {
- return $this->to_json();
- }
-
- return $this->data[$name];
- }
-
- public function get_html() {
- $fn = self::$markdown_engine;
- $this->content_html ??= $fn($this);
-
- return $this->content_html;
- }
- public function get_markdown() {
- $this->content_markdown ??=
- $this->handler->get_markdown_for_id($this->data['id']);
-
- return $this->content_markdown;
- }
-
- public function to_json($with_markdown = false, $with_html = false) {
- $out_data = $this->data;
-
- if($with_markdown) {
- $out_data['markdown'] = $this->get_markdown();
- }
- if($with_html) {
- $out_data['html'] = $this->get_html();
- }
-
- return json_encode($out_data);
- }
-
-
- public function get_parent_post() {
- $parent_path = dirname($this->data['path']);
- if($parent_path == '')
- return null;
-
- $this->parent_post ??= new PostData($this->handler,
- $this->handler->get_post_by_path($parent_path));
-
- return $this->parent_post;
- }
-
- public function get_child_posts() {
- if(isset($this->child_posts))
- return $this->child_posts;
-
- $child_data = $this->handler->get_subposts_by_path($this->data['path']);
-
- $this->child_posts = array_map(function($data) {
- return new PostData($this->handler, $data);
- }, $child_data);
- }
-}
-
-?>
\ No newline at end of file
diff --git a/www/post_adapter.php b/www/post_adapter.php
deleted file mode 100644
index 05927e4..0000000
--- a/www/post_adapter.php
+++ /dev/null
@@ -1,221 +0,0 @@
-data_directory = 'raw/' . $this->SITE_CONFIG['HTTP_HOST'];
- }
-
- function deduce_post_type($post_path) {
- $ext = pathinfo($post_path, PATHINFO_EXTENSION);
-
- if(preg_match("/\.(\w+)\.md$/", $post_path, $ext_match)) {
- $ext = $ext_match[1];
- }
-
- $ext_mapping = [
- '' => 'directory',
- 'md' => 'text/markdown',
- 'png' => 'image',
- 'jpg' => 'image',
- 'jpeg' => 'image'
- ];
-
- return $ext_mapping[$ext] ?? '?';
- }
-
- function fill_in_post_meta($post_path, $meta) {
- $icon_mapping = [
- '' => 'question',
- 'text/markdown' => 'markdown',
- 'blog' => 'markdown',
- 'directory' => 'folder',
- 'gallery' => 'images',
- 'blog_list' => 'rectangle-list',
- 'image' => 'image'
- ];
-
- $meta["title"] ??= basename($post_path);
-
- if($meta["title"] == "") {
- $meta["title"] = "root";
- }
-
- if(!isset($meta['media_file']) and preg_match("/\.(\w+)\.md$/", $post_path)) {
- $meta['media_file'] = "https://" . $this->SITE_CONFIG['HTTP_HOST'] . chop($post_path, ".md");
- }
-
- $meta['tags'] ??= [];
- $meta['type'] ??= $this->deduce_post_type($post_path);
-
- $meta['icon'] ??= $icon_mapping[$meta['type']] ?? 'question';
-
- return $meta;
- }
-
- function _normalize_post_data($post_data) {
- $post_data = parent::_normalize_post_data($post_data);
-
- if(!$post_data['found']) {
- return $post_data;
- }
-
- $post_data["post_basename"] = basename($post_data["post_path"]);
-
- $post_meta = $post_data['post_metadata'];
-
- $post_data['post_metadata'] = $this->fill_in_post_meta(
- $post_data['post_path'],
- $post_meta);
-
- $post_data["post_file_dir"] = '/raw' . $post_data["post_path"];
-
- return $post_data;
- }
-
- function make_post_directory($directory) {
- $data_directory = $this->data_directory . $directory;
-
- is_dir($data_directory) || mkdir($data_directory, 0777, true);
-
- parent::make_post_directory($directory);
- }
-
- function update_or_create_post(...$args) {
- $this->_exec("TRUNCATE feed_cache");
- parent::update_or_create_post(...$args);
- }
-
- function save_file($post_path, $file_path) {
- move_uploaded_file($file_path, $this->data_directory . $post_path);
- }
-
- function save_markdown_post($post_path, $post_data) {
- if(basename($post_path) == "README.md") {
- $post_path = dirname($post_path);
- }
-
- $frontmatter_post = YamlFrontMatter::parse($post_data);
- $post_path = $this->_sanitize_path($post_path);
-
- $post_content = $frontmatter_post->body();
-
- $post_metadata = $frontmatter_post->matter();
-
- $post_metadata = $this->fill_in_post_meta(
- $post_path,
- $post_metadata);
-
- $post_metadata['tags'][]= 'type:' . $post_metadata['type'];
-
- $this->update_or_create_post($post_path, $post_metadata, $post_content);
- }
-
- function handle_upload($post_path, $file_path) {
- $post_path = $this->_sanitize_path($post_path);
- $ext = pathinfo($post_path, PATHINFO_EXTENSION);
-
- switch($ext) {
- case "md":
- $this->save_markdown_post($post_path, file_get_contents($file_path));
-
- $this->make_post_directory(dirname($post_path));
- move_uploaded_file($file_path, $this->data_directory . $post_path);
- break;
- default:
- $this->save_file($post_path, $file_path);
- }
- }
-
- function try_get_cached_feed($path, $export_opt) {
- $post_cache = $this->_exec("SELECT feed_content, feed_created_on
- FROM feed_cache
- WHERE host=? AND search_path=? AND export_type=?",
- "sss", $this->SITE_CONFIG['HTTP_HOST'], $path, $export_opt)->fetch_assoc();
-
- if(!isset($post_cache)) {
- return null;
- }
-
- return ['feed' => $post_cache['feed_content'], 'feed_ts' => $post_cache['feed_created_on']];
- }
-
- function construct_feed($path) {
- $path = $this->_sanitize_path($path);
-
- $feed = @new Feed;
-
- $feed->setTitle("DergFeed");
- $feed->setLink($this->SITE_CONFIG['uri_prefix'] . $path);
- $feed->setFeedLink($this->SITE_CONFIG['uri_prefix'] . "/feeds/atom" . $path, "atom");
-
- $feed->setDateModified(time());
-
- $feed->setDescription("DergenFeed for all your " . $path . " needs");
-
- $feed_posts = $this->_exec("SELECT
- post_path,
- post_create_time, post_update_time,
- post_content,
- post_metadata
- FROM posts
- WHERE (host = ?) AND ((post_path = ?) OR (post_path LIKE ?))
- ORDER BY post_create_time DESC LIMIT 200",
- "sss", $this->SITE_CONFIG['HTTP_HOST'], $path, $path . '/%');
-
- while($row = $feed_posts->fetch_array(MYSQLI_ASSOC)) {
- $row = $this->_normalize_post_data($row);
- $pmeta = $row['post_metadata'];
-
- if($pmeta['type'] == 'directory') {
- continue;
- }
-
- $entry = $feed->createEntry();
-
- $entry->setTitle($row['post_path'] . '> ' . $pmeta['title']);
- $entry->setLink($this->SITE_CONFIG['uri_prefix'] . $row['post_path']);
- $entry->setDateModified(strtotime($row['post_update_time']));
- $entry->setDateCreated(strtotime($row['post_create_time']));
-
- $entry->setDescription($pmeta['brief'] ?? $pmeta['title']);
-
- $feed->addEntry($entry);
- }
-
- return $feed;
- }
-
- function get_laminas_feed($path, $export_opt) {
- $path = $this->_sanitize_path($path);
-
- $feed_cache = $this->try_get_cached_feed($path, $export_opt);
-
- if(isset($feed_cache)) {
- return $feed_cache;
- }
-
- $feed = $this->construct_feed($path);
-
- $this->_exec("INSERT INTO feed_cache
- (host, search_path, export_type, feed_content)
- VALUES
- (?, ?, 'atom', ?),
- (?, ?, 'rss', ?)",
- "ssssss",
- $this->SITE_CONFIG['HTTP_HOST'], $path, $feed->export('atom'),
- $this->SITE_CONFIG['HTTP_HOST'], $path, $feed->export('rss'));
-
- return $this->try_get_cached_feed($path, $export_opt);
- }
-}
-
-?>
\ No newline at end of file
diff --git a/www/src/db_handler/analytics_interface.php b/www/src/db_handler/analytics_interface.php
new file mode 100644
index 0000000..fbe3400
--- /dev/null
+++ b/www/src/db_handler/analytics_interface.php
@@ -0,0 +1,17 @@
+
+
\ No newline at end of file
diff --git a/www/src/db_handler/db_interface.php b/www/src/db_handler/db_interface.php
new file mode 100644
index 0000000..ea72459
--- /dev/null
+++ b/www/src/db_handler/db_interface.php
@@ -0,0 +1,86 @@
+
+escape_tag($matches[2]) . $matches[3];
+}
+
+interface PostdataInterface {
+ /* Postdata format:
+ *
+ * The Postdata array is a simple intermediate data format
+ * for the Post content and metadata.
+ * It is slightly abstracted from the SQL format itself but will
+ * only reformat keys, *not* do any alteration of the data itself.
+ *
+ * Any supported fields will be integrated into the database.
+ * Other fields will be saved in a JSON structure, and will
+ * be restored afterward.
+ *
+ * The following fields are mandatory for *writing*
+ * - path: String, must be sanitized to consist of just alphanumeric
+ * characters, `_-./`
+ * used to identify the post itself
+ *
+ * The following fields may be returned by the database:
+ * - id
+ * - created_at
+ * - updated_at
+ * - view_count
+ *
+ * The following fields may be supported by the database:
+ * - markdown: String, markdown of the post. May be
+ * stored separately and won't be returned by default!
+ * - type: String, defining the type of the post
+ * - title: String, self-explanatory
+ * - tags: Array of strings
+ * - settings: Hash, recursively merged settings (calculated by DB!)
+ *
+ * The following fields are *recommended*, but nothing more:
+ * - icon: String, optionally defining
+ */
+
+ public function stub_postdata($path);
+ public function stub_postdata_tree($path);
+
+ public function set_postdata($data);
+ public function set_post_markdown($id, $markdown);
+
+ public function get_postdata($path);
+ // Returns a key-value pair of child paths => child data
+ public function get_post_children($path,
+ $limit = 50, $depth_start = 1, $depth_end = 1,
+ $order_by = 'path');
+
+ public function get_post_markdown($id);
+}
+
+?>
\ No newline at end of file
diff --git a/www/src/db_handler/mysql_handler.php b/www/src/db_handler/mysql_handler.php
new file mode 100644
index 0000000..def19df
--- /dev/null
+++ b/www/src/db_handler/mysql_handler.php
@@ -0,0 +1,348 @@
+
+sql_connection = $sql_connection;
+ $this->hostname = $hostname;
+
+ $this->debugging = false;
+ }
+
+ private function _dbg($message) {
+ if($this->debugging) {
+ echo $message;
+ }
+ }
+
+ private function _exec($qery, $argtypes = '', ...$args) {
+ $stmt = $this->sql_connection->prepare($qery);
+
+ if($argtypes != ""){
+ $stmt->bind_param($argtypes, ...$args);
+ }
+ $stmt->execute();
+
+ return $stmt->get_result();
+ }
+
+ private function clear_post_settings_cache($post_path) {
+ $post_path = sanitize_post_path($post_path);
+
+ $this->_exec("
+ UPDATE posts
+ SET post_settings_cache=NULL
+ WHERE host = ? AND post_path LIKE ?;
+ ", "ss", $this->hostname, $post_path . "%");
+ }
+
+ public function stub_postdata($path) {
+ $post_path = sanitize_post_path($path);
+ $path_depth = substr_count($post_path, "/");
+
+
+ $qry = "
+ INSERT INTO posts
+ (host, post_path, post_path_depth)
+ VALUES
+ ( ?, ?, ?) AS new
+ ON DUPLICATE KEY UPDATE post_path=new.post_path;";
+
+ $this->_exec($qry, "ssi",
+ $this->hostname,
+ $post_path,
+ $path_depth);
+ }
+
+ public function stub_postdata_tree($path) {
+ $post_path = sanitize_post_path($path);
+
+ while(true) {
+ if($post_path == '/') {
+ $post_path = '';
+ }
+
+ try {
+ $this->stub_postdata($post_path);
+ }
+ catch(Exception $e) {
+ }
+
+ $post_path = dirname($post_path);
+ if(strlen($post_path) == 0) {
+ break;
+ }
+ }
+ }
+
+ public function set_postdata($data) {
+ $data['path'] = sanitize_post_path($data['path']);
+ $post_path = $data['path'];
+ unset($data['path']);
+
+ $this->stub_postdata_tree($post_path);
+
+ $data['title'] ??= basename($post_path);
+
+ $post_tags = $data['tags'] ?? [];
+ array_push($post_tags,
+ 'path:' . $post_path
+ );
+
+ $sql_args = [
+ $this->hostname,
+ $post_path,
+ substr_count($post_path, "/"),
+ $data['title'],
+ taglist_to_sql_string($post_tags),
+ $data['brief'] ?? null
+ ];
+
+ unset($data['title']);
+ unset($data['brief']);
+
+ $post_markdown = $data['markdown'] ?? null;
+ unset($data['markdown']);
+ unset($data['html']);
+
+ array_push($sql_args, json_encode($data));
+
+ $qry =
+ "INSERT INTO posts
+ (host,
+ post_path, post_path_depth,
+ post_title, post_tags, post_brief,
+ post_metadata, post_settings_cache)
+ VALUES
+ ( ?, ?, ?, ?, ?, ?, ?, null) AS new
+ ON DUPLICATE KEY
+ UPDATE post_title=new.post_title,
+ post_tags=new.post_tags,
+ post_brief=new.post_brief,
+ post_metadata=new.post_metadata,
+ post_updated_at=CURRENT_TIMESTAMP;
+ ";
+
+ $this->_exec($qry, "ssissss", ...$sql_args);
+
+ if(isset($post_markdown)) {
+ $this->set_post_markdown($this->sql_connection->insert_id, $post_markdown);
+ }
+
+ $this->clear_post_settings_cache($post_path);
+ }
+
+ public function set_post_markdown($id, $markdown) {
+ $qry =
+ "INSERT INTO post_markdown ( post_id, post_markdown )
+ VALUES (?, ?) AS new
+ ON DUPLICATE KEY UPDATE post_markdown=new.post_markdown;
+ ";
+
+ $this->_exec($qry, "is", $id, $markdown);
+ }
+
+ private function get_post_settings($post_path) {
+ $post_path = sanitize_post_path($post_path);
+
+ $this->_dbg("-> gps: getting path " . $post_path . "\n");
+
+ $post_settings = $this->_exec("
+ SELECT post_settings_cache
+ FROM posts
+ WHERE post_path = ? AND host = ?
+ ", "ss", $post_path, $this->hostname)->fetch_assoc();
+
+ if(!isset($post_settings)) {
+ $this->_dbg("-> gps: Returning because of no result\n");
+ return [];
+ }
+ if(isset($post_settings['post_settings_cache'])) {
+ $result = json_decode($post_settings['post_settings_cache'], true);
+ if($this->debugging) {
+ echo "-> gps: Returning because of cached result:\n";
+ echo "--> " . json_encode($result) . "\n";
+ }
+ return $result;
+ }
+
+ $parent_settings = [];
+ if($post_path != "") {
+ $parent_settings = $this->get_post_settings(dirname($post_path));
+ }
+
+ $post_settings = [];
+ $post_metadata = $this->_exec("
+ SELECT post_path, post_metadata
+ FROM posts
+ WHERE post_path = ? AND host = ?
+ ", "ss", $post_path, $this->hostname)->fetch_assoc();
+
+ if(isset($post_metadata['post_metadata'])) {
+ $post_metadata = json_decode($post_metadata['post_metadata'], true);
+
+ if(isset($post_metadata['settings'])) {
+ $post_settings = $post_metadata['settings'];
+ }
+ }
+
+ $post_settings = array_merge($parent_settings, $post_settings);
+
+ $this->_dbg("-> gps: Merged post settings are " . json_encode($post_settings) . ", saving...\n");
+
+ $this->_exec("
+ UPDATE posts SET post_settings_cache=? WHERE post_path=? AND host=?
+ ", "sss",
+ json_encode($post_settings), $post_path, $this->hostname);
+
+ return $post_settings;
+ }
+
+ private function process_postdata($data) {
+ if(!isset($data)) {
+ return null;
+ }
+
+ if(!isset($data['post_path'])) {
+ echo "ERROR, trying to get a post data package without path!";
+ die();
+ }
+
+ $outdata = [];
+ foreach($this::SQL_READ_COLUMNS as $key) {
+ if(isset($data['post_' . $key])) {
+ $outdata[$key] = $data['post_' . $key];
+ }
+ }
+
+ $post_metadata = json_decode($data['post_metadata'] ?? '{}', true);
+
+ $post_settings = [];
+
+ if(isset($data['post_settings_cache'])) {
+ $post_settings = json_decode($data['post_settings_cache'], true);
+ }
+ else {
+ $post_settings = $this->get_post_settings($data['post_path']);
+ }
+
+ $outdata = array_merge($post_settings, $post_metadata, $outdata);
+
+ return $outdata;
+ }
+
+ public function get_postdata($path) {
+ $path = sanitize_post_path($path);
+
+ $qry = "
+ SELECT *
+ FROM posts
+ WHERE post_path = ? AND host = ?;
+ ";
+
+ $data = $this->_exec($qry, "ss", $path, $this->hostname)->fetch_assoc();
+
+ return $this->process_postdata($data);
+ }
+
+ public function get_post_children($path,
+ $limit = 50, $depth_start = 1, $depth_end = 1,
+ $order_by = 'path') {
+
+ $path = sanitize_post_path($path);
+
+ $path_depth = substr_count($path, "/");
+
+ $allowed_ordering = [
+ 'path' => true,
+ 'path DESC' => true,
+ 'created_at' => true,
+ 'created_at DESC' => true,
+ 'modified_at' => true,
+ 'modified_at DESC' => true
+ ];
+
+ if(!isset($allowed_ordering[$order_by])) {
+ throw new Exception('Children ordering not allowed');
+ }
+ $order_by = 'post_' . $order_by;
+
+ if($this->debugging) {
+ echo "-> GPC: Getting children for path " . $path;
+ }
+
+ $qry = "
+ SELECT *
+ FROM posts
+ WHERE post_path_depth BETWEEN ? AND ?
+ AND post_path LIKE ?
+ ORDER BY " . $order_by .
+ " LIMIT ?";
+
+ $data = $this->_exec($qry, "iisi",
+ $path_depth + $depth_start, $path_depth + $depth_end,
+ $path.'/%', $limit
+ )->fetch_all(MYSQLI_ASSOC);
+ $outdata = [];
+
+ foreach($data AS $post_element) {
+ $outdata[$post_element['post_path']] =
+ $this->process_postdata($post_element);
+ }
+
+ return $outdata;
+ }
+
+ public function get_post_markdown($id) {
+ $qry =
+ "SELECT post_markdown
+ FROM post_markdown
+ WHERE post_id = ?
+ ";
+
+ $data = $this->_exec($qry, "i", $id)->fetch_assoc();
+
+ if(!isset($data)) {
+ return "";
+ }
+
+ return $data['post_markdown'];
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/www/src/db_handler/post.php b/www/src/db_handler/post.php
new file mode 100644
index 0000000..4e9494e
--- /dev/null
+++ b/www/src/db_handler/post.php
@@ -0,0 +1,213 @@
+
+ -1,
+ 'path' => '/404.md',
+ 'title' => '404 Page',
+ 'metadata' => [
+ 'type' => '404'
+ ]
+ ];
+
+ return $post_data;
+ }
+
+ public static function _deduce_type($path) {
+ $ext = pathinfo($path, PATHINFO_EXTENSION);
+
+ if(preg_match("/\.(\w+)\.md$/", $path, $ext_match)) {
+ $ext = $ext_match[1];
+ }
+
+ $ext_mapping = [
+ '' => 'directory',
+ 'md' => 'text/markdown',
+ 'png' => 'image',
+ 'jpg' => 'image',
+ 'jpeg' => 'image'
+ ];
+
+ return $ext_mapping[$ext] ?? '?';
+ }
+
+ public static function _deduce_icon($type) {
+ $icon_mapping = [
+ '' => 'question',
+ 'text/markdown' => 'markdown',
+ 'blog' => 'markdown',
+ 'blog_list' => 'rectangle-list',
+ 'directory' => 'folder',
+ 'gallery' => 'images',
+ 'image' => 'image'
+ ];
+
+ return $icon_mapping[$type] ?? 'unknown';
+ }
+
+ function __construct($post_handler, $post_data, $site_defaults) {
+ $this->handler = $post_handler;
+
+ $this->content_html = null;
+ $this->content_markdown = null;
+
+ $this->site_defaults = $site_defaults;
+
+ if(!isset($post_data) or !isset($post_data['id'])) {
+ $post_data = $this->_generate_404($post_data);
+ }
+
+ $data = $post_data;
+
+ if($data['path'] == '') {
+ $data['path'] = '/';
+ $data['title'] ??= 'root';
+ $data['basename'] ??= 'root';
+ }
+
+ $post_data['host'] ??= 'localhost:8081';
+
+ $data['url'] ??= 'http://' . $post_data['host'] . $post_data['path'];
+
+ $data['basename'] ??= basename($data['path']);
+
+ $data['title'] ??= basename($data['path']);
+
+ $data['tags'] ??= [];
+
+ $data['type'] ??= self::_deduce_type($post_data['path']);
+
+ $data['icon'] ??= self::_deduce_icon($data['type']);
+
+ if(isset($sql_meta['media_url'])) {
+ $data['thumb_url'] ??= $data['media_url'];
+ }
+
+ $data['preview_image'] ??= $data['banners'][0]['src'] ?? null;
+
+ $data['brief'] ??= $data['title'];
+
+ $this->data = $data;
+ }
+
+ public function __get($name) {
+ if($name == 'html') {
+ return $this->get_html();
+ }
+ if($name == 'markdown') {
+ return $this->get_markdown();
+ }
+ if($name == 'json') {
+ return $this->to_json();
+ }
+ if($name == 'child_posts') {
+ return $this->get_child_posts();
+ }
+ if($name == 'parent') {
+ return $this->get_parent_post();
+ }
+
+ if(isset($this->data[$name])) {
+ return $this->data[$name];
+ }
+
+ if(is_null($this->site_defaults)) {
+ throw new RuntimeException("Post site defaults have not been set properly!");
+ }
+
+ return $this->site_defaults[$name] ?? null;
+ }
+
+ public function offsetGet($offset) : mixed {
+ return $this->__get($offset) ?? null;
+ }
+ public function offsetExists($offset) : bool {
+ if(isset($this->data[$offset])) {
+ return true;
+ }
+ if(isset($this->site_defaults[$offset])) {
+ return true;
+ }
+
+ return !is_null($this->offsetGet($offset));
+ }
+ public function offsetSet($offset, $value) : void {
+ $this->data[$offset] = $value;
+ }
+ public function offsetUnset($offset) : void {
+ unset($this->data[$offset]);
+ }
+
+ public function get_html() {
+ $this->content_html ??= $this->handler->render_post($this);
+
+ return $this->content_html;
+ }
+ public function get_markdown() {
+ $this->content_markdown ??=
+ $this->handler->get_markdown_for($this);
+
+ return $this->content_markdown;
+ }
+
+ public function get_child_posts(...$search_args) {
+ if(count($search_args) == 0) {
+ $this->_child_posts ??=
+ $this->handler->get_children_for($this);
+
+ return $this->_child_posts;
+ }
+ else {
+ return $this->handler->get_children_for($this, ...$search_args);
+ }
+ }
+
+ public function to_array($options = []) {
+ $out_data = $this->data;
+
+ if(isset($options['markdown'])) {
+ $out_data['markdown'] = $this->get_markdown();
+ }
+ if(isset($options['html'])) {
+ $out_data['html'] = $this->get_html();
+ }
+ if(isset($options['children'])) {
+ die();
+ }
+
+ return $out_data;
+ }
+ public function to_json($options = []) {
+ return json_encode($this->to_array($options));
+ }
+
+
+ public function get_parent_post() {
+ $parent_path = dirname($this->data['path']);
+ if($parent_path == '')
+ return null;
+
+ $this->_parent_post ??= $this->handler->get_post($parent_path);
+
+ return $this->_parent_post;
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/www/src/db_handler/post_handler.php b/www/src/db_handler/post_handler.php
new file mode 100644
index 0000000..06fd3fc
--- /dev/null
+++ b/www/src/db_handler/post_handler.php
@@ -0,0 +1,61 @@
+db = $db_adapter;
+ $this->posts = [];
+
+ $this->site_defaults = null;
+
+ $this->markdown_engine = null;
+ }
+
+ public function get_post($key) {
+ $key = sanitize_post_path($key);
+
+ if(isset($this->posts[$key])) {
+ return $this->posts[$key];
+ }
+
+ $post_data = $this->db->get_postdata($key);
+ $post = null;
+ if(isset($post_data)) {
+ $post = new Post($this, $post_data, $this->site_defaults);
+ }
+
+ $this->posts[$key] = $post;
+
+ return $post;
+ }
+
+ public function get_markdown_for($post) {
+ return $this->db->get_post_markdown($post->id);
+ }
+
+ public function render_post($post) {
+ return ($this->markdown_engine)($post);
+ }
+
+ public function get_children_for($post, ...$search_opts) {
+ $child_list = $this->db->get_post_children($post->path, ...$search_opts);
+
+ $out_list = [];
+ foreach($child_list as $child_data) {
+ array_push($out_list, new Post($this, $child_data, $this->site_defaults));
+ }
+
+ return $out_list;
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/www/src/dbtest.php b/www/src/dbtest.php
new file mode 100644
index 0000000..ffbc378
--- /dev/null
+++ b/www/src/dbtest.php
@@ -0,0 +1,191 @@
+';
+ echo 'Error number: ' . mysqli_connect_errno() . ' ';
+ echo 'Error message: ' . mysqli_connect_error() . ' ';
+ die();
+}
+
+$db_connection->execute_query("DELETE FROM posts;");
+
+$sql_adapter = new MySQLHandler($db_connection, $SERVER_HOST);
+$adapter = new PostHandler($sql_adapter);
+
+$sql_adapter->debugging = true;
+
+function test_accounce($title) {
+ echo "\n\n===========================================
+ _______ ______ _____ _______
+ |__ __| ____|/ ____|__ __|
+ | | | |__ | (___ | | (_)
+ | | | __| \___ \ | |
+ | | | |____ ____) | | | _
+ |_| |______|_____/ |_| (_)
+
+";
+ echo "==== " . $title . "\n";
+ echo "===========================================\n";
+}
+
+function adapter_fetch($post_path) {
+ global $db_connection;
+ global $sql_adapter;
+
+ echo "-> Fetching path " . $post_path . "\n";
+
+ echo json_encode($db_connection->execute_query("SELECT * FROM posts WHERE post_path=?", [
+ $post_path
+ ])->fetch_assoc(), JSON_PRETTY_PRINT);
+
+ echo "\n-> Adapter output:\n";
+
+ echo json_encode($sql_adapter->get_postdata($post_path), JSON_PRETTY_PRINT) . "\n";
+}
+
+echo "Starting test...\n";
+
+echo "Trying just a stub...\n";
+$sql_adapter->stub_postdata_tree('/testing/stubtest/1/2/3.md');
+echo "Stubbed~\n\n";
+
+echo "Getting the stub post...\n";
+
+echo json_encode($sql_adapter->get_postdata('/testing'), JSON_PRETTY_PRINT);
+
+echo "\n\n";
+
+test_accounce("Basic postdata setting");
+
+$sql_adapter->set_postdata([
+ 'path' => '/testing/settest/test.md',
+ 'title' => 'One heck of a test!',
+ 'type' => 'text/markdown',
+ 'tags' => [
+ 'test',
+ 'type:text'
+ ],
+ 'overridetest' => 'metadata'
+]);
+
+echo "\nDone!";
+
+adapter_fetch('/testing/settest/test.md');
+
+echo "Done!\n\n";
+
+test_accounce("Setting post markdown...");
+$sql_adapter->set_postdata([
+ 'path' => '/testing/markdowntest',
+ 'markdown' => 'Inline markdown test should work...',
+ 'title' => "A Markdown Test"
+]);
+$post = $sql_adapter->get_postdata('/testing/markdowntest');
+var_dump($sql_adapter->get_post_markdown($post['id']));
+
+$sql_adapter->set_post_markdown($post['id'],
+ '
+ This is one hell of a cute test!
+> Just checking in...
+ '
+);
+var_dump($sql_adapter->get_post_markdown($post['id']));
+unset($post);
+
+test_accounce("Settings inheritance test...");
+echo "Setting on a parent file...\n";
+
+$sql_adapter->set_postdata([
+ 'path' => '/testing/settest',
+ 'settings' => [
+ 'nom' => true,
+ 'type' => 'frame',
+ 'overridetest' => 'settings'
+ ]
+]);
+
+echo "\nAnd checking if that held!\n";
+
+adapter_fetch('/testing/settest');
+adapter_fetch('/testing/settest/test.md');
+
+test_accounce("Testing getting child posts");
+
+echo json_encode($sql_adapter->get_post_children('/testing'), JSON_PRETTY_PRINT);
+
+echo "\n\n------------------------------------------------------\n";
+
+echo "TEST PHASE: Adapter testing";
+echo "\n------------------------------------------------------\n\n";
+
+$post = $adapter->get_post('/testing/markdowntest');
+echo "Post path is " . $post->path . "\n";
+echo "Post markdown is " . $post->markdown . "\n";
+echo $post->to_json();
+
+echo "\n\n";
+
+echo $post->to_json([
+ 'markdown' => true
+]);
+
+test_accounce("Fetching child posts");
+echo "Root children:\n". json_encode(array_map(function($data) {
+ return $data->to_array();
+}, $adapter->get_post('/')->child_posts), JSON_PRETTY_PRINT);
+echo "\n\n";
+
+echo "Root children, extended:\n" . json_encode(array_map(function($data) {
+ return $data->to_array();
+}, $adapter->get_post('/')->get_child_posts(depth_end: 3)), JSON_PRETTY_PRINT);
+echo "\n\n";
+?>
\ No newline at end of file
diff --git a/www/dergdown.php b/www/src/dergdown.php
similarity index 100%
rename from www/dergdown.php
rename to www/src/dergdown.php
diff --git a/www/fontawesome.php b/www/src/fontawesome.php
similarity index 100%
rename from www/fontawesome.php
rename to www/src/fontawesome.php
diff --git a/www/mysql_adapter.php b/www/src/old_mysql_adapter.php
similarity index 100%
rename from www/mysql_adapter.php
rename to www/src/old_mysql_adapter.php
diff --git a/www/router.php b/www/src/old_router.php
similarity index 91%
rename from www/router.php
rename to www/src/old_router.php
index 8e0d1e7..e15593d 100644
--- a/www/router.php
+++ b/www/src/old_router.php
@@ -4,8 +4,8 @@ $data_time_start = microtime(true);
require_once 'vendor/autoload.php';
-require_once 'post_adapter.php';
-
+require_once 'db_handler/mysql_handler.php';
+require_once 'db_handler/post_handler.php';
require_once 'post.php';
require_once 'fontawesome.php';
@@ -24,7 +24,30 @@ $SITE_CONFIG = Yaml::parseFile('secrets/' . $SERVER_HOST . '.config.yml');
$SITE_CONFIG['uri_prefix'] = $SERVER_PREFIX;
$SITE_CONFIG['HTTP_HOST'] = $SERVER_HOST;
-$adapter = new PostHandler($SITE_CONFIG);
+$db_params = $SITE_CONFIG['db'];
+$db_connection = null;
+try {
+ if(false !== getenv('MYSQL_HOST')) {
+ $db_connection = mysqli_connect(getenv('MYSQL_HOST'),
+ getenv('MYSQL_USER'), getenv('MYSQL_PASSWORD'),
+ getenv('MYSQL_DATABASE'),
+ getenv('MYSQL_PORT'));
+ }
+ else {
+ $db_connection = mysqli_connect($db_params['host'],
+ $db_params['user'], $db_params['password'],
+ $db_params['database'],
+ $db_params['port']);
+ }
+} catch (\Throwable $th) {
+ echo 'Connection failed ';
+ echo 'Error number: ' . mysqli_connect_errno() . ' ';
+ echo 'Error message: ' . mysqli_connect_error() . ' ';
+ die();
+}
+
+$sql_adapter = new MySQLHandler($db_connection, $SERVER_HOST);
+$adapter = new PostHandler($sql_adapter);
$loader = new \Twig\Loader\FilesystemLoader(['./templates', './user_content']);
diff --git a/www/src/router.php b/www/src/router.php
new file mode 100644
index 0000000..c2f3dc7
--- /dev/null
+++ b/www/src/router.php
@@ -0,0 +1,31 @@
+
\ No newline at end of file
diff --git a/www/src/serve/ajax.php b/www/src/serve/ajax.php
new file mode 100644
index 0000000..679afe0
--- /dev/null
+++ b/www/src/serve/ajax.php
@@ -0,0 +1,26 @@
+get_post($REQUEST_QUERY['page']);
+}
+
+
+$ajax_args['fa'] = $FONT_AWESOME_ARRAY;
+$ajax_args['page'] ??= $SITE_CONFIG['site_defaults'];
+
+echo $twig->render('/ajax/' . $AJAX_REQUEST_TEMPLATE, $ajax_args);
+
+?>
\ No newline at end of file
diff --git a/www/src/serve/post.php b/www/src/serve/post.php
new file mode 100644
index 0000000..6430550
--- /dev/null
+++ b/www/src/serve/post.php
@@ -0,0 +1,48 @@
+get_post($REQUEST_PATH);
+
+function render_root_template($template, $args = []) {
+ global $twig;
+ global $FONT_AWESOME_ARRAY;
+ global $SITE_CONFIG;
+
+ $args['fa'] = $FONT_AWESOME_ARRAY;
+ $args['page'] ??= $SITE_CONFIG['site_defaults'];
+
+ $page = $args['page'];
+ $page['base'] ??= $page['url'];
+
+ $args['opengraph'] = [
+ "site_name" => $page['site_name'] ?? 'Nameless Site',
+ "title" => $page['title'] ?? 'Titleless',
+ "url" => $page['url'] ?? $page['path'] ?? 'No URL set',
+ "description" => $page['description'] ?? 'No description set'
+ ];
+
+ $args['banners'] = json_encode($page['banners'] ?? []);
+
+ $args['age_gate'] = (!isset($_COOKIE['AgeConfirmed']))
+ && isset($SITE_CONFIG['age_gate']);
+
+ echo $twig->render($template, $args);
+}
+
+function render_pathed_content_template($template, $args = []) {
+ render_root_template($template, $args);
+}
+
+render_pathed_content_template('post_types/markdown.html', [
+ 'page' => $post
+]);
+die();
+
+if(!isset($post)) {
+ render_404();
+ die();
+}
+
+
+?>
\ No newline at end of file
diff --git a/www/src/setup_db.php b/www/src/setup_db.php
new file mode 100644
index 0000000..70b3d88
--- /dev/null
+++ b/www/src/setup_db.php
@@ -0,0 +1,45 @@
+';
+ echo 'Error number: ' . mysqli_connect_errno() . ' ';
+ echo 'Error message: ' . mysqli_connect_error() . ' ';
+ die();
+}
+
+$sql_adapter = new MySQLHandler($db_connection, $SERVER_HOST);
+$adapter = new PostHandler($sql_adapter);
+
+require_once 'dergdown.php';
+
+function dergdown_to_html($text) {
+ $Parsedown = new Dergdown();
+
+ return $Parsedown->text($text);
+}
+function post_to_html($post) {
+ return dergdown_to_html($post->markdown);
+}
+$adapter->markdown_engine = "post_to_html";
+
+$adapter->site_defaults = $SITE_CONFIG['site_defaults'];
+
+?>
\ No newline at end of file
diff --git a/www/src/setup_site_config.php b/www/src/setup_site_config.php
new file mode 100644
index 0000000..683cb91
--- /dev/null
+++ b/www/src/setup_site_config.php
@@ -0,0 +1,19 @@
+
\ No newline at end of file
diff --git a/www/src/setup_twig.php b/www/src/setup_twig.php
new file mode 100644
index 0000000..e674428
--- /dev/null
+++ b/www/src/setup_twig.php
@@ -0,0 +1,24 @@
+ true,
+ 'cache' => 'twig_cache'
+]);
+$twig->addExtension(new Twig\Extra\Markdown\MarkdownExtension());
+
+use Twig\Extra\Markdown\DefaultMarkdown;
+use Twig\Extra\Markdown\MarkdownRuntime;
+use Twig\RuntimeLoader\RuntimeLoaderInterface;
+
+$twig->addRuntimeLoader(new class implements RuntimeLoaderInterface {
+ public function load($class) {
+ if (MarkdownRuntime::class === $class) {
+ return new MarkdownRuntime(new DefaultMarkdown());
+ }
+ }
+});
+
+
+?>
\ No newline at end of file
diff --git a/www/static/dergstyle.css b/www/static/dergstyle.css
index 2a4c1f9..6ccc0f6 100644
--- a/www/static/dergstyle.css
+++ b/www/static/dergstyle.css
@@ -311,12 +311,21 @@ body.htmx-request::before {
.folder-listing input {
display: none;
}
-.folder-listing input + ul {
+.folder-listing input ~ ul {
display: none;
}
-.folder-listing input:checked + ul {
+.folder-listing input:checked ~ ul {
display: block;
}
+.folder-listing label > :nth-child(2) {
+ display: none;
+}
+.folder-listing input:checked ~ label > :nth-child(1) {
+ display: none;
+}
+.folder-listing input:checked ~ label > :nth-child(2) {
+ display: inline-block;
+}
#navbar-expand-label {
cursor: pointer;
diff --git a/www/templates/ajax/closed_folder_listing.html b/www/templates/ajax/closed_folder_listing.html
deleted file mode 100644
index 399894f..0000000
--- a/www/templates/ajax/closed_folder_listing.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- {{ fa[post.post_metadata.icon] | raw }}
-
-
-
- {{ post.post_metadata.title }}
-
-
\ No newline at end of file
diff --git a/www/templates/ajax/compact_filelist/entry.html b/www/templates/ajax/compact_filelist/entry.html
new file mode 100644
index 0000000..6c63345
--- /dev/null
+++ b/www/templates/ajax/compact_filelist/entry.html
@@ -0,0 +1,27 @@
+
+
+
+ {% set folder_key = random() %}
+
+
+
+
+ {{ fa['folder'] | raw }}
+ {{ fa['folder-open'] | raw }}
+
+
+
+ {{ post.basename }} - {{ post.title }}
+
+
+
+
\ No newline at end of file
diff --git a/www/templates/ajax/compact_filelist/listing.html b/www/templates/ajax/compact_filelist/listing.html
new file mode 100644
index 0000000..ccdc7c9
--- /dev/null
+++ b/www/templates/ajax/compact_filelist/listing.html
@@ -0,0 +1,4 @@
+
+{% for post in page.child_posts %}
+{{ include('ajax/compact_filelist/entry.html') }}
+{% endfor %}
\ No newline at end of file
diff --git a/www/templates/ajax/folder_listing.html b/www/templates/ajax/folder_listing.html
deleted file mode 100644
index b90fb59..0000000
--- a/www/templates/ajax/folder_listing.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
-{% for post in subposts %}
-{{ include('ajax/folder_listing_entry.html') }}
-{% endfor %}
\ No newline at end of file
diff --git a/www/templates/ajax/folder_listing_entry.html b/www/templates/ajax/folder_listing_entry.html
deleted file mode 100644
index e47bf9b..0000000
--- a/www/templates/ajax/folder_listing_entry.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
- {% set folder_key = random() %}
-
-
-
- {{ fa[post.post_metadata.icon] | raw }}
-
-
-
- {{ post.post_metadata.title }}
-
-
-
-
-
\ No newline at end of file
diff --git a/www/templates/ajax/open_folder_listing.html b/www/templates/ajax/open_folder_listing.html
deleted file mode 100644
index 9bd6414..0000000
--- a/www/templates/ajax/open_folder_listing.html
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
- {{ fa[post.post_metadata.icon] | raw }}
-
-
-
- {{ post.post_metadata.title }}
-
-
-
- {% for post in subposts %}
- {{ include('ajax/closed_folder_listing.html') }}
- {% endfor %}
-
-
\ No newline at end of file
diff --git a/www/templates/fragments/filepath_bar.html b/www/templates/fragments/filepath_bar.html
index 314e019..f4a43a2 100644
--- a/www/templates/fragments/filepath_bar.html
+++ b/www/templates/fragments/filepath_bar.html
@@ -1,11 +1,11 @@
- {{ post.post_metadata.title }}
+ {{ page.basename }}
- {% set split_post = post.post_path |split('/') %}
+ {% set split_post = page.path |split('/') %}
{% for i in range(0, split_post|length - 1) %}
{% if i != 0 %}
@@ -22,7 +22,7 @@
{{ fa['bars'] | raw }}
+ style="padding-left: 0.3rem;" href="/feed/rss{{page.path}}">
{{ fa['rss']|raw }}
@@ -32,7 +32,7 @@
Full path:
- {% set split_post = post.post_path |split('/') %}
+ {% set split_post = page.path |split('/') %}
{% for i in range(0, split_post|length - 1) %}
{% if i != 0 %}
@@ -47,8 +47,8 @@
Dev links:
-
raw
-
api
+
raw
+
api
Folder browser:
@@ -58,12 +58,10 @@
{{ fa['turn-up'] | raw}}
-
..
+
..
-
- {% for post in subposts %}
- {{ include('ajax/folder_listing_entry.html') }}
- {% endfor %}
+
+ {{ include('ajax/compact_filelist/listing.html') }}
diff --git a/www/templates/pathed_content.html b/www/templates/pathed_content.html
index 90a0350..c8a3ffa 100644
--- a/www/templates/pathed_content.html
+++ b/www/templates/pathed_content.html
@@ -6,11 +6,11 @@
{{ parent() }}
-
+
{% endblock %}
{% block second_title %}
- {{ post.post_metadata.title }}
+ {{ page.title }}
{% endblock %}
{%block main_content%}
@@ -22,7 +22,7 @@
{%endblock%}
diff --git a/www/templates/post_types/markdown.html b/www/templates/post_types/markdown.html
index b9d147c..f00142c 100644
--- a/www/templates/post_types/markdown.html
+++ b/www/templates/post_types/markdown.html
@@ -9,5 +9,9 @@
{%endblock %}
{%block content_article%}
- {{ content_html|raw }}
+ {% if page.title %}
+ {{ page.title }}
+ {% endif %}
+
+ {{ page.html|raw }}
{% endblock %}
\ No newline at end of file
diff --git a/www/templates/root.html b/www/templates/root.html
index 0919f0e..08c3de4 100644
--- a/www/templates/root.html
+++ b/www/templates/root.html
@@ -1,7 +1,7 @@
- {{og.site_name}} - {{og.title}}
+ {{opengraph.site_name}} - {{opengraph.title}}
@@ -12,7 +12,6 @@
-
@@ -20,27 +19,31 @@
+ {% if page.base %}
+
+ {% endif %}
+
{% block feed_links %}
-
+
{% endblock %}
{% block extra_head %}{% endblock %}
{% block opengraph_tags %}
-
+
-
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
@@ -71,25 +74,29 @@
full picture
- {% block big_title %}{{og.site_name}}{%endblock%}
+ {% block big_title %}{{opengraph.site_name}}{%endblock%}
{% block second_title %}{% endblock %}
- About
- Blog
- Projects
- Artworks
+ {% for link in page.navbar_links %}
+ {{link.text}}
+ {% endfor %}
- {% block main_content %}Soon there shall be content! {% endblock %}
+ {% block main_content %}
+ This here should have been replaced by content.
+
+
+ If you can see this, complain to your nearest dragon.
+ {% endblock %}