diff options
Diffstat (limited to 'templates/layouts')
-rw-r--r-- | templates/layouts/app.html.ep | 320 | ||||
-rw-r--r-- | templates/layouts/default.html.ep | 214 | ||||
-rw-r--r-- | templates/layouts/legacy.html.ep | 66 |
3 files changed, 386 insertions, 214 deletions
diff --git a/templates/layouts/app.html.ep b/templates/layouts/app.html.ep new file mode 100644 index 0000000..c557bee --- /dev/null +++ b/templates/layouts/app.html.ep @@ -0,0 +1,320 @@ +<!DOCTYPE html> +<html lang="de"> +<head> + <title><%= stash('title') // 'DBF' %></title> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="keywords" content="Abfahrtsmonitor, Bahnhofstafel, Abfahrten, Abfahrtstafel, Nahverkehr, Regionalverkehr, Fernverkehr, ICE, IC, RE, RB, S-Bahn"> + <meta name="description" content="<%= stash('description') // 'Inoffizieller Abfahrtsmonitor für Nah-, Reginol- und Fernverkehr' %>"> + <meta name="theme-color" content="#00838f"> + <link rel="icon" type="image/png" href="/static/icons/icon-16x16.png" sizes="16x16"> + <link rel="icon" type="image/png" href="/static/icons/icon-32x32.png" sizes="32x32"> + <link rel="icon" type="image/png" href="/static/icons/icon-96x96.png" sizes="96x96"> + <link rel="apple-touch-icon" href="/static/icons/icon-120x120.png"> + <link rel="apple-touch-icon" sizes="180x180" href="/static/icons/icon-180x180.png"> + <link rel="apple-touch-icon" sizes="152x152" href="/static/icons/icon-152x152.png"> + <link rel="apple-touch-icon" sizes="167x167" href="/static/icons/icon-167x167.png"> +% if ($self->stash('refresh_interval')) { + <meta http-equiv="refresh" content="<%= $self->stash('refresh_interval') %>"/> +% } + + % my $av = 'v110'; # asset version + % if (session('theme') and session('theme') eq 'dark' or param('dark')) { + %= stylesheet "/static/${av}/css/dark.min.css", id => 'theme' + % } + % else { + %= stylesheet "/static/${av}/css/light.min.css", id => 'theme' + % } + <script> + function addStyleSheet(name, id) { + const path = '/static/<%=$av%>/css/' + name + '.min.css'; + const old = document.getElementById(id); + if (old && (old.href != path)) { + old.href = path; + document.cookie = 'theme=' + name + ';SameSite=None;Secure'; + } + } + const otherTheme = { + 'dark': 'light', + 'light': 'dark', + }; + var currentTheme = localStorage.getItem('theme'); + if (!otherTheme.hasOwnProperty(currentTheme)) { + currentTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; + } + addStyleSheet(currentTheme, 'theme'); + </script> + %= stylesheet "/static/${av}/css/material-icons.css" + %= stylesheet "/static/${av}/css/jquery-ui.min.css" + %= javascript '/static/js/jquery-3.4.1.min.js', defer => undef + %= javascript "/static/${av}/js/jquery-ui.min.js", defer => undef + %= javascript "/static/${av}/js/dbf.min.js", defer => undef + % if (not stash('hide_opts')) { + %= javascript "/dyn/${av}/autocomplete.js", defer => undef + % } + % if (stash('with_geostop')) { + %= javascript "/static/${av}/js/geostop.min.js", defer => undef + % } + % if (stash('with_map')) { + %= stylesheet "/static/${av}/leaflet/leaflet.css" + %= javascript "/static/${av}/leaflet/leaflet.js" + %= javascript "/static/${av}/js/map-refresh.min.js", defer => undef + % } +</head> +<body> + +<div class="navbar-fixed"> + <nav style="color: #ffffff; background-color: #00838f;"> + <div class="nav-wrapper container"> + % if (my $nav_link = stash('nav_link')) { + <a class="brand-logo" style="float: left;" href="<%= $nav_link %>"> + %= stash('title') || 'DBF' + </a> + % } + % else { + <span class="brand-logo"> + %= stash('title') || 'DBF' + </span> + % } + <ul id="nav-mobile" style="float: right;"> + % if (stash('api_link')) { + <li class="waves-effect waves-light"> + <a href="<%= stash('api_link') %>"><span class="visually-hidden"><%= stash('api_text') %></span><i class="material-icons" aria-hidden="true"><%= stash('api_icon') %></i></a> + </li> + % } + % if (stash('hide_opts')) { + <li><a href="/"><span class="visually-hidden">Hauptseite</span><i class="material-icons" aria-hidden="true">edit</i></a></li> + % } + % else { + <li><a href="#stationinput"><span class="visually-hidden">Menü</span><i class="material-icons" aria-hidden="true">edit</i></a></li> + % } + </ul> + </div> + </nav> +</div> + +<div class="container"> +% if (my $error = stash 'error') { +<div class="error"><strong>Fehler:</strong> +<p> +%= $error +</p> +</div> +% } +% elsif (stash('stationlist')) { +<div class="error"><strong>Mehrdeutige Eingabe.</strong> +Bitte eine Station aus der Liste auswählen</div> +% } +</div> + +<div class="content"> +%= content +</div> + +% if (not stash('hide_opts')) { +<div class="container"> +<div class="input-field"> + + +%= form_for _redirect => begin +%= hidden_field efa => param('efa') +%= hidden_field hafas => param('hafas') +<div> + <div class="field"> +% if (stash('stationlist')) { + %= select_field input => stash('stationlist') +% } +% elsif (stash('input')) { + %= text_field 'input', class => 'station', placeholder => 'Stationsname oder Fahrtnummer', id => 'stationinput' +% } +% else { + %= text_field 'input', class => 'station', placeholder => 'Stationsname oder Fahrtnummer', id => 'stationinput', autofocus => 'autofocus' +% } + </div> + <div class="field"> + %= submit_button 'Abfahrtstafel' + </div> + % if (stash('input')) { + <div class="geolink"> + <a class="button" href="<%= url_for('_autostop')->to_abs->scheme('https')->query({efa => param('efa'), hafas => param('hafas')}) %>">Stationen in der Umgebung suchen</a> + </div> + % } + <div class="backendlink"> + <a class="button button-light" href="<%= url_for('_backend')->query({efa => param('efa'), hafas => param('hafas')}) %>">Backend: <%= param('efa') ? param('efa') . ' (EFA)' : param('hafas') ? param('hafas') . ' (HAFAS)' : 'DB (IRIS-TTS)' %></a> + </div> + <div class="break"></div> + <div class="moresettings-header moresettings-header-collapsed button button-light">Weitere Einstellungen</div> + <div class="moresettings moresettings-collapsed"> + <div class="field"> + <div class="desc"> + %= check_box 'hidelowdelay' => 1, id => 'id_hidelowdelay' + <label for="id_hidelowdelay"> + Verspätungen erst ab 5 Minuten anzeigen + </label> + </div> + </div> + <div class="field"> + <div class="desc"> + %= check_box 'detailed' => 1, id => 'id_detailed' + <label for="id_detailed"> + Mehr Details + </label> + </div> + </div> + <div class="field"> + <div class="desc"> + %= check_box 'past' => 1, id => 'past' + <label for="past"> + Fahrten der vergangenen 60 Minuten zeigen + </label> + </div> + </div> + <div class="field"> + <div class="desc"> + %= check_box 'hide_opts' => 1, id => 'id_hide_opts' + <label for="id_hide_opts"> + Formular verstecken + </label> + </div> + </div> + <div class="field"> + <div class="desc"> + Nur Fahrten über + </div> + <div> + %= text_field 'via', placeholder => 'Bahnhof 1, Bhf2, ... (oder regulärer Ausdruck)', class => 'station' + </div> + </div> + <div class="field"> + <div class="desc"> + Gleise + </div> + <div> + %= text_field 'platforms', placeholder => '1, 2, 5, ...' + </div> + </div> + <div class="field"> + <div class="desc"> + Ankunfts- oder Abfahrtszeit anzeigen? + </div> + <div> + %= select_field admode => [['Abfahrt bevorzugen' => 'deparr'], ['Nur Abfahrt' => 'dep'], ['Nur Ankunft' => 'arr']] + </div> + </div> + <div class="field"> + <div class="desc"> + Frontend + </div> + <div> + %= select_field mode => [ ['App' => 'app'], ['Infoscreen' => 'infoscreen'], ['Bahnhofstafel (legacy)' => 'multi'], ['Gleisanzeiger (legacy)' => 'single'] ] + </div> + </div> + <div class="field"> + %= submit_button 'Anzeigen' + </div> + </div> <!-- moresettings --> +</div> +% end + +</div> <!-- input-field --> + +<div class="notes"> + <div class="developers-header developers-header-collapsed button button-light">API</div> + <div class="developers developers-collapsed"> + <ul> + % if (0) { + <li>You're welcome to embed DBF departure boards as iframes or use them + in full-screen browser setups. The App frontend works best for + small screens, whereas the legacy Infoscreen mode is better suited + for large displays.</li> + <li>The departure board supports names, EVA IDs, and (in IRIS mode) + DS100/Ril100 codes as station identifiers.</li> + <li>Requests for train details can optionally be suffixed with the + DD.MM.[YYYY] date of the requested trip, e.g. "ICE 921 (1.1.)" or + "ICE 921 @ 1.1.". The date refers to the scheduled departure at the + train's origin station.</li> + <li>A JSON IRIS API is avaliable via + <span style="font-family: monospace;">mode=json&version=3</span> + (or just <span style="font-family: monospace;">https://dbf.finalrewind.org/Station.json?version=3</span>). + Route elements may contain "isAdditional" and "isCancelled"; the rest + should be self-explanatory. Please do not send more than 30 requests + per minute and only one request per station per minute.</li> + <li>There is no JSON API for train details yet.</li> + <li>The optional <span style="font-family: monospace;">limit</span> + parameter limits the number of returnd departures; e.g. + <span style="font-family: monospace;">limit=10</span> will result in no more than ten.</li> + <li>DBF is available as Open Source software + (<a href="https://github.com/derf/db-fakedisplay/blob/master/README.md">installation instructions</a>). + Please use your own installation for automated crawlers that request dozens of stations per minute.</li> + % } + % else { + <li>DBF-Abfahrtstafeln können gerne als iframe eingebunden oder in + fest installierten Vollbild-Browserfenstern verwendet werden. + Für eine kleine Ansicht (z.B. iframe in einer normalen Website) + empfiehlt sich das "App"-Frontend. Für eine große Ansicht + (z.B. als alleinstehender Infoscreen) gibt es den "Infoscreen"-Modus.</li> + <li>Die Abfahrtstafel unterstützt Namen, EVA-IDs, und (im IRIS-Backend) + DS100/Ril100-Codes zur Identifikation von Stationen.</li> + <li>Abfahrten werden mit Echtzeitdaten bzw. Prognosen angegeben und + danach sortiert. Mit dem Parameter + <span style="font-family: monospace;">rt=0</span> wwerden stattdessen + Plandaten angegeben und zur Sortierung genutzt.</li> + <li>Bei HAFAS-Backends können optional Details für spezifische Fahrten im + DD.MM.[YYYY]-Format abgefragt werden, z.B. "ICE 921 (1.1.)" oder + "ICE 921 @ 1.1.". Das Datum bezieht sich auf die geplante + Abfahrtszeit am Startbahnhof der Fahrt.</li> + <li>Viele Seiten sind auch als JSON verfügbar, wahlweise mittels + <span style="font-family: monospace;">Accept: application/json</span> oder + durch <span style="font-family: monospace;">.json</span> in der URL. + HAFAS- und IRIS-Abfahrtstafeln liefern mit dem GET-Parameter <span style="font-family: monospace;">version=3</span> eine stabile JSON-API. + Alle anderen Endpunkte (sowie Abfahrtstafeln mit <span style="font-family: monospace;">version=raw</span>) erlauben direkten Zugriff auf die serialisierten Travel::Status::DE::{EFA,HAFAS,IRIS}-Objekte ohne stabile API.</li> + <li>Bitte maximal 30 Anfragen pro Minute und insbesondere nur eine Anfrage + pro Station und Minute – eine höhere Auflösung haben die Backenddaten + ohnehin nicht.</li> + <li>Mit <span style="font-family: monospace;">limit</span> kann die Anzahl der + angezeigten / im JSON enthaltenen Abfahrten eingeschränkt werden, z.B. + <span style="font-family: monospace;">limit=10</span> für die ersten zehn.</li> + <li>Dieser Dienst ist Open Source-Software und kann leicht auf eigenen Servern + <a href="https://github.com/derf/db-fakedisplay/blob/master/README.md">installiert</a> + werden. Automatisierte Crawler, die mehrere Dutzend Stationen pro Minute + abfragen, bitte nur auf eigenen Instanzen betreiben.</li> + % } + </ul> + </div> <!-- developers --> +</div> <!-- notes --> + +</div> <!-- container --> + +<div class="container"> +<div class="config"> +Farbschema: +<a onClick="javascript:setTheme('light')">hell</a> +· +<a onClick="javascript:setTheme('dark')">dunkel</a> +· +<a onClick="javascript:setTheme('default')">automatisch</a> +<!--Language: +<br/> +<a onClick="javascript:setLang('de')">DE</a> +· +<a onClick="javascript:setLang('en')">EN</a> +· +<a onClick="javascript:setLang('default')">system language</a> +--> +</div> <!-- config --> +</div> <!-- container --> +% } +% if (not stash('hide_footer')) { +<div class="container"> +<div class="about"> +<a href="_about">DBF</a> v<%= stash('version') // '???' %> +· +<a href="_datenschutz" rel="nofollow">Datenschutz</a> +· +<a href="_impressum" rel="nofollow">Impressum</a> +</div> <!-- about --> +</div> <!-- container --> +% } + +</body> +</html> diff --git a/templates/layouts/default.html.ep b/templates/layouts/default.html.ep deleted file mode 100644 index 54bda52..0000000 --- a/templates/layouts/default.html.ep +++ /dev/null @@ -1,214 +0,0 @@ -<!DOCTYPE html> -<html lang="de"> -<head> - <title><%= stash('title') // 'db-infoscreen' %></title> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> -% if ($self->stash('refresh_interval')) { - <meta http-equiv="refresh" content="<%= $self->stash('refresh_interval') %>"/> -% } - - - %= stylesheet '/static/default.css' - %= stylesheet '/static/jquery-ui.min.css' -% my $force_mobile = param('force_mobile') // -1; -% if ($force_mobile == 1 or ($self->browser->mobile and $force_mobile != 0)) { - %= stylesheet '/static/mobile.css' -% } - %= javascript '/static/jquery-1.10.2.min.js' - %= javascript '/static/jquery-ui.min.js' - %= javascript '/static/autocomplete.js' - %= javascript '/static/collapse.js' - %= javascript '/static/marquee.js' - %= javascript begin - $(function () { $('marquee').marquee() }); - % end - % if (stash('with_geolocation')) { - %= javascript '/static/geolocation.js' - % } -</head> -<body style="<%= (stash('hide_opts') ? 'margin: 0; padding: 0;' : q{}) %>"> - -<div class="container"> -% if (my $error = stash 'error') { -<div class="error"><strong>Backend-Fehler:</strong> -<pre> -%= $error -</pre> -</div> -% } -% elsif (stash('stationlist')) { -<div class="error"><strong>Mehrdeutige Eingabe.</strong> -Bitte eine Station aus der Liste auswählen</div> -% } -</div> - -%= content - -% if (not stash('hide_opts')) { -<div class="container"> -<div class="input-field"> - - -%= form_for _redirect => begin -<div> - <div class="field"> - <div class="desc">Bahnhof / Haltestelle</div> - <div> -% if (stash('stationlist')) { - %= select_field station => stash('stationlist') -% } -% elsif (stash('station')) { - %= text_field 'station', class => 'station' -% } -% else { - %= text_field 'station', class => 'station', autofocus => 'autofocus' -% } - </div> - </div> - <div class="field"> - %= submit_button 'Abfahrtsmonitor' - </div> - <div class="break"></div> - <div class="moresettings-header moresettings-header-collapsed button button-light">Weitere Einstellungen</div> - <div class="moresettings moresettings-collapsed"> - <div class="field"> - <div class="desc"> - Frontend - </div> - <div> - %= select_field mode => [ ['App / Infoscreen' => 'clean'], ['Bahnhofstafel' => 'multi'], ['Gleis' => 'single'] ] - </div> - </div> - <div class="field"> - <div class="desc"> - Backend - </div> - <div> - %= select_field backend => [ ['IRIS' => 'iris'], ['HAFAS' => 'ris'] ] - </div> - </div> - <div class="field"> - <div class="desc"> - Nur Züge über - </div> - <div> - %= text_field 'via', placeholder => 'Bahnhof 1, Bhf2, ... (oder regulärer Ausdruck)', class => 'station' - </div> - </div> - <div class="field"> - <div class="desc"> - Gleise - </div> - <div> - %= text_field 'platforms', placeholder => '1, 2, 5, ...' - </div> - </div> - <div class="field"> - <div class="desc"> - %= check_box 'hidelowdelay' => 1, id => 'id_hidelowdelay' - <label for="id_hidelowdelay"> - Nur Verspätungen >5 Min. anzeigen - </label> - </div> - </div> - <div class="field"> - <div class="desc"> - %= check_box 'hide_opts' => 1, id => 'id_hide_opts' - <label for="id_hide_opts"> - Formular verstecken (für Infoscreens) - </label> - </div> - </div> - <div class="break"></div> - <span class="optional">Nur für IRIS-Backend:</span> - <div class="field"> - <div class="desc"> - Ankunfts- oder Abfahrtszeit anzeigen? - </div> - <div> - %= select_field admode => [['Abfahrt bevorzugen' => 'deparr'], ['Nur Abfahrt' => 'dep'], ['Nur Ankunft' => 'arr']] - </div> - </div> - <div class="field"> - <div class="desc"> - %= check_box 'show_realtime' => 1, id => 'id_show_realtime' - <label for="id_show_realtime"> - Erwartete Zeiten statt Fahrplandaten - </label> - </div> - </div> - <div class="field"> - <div class="desc"> - %= check_box 'no_related' => 1, id => 'id_no_related' - <label for="id_no_related"> - Betriebliche Bahnhofstrennungen berücksichtigen (z.B. "Hbf (Fern+Regio)" vs. "Hbf (S)") - </label> - </div> - </div> - <div class="field"> - %= submit_button 'Anzeigen' - </div> - </div> <!-- moresettings --> -</div> -% end - -</div> <!-- input-field --> - -<div class="notes"> -<span class="notes">Beispiele:</span> -<ul> -<li><a href="/Essen%20Hbf?mode=multi">Essen HBf</a> (IRIS, Bahnhofstafel)</li> -<li><a href="/Dortmund%20Hbf/Bochum%7CHamm?mode=multi">Dortmund HBf</a> (IRIS, Bahnhofstafel, -nur Züge via Bochum oder Hamm)</li> -<li><a href="/Dortmund%20Universität?mode=clean">Dortmund Universität</a> (IRIS, Mobile/Infoscreen)</li> -<li><a href="/KD?mode=single">Düsseldorf HBf</a> (IRIS, Gleistafel)</li> -</ul> -</div> - -<div class="notes"> -<span class="notes">Siehe auch:</span> -<ul> -<li><a href="http://reiseauskunft.bahn.de/bin/bhftafel.exe/dn">DB RIS</a> - (<a href="http://mobile.bahn.de/bin/mobil/bhftafel.exe/dox">mobil</a>)</li> -<li><a href="http://data.deutschebahn.com/datasets/betriebsstellen/">Betriebsstellenliste</a></li> -<li><a href="https://vrrf.finalrewind.org/">vrr-infoscreen</a></li> -</ul> -</div> <!-- notes --> - -<div class="notes"> -<span class="notes">Developers Developers Developers Developers:</span> -<ul> -<li>Diese Seite kann gerne als iframe in eigene Infoscreens o.ä. eingebunden werden. - Das App/Infoscreen-Template kann dazu (falls nötig) mit - <span style="font-family: monospace;">force_mobile=1</span> bzw. - <span style="font-family: monospace;">force_mobile=0</span> auf die mobile - bzw. die Desktopversion festgelegt werden</li> -<li>Die Parameter <span style="font-family: monospace;">mode=marudor&version=3</span> - liefern ein JSON-Interface. Die route-Elemente können zusätzlich - die Felder "isAdditional" oder "isCancelled" enthalten, der Rest sollte - selbsterklärend sein</li> -</ul> -</div> <!-- notes --> - -</div> <!-- container --> - -<div class="container"> -<div class="about"> -<a href="https://finalrewind.org/projects/db-fakedisplay/">db-infoscreen</a> -v<%= stash('version') // '???' %><br/> -Backends:<br/> -<a href="https://finalrewind.org/projects/Travel-Status-DE-DeutscheBahn/">Travel::Status::DE::HAFAS</a> -v<%= $Travel::Status::DE::HAFAS::VERSION %><br/> -<a href="https://finalrewind.org/projects/Travel-Status-DE-IRIS/">Travel::Status::DE::IRIS</a> -v<%= $Travel::Status::DE::IRIS::VERSION %><br/> -<a href="http://data.deutschebahn.com/dataset/data-haltestellen">Haltestellendaten</a> -© DB Station&Service AG, -Europaplatz 1, -10557 Berlin, lizensiert unter CC-BY 4.0 -</div> <!-- about --> -</div> <!-- container --> -% } - -</body> -</html> diff --git a/templates/layouts/legacy.html.ep b/templates/layouts/legacy.html.ep new file mode 100644 index 0000000..e7e59ec --- /dev/null +++ b/templates/layouts/legacy.html.ep @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<html lang="de"> +<head> + <title><%= stash('title') // 'DBF' %></title> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="keywords" content="Abfahrtsmonitor, Bahnhofstafel, Abfahrten, Abfahrtstafel, ICE, IC, RE, RB, S-Bahn"> + <meta name="description" content="Inoffizieller Abfahrtsmonitor für Bahnhöfe der DB"> + <link rel="icon" type="image/png" href="/static/icons/icon-16x16.png" sizes="16x16"> + <link rel="icon" type="image/png" href="/static/icons/icon-32x32.png" sizes="32x32"> + <link rel="icon" type="image/png" href="/static/icons/icon-96x96.png" sizes="96x96"> + <link rel="apple-touch-icon" href="/static/icons/icon-120x120.png"> + <link rel="apple-touch-icon" sizes="180x180" href="/static/icons/icon-180x180.png"> + <link rel="apple-touch-icon" sizes="152x152" href="/static/icons/icon-152x152.png"> + <link rel="apple-touch-icon" sizes="167x167" href="/static/icons/icon-167x167.png"> +% if ($self->stash('refresh_interval')) { + <meta http-equiv="refresh" content="<%= $self->stash('refresh_interval') %>"/> +% } + + % my $av = 'v110'; # asset version + %= stylesheet "/static/${av}/css/legacy.css" + %= stylesheet "/static/${av}/css/material-icons.css" + %= stylesheet "/static/${av}/css/jquery-ui.min.css" +% my $force_mobile = param('force_mobile') // stash('force_mobile'); +% if ($force_mobile) { + %= stylesheet "/static/${av}/css/legacy-mobile.css" +% } + %if (stash('load_marquee')) { + %= javascript '/static/js/jquery-3.4.1.min.js' + %= javascript "/static/${av}/js/jquery-ui.min.js" + %= javascript "/static/${av}/js/dbf.min.js" + % if (not stash('hide_opts')) { + %= javascript "/dyn/${av}/autocomplete.js", defer => undef + % } + %= javascript "/static/${av}/js/marquee.min.js" + %= javascript begin + $(function () { $('marquee').marquee() }); + % end + % } else { + %= javascript '/static/js/jquery-3.4.1.min.js', defer => undef + %= javascript "/static/${av}/js/jquery-ui.min.js", defer => undef + %= javascript "/static/${av}/js/dbf.min.js", defer => undef + % } +</head> +<body style="<%= (param('dark') ? 'background-color: #000000; color: #ffffff;' : q{}) %>"> + +<div class="container"> +% if (my $error = stash 'error') { +<div class="error"><strong>Backend-Fehler:</strong> +<pre> +%= $error +</pre> +</div> +% } +% elsif (stash('stationlist')) { +<div class="error"><strong>Mehrdeutige Eingabe.</strong> +Bitte eine Station aus der Liste auswählen</div> +% } +</div> + +<div class="content"> +%= content +</div> + +</body> +</html> |