pub / tn

Tech News Aggregator
git clone src.jayvii.de/pub/tn.git
Home | Log | Files | Exports | Refs | RSS

index.tt (4750B)


      1 <!-- SPDX-License-Identifier: AGPL-3.0-or-later
      2      SPDX-FileCopyrightText: 2026 JayVii <jayvii+tn[AT]posteo[DOT]de>
      3 -->
      4 
      5 <!DOCTYPE html>
      6 <html>
      7   <head>
      8     <meta charset="utf-8">
      9     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
     10     <title>[% feed.title %]</title>
     11     <meta name="description" content="[% feed.description %]">
     12     [% IF feed.author %]
     13     <meta name="author" content="[% feed.author %]">
     14     [% END %]
     15     <link rel="icon" type="image/png" href="assets/favicon.png">
     16     <link rel="icon" type="image/png" sizes="16x16"
     17       href="assets/favicon_16.png"
     18     />
     19     <link rel="icon" type="image/png" sizes="32x32"
     20       href="assets/favicon_32.png"
     21     />
     22     <link rel="icon" type="image/png" sizes="64x64"
     23       href="assets/favicon_64.png"
     24     />
     25     <link rel="icon" type="image/png" sizes="128x128"
     26       href="assets/favicon_128.png"
     27     />
     28     <link rel="apple-touch-icon" href="assets/favicon.png">
     29     <link rel="stylesheet" type="text/css" href="assets/css/simple.min.css">
     30     <link rel="stylesheet" type="text/css" href="assets/css/custom.css">
     31     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     32     <meta name="robots" content="noindex">
     33   </head>
     34 
     35   <body>
     36 
     37     <header>
     38       <nav>
     39         <!-- About Button -->
     40         <a
     41           href="#about"
     42           title="About this page"
     43         >About</a>
     44         <!-- OPML Button -->
     45         <a
     46           href="./tn.opml"
     47           title="Import all these feeds into your own RSS reader"
     48         >OPML</a>
     49         <!-- Privacy Policy -->
     50         <a href="https://www.jayvii.de/privacy/#tnjayviide" target="_blank">
     51           Privacy
     52         </a>
     53       </nav>
     54       <!-- Feed Title -->
     55       <h1 id="top">[% feed.title | html %]</h1>
     56       <p>[% feed.description | html %]</p>
     57     </header>
     58 
     59     <main>
     60 
     61       <?php
     62 
     63         $news = array();
     64         [% FOREACH entry IN feed.entries %]
     65         array_push(
     66           $news,
     67           array(
     68             "title" => "[%entry.title | html %]",
     69             "url" => "[% entry.link | url %]",
     70             "date" => strtotime("[% entry.issued | html %]")
     71           )
     72         );
     73         [% END %]
     74 
     75         // Sort News item by time stamp and remove duplicate entries
     76         function compare(array $a, array $b) {
     77           return $b["date"] - $a["date"];
     78         }
     79         usort($news, "compare");
     80         $news = array_intersect_key(
     81           $news,
     82           array_unique(
     83             array_map('serialize', $news)
     84           )
     85         );
     86       
     87       ?>
     88     
     89 
     90       <!-- Content Entries -->
     91       <?php
     92         $counter = 0;
     93         foreach ($news as $entry) {
     94 
     95           if ($entry["date"] < strtotime("-24 hours")) {
     96             continue;
     97           }
     98           $counter++;
     99           $entry["domain"] = preg_replace(
    100             '/^http(s)*:\/\/([^\/]+)\/.*$/',
    101             '${2}',
    102             $entry["url"]
    103           );
    104 
    105       ?>
    106 
    107         <section>
    108           <!-- Headline -->
    109           <strong>
    110             <stretch><?php echo $counter . ". " . $entry["title"]; ?></stretch>
    111           </strong>
    112         <!-- Information -->
    113         <div style="width:100%;margin-bottom:1em;">
    114           <em style="margin-left:0.25em;color:var(--border);">
    115             <?php echo date("Y-m-d, H:i", $entry["date"]); ?>
    116           </em>
    117           <em style="margin-left:0.25em;color:var(--border);">
    118             <?php echo $entry["domain"]; ?>
    119           </em>
    120           <a href="<?php echo $entry["url"]; ?>"
    121             target="_blank"
    122             rel="nofollow ugc"
    123             style="margin-left:0.25em;"
    124           >
    125             <em>Read more</em>
    126           </a>
    127         </div>
    128 
    129         </section>
    130 
    131       <?php
    132         }
    133       ?>
    134 
    135     </main>
    136 
    137     <footer>
    138       <h4 id="about">What is this?</h4>
    139       <p>
    140         This website <em>tn</em> gathers tech news from
    141         <a href="./tn.opml">various sources</a> and aggregates them into a time
    142         sorted list. It is inspired by the likes of <em>Hacker News</em> or
    143         <em>Lobsters</em>, however it does not allow to upvote, comment or any
    144         other interactivity. The goal of <em>tn</em> is to display news, nothing
    145         more.
    146       </p>
    147       <h4 id="disclaimer">Disclaimer:</h4>
    148       <p>
    149         The news headlines, content or attitudes of the editors and authors of
    150         the news outlets, blogs and newspapers featured here do not necessarily
    151         reflect the opinions and attitudes of the operators of this
    152         <em>tn</em> instance and this website. <em>tn</em> is a
    153         news aggregator that brings together content from many different
    154         sources, but has no influence on the editorial content directly.
    155       </p>
    156       <a class="button" href="#top">Backto the top</a>
    157     </footer>
    158 
    159   </body>
    160 </html>