src/StartPlatz/Bundle/EventBundle/Resources/views/Default/event-single.tailwind.html.twig line 98

Open in your IDE?
  1. {% extends "@StartPlatzStyleBundle/base.tailwind.public.html.twig" %}
  2. {% set currentPath = app.request.get('_route') %}
  3. {# Language Detection - uses event.lang as default if set #}
  4. {% set lang = app.request.get('lang', event.lang|default('de'))|lower %}
  5. {% set isEnglish = lang == 'en' %}
  6. {# SEO + Social: via EventContentResolver (Batch-Override bei Multi-Batch, sonst Event) #}
  7. {% set seoTitle = resolved.seoTitle %}
  8. {% set seoDescription = resolved.seoDescription %}
  9. {% set seoKeyword = resolved.seoKeyword %}
  10. {% set socialImage = resolved.imagelink %}
  11. {% block metaData %}
  12.     {# Optimize meta description for archived events #}
  13.     {% if event.status == 'archive' %}
  14.         {% set archivePrefix = isEnglish ? 'Past event from ' ~ event.startDate|date('F j, Y') ~ ': ' : 'Vergangene Veranstaltung vom ' ~ event.startDate|date('d.m.Y') ~ ': ' %}
  15.         <meta name="description" content="{{ archivePrefix }}{{ seoDescription|slice(0, 140) }}">
  16.     {% else %}
  17.         <meta name="description" content="{{ seoDescription }}">
  18.     {% endif %}
  19.     <meta name="keywords" content="{{ seoKeyword }}">
  20.     <meta name="author" content="{{ resolved.trainer }}">
  21.     {% if app.environment == 'prod' %}
  22.         <meta name="robots" content="index,follow">
  23.         {% if event.seriesTag is not empty %}
  24.             <link rel="canonical" href="{{ path('event_series', {'seriesTag': event.seriesTag, 'lang': lang}) }}" />
  25.         {% else %}
  26.             <link rel="canonical" href="https://www.startplatz.de/event/{{ event.slug | url_encode }}{% if lang == 'en' %}?lang=en{% endif %}" />
  27.         {% endif %}
  28.         {# hreflang tags for bilingual support #}
  29.         {% if event.hasEnglishVersion %}
  30.             <link rel="alternate" hreflang="de" href="https://www.startplatz.de/event/{{ event.slug | url_encode }}?lang=de" />
  31.             <link rel="alternate" hreflang="en" href="https://www.startplatz.de/event/{{ event.slug | url_encode }}?lang=en" />
  32.             <link rel="alternate" hreflang="x-default" href="https://www.startplatz.de/event/{{ event.slug | url_encode }}" />
  33.         {% endif %}
  34.     {% else %}
  35.         <meta name="robots" content="noindex,nofollow">
  36.     {% endif %}
  37.     {# Open Graph with language support #}
  38.     <meta property="og:title" content="{{ seoTitle }}">
  39.     <meta property="og:description" content="{{ seoDescription }}">
  40.     <meta property="og:image" content="{{ socialImage }}">
  41.     <meta property="og:locale" content="{{ lang == 'en' ? 'en_US' : 'de_DE' }}">
  42.     {% if event.hasEnglishVersion %}
  43.         <meta property="og:locale:alternate" content="{{ lang == 'en' ? 'de_DE' : 'en_US' }}">
  44.     {% endif %}
  45.     {# Twitter Card #}
  46.     <meta name="twitter:card" content="summary">
  47.     <meta name="twitter:title" content="{{ seoTitle }}">
  48.     <meta name="twitter:description" content="{{ seoDescription }}">
  49.     <meta name="twitter:image" content="{{ socialImage }}">
  50. {% endblock %}
  51. {% block title %}{{ seoTitle|default(resolved.title) }}{% endblock %}
  52. {% block styles %}
  53. {#
  54.    ╔═══════════════════════════════════════════════════════════════════════╗
  55.    ║  DEFAULT STYLES - werden durch event.additionalCss überschrieben      ║
  56.    ║                                                                       ║
  57.    ║  Anpassbar via additionalCss (Beispiel Dark Theme):                   ║
  58.    ║  body { background-color: #0a0a0a; }                                  ║
  59.    ║  .bg-registration { background-color: #171717; }                      ║
  60.    ║  .registration-accent { --registration-accent: #3D9DD6; }             ║
  61.    ║  .bg-tags { background-color: #171717; }                              ║
  62.    ║  .bg-promote { background-color: #171717; }                           ║
  63.    ║  .bg-admin-section { background-color: #171717; }                     ║
  64.    ╚═══════════════════════════════════════════════════════════════════════╝
  65. #}
  66. <style>
  67.     /* Page Background - visible between sections */
  68.     body { background-color: #FFFFFF; }
  69.     /* Registration Section */
  70.     .bg-registration { background-color: #9632FF; }
  71.     .registration-accent { --registration-accent: #9632FF; }
  72.     /* Tags Section */
  73.     .bg-tags { background-color: #F3F4F6; }
  74.     /* Promote This Event Section */
  75.     .bg-promote { background-color: #F3F4F6; }
  76.     /* Admin Section */
  77.     .bg-admin-section { background-color: #F9FAFB; }
  78. </style>
  79. {% endblock %}
  80. {% block additionalHead %}
  81.     {# Custom CSS via Resolver (Batch-Override bei Multi-Batch) #}
  82.     {% if resolved.additionalCss is not empty %}
  83.         <style>
  84.             {{ include(template_from_string(resolved.additionalCss), {
  85.                 'event': event,
  86.                 'batch': batch,
  87.                 'isMultiBatchEvent': isMultiBatchEvent
  88.             }) }}
  89.         </style>
  90.     {% endif %}
  91.     {% include "@StartPlatzStyleBundle/_meta-pixel.html.twig" with { meta_pixel_id: event.metaPixelId|default(null) } only %}
  92. {% endblock %}
  93. {% block content %}
  94.     {# Content via Resolver (Multi-Batch: Batch gewinnt; EN fallback auf DE) #}
  95.     {% set navbar = resolved.navbar %}
  96.     {% set teaser = resolved.teaser %}
  97.     {% set content = resolved.content %}
  98.     {% set contentTwig = resolved.contentTwig %}
  99.     {% set postCtaContent = resolved.postCtaContent %}
  100.     {# Navbar Section #}
  101.     {% if navbar %}
  102.         {{ include(template_from_string(navbar), {
  103.             'event': event,
  104.             'batch': batch,
  105.             'isMultiBatchEvent': isMultiBatchEvent,
  106.             'lang': lang,
  107.             'isEnglish': isEnglish,
  108.             'phrases': phrases
  109.         }) }}
  110.     {% endif %}
  111.     {# Teaser Section #}
  112.     {% if teaser %}
  113.         {{ include(template_from_string(teaser), {
  114.             'event': event,
  115.             'batch': batch,
  116.             'isMultiBatchEvent': isMultiBatchEvent,
  117.             'lang': lang,
  118.             'isEnglish': isEnglish,
  119.             'phrases': phrases
  120.         }) }}
  121.     {% endif %}
  122.     {# Archive Banner (SEO-optimized: no redirect) #}
  123.     {% include '@StartPlatzEvent/Default/_event.part.archive-banner.html.twig' with {
  124.         'event': event,
  125.         'isEnglish': isEnglish
  126.     } %}
  127.     {# Flash Messages (Notices) #}
  128.     {% if app.session.flashbag.has('notice') %}
  129.         <section class="bg-gray-100 py-3">
  130.             <div class="max-w-4xl mx-auto px-4">
  131.                 {% for flashMessage in app.session.flashbag.get('notice') %}
  132.                     <div class="text-center py-3 px-4 rounded-lg mb-2 {% if 'SUCCESS' in flashMessage %}bg-green-100 text-green-800{% elseif 'ERROR' in flashMessage %}bg-red-100 text-red-800{% else %}bg-gray-200 text-gray-800{% endif %}">
  133.                         {{ flashMessage|replace({'SUCCESS': ''})|raw }}
  134.                     </div>
  135.                 {% endfor %}
  136.                 {{ editFeedback|raw }}
  137.             </div>
  138.         </section>
  139.     {% endif %}
  140.     {# Application Status Feedback #}
  141.     {% if batch and application and application.applicationStatus %}
  142.         {% include "@StartPlatzEvent/Default/_event.part.feedback-application-process.html.twig" %}
  143.     {% endif %}
  144.     {# Main Content Section #}
  145.     {% if content %}
  146.         {{ include(template_from_string(content), {
  147.             'event': event,
  148.             'batch': batch,
  149.             'isMultiBatchEvent': isMultiBatchEvent,
  150.             'lang': lang,
  151.             'isEnglish': isEnglish,
  152.             'phrases': phrases
  153.         }) }}
  154.     {% endif %}
  155.     {# Dynamic Twig Content #}
  156.     {% if contentTwig %}
  157.         {{ include(template_from_string(contentTwig), {
  158.             'event': event,
  159.             'batch': batch,
  160.             'isMultiBatchEvent': isMultiBatchEvent,
  161.             'futureBatches': futureBatches,
  162.             'allBatches': allBatches,
  163.             'lang': lang,
  164.             'isEnglish': isEnglish,
  165.             'phrases': phrases
  166.         }) }}
  167.     {% endif %}
  168.     {# Registration Section #}
  169.     {% include "@StartPlatzEvent/Default/_registration.batch.tailwind.html.twig" with {
  170.         'event': event,
  171.         'batch': batch,
  172.         'batchIsOpen': batchIsOpen,
  173.         'application': application,
  174.         'settings': settings,
  175.         'isMultiBatchEvent': isMultiBatchEvent,
  176.         'futureBatches': futureBatches,
  177.         'lang': lang,
  178.         'isEnglish': isEnglish,
  179.         'phrases': phrases
  180.     } %}
  181.     {# Tags Section #}
  182.     {% include "@StartPlatzEvent/Default/_section.tags.tailwind.html.twig" %}
  183.     {# Post CTA Content #}
  184.     {% if postCtaContent %}
  185.         {{ include(template_from_string(postCtaContent), {
  186.             'event': event,
  187.             'batch': batch,
  188.             'isMultiBatchEvent': isMultiBatchEvent,
  189.             'lang': lang,
  190.             'isEnglish': isEnglish,
  191.             'phrases': phrases
  192.         }) }}
  193.     {% endif %}
  194.     {# Speakers Section #}
  195.     {% if speakers %}
  196.         {% include "@StartPlatzEvent/Default/_section.speakers-and-partners.winter-2025.html.twig" %}
  197.     {% endif %}
  198.     {# Past Batches Section #}
  199.     {% include "@StartPlatzEvent/Default/_section.past-batches.html.twig" with {
  200.         'event': event,
  201.         'isMultiBatchEvent': isMultiBatchEvent,
  202.         'pastBatches': pastBatches,
  203.         'isEnglish': isEnglish
  204.     } %}
  205.     {# Promote This Event (for logged-in users) #}
  206.     {% if app.user and batch %}
  207.         {% include "@StartPlatzEvent/Default/_section.promote-this-event.tailwind.html.twig" %}
  208.     {% endif %}
  209.     {# Participant List Access #}
  210.     {% if app.user is defined and application is defined and application is not null and application.canReadList %}
  211.         <section class="bg-gray-100 py-6">
  212.             <div class="max-w-4xl mx-auto px-4 text-center">
  213.                 <span class="text-gray-700">{{ isEnglish ? 'You can view the participant list here' : 'Hier kannst Du die Teilnehmerliste einsehen' }}</span>
  214.                 <a class="ml-2 inline-block px-4 py-2 border border-gray-800 rounded-lg hover:bg-gray-800 hover:text-white transition-colors" href="{{ path('admin_event_participants', {id: event.id} ) }}">
  215.                     participants
  216.                 </a>
  217.             </div>
  218.         </section>
  219.     {% endif %}
  220.     {# Admin Section #}
  221.     {% if app.user is defined %}
  222.         {% if app.user.admin is defined and app.user.admin %}
  223.             {% include "@StartPlatzEvent/Default/_section.startplatz-admin-section.tailwind.html.twig" %}
  224.         {% endif %}
  225.     {% endif %}
  226.     {# Language Switcher Component #}
  227.     {% if event.hasEnglishVersion %}
  228.         <div class="fixed top-32 right-5 z-50" x-data="{ hover: false }">
  229.             <div class="bg-white border-2 border-sp-purple rounded-full px-4 py-2 shadow-lg flex items-center gap-2">
  230.                 <a href="?lang=de" class="flex items-center gap-1 px-2 py-1 rounded-full transition-all {{ lang == 'de' ? 'bg-sp-purple text-white' : 'text-gray-800 hover:bg-gray-100' }}" title="Deutsch">
  231.                     <span class="text-xl">DE</span>
  232.                 </a>
  233.                 <span class="text-gray-300">|</span>
  234.                 <a href="?lang=en" class="flex items-center gap-1 px-2 py-1 rounded-full transition-all {{ lang == 'en' ? 'bg-sp-purple text-white' : 'text-gray-800 hover:bg-gray-100' }}" title="English">
  235.                     <span class="text-xl">EN</span>
  236.                 </a>
  237.             </div>
  238.         </div>
  239.     {% endif %}
  240. {% endblock %}
  241. {% block javascripts %}
  242.     {% if resolved.additionalJs is not empty %}
  243.         <script>
  244.             var eventData = {
  245.                 id: {{ event.id }},
  246.                 title: "{{ (resolved.title ?? event.title)|e('js') }}",
  247.                 slug: "{{ event.slug|e('js') }}",
  248.                 lang: "{{ lang }}",
  249.                 isEnglish: {{ isEnglish ? 'true' : 'false' }}
  250.             };
  251.             {{ include(template_from_string(resolved.additionalJs), {
  252.                 'event': event,
  253.                 'batch': batch,
  254.                 'lang': lang,
  255.                 'isEnglish': isEnglish
  256.             })|raw }}
  257.         </script>
  258.     {% endif %}
  259.     {# Sonderseite: batch-level JS (isSonderseite wurde mit Sonderseite-Rueckbau entfernt, Variable defensiv abgesichert) #}
  260.     {% if isSonderseite|default(false) and batch.landingPageJs is not empty %}
  261.         <script>{{ batch.landingPageJs|raw }}</script>
  262.     {% endif %}
  263. {% endblock %}