• Home
paristaime-org
keep your memories alive
Uncategorized

config

by admin juin 17, 2025
written by admin

<?php
/**

  • Paris T’aime – Global Configuration
  • Used by all components, pages, and templates.
    */

// 🔧 Error reporting for development (disable in production)
ini_set(‘display_errors’, 1);
ini_set(‘display_startup_errors’, 1);
error_reporting(E_ALL);

// 📁 Absolute base path of the project
define(‘BASE_PATH’, realpath(DIR));

// 🌍 Compute protocol and host for dynamic environments
$protocol = (!empty($_SERVER[‘HTTPS’]) && $_SERVER[‘HTTPS’] !== ‘off’) ? ‘https://’ : ‘http://’;
$host = $_SERVER[‘HTTP_HOST’] ?? ‘localhost’;
$subfolder = ‘/paristaime’; // << adapt if your folder name changes

// === Main URLs (always ends WITHOUT slash except /public assets)
define(‘BASE_URL’, $protocol . $host . $subfolder); // https://example.com/paristaime
define(‘ROOT_URL’, $subfolder); // /paristaime (for internal site links)
define(‘PUBLIC_URL’, BASE_URL . ‘/public’); // https://example.com/paristaime/public

// === Core paths (server filesystem)
define(‘PUBLIC_PATH’, BASE_PATH . ‘/public’);
define(‘COMPONENTS_PATH’, BASE_PATH . ‘/components’);
define(‘DATA_PATH’, BASE_PATH . ‘/data’);
define(‘TOOLS_PATH’, BASE_PATH . ‘/tools’);
define(‘LIB_PATH’, BASE_PATH . ‘/lib’);

// 📷 Default YouTube thumbnail (local fallback)
define(‘DEFAULT_THUMB’, PUBLIC_URL . ‘/img/default-thumb.jpg’);

// 🌐 Default language for the website
define(‘DEFAULT_LANG’, ‘fr’);

// 🔑 YouTube API Key (⚠️ store in .env in production, not here!)
define(‘YOUTUBE_API_KEY’, ‘AIzaSyA1-92oNun3G7msQ0bZopmlgAPQtTDo_dI’);

// 🧰 Include utility functions (helpers)
require_once LIB_PATH . ‘/helpers.php’;

/**

  • Usage Tips:
  • – Use ROOT_URL for site-relative links:
  • – Use PUBLIC_URL for assets:
  • – Use BASE_URL if you want full absolute URL: */
    function fetchYoutubePlaylistVideos($playlistId, $maxResults = 10) {
    if (!defined(‘YOUTUBE_API_KEY’) || empty(YOUTUBE_API_KEY)) {
    return [];
    }
    $apiKey = YOUTUBE_API_KEY;
    $videos = [];
    $pageToken =  »;
    $resultsCount = 0; do {
    $apiUrl = « https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId={$playlistId}&maxResults= » . min(50, $maxResults – $resultsCount) . « &key={$apiKey} »;
    if ($pageToken) $apiUrl .= « &pageToken=$pageToken »;
    $data = json_decode(@file_get_contents($apiUrl), true); if (!isset($data['items'])) break; foreach ($data['items'] as $item) { $snippet = $item['snippet']; $videos[] = [ 'title' => $snippet['title'], 'videoId' => $snippet['resourceId']['videoId'], 'thumb' => $snippet['thumbnails']['high']['url'] ?? null, 'desc' => $snippet['description'], ]; $resultsCount++; if ($resultsCount >= $maxResults) break 2; } $pageToken = $data['nextPageToken'] ?? ''; } while ($pageToken && $resultsCount < $maxResults); return $videos;
    }

helper

<?php
/**

  • Shared utility functions – Paris T’aime
    */

// — String normalization: accents, lower, trim —
if (!function_exists(‘normalize_str’)) {
function normalize_str(string $str): string {
$str = mb_convert_encoding($str, ‘UTF-8’, mb_detect_encoding($str));
$str = iconv(‘UTF-8’, ‘ASCII//TRANSLIT//IGNORE’, $str);
$str = mb_strtolower($str, ‘UTF-8’);
return trim($str);
}
}

// — Generate slug from string —
if (!function_exists(‘make_slug’)) {
function make_slug(string $str): string {
$str = normalize_str($str);
$str = preg_replace(‘/[^a-z0-9]+/’, ‘-‘, $str);
$str = preg_replace(‘/-+/’, ‘-‘, $str);
return trim($str, ‘-‘);
}
}

// — Parse tag string to array (comma-separated, normalized) —
if (!function_exists(‘parse_tags’)) {
function parse_tags($tagStr) {
$tags = explode(‘,’, $tagStr);
return array_values(array_filter(array_map(‘normalize_str’, $tags)));
}
}

// — Extract YouTube ID from URL or plain ID —
if (!function_exists(‘extract_youtube_id’)) {
function extract_youtube_id($str) {
if (preg_match(‘/(?:v=|youtu.be\/)([\w-]{11})/’, $str, $m)) return $m[1];
if (preg_match(‘/^[\w-]{11}$/’, $str)) return $str;
return  »;
}
}

// — Get the best YouTube thumbnail, with disk cache —
if (!function_exists(‘getYoutubeThumbnail’)) {
function getYoutubeThumbnail(string $videoId): string {
static $cache = [];

    if (isset($cache[$videoId])) return $cache[$videoId];

    $fallback = "https://i.ytimg.com/vi/$videoId/hqdefault.jpg";
    $cacheFile = __DIR__ . '/../cache/thumbs.json';

    if (!file_exists($cacheFile)) {
        @file_put_contents($cacheFile, '{}');
    }

    $jsonData = @file_get_contents($cacheFile);
    $thumbs = json_decode($jsonData, true) ?? [];

    if (!empty($thumbs[$videoId])) {
        return $cache[$videoId] = $thumbs[$videoId];
    }

    if (!defined('YOUTUBE_API_KEY') || empty(YOUTUBE_API_KEY)) {
        return $cache[$videoId] = $fallback;
    }

    $apiKey = YOUTUBE_API_KEY;
    $url = "https://www.googleapis.com/youtube/v3/videos?part=snippet&id=$videoId&key=$apiKey";
    $response = @file_get_contents($url);

    if (!$response) return $cache[$videoId] = $fallback;

    $data = json_decode($response, true);
    if (!isset($data['items'][0]['snippet']['thumbnails'])) {
        return $cache[$videoId] = $fallback;
    }

    $thumbnails = $data['items'][0]['snippet']['thumbnails'];
    $best = $thumbnails['maxres']['url']
        ?? $thumbnails['standard']['url']
        ?? $thumbnails['high']['url']
        ?? $fallback;

    $thumbs[$videoId] = $best;
    @file_put_contents($cacheFile, json_encode($thumbs, JSON_PRETTY_PRINT));

    return $cache[$videoId] = $best;
}

}

// — Find a video by slug or YouTube ID —
if (!function_exists(‘getVideoBySlugOrYT’)) {
function getVideoBySlugOrYT(array $videos, ?string $yt = null, ?string $slug = null): ?array {
foreach ($videos as $v) {
if (($slug && $v[‘slug’] === $slug) || ($yt && $v[‘youtube’] === $yt)) {
return $v;
}
}
return null;
}
}

// — Filter videos by category (accents/case insensitive) —
if (!function_exists(‘filter_videos_by_category’)) {
function filter_videos_by_category(array $videos, string $category): array {
$target = normalize_str($category);
return array_filter($videos, function ($v) use ($target) {
return isset($v[‘category’]) && normalize_str($v[‘category’]) === $target;
});
}
}

// — Filter videos by tag (in array, accents/case insensitive) —
if (!function_exists(‘filter_videos_by_tag’)) {
function filter_videos_by_tag(array $videos, string $tag): array {
$target = normalize_str($tag);
return array_filter($videos, function ($v) use ($target) {
return isset($v[‘tags’]) && is_array($v[‘tags’]) &&
in_array($target, array_map(‘normalize_str’, $v[‘tags’]));
});
}
}

// — Filter videos by author (accents/case insensitive) —
if (!function_exists(‘filter_videos_by_author’)) {
function filter_videos_by_author(array $videos, string $author): array {
$target = normalize_str($author);
return array_filter($videos, function ($v) use ($target) {
return isset($v[‘author’]) && normalize_str($v[‘author’]) === $target;
});
}
}

// — Filter videos by location (accents/case insensitive) —
if (!function_exists(‘filter_videos_by_location’)) {
function filter_videos_by_location(array $videos, string $location): array {
$target = normalize_str($location);
return array_filter($videos, function ($v) use ($target) {
return isset($v[‘location’]) && normalize_str($v[‘location’]) === $target;
});
}
}

// — Filter by minimum duration in seconds (« 3:45 » etc) —
if (!function_exists(‘filter_videos_by_min_duration’)) {
function filter_videos_by_min_duration(array $videos, int $minSeconds): array {
return array_filter($videos, function ($v) use ($minSeconds) {
if (!isset($v[‘duration’])) return false;
$parts = explode(‘:’, $v[‘duration’]);
if (count($parts) === 2) {
$seconds = ((int) $parts[0]) * 60 + ((int) $parts[1]);
return $seconds >= $minSeconds;
}
return false;
});
}
}

// — Normalize YouTube keys in video array (ensure youtube_id) —
if (!function_exists(‘normalize_youtube_keys’)) {
function normalize_youtube_keys(array &$videos): void {
foreach ($videos as &$v) {
if (!isset($v[‘youtube_id’]) && isset($v[‘youtube’])) {
$v[‘youtube_id’] = $v[‘youtube’];
}
}
unset($v); // Avoid reference bugs
}
}

// — Get all unique tags in dataset —
if (!function_exists(‘get_all_unique_tags’)) {
function get_all_unique_tags(array $videos) {
$tags = [];
foreach ($videos as $v) {
if (!empty($v[‘tags’]) && is_array($v[‘tags’])) {
foreach ($v[‘tags’] as $tag) {
$tags[] = normalize_str($tag);
}
}
}
return array_unique($tags);
}
}

// — Debug logging —
if (!function_exists(‘pt_log’)) {
function pt_log($msg) {
$file = DIR . ‘/../cache/debug.log’;
@file_put_contents($file, date(‘c’).’ – ‘.$msg.PHP_EOL, FILE_APPEND);
}
}

// — Flexible search (by any field) —
if (!function_exists(‘find_video’)) {
function find_video(array $videos, string $field, string $value) {
$target = normalize_str($value);
foreach ($videos as $v) {
if (isset($v[$field]) && normalize_str($v[$field]) === $target) {
return $v;
}
}
return null;
}
}

// — Universal function for best video image (Cloudinary, YouTube, fallback) —
if (!function_exists(‘videoImage’)) {
function videoImage(array $video): string {
// 1. Use feature image if available
if (!empty($video[‘img’])) {
return $video[‘img’];
}
// 2. Fallback: YouTube thumbnail
if (!empty($video[‘youtube’])) {
return « https://img.youtube.com/vi/ » . htmlspecialchars($video[‘youtube’]) . « /hqdefault.jpg »;
}
// 3. Final fallback: placeholder
return ‘/public/img/placeholder-16×9.jpg’;
}
}

Youtube API

<?php
if (!function_exists(‘getYoutubeThumbnail’)) {
function getYoutubeThumbnail($videoId) {
// Appelle l’API YouTube pour obtenir la miniature officielle (si disponible)
$apiKey = YOUTUBE_API_KEY;
$apiUrl = « https://www.googleapis.com/youtube/v3/videos?part=snippet&id=$videoId&key=$apiKey »;

$json = @file_get_contents($apiUrl);
if (!$json) return "https://i.ytimg.com/vi/$videoId/hqdefault.jpg";

$data = json_decode($json, true);
if (!isset($data['items'][0]['snippet']['thumbnails'])) return "https://i.ytimg.com/vi/$videoId/hqdefault.jpg";

$thumbs = $data['items'][0]['snippet']['thumbnails'];
return $thumbs['maxres']['url'] ?? $thumbs['standard']['url'] ?? $thumbs['high']['url'] ?? "https://i.ytimg.com/vi/$videoId/hqdefault.jpg";

}
}

Helpers

<?php
/**

  • Shared utility functions – Paris T’aime
    */

// — String normalization: accents, lower, trim —
if (!function_exists(‘normalize_str’)) {
function normalize_str(string $str): string {
$str = mb_convert_encoding($str, ‘UTF-8’, mb_detect_encoding($str));
$str = iconv(‘UTF-8’, ‘ASCII//TRANSLIT//IGNORE’, $str);
$str = mb_strtolower($str, ‘UTF-8’);
return trim($str);
}
}

// — Generate slug from string —
if (!function_exists(‘make_slug’)) {
function make_slug(string $str): string {
$str = normalize_str($str);
$str = preg_replace(‘/[^a-z0-9]+/’, ‘-‘, $str);
$str = preg_replace(‘/-+/’, ‘-‘, $str);
return trim($str, ‘-‘);
}
}

// — Parse tag string to array (comma-separated, normalized) —
if (!function_exists(‘parse_tags’)) {
function parse_tags($tagStr) {
$tags = explode(‘,’, $tagStr);
return array_values(array_filter(array_map(‘normalize_str’, $tags)));
}
}

// — Extract YouTube ID from URL or plain ID —
if (!function_exists(‘extract_youtube_id’)) {
function extract_youtube_id($str) {
if (preg_match(‘/(?:v=|youtu.be\/)([\w-]{11})/’, $str, $m)) return $m[1];
if (preg_match(‘/^[\w-]{11}$/’, $str)) return $str;
return  »;
}
}

// — Get the best YouTube thumbnail, with disk cache —
if (!function_exists(‘getYoutubeThumbnail’)) {
function getYoutubeThumbnail(string $videoId): string {
static $cache = [];

    if (isset($cache[$videoId])) return $cache[$videoId];

    $fallback = "https://i.ytimg.com/vi/$videoId/hqdefault.jpg";
    $cacheFile = __DIR__ . '/../cache/thumbs.json';

    if (!file_exists($cacheFile)) {
        @file_put_contents($cacheFile, '{}');
    }

    $jsonData = @file_get_contents($cacheFile);
    $thumbs = json_decode($jsonData, true) ?? [];

    if (!empty($thumbs[$videoId])) {
        return $cache[$videoId] = $thumbs[$videoId];
    }

    if (!defined('YOUTUBE_API_KEY') || empty(YOUTUBE_API_KEY)) {
        return $cache[$videoId] = $fallback;
    }

    $apiKey = YOUTUBE_API_KEY;
    $url = "https://www.googleapis.com/youtube/v3/videos?part=snippet&id=$videoId&key=$apiKey";
    $response = @file_get_contents($url);

    if (!$response) return $cache[$videoId] = $fallback;

    $data = json_decode($response, true);
    if (!isset($data['items'][0]['snippet']['thumbnails'])) {
        return $cache[$videoId] = $fallback;
    }

    $thumbnails = $data['items'][0]['snippet']['thumbnails'];
    $best = $thumbnails['maxres']['url']
        ?? $thumbnails['standard']['url']
        ?? $thumbnails['high']['url']
        ?? $fallback;

    $thumbs[$videoId] = $best;
    @file_put_contents($cacheFile, json_encode($thumbs, JSON_PRETTY_PRINT));

    return $cache[$videoId] = $best;
}

}

// — Find a video by slug or YouTube ID —
if (!function_exists(‘getVideoBySlugOrYT’)) {
function getVideoBySlugOrYT(array $videos, ?string $yt = null, ?string $slug = null): ?array {
foreach ($videos as $v) {
if (($slug && $v[‘slug’] === $slug) || ($yt && $v[‘youtube’] === $yt)) {
return $v;
}
}
return null;
}
}

// — Filter videos by category (accents/case insensitive) —
if (!function_exists(‘filter_videos_by_category’)) {
function filter_videos_by_category(array $videos, string $category): array {
$target = normalize_str($category);
return array_filter($videos, function ($v) use ($target) {
return isset($v[‘category’]) && normalize_str($v[‘category’]) === $target;
});
}
}

// — Filter videos by tag (in array, accents/case insensitive) —
if (!function_exists(‘filter_videos_by_tag’)) {
function filter_videos_by_tag(array $videos, string $tag): array {
$target = normalize_str($tag);
return array_filter($videos, function ($v) use ($target) {
return isset($v[‘tags’]) && is_array($v[‘tags’]) &&
in_array($target, array_map(‘normalize_str’, $v[‘tags’]));
});
}
}

// — Filter videos by author (accents/case insensitive) —
if (!function_exists(‘filter_videos_by_author’)) {
function filter_videos_by_author(array $videos, string $author): array {
$target = normalize_str($author);
return array_filter($videos, function ($v) use ($target) {
return isset($v[‘author’]) && normalize_str($v[‘author’]) === $target;
});
}
}

// — Filter videos by location (accents/case insensitive) —
if (!function_exists(‘filter_videos_by_location’)) {
function filter_videos_by_location(array $videos, string $location): array {
$target = normalize_str($location);
return array_filter($videos, function ($v) use ($target) {
return isset($v[‘location’]) && normalize_str($v[‘location’]) === $target;
});
}
}

// — Filter by minimum duration in seconds (« 3:45 » etc) —
if (!function_exists(‘filter_videos_by_min_duration’)) {
function filter_videos_by_min_duration(array $videos, int $minSeconds): array {
return array_filter($videos, function ($v) use ($minSeconds) {
if (!isset($v[‘duration’])) return false;
$parts = explode(‘:’, $v[‘duration’]);
if (count($parts) === 2) {
$seconds = ((int) $parts[0]) * 60 + ((int) $parts[1]);
return $seconds >= $minSeconds;
}
return false;
});
}
}

// — Normalize YouTube keys in video array (ensure youtube_id) —
if (!function_exists(‘normalize_youtube_keys’)) {
function normalize_youtube_keys(array &$videos): void {
foreach ($videos as &$v) {
if (!isset($v[‘youtube_id’]) && isset($v[‘youtube’])) {
$v[‘youtube_id’] = $v[‘youtube’];
}
}
unset($v); // Avoid reference bugs
}
}

// — Get all unique tags in dataset —
if (!function_exists(‘get_all_unique_tags’)) {
function get_all_unique_tags(array $videos) {
$tags = [];
foreach ($videos as $v) {
if (!empty($v[‘tags’]) && is_array($v[‘tags’])) {
foreach ($v[‘tags’] as $tag) {
$tags[] = normalize_str($tag);
}
}
}
return array_unique($tags);
}
}

// — Debug logging —
if (!function_exists(‘pt_log’)) {
function pt_log($msg) {
$file = DIR . ‘/../cache/debug.log’;
@file_put_contents($file, date(‘c’).’ – ‘.$msg.PHP_EOL, FILE_APPEND);
}
}

// — Flexible search (by any field) —
if (!function_exists(‘find_video’)) {
function find_video(array $videos, string $field, string $value) {
$target = normalize_str($value);
foreach ($videos as $v) {
if (isset($v[$field]) && normalize_str($v[$field]) === $target) {
return $v;
}
}
return null;
}
}

// — Universal function for best video image (Cloudinary, YouTube, fallback) —
if (!function_exists(‘videoImage’)) {
function videoImage(array $video): string {
// 1. Use feature image if available
if (!empty($video[‘img’])) {
return $video[‘img’];
}
// 2. Fallback: YouTube thumbnail
if (!empty($video[‘youtube’])) {
return « https://img.youtube.com/vi/ » . htmlspecialchars($video[‘youtube’] ??  ») . « /hqdefault.jpg »;
}
// 3. Final fallback: placeholder
return ‘/public/img/placeholder-16×9.jpg’;
}
}

if (!function_exists(‘filter_videos’)) {
function filter_videos(array $videos, array $filters): array {
foreach ($filters as $field => $val) {
$val = normalize_str($val);
$videos = array_filter($videos, function($v) use ($field, $val) {
if (!isset($v[$field])) return false;

            $field_value = $v[$field];
            if (is_array($field_value)) {
                $normalized_array = array_map('normalize_str', $field_value);
                return in_array($val, $normalized_array);
            } else {
                return normalize_str($field_value) === $val;
            }
        });
    }
    return array_values($videos);
}

}
// — Universal flexible video filter by field(s) (accents/case-insensitive) —
if (!function_exists(‘filter_videos’)) {
/**
* Filter videos by one or many fields.
* @param array $videos
* @param array $filters (eg. [‘category’ => ‘Artists’, ‘tags’ => ‘montmartre’])
* @return array
*/
function filter_videos(array $videos, array $filters): array {
foreach ($filters as $field => $val) {
$val = normalize_str($val);
$videos = array_filter($videos, function($v) use ($field, $val) {
if (!isset($v[$field])) return false;

            $field_value = $v[$field];
            if (is_array($field_value)) {
                // Field is array (eg. tags)
                $normalized_array = array_map('normalize_str', $field_value);
                return in_array($val, $normalized_array);
            } else {
                // Field is string (eg. category, author)
                return normalize_str($field_value) === $val;
            }
        });
    }
    return array_values($videos);
}

}

homepage

<?php
require_once DIR . ‘/config.php’;
require_once DIR . ‘/lib/helpers.php’;

$video_data = require DATA_PATH . ‘/video-data.php’;
function tagHasEnoughVideos($video_data, $tag, $min = 6) {
return count(filter_videos_by_tag($video_data, $tag)) >= $min;
}

// Carousel Hero setup
$hero_tag = ‘attic sale’;
$hero_videos = filter_videos_by_tag($video_data, $hero_tag);
$GLOBALS[‘carousel_hero_videos’] = array_slice($hero_videos, 0, 6);

// Promo Banners, Testimonials, etc.
$promo_banners = [
1 => [
‘img_large’ => ‘https://res.cloudinary.com/dtrsr8anj/image/upload/v1749670270/banner/promotion-banner-m-large_qvwy9o.jpg’,
‘img_small’ => ‘https://res.cloudinary.com/dtrsr8anj/image/upload/v1749677678/banner/promotion-banner-m-small_z9dvau.jpg’,
‘title’ => ‘The Secret Agent’,
‘text’ => ‘Une aventure élégante et 100% Paris T’aime !’,
‘link’ => ‘video-detail.php?yt=LBRT6bcLJH0’,
‘btn’ => ‘Voir la vidéo’
],
2 => [
‘img_large’ => ‘https://res.cloudinary.com/dtrsr8anj/image/upload/v1750116169/promotion-banner-m-large-b44f0b-a3929b-0_3x_h5krgo.jpg’,
‘img_small’ => ‘https://res.cloudinary.com/dtrsr8anj/image/upload/v1750116272/promotion-banner-m-small-9fec1c-065b9c-0_3x_m33kem.jpg’,
‘title’ => ‘Montmartre Dreams’,
‘text’ => ‘Voyage sensible à travers les rues de Paris.’,
‘link’ => ‘video-detail.php?yt=ZXY123abc’,
‘btn’ => ‘Regarder’
],
];

$testimonials = [
[
‘name’ => ‘Marie Dupont’,
‘text’ => ‘A magical experience in Paris T’aime!’,
‘location’ => ‘Montmartre’,
‘avatar’ => ‘https://randomuser.me/api/portraits/women/1.jpg’
],
];

$homepage_blocks = [
[ ‘type’ => ‘hero’ ],
[ ‘type’ => ‘quote’, ‘text’ => « Paris is not a city, it’s a world. », ‘author’ => ‘King Francis I’ ],
[ ‘type’ => ‘block-carousel-district’ ],
[ ‘type’ => ‘portrait’, ‘tag’ => ‘Avnue-Parmentier’, ‘title’ => ‘Avnue-Parmentier’, ‘subtitle’ =>  », ‘max’ => 10 ],
[ ‘type’ => ‘portrait’, ‘tag’ => ‘Rue-du-Chateau’, ‘title’ => ‘Rue-du-Château’, ‘subtitle’ =>  », ‘max’ => 10 ],
[ ‘type’ => ‘portrait’, ‘tag’ => ‘Montmartre-Stars’, ‘title’ => ‘Montmartre Stars’, ‘subtitle’ =>  », ‘max’ => 10 ],
[ ‘type’ => ‘portrait’, ‘tag’ => ‘streetlife’, ‘title’ => ‘Street Musicians’, ‘subtitle’ =>  », ‘max’ => 10 ],
[ ‘type’ => ‘category-wide’, ‘category’ => ‘Paris Old Time’, ‘title’ => ‘Paris Old Time’, ‘subtitle’ =>  », ‘max’ => 8 ],
[ ‘type’ => ‘promo’, ‘index’ => 1 ],
[ ‘type’ => ‘portrait’, ‘tag’ => ‘wish’, ‘title’ => ‘Mr. Wish is in Paris’, ‘subtitle’ =>  », ‘max’ => 10 ],
[ ‘type’ => ‘portrait’, ‘tag’ => ‘street-painters’, ‘title’ => ‘Street Painters’, ‘subtitle’ =>  », ‘max’ => 10 ],
[ ‘type’ => ‘location-wide’, ‘location’ => ‘Gare de Lyon’, ‘title’ => ‘Street Wide’, ‘subtitle’ =>  », ‘max’ => 8 ],
[ ‘type’ => ‘testimonial’, ‘testimonials’ => $testimonials ],
[ ‘type’ => ‘promo’, ‘index’ => 2 ],
[ ‘type’ => ‘portrait’, ‘tag’ => ‘Gavroche’, ‘title’ => ‘Attic Sale’, ‘subtitle’ =>  », ‘max’ => 10 ],
[ ‘type’ => ‘portrait’, ‘tag’ => ‘la-roquette’, ‘title’ => ‘La Roqutte’, ‘subtitle’ =>  », ‘max’ => 10 ],
[ ‘type’ => ‘author-portrait’, ‘author’ => ‘LI Yongxin’, ‘title’ => ‘By Li Yongxin’, ‘subtitle’ =>  », ‘max’ => 8 ],
[ ‘type’ => ‘portrait’, ‘tag’ => ‘portrait1’, ‘title’ => ‘Portraits de Paris’, ‘subtitle’ =>  », ‘max’ => 10 ],
[ ‘type’ => ‘category-portrait’, ‘category’ => ‘Paris Old Time’, ‘title’ => ‘Paris Old Time Faces’, ‘subtitle’ =>  », ‘max’ => 8 ],
[ ‘type’ => ‘wide’, ‘tag’ => ‘shoubo’, ‘title’ => ‘Paris Wide’, ‘subtitle’ =>  », ‘max’ => 8 ],
// …add more as you wish!
];

?>


Paris T’aime – Home

$block[‘tag’], ‘title’ => $block[‘title’], ‘subtitle’ => $block[‘subtitle’], ‘style’ => ‘wide’, ‘max’ => $block[‘max’], ‘showNumbers’ => false, ‘class’ => ‘block-wide-‘ . $block[‘tag’], ‘swiper_class’ => ‘swiper-wide-‘ . $block[‘tag’] ]; $block = $blockConfig; include COMPONENTS_PATH . ‘/homepage/block-carousel-universal.php’; break; case ‘category-portrait’: $videos = filter_videos_by_category($video_data, $block[‘category’]); $title = $block[‘title’]; $subtitle = $block[‘subtitle’]; $style = ‘portrait’; $showNumbers = false; $max = $block[‘max’]; $class = ‘block-category-‘ . (isset($block[‘category’]) ? $block[‘category’] : ‘portrait’); include COMPONENTS_PATH . ‘/homepage/block-carousel-standard.php’; break; case ‘category-wide’: $videos = filter_videos_by_category($video_data, $block[‘category’]); $blockConfig = [ ‘category’ => $block[‘category’], ‘title’ => $block[‘title’], ‘subtitle’ => $block[‘subtitle’], ‘style’ => ‘wide’, ‘max’ => $block[‘max’], ‘showNumbers’ => false, ‘class’ => ‘block-category-wide-‘ . $block[‘category’], ‘swiper_class’ => ‘swiper-category-wide-‘ . $block[‘category’] ]; $block = $blockConfig; include COMPONENTS_PATH . ‘/homepage/block-carousel-universal.php’; break; case ‘author-portrait’: $videos = filter_videos_by_author($video_data, $block[‘author’]); $title = $block[‘title’]; $subtitle = $block[‘subtitle’]; $style = ‘portrait’; $showNumbers = false; $max = $block[‘max’]; $class = ‘block-author-‘ . (isset($block[‘author’]) ? $block[‘author’] : ‘portrait’); include COMPONENTS_PATH . ‘/homepage/block-carousel-standard.php’; break; case ‘location-wide’: $videos = filter_videos_by_location($video_data, $block[‘location’]); echo «  »; $blockConfig = [ ‘location’ => $block[‘location’], ‘title’ => $block[‘title’], ‘subtitle’ => $block[‘subtitle’], ‘style’ => ‘wide’, ‘max’ => $block[‘max’], ‘showNumbers’ => false, ‘class’ => ‘block-location-wide-‘ . $block[‘location’], ‘swiper_class’ => ‘swiper-location-wide-‘ . $block[‘location’], ‘videos’ => $videos // VERY IMPORTANT ]; $block = $blockConfig; include COMPONENTS_PATH . ‘/homepage/block-carousel-universal.php’; break; case ‘block-carousel-district’: if (file_exists(COMPONENTS_PATH . ‘/homepage/block-carousel-district.php’)) { include COMPONENTS_PATH . ‘/homepage/block-carousel-district.php’; } break; case ‘promo’: $banner = $promo_banners[$block[‘index’]]; include COMPONENTS_PATH . ‘/homepage/block-promo.php’; break; case ‘quote’: $quote = $block; include COMPONENTS_PATH . ‘/homepage/block-quote-banner.php’; break; case ‘testimonial’: if (isset($block[‘testimonials’])) $testimonials = $block[‘testimonials’]; include COMPONENTS_PATH . ‘/homepage/block-testimonial-carousel.php’; break; case ‘featured’: include COMPONENTS_PATH . ‘/homepage/block-featured-video.php’; break; case ‘gallery’: include COMPONENTS_PATH . ‘/homepage/block-gallery-snapshot.php’; break; case ‘neighborhood’: include COMPONENTS_PATH . ‘/homepage/block-neighborhood-strip.php’; break; case ‘cta’: include COMPONENTS_PATH . ‘/homepage/block-call-to-action.php’; break; case ‘languages’: include COMPONENTS_PATH . ‘/homepage/block-language-diversity.php’; break; } ?>

<?php
/**

  • Standard Carousel Block (unique navigation per instance)
    */
    require_once DIR . ‘/../../lib/helpers.php’;
    $video_data = $video_data ?? (require DATA_PATH . ‘/video-data.php’);

// Generate a unique ID per block instance (so nav/pagination don’t conflict)
$carousel_uid = uniqid(‘carousel_’);

if (isset($block) && is_array($block)) {
$title = $title ?? ($block[‘title’] ??  »);
$subtitle = $subtitle ?? ($block[‘subtitle’] ??  »);
$class = $class ?? ($block[‘class’] ??  »);
$style = $style ?? ($block[‘style’] ?? ‘portrait’);
$showNumbers = $showNumbers ?? (!empty($block[‘showNumbers’]));
$max = $max ?? ($block[‘max’] ?? 10);
$videos = $videos ?? ($block[‘videos’] ?? []);
// … filtering logic as before …
if (empty($videos)) {
// … all filter logic as before …
// (same as your original code)
}
} else {
$title = $title ??  »;
$subtitle = $subtitle ??  »;
$class = $class ??  »;
$style = $style ?? ‘portrait’;
$showNumbers = $showNumbers ?? false;
$max = $max ?? 10;
$videos = $videos ?? [];
}
$videos = array_slice($videos, 0, $max);
$style_class = « carousel-style- » . htmlspecialchars($style);
?>

$video): ?>

<?= htmlspecialchars($video['title'] ?? '') ?>

‘market’, // OR * ‘category’ => ‘quartier’, // You can use either * ‘title’ => ‘🧺 Markets of Paris’, * ‘subtitle’ => ‘Life at the city’s markets’, * ‘max’ => 8, * ‘showNumbers’ => true, * ‘class’ => ‘block-markets’ * ]; * include COMPONENTS_PATH . ‘/block-carousel-universal.php’; */ if (!isset($block)) return; // Helper if (!function_exists(‘videoImage’)) { function videoImage($video) { if (!empty($video[‘img’])) return $video[‘img’]; if (!empty($video[‘youtube’])) return « https://img.youtube.com/vi/ » . htmlspecialchars($video[‘youtube’] ??  ») . « /hqdefault.jpg »; return ‘/public/img/placeholder-16×9.jpg’; } } $video_data = $video_data ?? (require DATA_PATH . ‘/video-data.php’); $title = $block[‘title’] ??  »; $subtitle = $block[‘subtitle’] ??  »; $max = $block[‘max’] ?? 10; $showNumbers = !empty($block[‘showNumbers’]); $extraClass = $block[‘class’] ??  »; $tag = isset($block[‘tag’]) ? strtolower($block[‘tag’]) : null; $category = isset($block[‘category’]) ? strtolower($block[‘category’]) : null; // Filter by tag or category $videos = array_values(array_filter($video_data, function($v) use ($tag, $category) { $ok = true; if ($tag) { $tags = $v[‘tags’] ?? []; if (!is_array($tags)) $tags = explode(‘,’, $tags); $tags = array_map(‘strtolower’, array_map(‘trim’, $tags)); $ok = $ok && in_array($tag, $tags); } if ($category) { $cat = strtolower($v[‘category’] ??  »); $ok = $ok && ($cat === $category); } return $ok; })); $videos = array_slice($videos, 0, $max); if (empty($videos)) { echo « 

No stories found for  » . ($tag ? ‘tag ‘ . htmlspecialchars($tag) . ‘‘ :  ») . ($tag && $category ? ‘ and ‘ :  ») . ($category ? ‘category ‘ . htmlspecialchars($category) . ‘‘ :  ») . « . »; return; } ?>

$video): ?>

<?= htmlspecialchars($video['title'] ?? '') ?>

juin 17, 2025 0 comment
0 FacebookTwitterPinterestEmail
Uncategorized

Hello world!

by admin mai 26, 2025
written by admin

Welcome to WordPress. This is your first post. Edit or delete it, then start writing!

mai 26, 2025 1 comment
1 FacebookTwitterPinterestEmail

Recent Posts

  • config
  • Hello world!

Recent Comments

  1. A WordPress Commenter sur Hello world!
  • Facebook
  • Twitter

@2021 - All Right Reserved. Designed and Developed by PenciDesign


Back To Top
paristaime-org
  • Home