Autosave: 20260330-225236

This commit is contained in:
Flatlogic Bot 2026-03-30 22:52:37 +00:00
parent 4b40c1c287
commit e22ae9d08f
32 changed files with 1986 additions and 133 deletions

View File

@ -1,18 +1,10 @@
DirectoryIndex index.php index.html
Options -Indexes
Options -MultiViews
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
# 0) Serve existing files/directories as-is
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# 1) Internal map: /page or /page/ -> /page.php (if such PHP file exists)
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]
# 2) Optional: strip trailing slash for non-directories (keeps .php links working)
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ $1 [R=301,L]
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

4
admin_credentials.txt Normal file
View File

@ -0,0 +1,4 @@
WordPress Admin Credentials:
URL: https://nazar-kebap-website-febe.dev.flatlogic.app/wp-admin
Username: admin
Password: SnGlSaQ9VNSqHB4u

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@ -1,16 +1,26 @@
<?php
if ( defined( 'WP_CLI' ) ) {
if ( defined( 'WP_CLI' ) && empty( $_SERVER['HTTP_HOST'] ) ) {
$_SERVER['HTTP_HOST'] = 'localhost';
}
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
if ( ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && strpos( $_SERVER['HTTP_X_FORWARDED_PROTO'], 'https' ) !== false ) {
$_SERVER['HTTPS'] = 'on';
}
if (isset($_SERVER['HTTP_HOST'])) {
$http_protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
define('WP_HOME', $http_protocol . '://' . $_SERVER['HTTP_HOST']);
define('WP_SITEURL', $http_protocol . '://' . $_SERVER['HTTP_HOST']);
$detected_host = '';
if ( ! empty( $_SERVER['HTTP_X_FORWARDED_HOST'] ) ) {
$forwarded_hosts = explode( ',', $_SERVER['HTTP_X_FORWARDED_HOST'] );
$detected_host = trim( $forwarded_hosts[0] );
} elseif ( ! empty( $_SERVER['HTTP_HOST'] ) ) {
$detected_host = $_SERVER['HTTP_HOST'];
}
if ( $detected_host ) {
$_SERVER['HTTP_HOST'] = $detected_host;
$_SERVER['SERVER_NAME'] = $detected_host;
$http_protocol = ( isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] === 'on' ) ? 'https' : 'http';
define( 'WP_HOME', $http_protocol . '://' . $detected_host );
define( 'WP_SITEURL', $http_protocol . '://' . $detected_host );
}
/**

View File

@ -0,0 +1,63 @@
<?php
/**
* Plugin Name: Flatlogic URL Preserver
* Description: Automatically attaches fl_project to all links on the page.
*/
if ( ! defined( 'ABSPATH' ) ) exit;
// Function to fetch the ID once per request
function fl_get_env_project_id() {
static $cached_id = null;
if ($cached_id !== null) return $cached_id;
$cached_id = getenv('PROJECT_ID');
if (!$cached_id) {
$envPath = ABSPATH . '../.env';
if (file_exists($envPath)) {
$lines = file($envPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
if (strpos(trim($line), 'PROJECT_ID=') === 0) {
$cached_id = trim(str_replace('PROJECT_ID=', '', $line), "\"' ");
break;
}
}
}
}
return $cached_id;
}
// The core function to modify the URL
function fl_append_project_param( $url ) {
$pid = fl_get_env_project_id();
if ( ! $pid || empty( $url ) || strpos( $url, '#' ) === 0 ) {
return $url;
}
// Only append if it's an internal link
if ( strpos( $url, home_url() ) === 0 || ( strpos( $url, '/' ) === 0 && strpos( $url, '//' ) !== 0 ) ) {
return add_query_arg( 'fl_project', $pid, $url );
}
return $url;
}
// Apply to all link filters
$filters = [
'post_link', 'page_link', 'post_type_link',
'term_link', 'attachment_link',
'author_link', 'category_link', 'tag_link'
];
foreach ( $filters as $f ) {
add_filter( $f, 'fl_append_project_param' );
}
// Special case: Navigation Menus
add_filter( 'nav_menu_link_attributes', function( $atts ) {
if ( isset( $atts['href'] ) ) {
$atts['href'] = fl_append_project_param( $atts['href'] );
}
return $atts;
}, 10, 1 );

View File

@ -0,0 +1,107 @@
(function () {
function initReservationForm(form) {
var dateInput = form.querySelector('[data-reservation-date]');
var partySelect = form.querySelector('[data-party-size]');
var timeSelect = form.querySelector('[data-reservation-time]');
var note = form.querySelector('[data-availability-note]');
if (!dateInput || !partySelect || !timeSelect || !note || typeof nazarReservationData === 'undefined') {
return;
}
var messages = nazarReservationData.messages || {};
var requestCounter = 0;
function setPlaceholder(text, disabled) {
timeSelect.innerHTML = '';
var option = document.createElement('option');
option.value = '';
option.textContent = text;
timeSelect.appendChild(option);
timeSelect.disabled = !!disabled;
timeSelect.value = '';
}
function updateAvailability() {
var date = dateInput.value;
var partySize = partySelect.value;
if (!date || !partySize) {
setPlaceholder(messages.chooseDateAndParty || 'Bitte wählen Sie zuerst Datum und Personenzahl.', true);
note.textContent = messages.chooseDateAndParty || 'Bitte wählen Sie zuerst Datum und Personenzahl.';
return;
}
requestCounter += 1;
var currentRequest = requestCounter;
setPlaceholder(messages.loading || 'Verfügbare Uhrzeiten werden geladen …', true);
note.textContent = messages.loading || 'Verfügbare Uhrzeiten werden geladen …';
var body = new URLSearchParams();
body.append('action', 'nazar_get_available_times');
body.append('nonce', nazarReservationData.nonce);
body.append('reservation_date', date);
body.append('party_size', partySize);
fetch(nazarReservationData.ajaxUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
body: body.toString()
})
.then(function (response) {
return response.json();
})
.then(function (payload) {
if (currentRequest !== requestCounter) {
return;
}
if (!payload || !payload.success || !payload.data) {
throw new Error('invalid_response');
}
var times = Array.isArray(payload.data.times) ? payload.data.times : [];
if (!times.length) {
setPlaceholder(messages.empty || 'Für diese Auswahl ist aktuell keine freie Uhrzeit verfügbar.', true);
note.textContent = payload.data.message || messages.empty || 'Für diese Auswahl ist aktuell keine freie Uhrzeit verfügbar.';
return;
}
timeSelect.innerHTML = '';
var defaultOption = document.createElement('option');
defaultOption.value = '';
defaultOption.textContent = 'Bitte wählen';
timeSelect.appendChild(defaultOption);
times.forEach(function (slot) {
var option = document.createElement('option');
option.value = slot.value;
option.textContent = slot.label;
timeSelect.appendChild(option);
});
timeSelect.disabled = false;
note.textContent = payload.data.message || '';
})
.catch(function () {
if (currentRequest !== requestCounter) {
return;
}
setPlaceholder(messages.error || 'Die verfügbaren Uhrzeiten konnten gerade nicht geladen werden. Bitte versuchen Sie es erneut.', true);
note.textContent = messages.error || 'Die verfügbaren Uhrzeiten konnten gerade nicht geladen werden. Bitte versuchen Sie es erneut.';
});
}
dateInput.addEventListener('change', updateAvailability);
partySelect.addEventListener('change', updateAvailability);
}
document.addEventListener('DOMContentLoaded', function () {
document.querySelectorAll('[data-availability-form]').forEach(initReservationForm);
});
})();

View File

@ -0,0 +1,467 @@
:root {
--nazar-primary: #c88d2b;
--nazar-secondary: #9f2f1d;
--nazar-bg: #120f0d;
--nazar-surface: #1f1a17;
--nazar-surface-2: #2a2320;
--nazar-text: #f5eee7;
--nazar-muted: #d1c2b3;
--nazar-border: rgba(255,255,255,0.08);
--nazar-radius: 20px;
--nazar-shadow: 0 24px 60px rgba(0,0,0,0.28);
}
body.nazar-site {
background: #f7f1eb;
color: #241b16;
}
body.nazar-site .wp-site-blocks {
background:
radial-gradient(circle at top right, rgba(200,141,43,0.15), transparent 20%),
linear-gradient(180deg, #fffaf4 0%, #f7f1eb 100%);
}
body.nazar-site .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)),
body.nazar-site .wp-block-group.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
max-width: 1180px;
}
body.nazar-site header.wp-block-template-part,
body.nazar-site footer.wp-block-template-part {
background: rgba(18, 15, 13, 0.94);
color: var(--nazar-text);
}
body.nazar-site header.wp-block-template-part a,
body.nazar-site footer.wp-block-template-part a,
body.nazar-site .wp-block-navigation .wp-block-navigation-item__content {
color: var(--nazar-text);
}
body.nazar-site .wp-block-site-title a,
body.nazar-site .wp-block-site-title {
color: var(--nazar-text);
font-weight: 700;
letter-spacing: 0.02em;
}
body.nazar-site .wp-element-button,
body.nazar-site .wp-block-button__link {
background: linear-gradient(135deg, var(--nazar-primary), #e7b357);
color: #1b120d;
border-radius: 999px;
padding: 0.95rem 1.45rem;
font-weight: 700;
box-shadow: 0 12px 30px rgba(200, 141, 43, 0.25);
border: none;
}
body.nazar-site .wp-block-button.is-style-outline .wp-block-button__link,
body.nazar-site .nazar-button-secondary {
background: transparent;
color: var(--nazar-text);
border: 1px solid rgba(255,255,255,0.25);
box-shadow: none;
}
.nazar-hero {
position: relative;
overflow: hidden;
margin-top: 0;
padding: clamp(3rem, 4vw, 5rem);
border-radius: 36px;
background:
radial-gradient(circle at top left, rgba(231,179,87,0.22), transparent 25%),
radial-gradient(circle at bottom right, rgba(159,47,29,0.35), transparent 30%),
linear-gradient(135deg, #18110f 0%, #2a1b14 55%, #0f0d0c 100%);
color: var(--nazar-text);
box-shadow: var(--nazar-shadow);
}
.nazar-hero::after {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(90deg, rgba(255,255,255,0.06), transparent 30%);
pointer-events: none;
}
.nazar-eyebrow {
display: inline-flex;
gap: 0.5rem;
align-items: center;
padding: 0.45rem 0.85rem;
border-radius: 999px;
background: rgba(255,255,255,0.08);
color: #ffe3ad;
font-size: 0.92rem;
margin-bottom: 1rem;
}
.nazar-hero h1,
.nazar-section-dark h2,
.nazar-page-hero h1 {
font-size: clamp(2.6rem, 6vw, 5.2rem);
line-height: 0.96;
margin-bottom: 1rem;
}
.nazar-lead {
font-size: 1.15rem;
color: rgba(245, 238, 231, 0.9);
max-width: 42rem;
}
.nazar-info-grid,
.nazar-card-grid,
.nazar-review-grid,
.nazar-menu-grid,
.nazar-contact-grid {
display: grid;
gap: 1.35rem;
}
.nazar-info-grid {
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
margin-top: 2rem;
}
.nazar-card-grid,
.nazar-review-grid,
.nazar-menu-grid,
.nazar-contact-grid {
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.nazar-card,
.nazar-info-card,
.nazar-review,
.nazar-menu-card,
.nazar-contact-card,
.nazar-form-wrap {
background: #fff;
border: 1px solid rgba(36,27,22,0.08);
border-radius: var(--nazar-radius);
padding: 1.5rem;
box-shadow: 0 16px 40px rgba(53, 33, 22, 0.08);
}
.nazar-hero .nazar-info-card {
background: rgba(255,255,255,0.08);
border-color: rgba(255,255,255,0.14);
color: var(--nazar-text);
box-shadow: none;
}
.nazar-card h3,
.nazar-menu-card h3,
.nazar-contact-card h3,
.nazar-review strong,
.nazar-info-card strong {
margin-top: 0;
margin-bottom: 0.35rem;
display: block;
}
.nazar-section {
padding: clamp(2.5rem, 3vw, 4rem) 0;
}
.nazar-section-dark {
padding: clamp(2.5rem, 3vw, 4rem);
border-radius: 32px;
background: linear-gradient(135deg, #1d1613, #34231d);
color: var(--nazar-text);
box-shadow: var(--nazar-shadow);
}
.nazar-section-dark p,
.nazar-section-dark li {
color: rgba(245,238,231,0.88);
}
.nazar-kicker {
color: var(--nazar-secondary);
text-transform: uppercase;
letter-spacing: 0.11em;
font-size: 0.85rem;
font-weight: 700;
margin-bottom: 0.4rem;
}
.nazar-review {
position: relative;
}
.nazar-review::before {
content: "★";
position: absolute;
top: 1rem;
right: 1rem;
color: var(--nazar-primary);
font-size: 1.2rem;
}
.nazar-form-wrap {
background: linear-gradient(180deg, #fff, #fff7ef);
}
.nazar-reservation-form label {
display: grid;
gap: 0.45rem;
margin-bottom: 1rem;
}
.nazar-form-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 1rem;
}
.nazar-reservation-form input,
.nazar-reservation-form select,
.nazar-reservation-form textarea {
width: 100%;
border-radius: 16px;
border: 1px solid rgba(36,27,22,0.12);
background: rgba(255,255,255,0.94);
padding: 0.9rem 1rem;
font: inherit;
}
.nazar-form-note {
color: #6c5b4e;
font-size: 0.95rem;
}
.nazar-alert {
padding: 1rem 1.15rem;
border-radius: 16px;
margin-bottom: 1rem;
}
.nazar-alert-success {
background: #edf9ee;
color: #215f25;
border: 1px solid #b8e0ba;
}
.nazar-alert-error {
background: #fff0ee;
color: #8f2b1f;
border: 1px solid #f0c0b9;
}
.nazar-mini-list {
list-style: none;
padding: 0;
margin: 0;
display: grid;
gap: 0.75rem;
}
.nazar-mini-list li {
display: flex;
justify-content: space-between;
gap: 1rem;
padding-bottom: 0.75rem;
border-bottom: 1px solid rgba(36,27,22,0.08);
}
.nazar-mini-list li:last-child {
border-bottom: none;
padding-bottom: 0;
}
.nazar-page-hero {
padding: 2.25rem 0 0.75rem;
}
.nazar-page-hero h1 {
font-size: clamp(2.3rem, 5vw, 4.2rem);
margin-bottom: 0.6rem;
}
.nazar-inline-actions {
display: flex;
flex-wrap: wrap;
gap: 0.9rem;
margin-top: 1.3rem;
}
.nazar-note {
color: #6c5b4e;
font-size: 0.95rem;
}
.nazar-legal {
background: #fff;
padding: 2rem;
border-radius: 24px;
box-shadow: 0 12px 30px rgba(53,33,22,0.07);
}
@media (max-width: 781px) {
.nazar-hero,
.nazar-section-dark {
border-radius: 24px;
padding: 2rem;
}
body.nazar-site .wp-element-button,
body.nazar-site .wp-block-button__link {
width: 100%;
justify-content: center;
text-align: center;
}
}
.nazar-availability-note {
margin: 0 0 1rem;
color: #6c5b4e;
font-size: 0.95rem;
}
.nazar-reservation-form select[disabled] {
opacity: 0.7;
cursor: not-allowed;
}
body.nazar-site header.wp-block-template-part {
position: sticky;
top: 0;
z-index: 50;
backdrop-filter: blur(18px);
box-shadow: 0 10px 32px rgba(0,0,0,0.18);
}
body.nazar-site .wp-block-navigation {
gap: 1.1rem;
}
body.nazar-site .wp-block-navigation .wp-block-navigation-item__content {
padding: 0.35rem 0.15rem;
font-weight: 600;
position: relative;
}
body.nazar-site .wp-block-navigation .current-menu-item > .wp-block-navigation-item__content::after,
body.nazar-site .wp-block-navigation .wp-block-navigation-item__content:hover::after {
content: "";
position: absolute;
left: 0;
right: 0;
bottom: -0.25rem;
height: 2px;
background: linear-gradient(90deg, var(--nazar-primary), #f2cb7a);
}
.nazar-page-hero {
margin-bottom: 1.5rem;
padding: clamp(2rem, 3vw, 3rem);
border-radius: 28px;
background: linear-gradient(135deg, rgba(200,141,43,0.12), rgba(159,47,29,0.08) 60%, rgba(255,255,255,0.85));
border: 1px solid rgba(36,27,22,0.08);
box-shadow: 0 20px 50px rgba(53, 33, 22, 0.08);
}
.nazar-page-hero h1 {
margin-bottom: 0.75rem;
}
.nazar-stat-grid,
.nazar-process-grid,
.nazar-feature-split {
display: grid;
gap: 1rem;
}
.nazar-stat-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.nazar-stat-card,
.nazar-process-step {
border-radius: 22px;
padding: 1.2rem;
border: 1px solid rgba(255,255,255,0.12);
background: rgba(255,255,255,0.08);
}
.nazar-stat-card strong,
.nazar-process-step strong {
display: block;
font-size: 1.1rem;
margin-bottom: 0.25rem;
}
.nazar-process-grid {
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}
.nazar-process-step {
background: #fff;
border: 1px solid rgba(36,27,22,0.08);
box-shadow: 0 16px 40px rgba(53, 33, 22, 0.08);
}
.nazar-process-step strong {
width: 2.1rem;
height: 2.1rem;
border-radius: 999px;
display: inline-grid;
place-items: center;
background: linear-gradient(135deg, var(--nazar-primary), #f2cb7a);
color: #1b120d;
}
.nazar-feature-split {
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.nazar-cta-band {
border-radius: 28px;
background: linear-gradient(135deg, rgba(159,47,29,0.08), rgba(200,141,43,0.16));
border: 1px solid rgba(36,27,22,0.08);
box-shadow: 0 16px 40px rgba(53, 33, 22, 0.08);
padding: clamp(2rem, 3vw, 3rem);
}
.nazar-menu-grid-wide {
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.nazar-inline-actions {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
margin-top: 1rem;
}
.nazar-legal {
background: #fff;
border-radius: 24px;
border: 1px solid rgba(36,27,22,0.08);
padding: 1.5rem;
box-shadow: 0 16px 40px rgba(53, 33, 22, 0.08);
}
.nazar-availability-note {
margin: 0.25rem 0 1rem;
color: #6c5b4e;
font-size: 0.95rem;
}
@media (max-width: 781px) {
.nazar-stat-grid {
grid-template-columns: 1fr;
}
.nazar-hero,
.nazar-page-hero,
.nazar-section-dark,
.nazar-cta-band {
border-radius: 24px;
}
}

View File

@ -0,0 +1,686 @@
<?php
/**
* Plugin Name: Nazar Kebap MVP
* Description: Restaurant landing page styling and simple table reservation workflow for Nazar Kebap - Gasthaus.
* Version: 1.2.0
* Author: OpenAI Codex
*/
if (!defined('ABSPATH')) {
exit;
}
class Nazar_Kebap_MVP {
const POST_TYPE = 'nazar_reservation';
const STATUS_META = '_reservation_status';
const AVAILABILITY_NONCE = 'nazar_reservation_availability';
const OPENING_TIME = '09:00';
const LAST_BOOKING_TIME = '23:30';
const TIME_STEP_MINUTES = 5;
public function __construct() {
add_action('init', [$this, 'register_post_type']);
add_action('init', [$this, 'register_shortcodes']);
add_action('wp_enqueue_scripts', [$this, 'enqueue_assets']);
add_action('admin_post_nazar_reserve_table', [$this, 'handle_reservation']);
add_action('admin_post_nopriv_nazar_reserve_table', [$this, 'handle_reservation']);
add_action('wp_ajax_nazar_get_available_times', [$this, 'ajax_get_available_times']);
add_action('wp_ajax_nopriv_nazar_get_available_times', [$this, 'ajax_get_available_times']);
add_filter('body_class', [$this, 'body_classes']);
add_filter('manage_' . self::POST_TYPE . '_posts_columns', [$this, 'admin_columns']);
add_action('manage_' . self::POST_TYPE . '_posts_custom_column', [$this, 'render_admin_columns'], 10, 2);
add_action('add_meta_boxes', [$this, 'add_meta_boxes']);
add_action('save_post_' . self::POST_TYPE, [$this, 'save_reservation_meta']);
}
public function register_post_type() {
register_post_type(self::POST_TYPE, [
'labels' => [
'name' => 'Reservierungen',
'singular_name' => 'Reservierung',
'menu_name' => 'Reservierungen',
'add_new_item' => 'Neue Reservierung',
'edit_item' => 'Reservierung bearbeiten',
'view_item' => 'Reservierung ansehen',
'search_items' => 'Reservierungen suchen',
],
'public' => false,
'show_ui' => true,
'show_in_menu' => true,
'menu_icon' => 'dashicons-calendar-alt',
'supports' => ['title'],
'map_meta_cap' => true,
]);
}
public function register_shortcodes() {
add_shortcode('nazar_reservation_form', [$this, 'reservation_form_shortcode']);
}
public function enqueue_assets() {
$plugin_url = plugin_dir_url(__FILE__);
$plugin_path = plugin_dir_path(__FILE__);
wp_enqueue_style(
'nazar-kebap-mvp',
$plugin_url . 'assets/site.css',
[],
filemtime($plugin_path . 'assets/site.css')
);
wp_enqueue_script(
'nazar-kebap-reservations',
$plugin_url . 'assets/reservation.js',
[],
filemtime($plugin_path . 'assets/reservation.js'),
true
);
wp_localize_script('nazar-kebap-reservations', 'nazarReservationData', [
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce(self::AVAILABILITY_NONCE),
'messages' => [
'chooseDateAndParty' => 'Bitte wählen Sie zuerst Datum und Personenzahl.',
'loading' => 'Verfügbare Uhrzeiten werden geladen …',
'empty' => 'Für diese Auswahl ist aktuell keine freie Uhrzeit verfügbar.',
'error' => 'Die verfügbaren Uhrzeiten konnten gerade nicht geladen werden. Bitte versuchen Sie es erneut.',
],
]);
}
public function body_classes($classes) {
$classes[] = 'nazar-site';
return $classes;
}
public function reservation_form_shortcode() {
$status = isset($_GET['reservation']) ? sanitize_key(wp_unslash($_GET['reservation'])) : '';
$messages = [
'success' => 'Danke! Ihre Reservierungsanfrage wurde erfolgreich übermittelt. Sie erhalten in Kürze eine Bestätigung per E-Mail mit allen Buchungsdetails.',
'error' => 'Bitte prüfen Sie Ihre Eingaben. Alle Pflichtfelder müssen ausgefüllt sein.',
'conflict' => 'Diese Uhrzeit ist leider nicht mehr verfügbar. Bitte wählen Sie eine andere freie Uhrzeit.',
];
ob_start();
?>
<div class="nazar-form-wrap">
<?php if ($status && isset($messages[$status])) : ?>
<div class="nazar-alert nazar-alert-<?php echo esc_attr($status === 'conflict' ? 'error' : $status); ?>">
<?php echo esc_html($messages[$status]); ?>
</div>
<?php endif; ?>
<form class="nazar-reservation-form" method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" data-availability-form>
<input type="hidden" name="action" value="nazar_reserve_table">
<?php wp_nonce_field('nazar_reserve_table', 'nazar_reserve_nonce'); ?>
<div class="nazar-form-grid">
<label>
<span>Name *</span>
<input type="text" name="guest_name" required>
</label>
<label>
<span>Telefon *</span>
<input type="tel" name="guest_phone" required>
</label>
<label>
<span>E-Mail *</span>
<input type="email" name="guest_email" required>
</label>
<label>
<span>Personen *</span>
<select name="party_size" required data-party-size>
<option value="">Bitte wählen</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8+">8+</option>
</select>
</label>
<label>
<span>Datum *</span>
<input type="date" name="reservation_date" min="<?php echo esc_attr(wp_date('Y-m-d')); ?>" required data-reservation-date>
</label>
<label>
<span>Uhrzeit *</span>
<select name="reservation_time" required data-reservation-time disabled>
<option value="">Bitte erst Datum und Personen wählen</option>
</select>
</label>
</div>
<p class="nazar-availability-note" data-availability-note>Bitte wählen Sie zuerst Datum und Personenzahl.</p>
<label>
<span>Hinweise</span>
<textarea name="reservation_notes" rows="4" placeholder="z. B. Kinderstuhl, ruhiger Tisch, Allergien"></textarea>
</label>
<p class="nazar-form-note">Reservierungen werden direkt gegen bestehende Buchungen geprüft. Gesperrte Zeiten richten sich nach der Personenzahl: 1 Person = 10 Min., 2 Personen = 15 Min., 34 Personen = 30 Min., ab 5 Personen = 60 Min.</p>
<button type="submit" class="wp-element-button">Tisch anfragen</button>
</form>
</div>
<?php
return ob_get_clean();
}
public function handle_reservation() {
$redirect_url = wp_get_referer() ?: home_url('/reservierung/');
if (!isset($_POST['nazar_reserve_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nazar_reserve_nonce'])), 'nazar_reserve_table')) {
wp_safe_redirect(add_query_arg('reservation', 'error', $redirect_url));
exit;
}
$fields = [
'guest_name' => sanitize_text_field(wp_unslash($_POST['guest_name'] ?? '')),
'guest_phone' => sanitize_text_field(wp_unslash($_POST['guest_phone'] ?? '')),
'guest_email' => sanitize_email(wp_unslash($_POST['guest_email'] ?? '')),
'party_size' => sanitize_text_field(wp_unslash($_POST['party_size'] ?? '')),
'reservation_date' => sanitize_text_field(wp_unslash($_POST['reservation_date'] ?? '')),
'reservation_time' => sanitize_text_field(wp_unslash($_POST['reservation_time'] ?? '')),
'reservation_notes' => sanitize_textarea_field(wp_unslash($_POST['reservation_notes'] ?? '')),
];
if (!$fields['guest_name'] || !$fields['guest_phone'] || !$fields['guest_email'] || !$fields['party_size'] || !$fields['reservation_date'] || !$fields['reservation_time']) {
wp_safe_redirect(add_query_arg('reservation', 'error', $redirect_url));
exit;
}
$fields['reservation_time'] = $this->normalize_time($fields['reservation_time']);
if (!$fields['reservation_time'] || !$this->is_time_available($fields['reservation_date'], $fields['reservation_time'], $fields['party_size'])) {
wp_safe_redirect(add_query_arg('reservation', 'conflict', $redirect_url));
exit;
}
$title = sprintf(
'Reservierung %s %s %s',
$fields['guest_name'],
$fields['reservation_date'],
$fields['reservation_time']
);
$post_id = wp_insert_post([
'post_type' => self::POST_TYPE,
'post_status' => 'publish',
'post_title' => $title,
'meta_input' => [
'_guest_name' => $fields['guest_name'],
'_guest_phone' => $fields['guest_phone'],
'_guest_email' => $fields['guest_email'],
'_party_size' => $fields['party_size'],
'_reservation_date' => $fields['reservation_date'],
'_reservation_time' => $fields['reservation_time'],
'_reservation_notes' => $fields['reservation_notes'],
'_reservation_duration' => $this->get_duration_minutes($fields['party_size']),
self::STATUS_META => 'neu',
],
]);
if (is_wp_error($post_id) || !$post_id) {
wp_safe_redirect(add_query_arg('reservation', 'error', $redirect_url));
exit;
}
$notification_results = $this->send_new_reservation_notifications($post_id, $fields);
update_post_meta($post_id, '_admin_notification_sent', $notification_results['admin'] ? 'yes' : 'no');
update_post_meta($post_id, '_customer_notification_sent', $notification_results['customer'] ? 'yes' : 'no');
update_post_meta($post_id, '_notification_sent_at', current_time('mysql'));
wp_safe_redirect(add_query_arg('reservation', 'success', home_url('/reservierung/')));
exit;
}
public function ajax_get_available_times() {
check_ajax_referer(self::AVAILABILITY_NONCE, 'nonce');
$date = sanitize_text_field(wp_unslash($_POST['reservation_date'] ?? ''));
$party_size = sanitize_text_field(wp_unslash($_POST['party_size'] ?? ''));
if (!$date || !$party_size) {
wp_send_json_error([
'message' => 'Datum und Personenzahl sind erforderlich.',
], 400);
}
$times = $this->get_available_time_slots($date, $party_size);
$duration = $this->get_duration_minutes($party_size);
wp_send_json_success([
'times' => $times,
'duration' => $duration,
'message' => sprintf(
'Für %s blockiert eine Reservierung %d Minuten. Es werden nur freie Uhrzeiten angezeigt.',
$party_size,
$duration
),
]);
}
public function admin_columns($columns) {
return [
'cb' => $columns['cb'],
'title' => 'Anfrage',
'reservation_datetime' => 'Datum & Uhrzeit',
'party_size' => 'Personen',
'contact' => 'Kontakt',
'reservation_status' => 'Status',
'date' => 'Eingegangen',
];
}
public function render_admin_columns($column, $post_id) {
switch ($column) {
case 'reservation_datetime':
echo esc_html(get_post_meta($post_id, '_reservation_date', true));
echo '<br>';
echo esc_html(get_post_meta($post_id, '_reservation_time', true));
break;
case 'party_size':
echo esc_html(get_post_meta($post_id, '_party_size', true));
break;
case 'contact':
echo esc_html(get_post_meta($post_id, '_guest_name', true));
echo '<br>';
echo esc_html(get_post_meta($post_id, '_guest_phone', true));
$email = get_post_meta($post_id, '_guest_email', true);
if ($email) {
echo '<br>' . esc_html($email);
}
break;
case 'reservation_status':
echo esc_html(ucfirst(get_post_meta($post_id, self::STATUS_META, true) ?: 'neu'));
break;
}
}
public function add_meta_boxes() {
add_meta_box(
'nazar_reservation_details',
'Reservierungsdetails',
[$this, 'render_meta_box'],
self::POST_TYPE,
'normal',
'high'
);
}
public function render_meta_box($post) {
wp_nonce_field('nazar_save_reservation', 'nazar_save_reservation_nonce');
$status = get_post_meta($post->ID, self::STATUS_META, true) ?: 'neu';
?>
<table class="form-table">
<tr><th>Name</th><td><?php echo esc_html(get_post_meta($post->ID, '_guest_name', true)); ?></td></tr>
<tr><th>Telefon</th><td><?php echo esc_html(get_post_meta($post->ID, '_guest_phone', true)); ?></td></tr>
<tr><th>E-Mail</th><td><?php echo esc_html(get_post_meta($post->ID, '_guest_email', true)); ?></td></tr>
<tr><th>Datum</th><td><?php echo esc_html(get_post_meta($post->ID, '_reservation_date', true)); ?></td></tr>
<tr><th>Uhrzeit</th><td><?php echo esc_html(get_post_meta($post->ID, '_reservation_time', true)); ?></td></tr>
<tr><th>Personen</th><td><?php echo esc_html(get_post_meta($post->ID, '_party_size', true)); ?></td></tr>
<tr><th>Blockiert bis</th><td><?php echo esc_html($this->get_blocked_until_label($post->ID)); ?></td></tr>
<tr><th>Admin-E-Mail</th><td><?php echo esc_html($this->humanize_notification_status(get_post_meta($post->ID, '_admin_notification_sent', true))); ?></td></tr>
<tr><th>Kunden-E-Mail</th><td><?php echo esc_html($this->humanize_notification_status(get_post_meta($post->ID, '_customer_notification_sent', true))); ?></td></tr>
<tr><th>Status-E-Mail</th><td><?php echo esc_html($this->humanize_notification_status(get_post_meta($post->ID, '_status_notification_sent', true))); ?></td></tr>
<tr><th>Hinweise</th><td><?php echo nl2br(esc_html(get_post_meta($post->ID, '_reservation_notes', true))); ?></td></tr>
<tr>
<th><label for="nazar_reservation_status">Status</label></th>
<td>
<select name="nazar_reservation_status" id="nazar_reservation_status">
<?php foreach (['neu', 'bestätigt', 'abgelehnt', 'erledigt'] as $option) : ?>
<option value="<?php echo esc_attr($option); ?>" <?php selected($status, $option); ?>><?php echo esc_html(ucfirst($option)); ?></option>
<?php endforeach; ?>
</select>
</td>
</tr>
</table>
<?php
}
public function save_reservation_meta($post_id) {
if (!isset($_POST['nazar_save_reservation_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nazar_save_reservation_nonce'])), 'nazar_save_reservation')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (!current_user_can('edit_post', $post_id)) {
return;
}
$status = sanitize_text_field(wp_unslash($_POST['nazar_reservation_status'] ?? 'neu'));
$previous_status = get_post_meta($post_id, self::STATUS_META, true) ?: 'neu';
update_post_meta($post_id, self::STATUS_META, $status);
if ($status !== $previous_status) {
$status_sent = $this->send_status_update_notification($post_id, $status, $previous_status);
update_post_meta($post_id, '_status_notification_sent', $status_sent ? 'yes' : 'no');
update_post_meta($post_id, '_status_notification_sent_at', current_time('mysql'));
}
}
public function get_available_time_slots($date, $party_size) {
if (!$this->is_valid_reservation_date($date) || !$this->parse_party_size($party_size)) {
return [];
}
$slots = [];
$start = $this->date_time_to_timestamp($date, self::OPENING_TIME);
$end = $this->date_time_to_timestamp($date, self::LAST_BOOKING_TIME);
if (!$start || !$end || $start > $end) {
return [];
}
for ($cursor = $start; $cursor <= $end; $cursor += self::TIME_STEP_MINUTES * MINUTE_IN_SECONDS) {
$time = wp_date('H:i', $cursor);
if ($this->is_time_available($date, $time, $party_size)) {
$slots[] = [
'value' => $time,
'label' => $time,
];
}
}
return $slots;
}
public function is_time_available($date, $time, $party_size, $exclude_post_id = 0) {
if (!$this->is_valid_reservation_date($date)) {
return false;
}
$time = $this->normalize_time($time);
$party_count = $this->parse_party_size($party_size);
if (!$time || !$party_count) {
return false;
}
$requested_start = $this->date_time_to_timestamp($date, $time);
$requested_end = $requested_start ? $requested_start + ($this->get_duration_minutes($party_size) * MINUTE_IN_SECONDS) : false;
if (!$requested_start || !$requested_end) {
return false;
}
foreach ($this->get_reservations_for_date($date, $exclude_post_id) as $reservation) {
if (($reservation['status'] ?? '') === 'abgelehnt') {
continue;
}
if (!$reservation['start'] || !$reservation['end']) {
continue;
}
if ($requested_start < $reservation['end'] && $requested_end > $reservation['start']) {
return false;
}
}
return true;
}
private function send_new_reservation_notifications($post_id, $fields) {
$admin_email = sanitize_email(get_option('admin_email'));
$admin_sent = false;
$customer_sent = false;
$details = $this->get_reservation_email_details($post_id, $fields);
if ($admin_email) {
$subject = sprintf('Neue Reservierung: %s am %s um %s', $details['name'], $details['date_label'], $details['time_label']);
$message = implode("
", [
'Eine neue Reservierungsanfrage wurde über die Website gesendet.',
'',
'Name: ' . $details['name'],
'Telefon: ' . $details['phone'],
'E-Mail: ' . $details['email'],
'Personen: ' . $details['party_size'],
'Datum: ' . $details['date_label'],
'Uhrzeit: ' . $details['time_label'],
'Blockiert bis: ' . $details['blocked_until_label'],
'Hinweise: ' . ($details['notes'] ?: 'Keine'),
'',
'Im Admin bearbeiten: ' . admin_url('post.php?post=' . $post_id . '&action=edit'),
]);
$admin_sent = wp_mail($admin_email, $subject, $message, $this->get_email_headers());
}
if ($details['email']) {
$subject = sprintf('Ihre Reservierungsanfrage bei %s', get_bloginfo('name'));
$message = implode("
", [
'Vielen Dank für Ihre Reservierungsanfrage bei ' . get_bloginfo('name') . '.',
'',
'Ihre Buchungsdaten:',
'Name: ' . $details['name'],
'Telefon: ' . $details['phone'],
'E-Mail: ' . $details['email'],
'Personen: ' . $details['party_size'],
'Datum: ' . $details['date_label'],
'Uhrzeit: ' . $details['time_label'],
'Reservierungsdauer: ' . $details['duration_label'],
'Hinweise: ' . ($details['notes'] ?: 'Keine'),
'',
'Falls wir Rückfragen haben, melden wir uns unter der angegebenen Telefonnummer oder E-Mail-Adresse.',
'Telefon Restaurant: +49 781 96643005',
'Adresse: Saarlandstraße 2, 77652 Offenburg',
]);
$customer_sent = wp_mail($details['email'], $subject, $message, $this->get_email_headers());
}
return [
'admin' => (bool) $admin_sent,
'customer' => (bool) $customer_sent,
];
}
private function send_status_update_notification($post_id, $new_status, $old_status) {
$email = sanitize_email(get_post_meta($post_id, '_guest_email', true));
if (!$email) {
return false;
}
$details = $this->get_reservation_email_details($post_id);
$status_labels = [
'neu' => 'neu',
'bestätigt' => 'bestätigt',
'abgelehnt' => 'abgelehnt',
'erledigt' => 'erledigt',
];
$new_label = $status_labels[$new_status] ?? $new_status;
$old_label = $status_labels[$old_status] ?? $old_status;
$subject = sprintf('Update zu Ihrer Reservierung bei %s', get_bloginfo('name'));
$message = implode("
", [
'Es gibt ein Update zu Ihrer Reservierung bei ' . get_bloginfo('name') . '.',
'',
'Bisheriger Status: ' . $old_label,
'Neuer Status: ' . $new_label,
'',
'Name: ' . $details['name'],
'Personen: ' . $details['party_size'],
'Datum: ' . $details['date_label'],
'Uhrzeit: ' . $details['time_label'],
'',
'Bei Fragen erreichen Sie uns unter +49 781 96643005.',
]);
return (bool) wp_mail($email, $subject, $message, $this->get_email_headers());
}
private function get_reservation_email_details($post_id = 0, $fields = []) {
$name = $fields['guest_name'] ?? get_post_meta($post_id, '_guest_name', true);
$phone = $fields['guest_phone'] ?? get_post_meta($post_id, '_guest_phone', true);
$email = $fields['guest_email'] ?? get_post_meta($post_id, '_guest_email', true);
$party_size = $fields['party_size'] ?? get_post_meta($post_id, '_party_size', true);
$date = $fields['reservation_date'] ?? get_post_meta($post_id, '_reservation_date', true);
$time = $fields['reservation_time'] ?? get_post_meta($post_id, '_reservation_time', true);
$notes = $fields['reservation_notes'] ?? get_post_meta($post_id, '_reservation_notes', true);
$date_label = $date ? wp_date('d.m.Y', strtotime($date)) : '';
$time_label = $this->normalize_time($time) ?: '';
$duration = $this->get_duration_minutes($party_size);
$blocked_until_label = '';
if ($date && $time_label) {
$start = $this->date_time_to_timestamp($date, $time_label);
if ($start) {
$blocked_until_label = wp_date('d.m.Y H:i', $start + ($duration * MINUTE_IN_SECONDS));
}
}
return [
'name' => $name ?: '',
'phone' => $phone ?: '',
'email' => $email ?: '',
'party_size' => $party_size ?: '',
'date_label' => $date_label,
'time_label' => $time_label,
'duration_label' => $duration ? ($duration . ' Minuten') : '',
'blocked_until_label' => $blocked_until_label,
'notes' => $notes ?: '',
];
}
private function get_email_headers() {
$blogname = wp_specialchars_decode(get_bloginfo('name'), ENT_QUOTES);
$admin_email = sanitize_email(get_option('admin_email'));
return [
'Content-Type: text/plain; charset=UTF-8',
sprintf('Reply-To: %s <%s>', $blogname, $admin_email),
];
}
private function humanize_notification_status($status) {
return $status === 'yes' ? 'Gesendet' : ($status === 'no' ? 'Fehlgeschlagen' : '');
}
private function get_reservations_for_date($date, $exclude_post_id = 0) {
$query = new WP_Query([
'post_type' => self::POST_TYPE,
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids',
'meta_key' => '_reservation_date',
'meta_value' => $date,
'orderby' => 'meta_value',
'order' => 'ASC',
'post__not_in' => $exclude_post_id ? [(int) $exclude_post_id] : [],
]);
$reservations = [];
foreach ($query->posts as $post_id) {
$time = $this->normalize_time(get_post_meta($post_id, '_reservation_time', true));
$party_size = get_post_meta($post_id, '_party_size', true);
$start = $time ? $this->date_time_to_timestamp($date, $time) : false;
$duration = $this->get_duration_minutes($party_size);
$reservations[] = [
'post_id' => $post_id,
'status' => get_post_meta($post_id, self::STATUS_META, true) ?: 'neu',
'time' => $time,
'party_size' => $party_size,
'duration' => $duration,
'start' => $start,
'end' => $start ? $start + ($duration * MINUTE_IN_SECONDS) : false,
];
}
wp_reset_postdata();
return $reservations;
}
private function get_duration_minutes($party_size) {
$count = $this->parse_party_size($party_size);
if ($count <= 0) {
return 0;
}
if ($count === 1) {
return 10;
}
if ($count === 2) {
return 15;
}
if ($count <= 4) {
return 30;
}
return 60;
}
private function parse_party_size($party_size) {
if (is_numeric($party_size)) {
return max(0, (int) $party_size);
}
if (is_string($party_size) && preg_match('/^(\d+)\+?$/', $party_size, $matches)) {
return max(0, (int) $matches[1]);
}
return 0;
}
private function normalize_time($time) {
if (!is_string($time) || $time === '') {
return '';
}
$date_time = date_create_from_format('H:i', $time, wp_timezone()) ?: date_create_from_format('H:i:s', $time, wp_timezone());
if (!$date_time) {
return '';
}
return $date_time->format('H:i');
}
private function is_valid_reservation_date($date) {
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', (string) $date)) {
return false;
}
$candidate = date_create_immutable_from_format('Y-m-d', $date, wp_timezone());
return $candidate && $candidate->format('Y-m-d') === $date;
}
private function date_time_to_timestamp($date, $time) {
$date_time = date_create_immutable_from_format('Y-m-d H:i', $date . ' ' . $time, wp_timezone());
return $date_time ? $date_time->getTimestamp() : false;
}
private function get_blocked_until_label($post_id) {
$date = get_post_meta($post_id, '_reservation_date', true);
$time = $this->normalize_time(get_post_meta($post_id, '_reservation_time', true));
$party_size = get_post_meta($post_id, '_party_size', true);
$start = ($date && $time) ? $this->date_time_to_timestamp($date, $time) : false;
if (!$start) {
return '';
}
$end = $start + ($this->get_duration_minutes($party_size) * MINUTE_IN_SECONDS);
return wp_date('Y-m-d H:i', $end);
}
}
$GLOBALS['nazar_kebap_mvp'] = new Nazar_Kebap_MVP();

View File

@ -0,0 +1,524 @@
<?php
if (!defined('ABSPATH')) {
require_once dirname(__DIR__, 3) . '/wp-load.php';
}
function nazar_upsert_page($slug, $title, $content, $status = 'publish') {
$existing = get_page_by_path($slug, OBJECT, 'page');
$page_args = [
'post_type' => 'page',
'post_title' => $title,
'post_name' => $slug,
'post_content' => $content,
'post_status' => $status,
];
if ($existing) {
$page_args['ID'] = $existing->ID;
return wp_update_post($page_args, true);
}
return wp_insert_post($page_args, true);
}
function nazar_home_content($urls) {
return <<<HTML
<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:group {"align":"full","className":"nazar-hero","layout":{"type":"constrained"}} -->
<div class="wp-block-group alignfull nazar-hero"><!-- wp:paragraph {"className":"nazar-eyebrow"} -->
<p class="nazar-eyebrow">Nazar Kebap · Offenburg · Restaurant, Grill & Gastlichkeit</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":1} -->
<h1>Moderne Restaurant-Website mit echter Reservierung statt nur schöner Fassade.</h1>
<!-- /wp:heading -->
<!-- wp:paragraph {"className":"nazar-lead"} -->
<p class="nazar-lead">Ob kurzer Lunch, Abendessen mit Freunden oder eine größere Tischanfrage: Auf dieser Website finden Gäste die wichtigsten Informationen sofort, reservieren online und erhalten direkt eine Bestätigung per E-Mail.</p>
<!-- /wp:paragraph -->
<!-- wp:buttons -->
<div class="wp-block-buttons"><!-- wp:button -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="{$urls['reservierung']}">Jetzt reservieren</a></div>
<!-- /wp:button -->
<!-- wp:button {"className":"is-style-outline"} -->
<div class="wp-block-button is-style-outline"><a class="wp-block-button__link wp-element-button" href="{$urls['speisekarte']}">Speisekarte ansehen</a></div>
<!-- /wp:button -->
<!-- wp:button {"className":"is-style-outline"} -->
<div class="wp-block-button is-style-outline"><a class="wp-block-button__link wp-element-button" href="{$urls['kontakt']}">Kontakt &amp; Anfahrt</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons -->
<!-- wp:html -->
<div class="nazar-info-grid">
<div class="nazar-info-card"><strong>Öffnungszeiten</strong><span>Täglich 09:00 00:00 Uhr</span></div>
<div class="nazar-info-card"><strong>Telefon</strong><span><a href="tel:+4978196643005">+49 781 96643005</a></span></div>
<div class="nazar-info-card"><strong>Standort</strong><span>Saarlandstraße 2<br>77652 Offenburg</span></div>
<div class="nazar-info-card"><strong>Reservierung</strong><span>Verfügbare Zeiten werden live geprüft</span></div>
</div>
<!-- /wp:html --></div>
<!-- /wp:group -->
<!-- wp:group {"className":"nazar-section","layout":{"type":"constrained"}} -->
<div class="wp-block-group nazar-section"><!-- wp:paragraph {"className":"nazar-kicker"} -->
<p class="nazar-kicker">Premium-Auftritt</p>
<!-- /wp:paragraph -->
<!-- wp:heading -->
<h2>Alles klar strukturiert: entdecken, reservieren, vorbeikommen.</h2>
<!-- /wp:heading -->
<!-- wp:html -->
<div class="nazar-card-grid">
<div class="nazar-card"><h3>Mehrere klare Seiten</h3><p>Startseite, Speisekarte, Reservierung, Über uns, Gruppen &amp; Feiern und Kontakt haben jeweils eine eigene Aufgabe statt alles auf eine einzige Landingpage zu drücken.</p></div>
<div class="nazar-card"><h3>Reservierung mit Logik</h3><p>Zeiten werden je nach Personenzahl dynamisch blockiert, damit Gäste nicht dieselbe Zeit buchen können, wenn sie schon belegt ist.</p></div>
<div class="nazar-card"><h3>E-Mail-Bestätigung</h3><p>Nach jeder Anfrage werden die Buchungsdaten per E-Mail bestätigt, während im Admin gleichzeitig eine Benachrichtigung eingeht.</p></div>
</div>
<!-- /wp:html --></div>
<!-- /wp:group -->
<!-- wp:group {"className":"nazar-section-dark","layout":{"type":"constrained"}} -->
<div class="wp-block-group nazar-section-dark"><!-- wp:columns {"verticalAlignment":"center"} -->
<div class="wp-block-columns are-vertically-aligned-center"><!-- wp:column {"width":"58%"} -->
<div class="wp-block-column" style="flex-basis:58%"><!-- wp:paragraph {"className":"nazar-kicker"} -->
<p class="nazar-kicker">Signature Experience</p>
<!-- /wp:paragraph -->
<!-- wp:heading -->
<h2>Für spontane Besuche genauso stark wie für geplante Abende.</h2>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>Die Website verbindet warmes Branding, klare Nutzerführung und echte Restaurant-Funktionalität. Gäste sehen sofort, wann geöffnet ist, was sie erwartet und wie sie in wenigen Klicks einen Tisch anfragen können.</p>
<!-- /wp:paragraph -->
<!-- wp:buttons -->
<div class="wp-block-buttons"><!-- wp:button -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="{$urls['ueber-uns']}">Mehr über das Restaurant</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons --></div>
<!-- /wp:column -->
<!-- wp:column {"width":"42%"} -->
<div class="wp-block-column" style="flex-basis:42%"><!-- wp:html -->
<div class="nazar-stat-grid">
<div class="nazar-stat-card"><strong>09:00 00:00</strong><span>Täglich geöffnet</span></div>
<div class="nazar-stat-card"><strong>5-Minuten Raster</strong><span>Feine Verfügbarkeitslogik</span></div>
<div class="nazar-stat-card"><strong>E-Mail direkt</strong><span>Bestätigung für Gäste</span></div>
<div class="nazar-stat-card"><strong>Admin-Übersicht</strong><span>Reservierungen im WordPress-Backend</span></div>
</div>
<!-- /wp:html --></div>
<!-- /wp:column --></div>
<!-- /wp:columns --></div>
<!-- /wp:group -->
<!-- wp:group {"className":"nazar-section","layout":{"type":"constrained"}} -->
<div class="wp-block-group nazar-section"><!-- wp:columns {"verticalAlignment":"top"} -->
<div class="wp-block-columns are-vertically-aligned-top"><!-- wp:column {"width":"55%"} -->
<div class="wp-block-column" style="flex-basis:55%"><!-- wp:paragraph {"className":"nazar-kicker"} -->
<p class="nazar-kicker">Auf der Karte</p>
<!-- /wp:paragraph -->
<!-- wp:heading -->
<h2>Vom schnellen Klassiker bis zum Abendessen in Runde.</h2>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>Die Speisekarte ist als eigene Seite angelegt und zeigt die wichtigsten Kategorien für Gäste, die noch vor der Reservierung schnell entscheiden möchten.</p>
<!-- /wp:paragraph -->
<!-- wp:buttons -->
<div class="wp-block-buttons"><!-- wp:button -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="{$urls['speisekarte']}">Zur Speisekarte</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons --></div>
<!-- /wp:column -->
<!-- wp:column {"width":"45%"} -->
<div class="wp-block-column" style="flex-basis:45%"><!-- wp:html -->
<div class="nazar-menu-grid">
<div class="nazar-menu-card"><h3>Döner &amp; Grill</h3><p>Beliebte Klassiker für Lunch und Abend.</p></div>
<div class="nazar-menu-card"><h3>Pizza &amp; Ofen</h3><p>Warme Ofengerichte für Gruppen und Familien.</p></div>
<div class="nazar-menu-card"><h3>Vegetarisch</h3><p>Falafel, Salate und leichte Alternativen.</p></div>
<div class="nazar-menu-card"><h3>Getränke</h3><p>Vom schnellen Erfrischer bis zum Abendgetränk.</p></div>
</div>
<!-- /wp:html --></div>
<!-- /wp:column --></div>
<!-- /wp:columns --></div>
<!-- /wp:group -->
<!-- wp:group {"className":"nazar-section nazar-cta-band","layout":{"type":"constrained"}} -->
<div class="wp-block-group nazar-section nazar-cta-band"><!-- wp:paragraph {"className":"nazar-kicker"} -->
<p class="nazar-kicker">Nächster Schritt</p>
<!-- /wp:paragraph -->
<!-- wp:heading -->
<h2>Reservieren Sie online oder planen Sie einen größeren Abend mit Ihrer Gruppe.</h2>
<!-- /wp:heading -->
<!-- wp:buttons -->
<div class="wp-block-buttons"><!-- wp:button -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="{$urls['reservierung']}">Tisch anfragen</a></div>
<!-- /wp:button -->
<!-- wp:button {"className":"is-style-outline"} -->
<div class="wp-block-button is-style-outline"><a class="wp-block-button__link wp-element-button" href="{$urls['gruppen-feiern']}">Gruppen &amp; Feiern</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons --></div>
<!-- /wp:group --></div>
<!-- /wp:group -->
HTML;
}
function nazar_menu_content($urls) {
return <<<HTML
<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:group {"className":"nazar-page-hero","layout":{"type":"constrained"}} -->
<div class="wp-block-group nazar-page-hero"><!-- wp:paragraph {"className":"nazar-kicker"} -->
<p class="nazar-kicker">Speisekarte</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":1} -->
<h1>Die wichtigsten Kategorien auf einen Blick.</h1>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>Diese Seite gibt Gästen einen klaren ersten Eindruck vom Angebot und führt direkt zur Reservierung oder zum schnellen Anruf.</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group -->
<!-- wp:html -->
<div class="nazar-menu-grid nazar-menu-grid-wide">
<div class="nazar-menu-card"><h3>Döner &amp; Grill</h3><ul class="nazar-mini-list"><li><span>Döner im Brot</span><strong>Klassiker</strong></li><li><span>Dürüm</span><strong>Schnell serviert</strong></li><li><span>Döner Teller</span><strong>Mit Beilage</strong></li><li><span>Gemischter Grill</span><strong>Für mehr Hunger</strong></li></ul></div>
<div class="nazar-menu-card"><h3>Pizza &amp; Ofengerichte</h3><ul class="nazar-mini-list"><li><span>Pizza Margherita</span><strong>Beliebt</strong></li><li><span>Pizza Sucuk</span><strong>Hausstil</strong></li><li><span>Pizza Vegetarisch</span><strong>Leicht</strong></li><li><span>Lahmacun</span><strong>Würzig</strong></li></ul></div>
<div class="nazar-menu-card"><h3>Salate &amp; Vegetarisch</h3><ul class="nazar-mini-list"><li><span>Falafel Teller</span><strong>Vegetarisch</strong></li><li><span>Gemischter Salat</span><strong>Frisch</strong></li><li><span>Salat mit Dönerfleisch</span><strong>Herzhaft</strong></li><li><span>Vegetarische Beilagen</span><strong>Als Ergänzung</strong></li></ul></div>
<div class="nazar-menu-card"><h3>Getränke</h3><ul class="nazar-mini-list"><li><span>Softdrinks</span><strong>Kalt</strong></li><li><span>Ayran</span><strong>Klassisch</strong></li><li><span>Bier</span><strong>Zum Abend</strong></li><li><span>Heiße Getränke</span><strong>Auf Anfrage</strong></li></ul></div>
</div>
<!-- /wp:html -->
<!-- wp:group {"className":"nazar-section","layout":{"type":"constrained"}} -->
<div class="wp-block-group nazar-section"><!-- wp:columns {"verticalAlignment":"top"} -->
<div class="wp-block-columns are-vertically-aligned-top"><!-- wp:column -->
<div class="wp-block-column"><!-- wp:html -->
<div class="nazar-card"><h3>Hinweis für Gäste</h3><p>Die dargestellten Kategorien geben einen klaren Überblick. Finale Preise und tagesaktuelle Spezialitäten können im Restaurant oder direkt im WordPress-Editor gepflegt werden.</p></div>
<!-- /wp:html --></div>
<!-- /wp:column -->
<!-- wp:column -->
<div class="wp-block-column"><!-- wp:html -->
<div class="nazar-card"><h3>Jetzt weiter</h3><p>Wenn Sie bereits wissen, wann Sie kommen möchten, reservieren Sie direkt online und erhalten sofort eine E-Mail mit den wichtigsten Buchungsdaten.</p><div class="nazar-inline-actions"><a class="wp-element-button" href="{$urls['reservierung']}">Reservieren</a></div></div>
<!-- /wp:html --></div>
<!-- /wp:column --></div>
<!-- /wp:columns --></div>
<!-- /wp:group --></div>
<!-- /wp:group -->
HTML;
}
function nazar_reservation_content($urls) {
return <<<HTML
<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:group {"className":"nazar-page-hero","layout":{"type":"constrained"}} -->
<div class="wp-block-group nazar-page-hero"><!-- wp:paragraph {"className":"nazar-kicker"} -->
<p class="nazar-kicker">Reservierung</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":1} -->
<h1>Tisch online anfragen mit Bestätigung per E-Mail.</h1>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>Wählen Sie Datum, Personenzahl und eine freie Uhrzeit. Die Verfügbarkeit wird direkt geprüft, damit keine überlappenden Reservierungen entstehen.</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group -->
<!-- wp:columns {"verticalAlignment":"top"} -->
<div class="wp-block-columns are-vertically-aligned-top"><!-- wp:column {"width":"64%"} -->
<div class="wp-block-column" style="flex-basis:64%"><!-- wp:shortcode -->[nazar_reservation_form]<!-- /wp:shortcode --></div>
<!-- /wp:column -->
<!-- wp:column {"width":"36%"} -->
<div class="wp-block-column" style="flex-basis:36%"><!-- wp:html -->
<div class="nazar-contact-card">
<h3>So funktioniert die Anfrage</h3>
<ul class="nazar-mini-list">
<li><span>Datum + Gästezahl wählen</span><strong>Verfügbarkeit live</strong></li>
<li><span>Freie Zeit auswählen</span><strong>Keine Doppelbuchung</strong></li>
<li><span>Bestätigung erhalten</span><strong>Direkt per E-Mail</strong></li>
</ul>
</div>
<div class="nazar-contact-card" style="margin-top:1rem;">
<h3>Für Gruppen &amp; Feiern</h3>
<p>Für größere Runden, Geburtstage oder besondere Abende nutzen Sie die Gruppen-Seite oder rufen Sie direkt an.</p>
<div class="nazar-inline-actions"><a class="wp-element-button" href="{$urls['gruppen-feiern']}">Gruppen ansehen</a></div>
</div>
<div class="nazar-contact-card" style="margin-top:1rem;">
<h3>Direktkontakt</h3>
<p><strong>Telefon:</strong><br><a href="tel:+4978196643005">+49 781 96643005</a></p>
<p><strong>Adresse:</strong><br>Saarlandstraße 2<br>77652 Offenburg</p>
<p><strong>Öffnungszeiten:</strong><br>Täglich 09:00 00:00 Uhr</p>
</div>
<!-- /wp:html --></div>
<!-- /wp:column --></div>
<!-- /wp:columns --></div>
<!-- /wp:group -->
HTML;
}
function nazar_about_content($urls) {
return <<<HTML
<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:group {"className":"nazar-page-hero","layout":{"type":"constrained"}} -->
<div class="wp-block-group nazar-page-hero"><!-- wp:paragraph {"className":"nazar-kicker"} -->
<p class="nazar-kicker">Über uns</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":1} -->
<h1>Ein Restaurant, das schnell zugänglich wirkt und trotzdem Charakter zeigt.</h1>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>Nazar Kebap verbindet warme, unkomplizierte Gastfreundschaft mit einem Angebot, das vom schnellen Mittagessen bis zum entspannten Abend mit Freunden reicht.</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group -->
<!-- wp:html -->
<div class="nazar-feature-split">
<div class="nazar-card">
<p class="nazar-kicker">Was Gäste erwartet</p>
<h3>Klare Auswahl, direkter Service, unkomplizierte Reservierung.</h3>
<p>Die Website spiegelt genau das wider: einfache Wege, starke CTAs und ein Auftritt, der modern wirkt, ohne das Lokale und Persönliche zu verlieren.</p>
</div>
<div class="nazar-card">
<p class="nazar-kicker">Für wen es passt</p>
<ul class="nazar-mini-list">
<li><span>Mittagspause</span><strong>Schnell &amp; klar</strong></li>
<li><span>Abendessen</span><strong>Gemütlich mit Freunden</strong></li>
<li><span>Kleine Feiern</span><strong>Planbar im Voraus</strong></li>
<li><span>Spontane Besuche</span><strong>Kontakt direkt sichtbar</strong></li>
</ul>
</div>
</div>
<!-- /wp:html -->
<!-- wp:group {"className":"nazar-section","layout":{"type":"constrained"}} -->
<div class="wp-block-group nazar-section"><!-- wp:heading -->
<h2>Warum die neue Struktur besser funktioniert</h2>
<!-- /wp:heading -->
<!-- wp:html -->
<div class="nazar-card-grid">
<div class="nazar-card"><h3>Mehr Vertrauen</h3><p>Ein eigener Bereich für Über uns stärkt den Eindruck einer echten Marke statt einer simplen Kontaktseite.</p></div>
<div class="nazar-card"><h3>Mehr Übersicht</h3><p>Jede Unterseite hat einen klaren Zweck und hilft Gästen schneller zum nächsten Schritt.</p></div>
<div class="nazar-card"><h3>Mehr Conversion</h3><p>Reservierungs- und Kontaktwege bleiben auf jeder Seite sichtbar und logisch eingebunden.</p></div>
</div>
<!-- /wp:html --></div>
<!-- /wp:group -->
<!-- wp:buttons -->
<div class="wp-block-buttons"><!-- wp:button -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="{$urls['reservierung']}">Reservierung öffnen</a></div>
<!-- /wp:button -->
<!-- wp:button {"className":"is-style-outline"} -->
<div class="wp-block-button is-style-outline"><a class="wp-block-button__link wp-element-button" href="{$urls['kontakt']}">Kontakt</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons --></div>
<!-- /wp:group -->
HTML;
}
function nazar_groups_content($urls) {
return <<<HTML
<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:group {"className":"nazar-page-hero","layout":{"type":"constrained"}} -->
<div class="wp-block-group nazar-page-hero"><!-- wp:paragraph {"className":"nazar-kicker"} -->
<p class="nazar-kicker">Gruppen &amp; Feiern</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":1} -->
<h1>Mehr Platz für Geburtstage, Team-Essen und gemeinsame Abende.</h1>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>Für größere Runden lohnt sich eine kurze Voranfrage. So kann das Restaurant besser planen und Ihnen einen passenden Zeitrahmen anbieten.</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group -->
<!-- wp:html -->
<div class="nazar-card-grid">
<div class="nazar-card"><h3>Geburtstage</h3><p>Gemeinsame Essen mit Familie und Freunden lassen sich frühzeitig anfragen.</p></div>
<div class="nazar-card"><h3>Firmenrunden</h3><p>Ideal für unkomplizierte Team-Lunches oder Abendtermine.</p></div>
<div class="nazar-card"><h3>Wochenend-Abende</h3><p>Für stark nachgefragte Zeiten empfiehlt sich eine frühere Anfrage.</p></div>
</div>
<div class="nazar-process-grid" style="margin-top:1.25rem;">
<div class="nazar-process-step"><strong>1</strong><span>Wunschtermin wählen</span></div>
<div class="nazar-process-step"><strong>2</strong><span>Personenzahl angeben</span></div>
<div class="nazar-process-step"><strong>3</strong><span>Rückfrage per E-Mail oder Telefon erhalten</span></div>
</div>
<!-- /wp:html -->
<!-- wp:buttons -->
<div class="wp-block-buttons"><!-- wp:button -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="{$urls['reservierung']}">Zur Reservierung</a></div>
<!-- /wp:button -->
<!-- wp:button {"className":"is-style-outline"} -->
<div class="wp-block-button is-style-outline"><a class="wp-block-button__link wp-element-button" href="tel:+4978196643005">Direkt anrufen</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons --></div>
<!-- /wp:group -->
HTML;
}
function nazar_contact_content($urls) {
$maps = 'https://www.google.com/maps/search/?api=1&query=' . rawurlencode('Saarlandstraße 2, 77652 Offenburg, Germany');
return <<<HTML
<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:group {"className":"nazar-page-hero","layout":{"type":"constrained"}} -->
<div class="wp-block-group nazar-page-hero"><!-- wp:paragraph {"className":"nazar-kicker"} -->
<p class="nazar-kicker">Kontakt &amp; Anfahrt</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":1} -->
<h1>Alle wichtigen Infos für Ihren Besuch.</h1>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>Adresse, Öffnungszeiten, Telefon und die direkte Route sind auf dieser Seite bewusst schnell erreichbar gehalten.</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group -->
<!-- wp:html -->
<div class="nazar-contact-grid">
<div class="nazar-contact-card"><h3>Adresse</h3><p>Saarlandstraße 2<br>77652 Offenburg<br>Deutschland</p><div class="nazar-inline-actions"><a class="wp-element-button" href="{$maps}" target="_blank" rel="noopener">Route öffnen</a></div></div>
<div class="nazar-contact-card"><h3>Telefon</h3><p><a href="tel:+4978196643005">+49 781 96643005</a></p><p>Für spontane Fragen oder größere Gruppen am besten direkt anrufen.</p></div>
<div class="nazar-contact-card"><h3>Öffnungszeiten</h3><p>Täglich<br><strong>09:00 00:00 Uhr</strong></p><p>Für Reservierungen am selben Tag lohnt sich eine frühzeitige Anfrage.</p></div>
<div class="nazar-contact-card"><h3>Weiterklicken</h3><p>Sie kennen Ihren Wunschtermin schon? Dann senden Sie Ihre Anfrage direkt online.</p><div class="nazar-inline-actions"><a class="wp-element-button" href="{$urls['reservierung']}">Jetzt reservieren</a></div></div>
</div>
<!-- /wp:html --></div>
<!-- /wp:group -->
HTML;
}
function nazar_impressum_content() {
return <<<HTML
<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:group {"className":"nazar-page-hero","layout":{"type":"constrained"}} -->
<div class="wp-block-group nazar-page-hero"><!-- wp:heading {"level":1} -->
<h1>Impressum</h1>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>Die rechtlichen Angaben sollten vor dem Livegang vollständig geprüft und ergänzt werden.</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group -->
<!-- wp:html -->
<div class="nazar-legal">
<p><strong>Nazar Kebap Gasthaus</strong><br>Saarlandstraße 2<br>77652 Offenburg</p>
<p><strong>Bitte ergänzen:</strong><br>Vertretungsberechtigte Person<br>E-Mail-Adresse<br>Umsatzsteuer-ID, falls vorhanden</p>
</div>
<!-- /wp:html --></div>
<!-- /wp:group -->
HTML;
}
function nazar_datenschutz_content() {
return <<<HTML
<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:group {"className":"nazar-page-hero","layout":{"type":"constrained"}} -->
<div class="wp-block-group nazar-page-hero"><!-- wp:heading {"level":1} -->
<h1>Datenschutz</h1>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>Die Website verarbeitet Daten aus dem Reservierungsformular zur Bearbeitung von Tischanfragen. Vor Livegang sollte diese Seite final juristisch geprüft werden.</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group -->
<!-- wp:html -->
<div class="nazar-legal">
<p><strong>Erhobene Daten:</strong> Name, Telefon, E-Mail, Datum, Uhrzeit, Personenzahl und freiwillige Hinweise aus der Reservierungsanfrage.</p>
<p><strong>Zweck:</strong> Bearbeitung von Reservierungen und Rückfragen.</p>
<p><strong>Bitte ergänzen:</strong> Verantwortliche Stelle, Rechtsgrundlage, Speicherdauer, Hosting-Hinweise und Betroffenenrechte.</p>
</div>
<!-- /wp:html --></div>
<!-- /wp:group -->
HTML;
}
update_option('blogname', 'Nazar Kebap Gasthaus');
update_option('blogdescription', 'Moderne Restaurant-Website mit Online-Reservierung und Kontakt für Offenburg.');
update_option('timezone_string', 'Europe/Berlin');
$slugs = [
'startseite' => 'Startseite',
'speisekarte' => 'Speisekarte',
'reservierung' => 'Reservierung',
'ueber-uns' => 'Über uns',
'gruppen-feiern' => 'Gruppen & Feiern',
'kontakt-anfahrt' => 'Kontakt & Anfahrt',
'impressum' => 'Impressum',
'datenschutz' => 'Datenschutz',
];
foreach ($slugs as $slug => $title) {
if (!get_page_by_path($slug, OBJECT, 'page')) {
wp_insert_post([
'post_type' => 'page',
'post_title' => $title,
'post_name' => $slug,
'post_content' => '',
'post_status' => 'publish',
]);
}
}
$urls = [
'startseite' => '/',
'speisekarte' => '/speisekarte/',
'reservierung' => '/reservierung/',
'ueber-uns' => '/ueber-uns/',
'gruppen-feiern' => '/gruppen-feiern/',
'kontakt' => '/kontakt-anfahrt/',
'impressum' => '/impressum/',
'datenschutz' => '/datenschutz/',
];
nazar_upsert_page('startseite', 'Startseite', nazar_home_content($urls));
nazar_upsert_page('speisekarte', 'Speisekarte', nazar_menu_content($urls));
nazar_upsert_page('reservierung', 'Reservierung', nazar_reservation_content($urls));
nazar_upsert_page('ueber-uns', 'Über uns', nazar_about_content($urls));
nazar_upsert_page('gruppen-feiern', 'Gruppen & Feiern', nazar_groups_content($urls));
nazar_upsert_page('kontakt-anfahrt', 'Kontakt & Anfahrt', nazar_contact_content($urls));
nazar_upsert_page('impressum', 'Impressum', nazar_impressum_content());
nazar_upsert_page('datenschutz', 'Datenschutz', nazar_datenschutz_content());
$home_page = get_page_by_path('startseite', OBJECT, 'page');
if ($home_page) {
update_option('show_on_front', 'page');
update_option('page_on_front', $home_page->ID);
}
$nav_post = get_page_by_path('navigation', OBJECT, 'wp_navigation');
if (!$nav_post) {
$nav_post_id = wp_insert_post([
'post_type' => 'wp_navigation',
'post_status' => 'publish',
'post_title' => 'Navigation',
'post_name' => 'navigation',
]);
} else {
$nav_post_id = $nav_post->ID;
}
if (!is_wp_error($nav_post_id) && $nav_post_id) {
$navigation_pages = [
['label' => 'Start', 'slug' => 'startseite', 'url' => '/'],
['label' => 'Speisekarte', 'slug' => 'speisekarte', 'url' => '/speisekarte/'],
['label' => 'Reservierung', 'slug' => 'reservierung', 'url' => '/reservierung/'],
['label' => 'Über uns', 'slug' => 'ueber-uns', 'url' => '/ueber-uns/'],
['label' => 'Gruppen & Feiern', 'slug' => 'gruppen-feiern', 'url' => '/gruppen-feiern/'],
['label' => 'Kontakt', 'slug' => 'kontakt-anfahrt', 'url' => '/kontakt-anfahrt/'],
];
$nav_content = '';
foreach ($navigation_pages as $item) {
$page = get_page_by_path($item['slug'], OBJECT, 'page');
if (!$page) {
continue;
}
$nav_content .= sprintf(
'<!-- wp:navigation-link {"label":"%s","type":"page","id":%d,"url":"%s","kind":"post-type"} /-->',
esc_attr($item['label']),
$page->ID,
esc_url($item['url'])
);
}
wp_update_post([
'ID' => $nav_post_id,
'post_content' => $nav_content,
'post_title' => 'Navigation',
'post_name' => 'navigation',
]);
}
echo "Site setup complete\n";