index.php (9040B)
1 <!doctype html>
2 <html>
3
4 <!-- Process input (if given) -->
5 <?php
6
7 /* Load Configuration */
8 include("config/config.php");
9 include("lib/read_mappings.php");
10
11 /* Fetch and sanitize search query via GET request
12 * Allow both "query" and "q"
13 */
14 $_GET = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);
15 if (!is_null($_GET["query"])) {
16 $query = rawurldecode($_GET["query"]);
17 } else if (!is_null($_GET["q"])) {
18 $query = rawurldecode($_GET["q"]);
19 } else {
20 $query = null;
21 }
22
23 /* Handle Default Search Engine cookie or GET parameter */
24 if (
25 !is_null($_COOKIE["default_search"]) ||
26 !is_null($_GET["default_search"])
27 ) {
28 /* Use search engine stored in cookie or GET argument */
29 if (!is_null($_GET["default_search"])) {
30 $default_search = $_GET["default_search"];
31 } else {
32 $default_search = $_COOKIE["default_search"];
33 }
34 /* refresh cookie */
35 setcookie(
36 "default_search",
37 $default_search,
38 time() + (60 * 60 * 24 * 365)
39 );
40 }
41
42 if (strlen($query) > 0) {
43
44 /* Find keywords (only first one is considered) */
45 $keyword = preg_replace(
46 '/^.*?\!([A-Za-z0-9_\-\.]+).*$/',
47 '${1}',
48 $query
49 );
50 $keyword = strtolower($keyword);
51
52 /* Based on given keyword, choose a search engine or the fallback */
53 if (array_search($keyword, array_keys($searchkeys)) !== false) {
54 $search = $searchkeys[$keyword];
55 } else {
56 $search = $default_search;
57 }
58
59 /* Strip keyword from search term */
60 $search_term = preg_replace(
61 '/\![A-Za-z0-9_\-\.]+/',
62 '',
63 $query
64 );
65
66 /* Remove preceding and trailing spaces */
67 $search_term = preg_replace(
68 '/^\s+|\s+$/',
69 '',
70 $search_term
71 );
72
73 /* Construct search query */
74 $target = str_replace(
75 '%s',
76 rawurlencode($search_term),
77 $searches[$search]["query"]
78 );
79
80 /* Redirect to target search engine: 307 - Temporary Redirect */
81 header("Location: " . $target, true, 307);
82 die();
83 }
84
85 ?>
86
87 <!-- Head -->
88 <head>
89 <meta charset=utf-8>
90 <meta name=viewport content="width=device-width,initial-scale=1">
91 <link rel=icon href=/assets/img/favicon.png type=image/png>
92 <link rel=icon href=/assets/img/favicon.ico type=x-image/ico>
93 <link rel=stylesheet href=/assets/css/simple.min.css media=all>
94 <link rel=stylesheet href=/assets/css/custom.css>
95 <link rel="manifest" href="manifest.json">
96 <link
97 rel="search"
98 type="application/opensearchdescription+xml"
99 href="/opensearch.xml"
100 title="serĉi - search with !keywords"
101 >
102 <title>serĉi - search with !keywords</title>
103 </head>
104
105 <!-- Body -->
106 <body>
107
108 <!-- Search Bar -->
109 <h1>serĉi - Search with !keywords</h1>
110 <form id="searchform" action="/" method="get">
111 <input
112 id="searchbar"
113 name="query"
114 type="text"
115 autofocus
116 placeholder="I am thinking about... !keyword"
117 alt="Search the web"
118 onkeydown="if(event.keyCode===13)return this.form.submit(),!1"
119 >
120 <input
121 id="searchbutton"
122 name="submit"
123 type="submit"
124 value="🔎 Search"
125 >
126 </form>
127
128 <!-- FAQs -->
129 <h3>FAQs</h3>
130 <ul>
131 <li>
132 <a href="https://src.jayvii.de/pub/serci/#what-does-serĉi-mean"
133 target="_blank">What does <em>serĉi</em> mean?</a>
134 </li>
135 <li>
136 <a href="https://src.jayvii.de/pub/serci/#what-are-keywords"
137 target="_blank">What are keywords?</a>
138 </li>
139 <li>
140 <a href="https://src.jayvii.de/pub/serci/#how-can-i-use-serĉi"
141 target="_blank">How to use serĉi?</a>
142 </li>
143 <li>
144 <a href="https://src.jayvii.de/pub/serci/"
145 target="_blank">Help with development!</a>
146 </li>
147 </ul>
148
149 <!-- Search Engine Lists -->
150 <h3>Search Engines</h3>
151 <p>
152 Choose your default search:
153 <select
154 name="default_search"
155 id="default_search"
156 onchange="select_default_searchengine()"
157 >
158 <?php
159 /* Cycle through all available search engines
160 * Create <option> objects for each one
161 * Mark the default search engine as "selected"
162 */
163 foreach (array_keys($searches) as $search) {
164 ?>
165 <option
166 value="<?php echo $search; ?>"
167 <?php
168 if ($search == $default_search) {
169 echo "selected";
170 }
171 ?>
172 >
173 <?php echo $searches[$search]["name"]; ?>
174 </option>
175 <?php
176 }
177 ?>
178 </select>
179 </p>
180
181 <!-- Toggle-Button -->
182 <button onclick="toggle_details();">
183 Toggle Categories
184 </button>
185
186 <!-- Search Engine Categorical Lists -->
187 <?php
188 foreach ($searchcats as $category => $searchids) {
189 ?>
190
191 <details
192 id="<?php echo $category; ?>"
193 onclick="scroll_to('<?php echo $category; ?>');"
194 >
195 <summary>
196 <?php echo $categories[$category]["name"]; ?>
197 </summary>
198 <table>
199 <thead>
200 <tr>
201 <th>Engine</th>
202 <th>keywords</th>
203 <tr>
204 </thead>
205 <tbody>
206 <?php
207 /* Print one table row for each search engine in category */
208 foreach ($searchids as $searchid) {
209 ?>
210 <tr>
211 <td>
212 <a href="<?php echo $searches[$searchid]["website"]; ?>"
213 target="_blank">
214 <?php
215 echo $searches[$searchid]["name"];
216 ?>
217 </a>
218 </td>
219 <td>
220 <code>
221 <?php
222 echo "!" .
223 implode(
224 "</code>, <code>!",
225 $searches[$searchid]["keywords"]
226 );
227 ?>
228 </code>
229 </td>
230 </tr>
231 <?php
232 }
233 ?>
234 </tbody>
235 </table>
236 </details>
237 <?php
238 }
239 ?>
240
241 </body>
242
243 <!-- Script for selecting default Search Engine -->
244 <script>
245 select_default_searchengine = function() {
246 // Fetch the default search selection
247 var selections = document.querySelector('#default_search');
248 var selection = selections.selectedOptions[0].value;
249 // Set the expiration time for the cookie (1 year)
250 const d = new Date();
251 d.setTime(d.getTime() + (365*24*60*60*1000));
252 let expires = "expires="+ d.toUTCString();
253 // Set a cookie for the selection
254 document.cookie = "default_search=" + selection + ";" +
255 expires + ";SameSite=Strict;";
256 }
257 </script>
258
259 <!-- Script for toggling Search Engine tables -->
260 <script>
261 toggle_details = function() {
262 var setas = (1 - document.querySelector('details').open);
263 document.querySelectorAll('details').forEach(
264 function(d) {
265 d.open = setas;
266 }
267 );
268 }
269 </script>
270
271 <!-- Script to scroll entire category table into view -->
272 <script>
273 scroll_to = function(id) {
274 var obj = document.querySelector('#' + id);
275 // use a delay of 1ms to the object may already be expanded
276 setTimeout(
277 function() {
278 obj.scrollIntoView({
279 behavior: "smooth",
280 block: "start",
281 inline: "nearest"
282 });
283 },
284 1
285 );
286 }
287 </script>
288
289 </html>
290