app/views/templates/calendar.html.twig (139 lines of code) (raw):

{% extends 'base.html.twig' %} {% block head_additions %} {% set meta_description = 'Follow Firefox trains and major milestones easily!' %} <meta name="description" content="{{ meta_description }}"> <meta property="twitter:description" content="{{ meta_description }}"> <meta property="og:url" content="https://whattrainisitnow.com/calendar/"> {% endblock %} {% block header %} <header class="mx-auto"> <h1 class="fw-semibold">Firefox Release Calendar</h1> </header> {% endblock %} {% block main %} {% set year = 'now'|date('Y') %} {% set table_header = 'text-secondary-emphasis fw-semibold' %} <table class="table table-light table-fxt-clean caption-top table-hover table-sm w-auto justify-content-center mt-4 text-center"> <caption class="h4 text-center text-warning">Upcoming releases</caption> <thead> <tr> <th colspan="8" class="text-center table-warning">{{ year }}</th> </tr> <tr> <th scope="col" class="px-4 {{ table_header }}">Quarter</th> <th scope="col" class="px-4 {{ table_header }}">Version</th> <th scope="col" class="px-4 {{ table_header }}">Matching <abbr title="Extended Support Release">ESR</abbr></th> <th scope="col" class="px-4 {{ table_header }}">Release Owner</th> <th scope="col" class="px-4 {{ table_header }}">Nightly starts</th> <th scope="col" title="The Nightly soft code freeze is typically during the week prior to merge day. During this period high-risk patches should avoid landing until after the Nightly version bump lands on mozilla-central on merge day" class="px-4 {{ table_header }}">Soft code freeze</th> <th scope="col" class="px-4 {{ table_header }}">Beta starts</th> <th scope="col" class="px-4 {{ table_header }}">Release day</th> </tr> </thead> <tbody> {% set check = 0 %} {% set date_pattern = 'MMMM d' %} {% for values in upcoming_releases %} {% if values.release_date|format_date(pattern='YYYY') != year %} <tr> <th colspan="8" class="text-center table-warning force-default-bg">{{ values.release_date|format_date(pattern='YYYY') }}</th> </tr> {% set year = values.release_date|format_date(pattern='YYYY') %} {% endif %} <tr> {% if check != values.quarter %} {% set rowspan = upcoming_quarters[values.quarter] %} <th rowspan="{{ rowspan}}" class="force-default-bg align-middle border-end {{ table_header }}">{{ values.quarter | split('-', 2)[1] }}</th> {% set check = values.quarter %} {% endif %} <td><a href="/release/?version={{ values.version }}">{{ values.version }}</a></td> <td class="text-muted"> {% if values.esr starts with '115' %} <span data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-html="true" title="ESR 115 support is extended for <i>Windows 7-8.1</i> and <i>macOS 10.12-10.14</i> up to <b>September 2025</b>." class='text-muted'> {{ values.esr }}<sup class="text-danger">?</sup></span> {% else %} {{ values.esr }} {% endif %} </td> <td>{{ values.owner }}</td> <td title="{{ values.nightly_start|format_date('full') }}">{{ values.nightly_start|format_date(pattern=date_pattern)}}</td> <td title="{{ values.soft_freeze|format_date('full') }}">{{ values.soft_freeze|format_date(pattern=date_pattern)}}</td> <td title="{{ values.beta_start|format_date('full') }}">{{ values.beta_start|format_date(pattern=date_pattern) }}</td> <td title="{{ values.release_date|format_date('full') }}" class="text-color-1">{{ values.release_date|format_date(pattern=date_pattern) }}</td> </tr> {% endfor %} </tbody> </table> <p class="text-center bg-secundary text-light opacity-75 w-75 mx-auto mt-2"> Developer Edition follows the Beta schedule.<br> The above schedule can also be consulted as a <a href="/calendar/monthly/" class="opacity-100 link-info">detailed monthly view.</a> </p> <ul class="nav justify-content-center"> <li class="nav-item navbar-text"> Add to your calendar: </li> <li class="nav-item opacity-75"> <a class="nav-link link-info" title="Low noise, only contains Merge and Release dates" href="https://www.google.com/calendar/embed?src=mozilla.com_2d37383433353432352d3939%40resource.calendar.google.com">Release dates only</a> </li> <li class="nav-item opacity-75"> <a class="nav-link link-info" title="Highly detailed - 99.99% up to date" href="https://www.google.com/calendar/embed?src=bW96aWxsYS5jb21fZGJxODRhbnI5aTh0Y25taGFiYXRzdHY1Y29AZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ">Full schedule</a> </li> <li class="nav-item opacity-75"> <a class="nav-link link-info" title="Highly detailed - 99.99% up to date, ICS format" href="https://calendar.google.com/calendar/ical/mozilla.com_dbq84anr9i8tcnmhabatstv5co%40group.calendar.google.com/public/basic.ics">Full schedule (ICS)</a> </li> </ul> {% set date_pattern = 'YYYY-MM-dd' %} <details class="justify-content-center mt-4 text-center" id="Past_branch_dates"> <summary>Click to toggle past releases table data</summary> <table class="table caption-top table-light table-fxt-clean table-hover table-bordered table-sm w-auto justify-content-center mt-4 text-center"> <caption class="h4 text-center text-warning">Past releases</caption> <thead> <tr> <th scope="col" class="px-4 {{ table_header }}">Version</th> <th scope="col" class="px-4 {{ table_header }}">Matching ESR</th> <th scope="col" class="px-4 {{ table_header }}">Release owner</th> <th scope="col" class="px-4 {{ table_header }}">Nightly starts</th> <th scope="col" class="px-4 {{ table_header }}">Beta starts</th> <th scope="col" class="px-4 {{ table_header }}">Release day</th> </tr> </thead> <tbody> {% for values in past_releases %} <tr> <td><a href="/release/?version={{ values.version }}">{{ values.version }}</a></td> <td class="text-muted">{{ values.esr }}</td> <td>{{ values.owner }}</td> {% if values.version < 6 %} <td></td> {% else %} <td title="{{ values.nightly_start|format_date('full') }}">{{ values.nightly_start|format_date(pattern=date_pattern)}}</td> {% endif %} <td title="{{ values.beta_start|format_date('full') }}">{{ values.beta_start|format_date(pattern=date_pattern) }}</td> <td title="{{ values.release_date|format_date('full') }}">{{ values.release_date|format_date(pattern=date_pattern ) }}</td> </tr> {% endfor %} </tbody> </table> </details> {% endblock %} {% block footer %} {% include 'footer_UTC_warning.html.twig' %} <script nonce="{{constant('NONCE')}}"> $(function () { $('[data-bs-toggle="tooltip"]').tooltip() }) function openTarget() { var hash = location.hash.substring(1); if (hash) var details = document.getElementById(hash); if (details && details.tagName.toLowerCase() === 'details') { details.open = true; location.hash = hash; } } window.addEventListener('hashchange', openTarget); openTarget(); </script> {% endblock %}