Make base path configurable for root-domain deployment (IONOS)
Bisher war /hifi an mehreren Stellen fest einprogrammiert (vite base, Router basename, API-Client, Upload-URLs, .htaccess). Fuer den geplanten Deploy auf IONOS unter der Domain-Wurzel wird das jetzt ueber VITE_BASE_PATH (Frontend-Build) bzw. eine optionale base_path.php (Backend, gleiches Muster wie db.php/setup.php) gesteuert - lokal ohne diese Werte bleibt alles unveraendert bei /hifi. .htaccess.ionos enthaelt die Root-Domain-Variante fuer den CI-Build. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
a3854fe5b8
commit
618a32182c
10 changed files with 58 additions and 18 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -27,6 +27,10 @@
|
|||
# pro Umgebung unterschiedlich und darf nicht öffentlich einsehbar sein
|
||||
/hifi/api/config/setup.php
|
||||
|
||||
# Wird nur im IONOS-Deploy-Now-Build-Schritt geschrieben (Root-Domain statt /hifi),
|
||||
# lokal nicht vorhanden -> Fallback in config.php greift dann
|
||||
/hifi/api/config/base_path.php
|
||||
|
||||
# Claude-Code-Tooling (Skills/lokale Einstellungen) - gehört nicht zum Website-Projekt
|
||||
/hifi/.claude/
|
||||
/hifi/.agents/
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
const API_BASE = '/hifi/api';
|
||||
// BASE_URL spiegelt immer den "base"-Wert aus vite.config.js wider (mit
|
||||
// abschließendem Slash, z.B. "/hifi/" lokal oder "/" auf IONOS).
|
||||
export const API_BASE = `${import.meta.env.BASE_URL.replace(/\/$/, '')}/api`;
|
||||
|
||||
async function request(path, options = {}) {
|
||||
const res = await fetch(`${API_BASE}${path}`, {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import './index.css';
|
|||
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<React.StrictMode>
|
||||
<BrowserRouter basename="/hifi">
|
||||
<BrowserRouter basename={import.meta.env.BASE_URL.replace(/\/$/, '') || '/'}>
|
||||
<ThemeProvider>
|
||||
<AuthProvider>
|
||||
<CookieConsentProvider>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useState } from 'react';
|
||||
import { api } from '../../../api/client.js';
|
||||
import { api, API_BASE } from '../../../api/client.js';
|
||||
|
||||
export default function ExportImportSettings() {
|
||||
const [importFile, setImportFile] = useState(null);
|
||||
|
|
@ -38,7 +38,7 @@ export default function ExportImportSettings() {
|
|||
herunter. Benutzerkonten und Kontaktanfragen sind bewusst <strong>nicht</strong> enthalten.
|
||||
</p>
|
||||
<a
|
||||
href="/hifi/api/settings/export"
|
||||
href={`${API_BASE}/settings/export`}
|
||||
className="inline-block rounded-md bg-brand-500 px-4 py-2 text-sm font-semibold text-white hover:bg-brand-600"
|
||||
>
|
||||
Jetzt exportieren
|
||||
|
|
|
|||
|
|
@ -1,9 +1,14 @@
|
|||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
|
||||
// Lokal (XAMPP) läuft die Seite unter /hifi/, auf IONOS Deploy Now unter der
|
||||
// Domain-Wurzel. VITE_BASE_PATH wird nur im CI-Build-Schritt auf "/" gesetzt,
|
||||
// lokal bleibt der Default unverändert.
|
||||
const base = process.env.VITE_BASE_PATH || '/hifi/';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
base: '/hifi/',
|
||||
base,
|
||||
build: {
|
||||
outDir: '../hifi',
|
||||
emptyOutDir: false,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
# Für die lokale XAMPP-Entwicklung (Seite liegt unter /hifi/). Die Root-Domain-
|
||||
# Variante für den IONOS-Deploy-Now-Build liegt in .htaccess.ionos und wird dort
|
||||
# beim Bauen automatisch anstelle dieser Datei verwendet.
|
||||
RewriteEngine On
|
||||
RewriteBase /hifi/
|
||||
|
||||
|
|
|
|||
15
hifi/.htaccess.ionos
Normal file
15
hifi/.htaccess.ionos
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
RewriteEngine On
|
||||
RewriteBase /
|
||||
|
||||
# API-Requests an den PHP-Front-Controller weiterleiten
|
||||
RewriteCond %{REQUEST_URI} ^/api/
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^api/(.*)$ api/public/index.php [QSA,L]
|
||||
|
||||
# Dynamische sitemap.xml (DB-generiert)
|
||||
RewriteRule ^sitemap\.xml$ api/public/sitemap.php [L]
|
||||
|
||||
# Alles andere: SPA-Fallback auf index.html (React Router übernimmt das Routing)
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule ^ index.html [QSA,L]
|
||||
|
|
@ -24,8 +24,10 @@ return [
|
|||
'to_email' => 'kontakt@example.com',
|
||||
],
|
||||
'app' => [
|
||||
// Muss zum Vite "base" passen und wird für Session-Cookie-Pfad genutzt.
|
||||
'base_path' => '/hifi',
|
||||
// Muss zum Vite "base" passen und wird für Session-Cookie-Pfad und Upload-URLs
|
||||
// genutzt. Lokal (XAMPP) ist das /hifi, im IONOS-Deploy-Now-Build wird beim
|
||||
// Bauen eine base_path.php mit '/' geschrieben (siehe .github Workflow).
|
||||
'base_path' => is_file(__DIR__ . '/base_path.php') ? require __DIR__ . '/base_path.php' : '/hifi',
|
||||
'session_name' => 'hifi_admin_session',
|
||||
// Öffentliche Domain der Seite (für sitemap.xml, robots.txt, Canonical-URLs). Ohne abschließenden Slash.
|
||||
'site_url' => 'https://hifi-planet.de',
|
||||
|
|
|
|||
|
|
@ -21,7 +21,13 @@ class SettingsController
|
|||
'services' => ['id', 'icon_name', 'title', 'description', 'image_path', 'cta_label', 'cta_url', 'sort_order', 'created_at', 'updated_at'],
|
||||
];
|
||||
|
||||
private const UPLOADS_URL_PREFIX = '/hifi/api/uploads/';
|
||||
// Kein const, da abhängig von der Umgebung (base_path unterscheidet sich
|
||||
// zwischen lokalem /hifi und der Root-Domain auf IONOS).
|
||||
private static function uploadsUrlPrefix(): string
|
||||
{
|
||||
$config = require __DIR__ . '/../../config/config.php';
|
||||
return rtrim($config['app']['base_path'], '/') . '/api/uploads/';
|
||||
}
|
||||
|
||||
public static function exportData(): void
|
||||
{
|
||||
|
|
@ -164,7 +170,7 @@ class SettingsController
|
|||
|
||||
private static function collectImage(?string $path, array &$images): void
|
||||
{
|
||||
if (!$path || isset($images[$path]) || !str_starts_with($path, self::UPLOADS_URL_PREFIX)) {
|
||||
if (!$path || isset($images[$path]) || !str_starts_with($path, self::uploadsUrlPrefix())) {
|
||||
return;
|
||||
}
|
||||
$filename = basename($path);
|
||||
|
|
@ -190,14 +196,14 @@ class SettingsController
|
|||
private static function defaultServices(): array
|
||||
{
|
||||
return [
|
||||
['car', 'Car-Hifi', 'Individuelle Sound-Umbauten vom dezenten Upgrade bis zum kompromisslosen High-End-System – konfigurierbar direkt auf unserer Seite.', self::UPLOADS_URL_PREFIX . 'seed-leistung-car-hifi.jpg', 'Fahrzeug konfigurieren', '/fahrzeuge', 0],
|
||||
['caravan', 'Wohnmobil & Caravan', 'Sound- und Elektronik-Lösungen speziell für Reisemobile und Caravans – reversibel oder fest verbaut.', self::UPLOADS_URL_PREFIX . 'seed-leistung-wohnmobil.jpg', null, null, 1],
|
||||
['car-front', 'Oldtimer', 'Zeitgemäßer Klang für Klassiker – wir modernisieren die Anlage, ohne den Charakter deines Oldtimers zu verlieren.', self::UPLOADS_URL_PREFIX . 'seed-leistung-oldtimer.jpg', null, null, 2],
|
||||
['cog', 'CNC Zerspanen', 'Fräsen, Bohren, Schneiden und Schleifen auf einer Fläche von 1500 × 3000 mm – für Prototypen, Kleinserien und Großauflagen. Massivholz, Verbundwerkstoffe, Plattenmaterial und mehr.', self::UPLOADS_URL_PREFIX . 'seed-leistung-cnc-zerspanen.jpg', null, null, 3],
|
||||
['zap', 'CNC Lasertechnik', 'Präzises Laserschneiden und -gravieren für Leder, Glas, Acryl, Holz, Karton und mehr – für Einzelstücke ebenso wie Serienfertigung.', self::UPLOADS_URL_PREFIX . 'seed-leistung-cnc-laser.jpg', null, null, 4],
|
||||
['boxes', '3D-Druck', 'Über 20 Drucker (FDM & SLA) für individuelle Halterungen, Blenden und Kleinserien – Fertigung meist in 1–3 Tagen, auf Wunsch auch farbig.', self::UPLOADS_URL_PREFIX . 'seed-leistung-3d-druck.jpg', null, null, 5],
|
||||
['shield-alert', 'Alarmanlagen', 'Zuverlässiger Diebstahlschutz für dein Fahrzeug, abgestimmt auf deine Ansprüche und dein Budget.', self::UPLOADS_URL_PREFIX . 'seed-leistung-alarmanlagen.jpg', null, null, 6],
|
||||
['video', 'Dash Cams', 'Beweissichere Aufzeichnung fürs Auto – wir beraten dich zur passenden Kamera und übernehmen den unauffälligen Einbau.', self::UPLOADS_URL_PREFIX . 'seed-leistung-dashcam.jpg', null, null, 7],
|
||||
['car', 'Car-Hifi', 'Individuelle Sound-Umbauten vom dezenten Upgrade bis zum kompromisslosen High-End-System – konfigurierbar direkt auf unserer Seite.', self::uploadsUrlPrefix() . 'seed-leistung-car-hifi.jpg', 'Fahrzeug konfigurieren', '/fahrzeuge', 0],
|
||||
['caravan', 'Wohnmobil & Caravan', 'Sound- und Elektronik-Lösungen speziell für Reisemobile und Caravans – reversibel oder fest verbaut.', self::uploadsUrlPrefix() . 'seed-leistung-wohnmobil.jpg', null, null, 1],
|
||||
['car-front', 'Oldtimer', 'Zeitgemäßer Klang für Klassiker – wir modernisieren die Anlage, ohne den Charakter deines Oldtimers zu verlieren.', self::uploadsUrlPrefix() . 'seed-leistung-oldtimer.jpg', null, null, 2],
|
||||
['cog', 'CNC Zerspanen', 'Fräsen, Bohren, Schneiden und Schleifen auf einer Fläche von 1500 × 3000 mm – für Prototypen, Kleinserien und Großauflagen. Massivholz, Verbundwerkstoffe, Plattenmaterial und mehr.', self::uploadsUrlPrefix() . 'seed-leistung-cnc-zerspanen.jpg', null, null, 3],
|
||||
['zap', 'CNC Lasertechnik', 'Präzises Laserschneiden und -gravieren für Leder, Glas, Acryl, Holz, Karton und mehr – für Einzelstücke ebenso wie Serienfertigung.', self::uploadsUrlPrefix() . 'seed-leistung-cnc-laser.jpg', null, null, 4],
|
||||
['boxes', '3D-Druck', 'Über 20 Drucker (FDM & SLA) für individuelle Halterungen, Blenden und Kleinserien – Fertigung meist in 1–3 Tagen, auf Wunsch auch farbig.', self::uploadsUrlPrefix() . 'seed-leistung-3d-druck.jpg', null, null, 5],
|
||||
['shield-alert', 'Alarmanlagen', 'Zuverlässiger Diebstahlschutz für dein Fahrzeug, abgestimmt auf deine Ansprüche und dein Budget.', self::uploadsUrlPrefix() . 'seed-leistung-alarmanlagen.jpg', null, null, 6],
|
||||
['video', 'Dash Cams', 'Beweissichere Aufzeichnung fürs Auto – wir beraten dich zur passenden Kamera und übernehmen den unauffälligen Einbau.', self::uploadsUrlPrefix() . 'seed-leistung-dashcam.jpg', null, null, 7],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ class UploadController
|
|||
Http::error('Datei konnte nicht gespeichert werden', 500);
|
||||
}
|
||||
|
||||
Http::send(['path' => '/hifi/api/uploads/' . $filename], 201);
|
||||
$config = require __DIR__ . '/../../config/config.php';
|
||||
$prefix = rtrim($config['app']['base_path'], '/') . '/api/uploads/';
|
||||
|
||||
Http::send(['path' => $prefix . $filename], 201);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue