Pre-render website read pages
This commit is contained in:
parent
a47671e2af
commit
307094794f
|
|
@ -62,6 +62,7 @@ RUN set -eu; \
|
|||
COPY httpd-php-fpm.conf /etc/apache2/conf.d/php-fpm.conf
|
||||
COPY opcache.ini /usr/local/etc/php/conf.d/zz-opcache.ini
|
||||
COPY php-fpm-runtime.conf /usr/local/etc/php-fpm.d/zz-runtime.conf
|
||||
COPY render-static-pages.sh /usr/local/bin/render-static-pages
|
||||
COPY start-website.sh /usr/local/bin/start-website
|
||||
|
||||
COPY . /var/www/localhost/htdocs/
|
||||
|
|
@ -74,10 +75,13 @@ RUN rm -f /var/www/localhost/htdocs/index.html && \
|
|||
/var/log/apache2 \
|
||||
/var/www/localhost/htdocs/db \
|
||||
/tmp/website-lang && \
|
||||
chmod 0755 /usr/local/bin/render-static-pages && \
|
||||
/usr/local/bin/render-static-pages /var/www/localhost/htdocs && \
|
||||
chown -R apache:apache \
|
||||
/run/apache2 \
|
||||
/var/log/apache2 \
|
||||
/var/www/localhost/htdocs/db \
|
||||
/var/www/localhost/htdocs/static-pages \
|
||||
/tmp/website-lang && \
|
||||
chmod 0755 /usr/local/bin/start-website
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
<?php
|
||||
require_once __DIR__ . '/lang_helper.php';
|
||||
require_once __DIR__ . '/ideas_helper.php';
|
||||
|
||||
$activityKeys = [
|
||||
'blog_activity_1',
|
||||
|
|
@ -80,8 +79,6 @@ $caseStudyCards = [
|
|||
];
|
||||
|
||||
$treeHref = 'homelab-tree.php?lang=' . urlencode($lang);
|
||||
$ideaStatus = visitor_idea_clean((string) ($_GET['idea'] ?? ''), 20);
|
||||
$visitorIdeas = visitor_ideas_read();
|
||||
$giteaSourceBase = 'https://lab2025.duckdns.org/git/jv/my-homelab-configs/src/branch/main/';
|
||||
$stackSourceLinks = [
|
||||
'blog_stack_1' => [
|
||||
|
|
@ -814,7 +811,12 @@ function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $so
|
|||
<?php endforeach; ?>
|
||||
</ul>
|
||||
|
||||
<div class="visitor-ideas" id="visitor-ideas">
|
||||
<div class="visitor-ideas" id="visitor-ideas"
|
||||
data-recent-title="<?php echo htmlspecialchars($text['blog_ideas_recent_title']); ?>"
|
||||
data-status-thanks="<?php echo htmlspecialchars($text['blog_idea_status_thanks']); ?>"
|
||||
data-status-invalid="<?php echo htmlspecialchars($text['blog_idea_status_invalid']); ?>"
|
||||
data-status-slow="<?php echo htmlspecialchars($text['blog_idea_status_slow']); ?>"
|
||||
data-status-error="<?php echo htmlspecialchars($text['blog_idea_status_error']); ?>">
|
||||
<div class="section-heading">
|
||||
<p class="section-kicker"
|
||||
data-translate data-key="blog_ideas_kicker"
|
||||
|
|
@ -831,14 +833,6 @@ function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $so
|
|||
</p>
|
||||
</div>
|
||||
|
||||
<?php if (in_array($ideaStatus, ['thanks', 'invalid', 'slow', 'error'], true)): ?>
|
||||
<p class="idea-status idea-status-<?php echo htmlspecialchars($ideaStatus); ?>"
|
||||
data-translate data-key="blog_idea_status_<?php echo htmlspecialchars($ideaStatus); ?>"
|
||||
data-en="<?php echo htmlspecialchars($en['blog_idea_status_' . $ideaStatus]); ?>">
|
||||
<?php echo $text['blog_idea_status_' . $ideaStatus]; ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<form class="idea-form" action="save_idea.php" method="post">
|
||||
<input type="hidden" name="lang" value="<?php echo htmlspecialchars($lang); ?>">
|
||||
<label>
|
||||
|
|
@ -866,25 +860,6 @@ function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $so
|
|||
</button>
|
||||
</form>
|
||||
|
||||
<?php if ($visitorIdeas): ?>
|
||||
<div class="visitor-idea-list">
|
||||
<h4 data-translate data-key="blog_ideas_recent_title"
|
||||
data-en="<?php echo htmlspecialchars($en['blog_ideas_recent_title']); ?>">
|
||||
<?php echo $text['blog_ideas_recent_title']; ?>
|
||||
</h4>
|
||||
<?php foreach ($visitorIdeas as $visitorIdea): ?>
|
||||
<article class="visitor-idea-card">
|
||||
<p><?php echo nl2br(htmlspecialchars($visitorIdea['idea'])); ?></p>
|
||||
<footer>
|
||||
<span><?php echo htmlspecialchars($visitorIdea['name']); ?></span>
|
||||
<time datetime="<?php echo htmlspecialchars($visitorIdea['created_at']); ?>">
|
||||
<?php echo htmlspecialchars(substr($visitorIdea['created_at'], 0, 10)); ?>
|
||||
</time>
|
||||
</footer>
|
||||
</article>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
|
@ -893,6 +868,7 @@ function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $so
|
|||
window.OTHER_PAGES = ['/index.php', '/cv.php', '/homelab-tree.php'];
|
||||
</script>
|
||||
<script src="cv-theme.js"></script>
|
||||
<script src="visitor-ideas.js"></script>
|
||||
<?php require_once __DIR__ . '/partials/translation_ui.php'; ?>
|
||||
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,27 @@
|
|||
RewriteEngine On
|
||||
|
||||
RewriteCond %{QUERY_STRING} (^|&)lang=en(&|$)
|
||||
RewriteRule ^/?(?:index\.php)?$ /static-pages/en/index.html [END]
|
||||
RewriteCond %{QUERY_STRING} (^|&)lang=en(&|$)
|
||||
RewriteRule ^/?(cv|blog|demos|homelab-tree)\.php$ /static-pages/en/$1.html [END]
|
||||
|
||||
RewriteCond %{QUERY_STRING} (^|&)lang=nah(&|$)
|
||||
RewriteRule ^/?(?:index\.php)?$ /static-pages/nah/index.html [END]
|
||||
RewriteCond %{QUERY_STRING} (^|&)lang=nah(&|$)
|
||||
RewriteRule ^/?(cv|blog|demos|homelab-tree)\.php$ /static-pages/nah/$1.html [END]
|
||||
|
||||
RewriteCond %{QUERY_STRING} !(^|&)lang= [NC]
|
||||
RewriteCond %{HTTP:Accept-Language} ^en [NC]
|
||||
RewriteRule ^/?(?:index\.php)?$ /static-pages/en/index.html [END]
|
||||
RewriteCond %{QUERY_STRING} !(^|&)lang= [NC]
|
||||
RewriteCond %{HTTP:Accept-Language} ^en [NC]
|
||||
RewriteRule ^/?(cv|blog|demos|homelab-tree)\.php$ /static-pages/en/$1.html [END]
|
||||
|
||||
RewriteCond %{QUERY_STRING} !(^|&)lang= [NC]
|
||||
RewriteRule ^/?(?:index\.php)?$ /static-pages/nah/index.html [END]
|
||||
RewriteCond %{QUERY_STRING} !(^|&)lang= [NC]
|
||||
RewriteRule ^/?(cv|blog|demos|homelab-tree)\.php$ /static-pages/nah/$1.html [END]
|
||||
|
||||
<FilesMatch "\.php$">
|
||||
SetHandler "proxy:fcgi://127.0.0.1:9000"
|
||||
</FilesMatch>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
root="${1:-/var/www/localhost/htdocs}"
|
||||
|
||||
render_page() {
|
||||
lang="$1"
|
||||
source="$2"
|
||||
output="$3"
|
||||
request_uri="$4"
|
||||
|
||||
mkdir -p "$(dirname "$output")"
|
||||
# shellcheck disable=SC2016
|
||||
php -r '
|
||||
parse_str($argv[1], $_GET);
|
||||
$_SERVER["HTTP_ACCEPT_LANGUAGE"] = $argv[2];
|
||||
$_SERVER["REQUEST_METHOD"] = "GET";
|
||||
$_SERVER["REQUEST_URI"] = $argv[3];
|
||||
$_SERVER["PHP_SELF"] = "/" . $argv[4];
|
||||
chdir($argv[5]);
|
||||
include $argv[5] . "/" . $argv[4];
|
||||
' "lang=$lang" "$lang" "$request_uri" "$source" "$root" > "$output"
|
||||
}
|
||||
|
||||
for lang in en nah; do
|
||||
static_dir="$root/static-pages/$lang"
|
||||
render_page "$lang" index.php "$static_dir/index.html" "/?lang=$lang"
|
||||
render_page "$lang" cv.php "$static_dir/cv.html" "/cv.php?lang=$lang"
|
||||
render_page "$lang" blog.php "$static_dir/blog.html" "/blog.php?lang=$lang"
|
||||
render_page "$lang" demos.php "$static_dir/demos.html" "/demos.php?lang=$lang"
|
||||
render_page "$lang" homelab-tree.php "$static_dir/homelab-tree.html" "/homelab-tree.php?lang=$lang"
|
||||
done
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
(function () {
|
||||
const root = document.getElementById('visitor-ideas');
|
||||
if (!root) return;
|
||||
|
||||
const messages = {
|
||||
thanks: root.dataset.statusThanks,
|
||||
invalid: root.dataset.statusInvalid,
|
||||
slow: root.dataset.statusSlow,
|
||||
error: root.dataset.statusError,
|
||||
};
|
||||
|
||||
const status = new URLSearchParams(window.location.search).get('idea');
|
||||
if (status && messages[status]) {
|
||||
const statusEl = document.createElement('p');
|
||||
statusEl.className = `idea-status idea-status-${status}`;
|
||||
statusEl.textContent = messages[status];
|
||||
const form = root.querySelector('.idea-form');
|
||||
root.insertBefore(statusEl, form || root.firstChild);
|
||||
}
|
||||
|
||||
function addIdeaText(parent, text) {
|
||||
String(text || '').split('\n').forEach((line, index) => {
|
||||
if (index > 0) parent.appendChild(document.createElement('br'));
|
||||
parent.appendChild(document.createTextNode(line));
|
||||
});
|
||||
}
|
||||
|
||||
function renderIdeas(ideas) {
|
||||
const existing = root.querySelector('.visitor-idea-list');
|
||||
if (existing) existing.remove();
|
||||
if (!Array.isArray(ideas) || ideas.length === 0) return;
|
||||
|
||||
const list = document.createElement('div');
|
||||
list.className = 'visitor-idea-list';
|
||||
|
||||
const heading = document.createElement('h4');
|
||||
heading.textContent = root.dataset.recentTitle || 'Recent visitor ideas';
|
||||
list.appendChild(heading);
|
||||
|
||||
ideas.forEach((idea) => {
|
||||
const article = document.createElement('article');
|
||||
article.className = 'visitor-idea-card';
|
||||
|
||||
const body = document.createElement('p');
|
||||
addIdeaText(body, idea.idea);
|
||||
article.appendChild(body);
|
||||
|
||||
const footer = document.createElement('footer');
|
||||
const name = document.createElement('span');
|
||||
name.textContent = idea.name || 'Anonymous visitor';
|
||||
const time = document.createElement('time');
|
||||
time.dateTime = idea.created_at || '';
|
||||
time.textContent = String(idea.created_at || '').slice(0, 10);
|
||||
footer.appendChild(name);
|
||||
footer.appendChild(time);
|
||||
article.appendChild(footer);
|
||||
|
||||
list.appendChild(article);
|
||||
});
|
||||
|
||||
root.appendChild(list);
|
||||
}
|
||||
|
||||
fetch('/visitor_ideas.php', { headers: { Accept: 'application/json' } })
|
||||
.then((response) => (response.ok ? response.json() : { ideas: [] }))
|
||||
.then((data) => renderIdeas(data.ideas))
|
||||
.catch(() => renderIdeas([]));
|
||||
})();
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
require_once __DIR__ . '/ideas_helper.php';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
|
||||
http_response_code(405);
|
||||
exit;
|
||||
}
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
echo json_encode(
|
||||
['ideas' => visitor_ideas_read()],
|
||||
JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
|
||||
);
|
||||
Loading…
Reference in New Issue