PHP Classes

File: templates/shells/bbs-menu/base.twig

Recommend this page to a friend!
  Packages of Matthew Asham   Binkterm PHP   templates/shells/bbs-menu/base.twig   Download  
File: templates/shells/bbs-menu/base.twig
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: Binkterm PHP
Bulletin board system based on the Web
Author: By
Last change:
Date: 5 days ago
Size: 24,498 bytes
 

Contents

Class file image Download
<!DOCTYPE html> <html lang="{{ locale|default('en') }}"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="csrf-token" content="{{ csrf_token }}"> <title>{% block title %}{{ system_name }}{% endblock %}</title> {% block meta_description_tags %} {% if appearance.seo.description %} <meta name="description" content="{{ appearance.seo.description | e }}"> {% endif %} {% endblock %} {% block meta_tags %}{% endblock %} <!-- Favicons --> <link rel="icon" type="image/svg+xml" href="{{ favicon_svg }}"> <link rel="icon" type="image/x-icon" href="{{ favicon_ico }}"> <link rel="apple-touch-icon" href="{{ favicon_png }}"> <link rel="manifest" href="/appmanifestjson"> <link href="/vendor/bootstrap-5.3.0/css/bootstrap.min.css" rel="stylesheet"> <link href="/vendor/fontawesome-6.4.0/css/all.min.css" rel="stylesheet"> <link id="theme-stylesheet" href="{{ stylesheet }}" rel="stylesheet"> <link href="/css/ansisys.css" rel="stylesheet"> {% block head %}{% endblock %} <style> body.bbs-menu-shell { display: flex; flex-direction: column; min-height: 100vh; } .bbs-shell-header { background: var(--bs-primary, #0d6efd); color: #fff; padding: 0.5rem 1rem; display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; position: relative; z-index: 1030; /* Match Bootstrap's fixed navbar ? ensures dropdowns paint above footer */ } .bbs-shell-system-name { font-weight: bold; font-size: 1.1rem; } .bbs-shell-section { flex: 1; opacity: 0.85; font-size: 0.95rem; } .bbs-shell-home { color: #fff; text-decoration: none; font-size: 0.9rem; opacity: 0.9; } .bbs-shell-home:hover { opacity: 1; color: #fff; text-decoration: underline; } .bbs-shell-main { flex: 1; } /* Admin dropdown button in bbs-menu shell header ? scope tightly so the rule does NOT cascade into .dropdown-item.dropdown-toggle submenu links */ .bbs-shell-header > .dropdown > .dropdown-toggle { color: #fff; text-decoration: none; font-size: 0.9rem; opacity: 0.9; background: none; border: none; padding: 0; cursor: pointer; } .bbs-shell-header > .dropdown > .dropdown-toggle:hover { opacity: 1; } .bbs-shell-header .dropdown-submenu { position: relative; } /* Submenus open to the LEFT because the dropdown is right-aligned in the header; opening right would take them off-screen. */ .bbs-shell-header .dropdown-submenu > .dropdown-menu { top: 0; left: auto; right: 100%; margin-top: -1px; margin-right: -1px; } .bbs-shell-header .dropdown-submenu:hover > .dropdown-menu { display: block; } /* Caret points left (rotate -90°) to indicate the left-opening submenu */ .bbs-shell-header .dropdown-submenu > .dropdown-toggle::after { transform: rotate(-90deg); position: absolute; right: 10px; top: 50%; margin-top: -3px; } @media (max-width: 768px) { .bbs-shell-header .dropdown-submenu > .dropdown-menu { position: static !important; margin-left: 1rem; border-left: 2px solid rgba(0,0,0,0.1); } } {% if appearance.branding.accent_color %} :root { --fidonet-blue: {{ appearance.branding.accent_color | e }}; } .bbs-shell-header { background: {{ appearance.branding.accent_color | e }} !important; } .bg-primary { background-color: {{ appearance.branding.accent_color | e }} !important; } .btn-fidonet { background-color: {{ appearance.branding.accent_color | e }}; border-color: {{ appearance.branding.accent_color | e }}; } {% endif %} .file-menu-icon.unread, .file-menu-link.unread { color: #ffc107 !important; } </style> <script src="/vendor/bootstrap-5.3.0/js/bootstrap.bundle.min.js"></script> <script src="/vendor/jquery-3.7.1/jquery-3.7.1.min.js"></script> <script> window.appLocale = {{ locale|json_encode|raw }}; window.appDefaultLocale = {{ default_locale|json_encode|raw }}; window.appI18nNamespaces = {{ i18n_namespaces|json_encode|raw }}; window.siteConfig = { ansiRendererMode: {{ ansi_renderer_mode|json_encode|raw }}, sseTransportMode: {{ effective_sse_transport_mode|json_encode|raw }}, configuredRealtimeTransportMode: {{ configured_realtime_transport_mode|json_encode|raw }}, realtimeTransportMode: {{ effective_realtime_transport_mode|json_encode|raw }}, realtimeWsUrl: {{ realtime_ws_url|json_encode|raw }} }; </script> <script src="/js/app.js"></script> <script src="/js/ansisys.js"></script> {% if current_user %} <script src="/js/binkstream-client.js"></script> {% endif %} {% if current_user %} <script src="/js/notifier.js"></script> {% endif %} {% include 'custom/header.insert.twig' ignore missing %} {% if debug_ansi_not_perfect %} <style>.ansi-art-container pre, .ansi-art { font-family: inherit !important; }</style> {% elseif debug_ansi_use_consolas %} <style>.ansi-art-container pre, .ansi-art { font-family: Consolas, monospace !important; }</style> {% endif %} </head> <body class="bbs-menu-shell"> <header class="bbs-shell-header"> <span class="bbs-shell-system-name"> {% if appearance.branding.logo_url %} <img src="{{ appearance.branding.logo_url | e }}" alt="{{ system_name | e }}" style="max-height:32px;" class="me-1"> {% else %} {{ system_name }} {% endif %} </span> <span class="bbs-shell-section">{% block section_title %}{% endblock %}</span> {% if current_user %} {% if credits_enabled %} <span class="me-2 small" id="headerCreditBalance">{{ credits_symbol }}{{ credit_balance }}</span> {% endif %} <div class="dropdown me-2"> <button class="dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> <i class="fas fa-user"></i> {{ current_user.username }} </button> <ul class="dropdown-menu dropdown-menu-end"> <li><a class="dropdown-item" href="/profile"><i class="fas fa-id-card"></i> {{ t('ui.base.profile', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/settings"><i class="fas fa-cog"></i> {{ t('ui.base.settings', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/subscriptions"><i class="fas fa-bookmark"></i> {{ t('ui.base.subscriptions', {}, 'common') }}</a></li> <li><hr class="dropdown-divider"></li> <li><a class="dropdown-item" href="#" onclick="logout(); return false;"><i class="fas fa-sign-out-alt"></i> {{ t('ui.base.logout', {}, 'common') }}</a></li> </ul> </div> {% if current_user.is_admin %} <div class="dropdown"> <button class="dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> <i class="fas fa-cog"></i> {{ t('ui.base.admin', {}, 'common') }} </button> <ul class="dropdown-menu dropdown-menu-end"> <li><a class="dropdown-item" href="/whosonline"><i class="fas fa-user-friends"></i> {{ t('ui.base.admin.whos_online', {}, 'common') }}</a></li> <li><hr class="dropdown-divider"></li> <li><a class="dropdown-item" href="/admin/"><i class="fas fa-tachometer-alt"></i> {{ t('ui.base.admin.dashboard', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/binkp"><i class="fas fa-network-wired"></i> {{ t('ui.base.admin.binkp_status', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/users"><i class="fas fa-users"></i> {{ t('ui.base.admin.manage_users', {}, 'common') }}</a></li> <li><hr class="dropdown-divider"></li> <li class="dropdown-submenu"> <a class="dropdown-item dropdown-toggle" href="#"><i class="fas fa-folder-tree"></i> {{ t('ui.base.admin.area_management', {}, 'common') }}</a> <ul class="dropdown-menu"> <li><a class="dropdown-item" href="/echoareas"><i class="fas fa-comments"></i> {{ t('ui.base.admin.echo_areas', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/fileareas"><i class="fas fa-folder-open"></i> {{ t('ui.base.admin.file_areas', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/file-approvals"><i class="fas fa-user-check"></i> {{ t('ui.base.admin.file_approvals', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/filearea-rules"><i class="fas fa-filter"></i> {{ t('ui.base.admin.file_area_rules', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/subscriptions"><i class="fas fa-bookmark"></i> {{ t('ui.base.admin.subscriptions', {}, 'common') }}</a></li> <li><hr class="dropdown-divider"></li> <li><a class="dropdown-item" href="/admin/auto-feed"><i class="fas fa-rss"></i> {{ t('ui.base.admin.auto_feed', {}, 'common') }}</a></li> </ul> </li> <li class="dropdown-submenu"> <a class="dropdown-item dropdown-toggle" href="#"><i class="fas fa-users"></i> {{ t('ui.base.admin.community', {}, 'common') }}</a> <ul class="dropdown-menu"> <li><a class="dropdown-item" href="/admin/bbs-directory"><i class="fas fa-server"></i> {{ t('ui.base.admin.bbs_directory', {}, 'common') }}</a></li> <li class="dropdown-submenu"> <a class="dropdown-item dropdown-toggle" href="#"><i class="fas fa-comments"></i> {{ t('ui.base.admin.chat', {}, 'common') }}</a> <ul class="dropdown-menu"> <li><a class="dropdown-item" href="/admin/chat-rooms"><i class="fas fa-comment-dots"></i> {{ t('ui.base.admin.chat_rooms', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/mrc-settings"><i class="fas fa-satellite-dish"></i> {{ t('ui.base.admin.mrc_settings', {}, 'common') }}</a></li> </ul> </li> <li><a class="dropdown-item" href="/admin/polls"><i class="fas fa-vote-yea"></i> {{ t('ui.base.admin.polls', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/shoutbox"><i class="fas fa-bullhorn"></i> {{ t('ui.base.admin.shoutbox', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/weather-config"><i class="fas fa-cloud-sun"></i> {{ t('ui.base.admin.weather_config', {}, 'common') }}</a></li> </ul> </li> <li class="dropdown-submenu"> <a class="dropdown-item dropdown-toggle" href="#"><i class="fas fa-ad"></i> {{ t('ui.base.admin.ads_menu', {}, 'common') }}</a> <ul class="dropdown-menu"> <li><a class="dropdown-item" href="/admin/ads"><i class="fas fa-image"></i> {{ t('ui.base.admin.ads', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/ad-campaigns"><i class="fas fa-bullhorn"></i> {{ t('ui.base.admin.ad_campaigns', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/bulletins"><i class="fas fa-clipboard-list"></i> {{ t('ui.base.admin.bulletins', {}, 'common') }}</a></li> </ul> </li> <li class="dropdown-submenu"> <a class="dropdown-item dropdown-toggle" href="#"><i class="fas fa-gamepad"></i> {{ t('ui.base.admin.doors', {}, 'common') }}</a> <ul class="dropdown-menu"> <li><a class="dropdown-item" href="/admin/dosdoors"><i class="fas fa-terminal"></i> {{ t('ui.base.admin.doors_dos', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/native-doors"><i class="fas fa-door-open"></i> {{ t('ui.base.admin.doors_native', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/webdoors"><i class="fas fa-globe"></i> {{ t('ui.base.admin.doors_web', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/jsdosdoors"><i class="fas fa-floppy-disk"></i> {{ t('ui.base.admin.doors_jsdos', {}, 'common') }}</a></li> </ul> </li> <li><hr class="dropdown-divider"></li> <li class="dropdown-submenu"> <a class="dropdown-item dropdown-toggle" href="#"><i class="fas fa-chart-line"></i> {{ t('ui.base.admin.analytics', {}, 'common') }}</a> <ul class="dropdown-menu"> <li><a class="dropdown-item" href="/admin/activity-stats"><i class="fas fa-chart-bar"></i> {{ t('ui.base.admin.activity_stats', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/sharing"><i class="fas fa-share-alt"></i> {{ t('ui.base.admin.sharing', {}, 'common') }}</a></li> <li><a class="dropdown-item{% if not license_valid %} dropdown-item-locked{% endif %}" href="{{ license_valid ? '/admin/economy' : '#' }}"{% if not license_valid %} title="{{ t('ui.base.admin.registered_feature', {}, 'common') }}"{% endif %}><i class="fas fa-coins"></i> {{ t('ui.base.admin.economy_viewer', {}, 'common') }}{% if not license_valid %} <i class="fas fa-lock ms-1 small"></i>{% endif %}</a></li> <li><a class="dropdown-item{% if not license_valid %} dropdown-item-locked{% endif %}" href="{{ license_valid ? '/admin/referrals' : '#' }}"{% if not license_valid %} title="{{ t('ui.base.admin.registered_feature', {}, 'common') }}"{% endif %}><i class="fas fa-user-plus"></i> {{ t('ui.base.admin.referrals', {}, 'common') }}{% if not license_valid %} <i class="fas fa-lock ms-1 small"></i>{% endif %}</a></li> </ul> </li> <li class="dropdown-submenu"> <a class="dropdown-item dropdown-toggle" href="/admin/bbs-settings"><i class="fas fa-sliders-h"></i> {{ t('ui.base.admin.bbs_settings', {}, 'common') }}</a> <ul class="dropdown-menu"> <li><a class="dropdown-item" href="/admin/appearance"><i class="fas fa-palette"></i> {{ t('ui.base.admin.appearance', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/bbs-settings"><i class="fas fa-sliders-h"></i> {{ t('ui.base.admin.bbs_settings', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/binkp-config"><i class="fas fa-network-wired"></i> {{ t('ui.base.admin.binkp_configuration', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/networks"><i class="fas fa-globe"></i> {{ t('ui.base.admin.networks', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/i18n-overrides"><i class="fas fa-language"></i> {{ t('ui.base.admin.i18n_overrides', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/template-editor"><i class="fas fa-file-code"></i> {{ t('ui.base.admin.template_editor', {}, 'common') }}</a></li> </ul> </li> <li><hr class="dropdown-divider"></li> <li class="dropdown-submenu"> <a class="dropdown-item dropdown-toggle" href="#"><i class="fas fa-question-circle"></i> {{ t('ui.base.admin.help', {}, 'common') }}</a> <ul class="dropdown-menu"> <li><a class="dropdown-item" href="/admin/docs/view/README"><i class="fas fa-book"></i> {{ t('ui.base.admin.readme', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/docs"><i class="fas fa-book-open"></i> {{ t('ui.base.admin.docs', {}, 'common') }}</a></li> <li><a class="dropdown-item" href="/admin/docs/view/FAQ"><i class="fas fa-question-circle"></i> {{ t('ui.base.admin.faq', {}, 'common') }}</a></li> {% if has_upgrading_doc %}<li><a class="dropdown-item" href="/admin/upgrade-notes"><i class="fas fa-arrow-up-from-bracket"></i> {{ t('ui.base.admin.upgrade_notes', {'version': app_version}, 'common') }}</a></li>{% endif %} <li><a class="dropdown-item" href="https://github.com/awehttam/binkterm-php/issues" target="_blank"><i class="fas fa-bug"></i> {{ t('ui.base.admin.report_issue', {}, 'common') }}</a></li> </ul> </li> </ul> </div> {% endif %} {% else %} {% if bbs_feature_enabled('guest_doors_page') %} <a href="/guest-doors" class="bbs-shell-home me-2"> <i class="fas fa-terminal"></i> {{ t('ui.base.guest_doors', {}, 'common') }} </a> {% endif %} <a href="/login" class="bbs-shell-home me-2">{{ t('ui.base.login', {}, 'common') }}</a> {% endif %} <a href="/" class="bbs-shell-home" title="{{ t('ui.shell.menu_main_q_title', {}, 'common') }}"> <i class="fas fa-home"></i> {{ t('ui.shell.menu', {}, 'common') }} </a> </header> <main class="bbs-shell-main container-fluid py-3"> {% block content %}{% endblock %} </main> <footer class="bg-light py-2 border-top"> <div class="container text-center"> <small class="text-muted"> {% if license_valid and appearance.branding.footer_text %} {{ appearance.branding.footer_text | e }} {% else %} {{ system_name }} - Node {{ fidonet_origin }} - Sysop: {{ sysop_name }} {% endif %} | <a href="#" data-bs-toggle="modal" data-bs-target="#houseRulesModal">{{ t('ui.about.house_rules', {}, 'common') }}</a> {% if not (license_valid and appearance.branding.hide_powered_by) %} | {{ t('ui.footer.powered_by', {}, 'common') }} <a href="https://lovelybits.org/binktermphp">BinktermPHP</a> <a href="https://github.com/awehttam/binkterm-php">{{ app_version }}</a>{% if license_valid and license_system_name and appearance.branding.show_registration_badge != false %} - {{ t('ui.footer.registered_to', {'name': license_system_name}, 'common') }}{% endif %} {% endif %} </small> </div> </footer> <div class="modal fade" id="houseRulesModal" tabindex="-1" aria-labelledby="houseRulesModalLabel" aria-hidden="true"> <div class="modal-dialog modal-lg modal-dialog-scrollable"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="houseRulesModalLabel">{{ t('ui.about.house_rules', {}, 'common') }}</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> {% if appearance_houserules_html %} {{ appearance_houserules_html | raw }} {% else %} {% include 'rules.twig' %} {% endif %} </div> </div> </div> </div> <script> {% if current_user %} window.currentUserId = {{ current_user.user_id ?? current_user.id }}; window.currentUserIsAdmin = {{ current_user.is_admin ? 'true' : 'false' }}; {% endif %} window.isDevMode = {{ is_dev ? 'true' : 'false' }}; // Nested admin dropdown submenus $(document).ready(function() { $('.bbs-shell-header .dropdown-submenu').hover( function() { $(this).find('> .dropdown-menu').show(); }, function() { $(this).find('> .dropdown-menu').hide(); } ); $('.bbs-shell-header .dropdown-submenu > .dropdown-toggle').on('click', function(e) { e.preventDefault(); e.stopPropagation(); const $sub = $(this).next('.dropdown-menu'); $('.bbs-shell-header .dropdown-submenu .dropdown-menu').not($sub).hide(); $sub.toggle(); }); $('.bbs-shell-header .dropdown').on('hide.bs.dropdown', function() { $(this).find('.dropdown-submenu .dropdown-menu').hide(); }); }); // Render ANSI art if present on this page $(document).ready(function() { const pre = document.getElementById('shellMenuAnsi'); if (pre && (typeof renderAnsiBuffer === 'function' || typeof renderAnsiTerminal === 'function')) { const ansiSize = {{ appearance.shell.bbs_menu.ansi_size|default('80x25')|json_encode|raw }}; const dims = (function resolveAnsiMenuDimensions(size) { switch (size) { case '132x24': return { cols: 132, rows: 24 }; case '132x43': return { cols: 132, rows: 43 }; case '132x50': return { cols: 132, rows: 50 }; case 'full': return { cols: 132, rows: Math.max(25, Math.floor((window.innerHeight - 140) / 16)) }; case '80x25': default: return { cols: 80, rows: 25 }; } })(ansiSize); if (typeof renderAnsiBuffer === 'function') { pre.innerHTML = renderAnsiBuffer(pre.textContent, dims.cols, dims.rows, null, { preserveFullWidth: true, preserveFullHeight: true, rowCount: dims.rows }); } else { pre.innerHTML = renderAnsiTerminal(pre.textContent, dims.cols, dims.rows); } } }); // BBS-style keyboard navigation const bbsKeymap = {{ bbs_menu_items | json_encode | raw }}; function bbsNavigate(key) { if (key === 'q' || key === 'Q' || key === 'Escape') { window.location.href = '/'; return true; } const item = bbsKeymap.find(i => i.key.toUpperCase() === key.toUpperCase()); if (item) { window.location.href = item.url; return true; } return false; } // Desktop keyboard navigation document.addEventListener('keydown', function(e) { if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.tagName === 'SELECT') return; if (e.ctrlKey || e.altKey || e.metaKey) return; bbsNavigate(e.key); }); </script> {% block scripts %}{% endblock %} </body> </html>