Version 1.7.1 — auto default_page detection

- config.json now has default_page: auto for fresh installs
- CodePressCMS::detectDefaultPage() scans content/ for first available file
- getHomepageTitle() also respects auto mode
- Admin config form preserves auto as selectable option
- Save handler falls back to auto instead of index
This commit is contained in:
2026-07-28 15:39:12 +02:00
parent 8b454cd038
commit 2faea90872
6 changed files with 54 additions and 7 deletions
+1 -1
View File
@@ -17,7 +17,7 @@
<div class="col-md-6"> <div class="col-md-6">
<label for="default_page" class="form-label">Standaard/startpagina</label> <label for="default_page" class="form-label">Standaard/startpagina</label>
<select name="default_page" id="default_page" class="form-select"> <select name="default_page" id="default_page" class="form-select">
<option value="">-- Selecteer --</option> <option value="auto" <?= ($configData['default_page'] ?? 'auto') === 'auto' ? 'selected' : '' ?>>Auto (eerste beschikbare pagina)</option>
<?php foreach ($availablePages as $page): ?> <?php foreach ($availablePages as $page): ?>
<option value="<?= htmlspecialchars($page) ?>" <?= ($configData['default_page'] ?? '') === $page ? 'selected' : '' ?>> <option value="<?= htmlspecialchars($page) ?>" <?= ($configData['default_page'] ?? '') === $page ? 'selected' : '' ?>>
<?= htmlspecialchars(ucwords(str_replace(['-', '_'], ' ', $page))) ?> <?= htmlspecialchars(ucwords(str_replace(['-', '_'], ' ', $page))) ?>
+39 -1
View File
@@ -354,6 +354,9 @@ class CodePressCMS {
} }
$page = $_GET['page'] ?? $this->config['default_page']; $page = $_GET['page'] ?? $this->config['default_page'];
if ($page === 'auto') {
$page = $this->detectDefaultPage();
}
// Limit length // Limit length
$page = substr($page, 0, 255); $page = substr($page, 0, 255);
// Only remove file extension at the end, not all dots // Only remove file extension at the end, not all dots
@@ -1323,6 +1326,37 @@ class CodePressCMS {
return 'markdown'; return 'markdown';
} }
/**
* Auto-detect the first available content page
*
* Scans the content directory for the first .md/.php/.html file
* (preferring non-language-prefixed files) and returns its page key.
*
* @return string Detected page key, or 'index' as fallback
*/
private function detectDefaultPage(): string
{
$contentDir = $this->config['content_dir'];
if (!is_dir($contentDir)) return 'index';
$files = scandir($contentDir);
$candidates = [];
foreach ($files as $f) {
if (preg_match('/^((?:nl|en)\.)?(.+?)\.(md|php|html)$/', $f, $m)) {
$candidates[] = ['prefix' => $m[1], 'name' => $m[2], 'file' => $f];
}
}
if (empty($candidates)) return 'index';
// Prefer non-language-prefixed files (e.g. index.md over nl.index.md)
foreach ($candidates as $c) {
if (empty($c['prefix'])) return $c['name'];
}
return $candidates[0]['name'];
}
/** /**
* Get homepage title * Get homepage title
* *
@@ -1330,7 +1364,11 @@ class CodePressCMS {
*/ */
private function getHomepageTitle() { private function getHomepageTitle() {
// Use formatted filename for homepage title in navigation // Use formatted filename for homepage title in navigation
return $this->formatDisplayName($this->config['default_page']); $page = $this->config['default_page'];
if ($page === 'auto') {
$page = $this->detectDefaultPage();
}
return $this->formatDisplayName($page);
} }
/** /**
+1 -1
View File
@@ -2,8 +2,8 @@
"site_title": "CodePress", "site_title": "CodePress",
"content_dir": "content", "content_dir": "content",
"templates_dir": "cms\/templates", "templates_dir": "cms\/templates",
"default_page": "index",
"active_theme": "default", "active_theme": "default",
"default_page": "auto",
"language": { "language": {
"default": "nl", "default": "nl",
"available": [ "available": [
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "codepress", "name": "codepress",
"version": "1.7.0", "version": "1.7.1",
"description": "A lightweight, file-based Content Management System built with PHP and Bootstrap.", "description": "A lightweight, file-based Content Management System built with PHP and Bootstrap.",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
+1 -1
View File
@@ -736,7 +736,7 @@ function handleConfig(AdminAuth $auth, array $config): void
$messageType = 'danger'; $messageType = 'danger';
} else { } else {
$configData['site_title'] = trim($_POST['site_title'] ?? 'CodePress'); $configData['site_title'] = trim($_POST['site_title'] ?? 'CodePress');
$configData['default_page'] = trim($_POST['default_page'] ?? 'index'); $configData['default_page'] = trim($_POST['default_page'] ?? 'auto');
$configData['language']['default'] = trim($_POST['language_default'] ?? 'nl'); $configData['language']['default'] = trim($_POST['language_default'] ?? 'nl');
$configData['language']['available'] = $_POST['language_available'] ?? ['nl', 'en']; $configData['language']['available'] = $_POST['language_available'] ?? ['nl', 'en'];
$configData['seo']['description'] = trim($_POST['seo_description'] ?? ''); $configData['seo']['description'] = trim($_POST['seo_description'] ?? '');
+11 -2
View File
@@ -6,12 +6,21 @@
*/ */
return [ return [
'version' => '1.7.0', 'version' => '1.7.1',
'release_date' => '2026-07-28', 'release_date' => '2026-07-28',
'codename' => 'API', 'codename' => 'Auto',
'status' => 'stable', 'status' => 'stable',
'changelog' => [ 'changelog' => [
'1.7.1' => [
'date' => '2026-07-28',
'changes' => [
'Auto-detect first available content page when default_page is set to "auto"',
'default_page now defaults to "auto" in config.json for fresh installs',
'Admin config form preserves "auto" as a selectable option',
'No more empty "-- Selecteer --" option that silently saved "index"',
]
],
'1.7.0' => [ '1.7.0' => [
'date' => '2026-07-28', 'date' => '2026-07-28',
'changes' => [ 'changes' => [