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>