templates/base.html.twig line 1

Open in your IDE?
  1. <!DOCTYPE html>
  2. <html lang="fr">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>{% block title %}{{ site_setting('site_name', 'ActuFake') }} - {{ site_setting('site_tagline', 'L\'actualité satirique en temps réel') }}{% endblock %}</title>
  7.     <meta name="description" content="{% block description %}{{ site_setting('site_description', 'ActuFake est un site satirique et parodique. Les informations publiées sont FICTIVES et à but humoristique uniquement.') }}{% endblock %}">
  8.     {% set favicon_path = site_setting('site_favicon', 'build/favicon.ico') %}
  9.     <link rel="icon" href="{{ favicon_path starts with 'build/' ? asset(favicon_path) : base_path ~ '/' ~ favicon_path }}">
  10.     
  11.     {% block stylesheets %}
  12.         <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
  13.         <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
  14.         {{ encore_entry_link_tags('app') }}
  15.         <style>
  16.             :root {
  17.                 --primary-color: {{ site_setting('color_primary', '#000000') }};
  18.                 --accent-color: {{ site_setting('color_accent', '#dc3545') }};
  19.                 --bg-color: {{ site_setting('color_background', '#f5f5f5') }};
  20.                 --text-color: {{ site_setting('color_text', '#1a1a1a') }};
  21.             }
  22.             
  23.             body {
  24.                 background-color: var(--bg-color);
  25.             }
  26.             
  27.             .satirical-warning {
  28.                 position: sticky;
  29.                 top: 0;
  30.                 z-index: 1030;
  31.             }
  32.             
  33.             .navbar-brand {
  34.                 color: var(--primary-color) !important;
  35.             }
  36.             
  37.             .category-badge {
  38.                 background: var(--accent-color);
  39.                 color: white;
  40.             }
  41.             
  42.             .featured-article-hero {
  43.                 position: relative;
  44.                 overflow: hidden;
  45.                 border-radius: 0;
  46.                 margin-bottom: 2rem;
  47.             }
  48.             
  49.             .featured-article-hero img {
  50.                 width: 100%;
  51.                 height: 500px;
  52.                 object-fit: cover;
  53.             }
  54.             
  55.             .featured-overlay {
  56.                 position: absolute;
  57.                 bottom: 0;
  58.                 left: 0;
  59.                 right: 0;
  60.                 background: linear-gradient(to top, rgba(0,0,0,0.9) 0%, rgba(0,0,0,0.5) 50%, transparent 100%);
  61.                 padding: 3rem 2rem 2rem;
  62.                 color: white;
  63.             }
  64.             
  65.             .featured-overlay h1 {
  66.                 font-size: 2.75rem;
  67.                 margin-bottom: 1rem;
  68.                 color: white;
  69.                 text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
  70.             }
  71.             
  72.             .section-title {
  73.                 font-size: 1.5rem;
  74.                 font-weight: 900;
  75.                 text-transform: uppercase;
  76.                 border-bottom: 4px solid var(--accent-color);
  77.                 padding-bottom: 0.5rem;
  78.                 margin-bottom: 1.5rem;
  79.                 letter-spacing: 1px;
  80.             }
  81.             
  82.             .article-grid {
  83.                 display: grid;
  84.                 grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  85.                 gap: 1.5rem;
  86.             }
  87.             
  88.             .article-list-item {
  89.                 border-bottom: 1px solid #e0e0e0;
  90.                 padding-bottom: 1.5rem;
  91.                 margin-bottom: 1.5rem;
  92.             }
  93.             
  94.             .article-list-item:last-child {
  95.                 border-bottom: none;
  96.             }
  97.             .text-red {
  98.                 color: #dc3545;
  99.             }
  100.             .text-white {
  101.                 color: #ffffff;
  102.             }
  103.             .bg-red {
  104.                 background-color: #dc3545;
  105.             }
  106.             .bg-white {
  107.                 background-color: #ffffff;
  108.             }
  109.             .text-yellow {
  110.                 color: #ffc107;
  111.             }
  112.         </style>
  113.     {% endblock %}
  114. </head>
  115. <body>
  116.     {% if site_setting('header_warning_enabled', '1') == '1' %}
  117.     <div class="satirical-warning">
  118.         <i class="fas fa-exclamation-triangle"></i>
  119.         {{ site_setting('header_warning_text', 'SITE SATIRIQUE - CONTENU PARODIQUE ET FICTIF') }}
  120.         <i class="fas fa-exclamation-triangle"></i>
  121.     </div>
  122.     {% endif %}
  123.     <nav class="navbar navbar-light py-3 {% if site_setting('header_logo_centered', '0') == '1' %}navbar-logo-centered{% endif %}">
  124.         <div class="container bg-danger d-flex justify-content-center">
  125.             <a class="navbar-brand" href="{{ path('home') }}">
  126.                 {% set banner_image = site_setting('site_banner_image', '') %}
  127.                 {% set logo_image = site_setting('site_logo_image', '') %}
  128.                 {% if banner_image %}
  129.                     {% set banner_path = banner_image starts with '/' ? banner_image|slice(1) : banner_image %}
  130.                     <img src="{{ base_path ~ '/' ~ banner_path }}" alt="{{ site_setting('site_name', 'ActuFake') }}" class="header-banner">
  131.                 {% elseif logo_image %}
  132.                     {% set logo_path = logo_image starts with '/' ? logo_image|slice(1) : logo_image %}
  133.                     <img src="{{ base_path ~ '/' ~ logo_path }}" alt="{{ site_setting('site_name', 'ActuFake') }}" style="min-width: 400px; height: auto;">
  134.                 {% else %}
  135.                     {{ site_setting('site_logo_text', 'ActuFake') }}
  136.                 {% endif %}
  137.             </a>
  138.         </div>
  139.     </nav>
  140.     {% if global_categories is defined and global_categories|length > 0 %}
  141.     <div class="categories-bar bg-danger border-bottom">
  142.         <div class="container">
  143.             <nav class="d-flex align-items-center justify-content-between py-2">
  144.                 <div class="d-flex align-items-center">
  145.                     {% for category in global_categories %}
  146.                     <a href="{{ path('category_show', {slug: category.slug}) }}" 
  147.                        class="category-link text-decoration-none text-white px-3 py-2 d-flex align-items-center">
  148.                         {% if category.icon %}
  149.                         <i class="fas {{ category.icon }} me-2"></i>
  150.                         {% endif %}
  151.                         <span class="text-nowrap">{{ category.name }}</span>
  152.                     </a>
  153.                     {% endfor %}
  154.                 </div>
  155.                 <div class="d-flex align-items-center text-white gap-2">
  156.                     <a class="nav-link px-2" href="{{ path('search') }}" title="Recherche">
  157.                         <i class="fas fa-search"></i>
  158.                     </a>
  159.                     {% if is_granted('ROLE_ADMIN') or is_granted('ROLE_EDITOR') %}
  160.                     <a class="btn btn-sm btn-danger text-yellow px-3" href="{{ path('admin_dashboard') }}">
  161.                         <i class="fas fa-cog me-1"></i> Administration
  162.                     </a>
  163.                     <a class="nav-link px-2" href="{{ path('app_logout') }}" title="Déconnexion">
  164.                         <i class="fas fa-sign-out-alt"></i>
  165.                     </a>
  166.                     {% else %}
  167.                     <a class="btn btn-sm bg-white text-red px-3" href="{{ path('app_login') }}">
  168.                         <i class="fas fa-sign-in-alt me-1"></i> Connexion
  169.                     </a>
  170.                     {% endif %}
  171.                 </div>
  172.             </nav>
  173.         </div>
  174.     </div>
  175.     {% endif %}
  176.     <main>
  177.         {% for type, messages in app.flashes %}
  178.             <div class="container mt-3">
  179.                 {% for message in messages %}
  180.                     <div class="alert alert-{{ type == 'error' ? 'danger' : type }} alert-dismissible fade show">
  181.                         {{ message }}
  182.                         <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
  183.                     </div>
  184.                 {% endfor %}
  185.             </div>
  186.         {% endfor %}
  187.         {% block body %}{% endblock %}
  188.     </main>
  189.     <footer class="bg-dark text-white mt-5 py-5">
  190.         <div class="container">
  191.             <div class="row g-4">
  192.                 <div class="col-md-4">
  193.                     {% set logo_image = site_setting('site_logo_image', '') %}
  194.                     {% if logo_image %}
  195.                         {% set logo_path = logo_image starts with '/' ? logo_image|slice(1) : logo_image %}
  196.                         <img src="{{ base_path ~ '/' ~ logo_path }}" alt="{{ site_setting('site_name', 'ActuFake') }}" style="max-height: 100px; max-width: 300px; margin-bottom: 1rem;"class="btn btn-danger">
  197.                     {% else %}
  198.                         <h5 class="fw-bold mb-3" style="font-family: 'Impact', sans-serif; font-size: 1.5rem; letter-spacing: -0.5px;">
  199.                             {{ site_setting('site_name', 'ActuFake') }}
  200.                         </h5>
  201.                     {% endif %}
  202.                     <p class="mb-3" style="line-height: 1.7;">{{ site_setting('footer_about_text', 'L\'actualité satirique en temps réel') }}</p>
  203.                     <div class="alert alert-warning bg-warning bg-opacity-25 border-warning border-2 mb-0">
  204.                         <p class="small mb-0 text-white" style="line-height: 1.6; color:rgba(233, 227, 227, 0.9);">
  205.                             <i class="fas fa-exclamation-triangle" style="color:rgb(246, 242, 26);"></i>
  206.                             {{ site_setting('footer_disclaimer', 'Toutes les informations publiées sur ce site sont FICTIVES et à but humoristique uniquement.') }}
  207.                         </p>
  208.                     </div>
  209.                 </div>
  210.                 <div class="col-md-4">
  211.                     <h6 class="fw-bold text-uppercase mb-3" style="letter-spacing: 1px; font-size: 0.85rem;">Navigation</h6>
  212.                     <ul class="list-unstyled">
  213.                         <li class="mb-2"><a href="{{ path('home') }}" class="text-white-50 text-decoration-none">Accueil</a></li>
  214.                         <li class="mb-2"><a href="{{ path('about') }}" class="text-white-50 text-decoration-none">À propos</a></li>
  215.                         <li class="mb-2"><a href="{{ path('legal') }}" class="text-white-50 text-decoration-none">Mentions légales</a></li>
  216.                         <li class="mb-2"><a href="{{ path('privacy') }}" class="text-white-50 text-decoration-none">Politique de confidentialité</a></li>
  217.                         <li class="mb-2"><a href="{{ path('contact') }}" class="text-white-50 text-decoration-none">Contact</a></li>
  218.                     </ul>
  219.                 </div>
  220.                 <div class="col-md-4">
  221.                     <h6 class="fw-bold text-uppercase mb-3" style="letter-spacing: 1px; font-size: 0.85rem;">Contact Rapide</h6>
  222.                     <form id="footer-contact-form" action="{{ path('contact_submit') }}" method="post">
  223.                         <div class="mb-2">
  224.                             <input type="text" name="name" class="form-control form-control-sm bg-dark text-white border-secondary" placeholder="Votre nom" required>
  225.                         </div>
  226.                         <div class="mb-2">
  227.                             <input type="email" name="email" class="form-control form-control-sm bg-dark text-white border-secondary" placeholder="Votre email" required>
  228.                         </div>
  229.                         <div class="mb-2">
  230.                             <input type="text" name="subject" class="form-control form-control-sm bg-dark text-white border-secondary" placeholder="Sujet (optionnel)">
  231.                         </div>
  232.                         <div class="mb-2">
  233.                             <textarea name="message" class="form-control form-control-sm bg-dark text-white border-secondary" rows="3" placeholder="Votre message..." required></textarea>
  234.                         </div>
  235.                         <input type="hidden" name="_token" value="{{ csrf_token('contact_submit') }}">
  236.                         <button type="submit" class="btn btn-sm btn-danger w-100">
  237.                             <i class="fas fa-paper-plane me-1"></i> Envoyer
  238.                         </button>
  239.                     </form>
  240.                     <div class="social-links d-flex gap-3 mt-3">
  241.                         <a href="{{ site_setting('social_twitter_url', '#') }}" class="text-white-50" target="_blank" title="Twitter">
  242.                             <i class="fab fa-twitter fa-lg"></i>
  243.                         </a>
  244.                         <a href="{{ site_setting('social_instagram_url', '#') }}" class="text-white-50" target="_blank" title="Instagram">
  245.                             <i class="fab fa-instagram fa-lg"></i>
  246.                         </a>
  247.                         <a href="{{ site_setting('social_threads_url', '#') }}" class="text-white-50" target="_blank" title="Threads">
  248.                             <i class="fab fa-threads fa-lg"></i>
  249.                         </a>
  250.                     </div>
  251.                 </div>
  252.             </div>
  253.             <hr class="border-secondary my-4">
  254.             <div class="d-flex flex-column flex-md-row justify-content-between align-items-center">
  255.                 <p class="small mb-2 mb-md-0 text-white-50">
  256.                     &copy; {{ 'now'|date('Y') }} {{ site_setting('footer_copyright', 'ActuFake. Site satirique et parodique.') }}
  257.                 </p>
  258.                 <p class="small mb-0 text-white-50">
  259.                     Propulsé par Symfony {{ constant('Symfony\\Component\\HttpKernel\\Kernel::VERSION') }}
  260.                 </p>
  261.             </div>
  262.         </div>
  263.     </footer>
  264.     {% block javascripts %}
  265.         <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
  266.         {{ encore_entry_script_tags('app') }}
  267.         <script>
  268.             document.addEventListener('DOMContentLoaded', function() {
  269.                 const contactForm = document.getElementById('footer-contact-form');
  270.                 if (contactForm) {
  271.                     contactForm.addEventListener('submit', function(e) {
  272.                         e.preventDefault();
  273.                         
  274.                         const formData = new FormData(contactForm);
  275.                         const submitBtn = contactForm.querySelector('button[type="submit"]');
  276.                         const originalText = submitBtn.innerHTML;
  277.                         
  278.                         submitBtn.disabled = true;
  279.                         submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin me-1"></i> Envoi...';
  280.                         
  281.                         fetch(contactForm.action, {
  282.                             method: 'POST',
  283.                             body: formData,
  284.                             headers: {
  285.                                 'X-Requested-With': 'XMLHttpRequest'
  286.                             }
  287.                         })
  288.                         .then(response => response.json())
  289.                         .then(data => {
  290.                             if (data.success) {
  291.                                 submitBtn.innerHTML = '<i class="fas fa-check me-1"></i> Envoyé!';
  292.                                 submitBtn.classList.remove('btn-primary');
  293.                                 submitBtn.classList.add('btn-success');
  294.                                 contactForm.reset();
  295.                                 
  296.                                 setTimeout(() => {
  297.                                     submitBtn.innerHTML = originalText;
  298.                                     submitBtn.classList.remove('btn-success');
  299.                                     submitBtn.classList.add('btn-primary');
  300.                                     submitBtn.disabled = false;
  301.                                 }, 3000);
  302.                             }
  303.                         })
  304.                         .catch(error => {
  305.                             submitBtn.innerHTML = '<i class="fas fa-times me-1"></i> Erreur';
  306.                             submitBtn.classList.remove('btn-primary');
  307.                             submitBtn.classList.add('btn-danger');
  308.                             submitBtn.disabled = false;
  309.                             
  310.                             setTimeout(() => {
  311.                                 submitBtn.innerHTML = originalText;
  312.                                 submitBtn.classList.remove('btn-danger');
  313.                                 submitBtn.classList.add('btn-primary');
  314.                             }, 3000);
  315.                         });
  316.                     });
  317.                 }
  318.             });
  319.         </script>
  320.     {% endblock %}
  321. </body>
  322. </html>