pub / serci

Search the web with !keywords
git clone https://src.jayvii.de/pub/serci.git
Home | Home | Log | Files | Exports | Exports | Refs | README | RSS | RSS

index.php (15944B)


      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 Fallback Search Engine via cookie or GET argument
     24     *  Fallback is always defined in config/configs.php
     25     */
     26     if (!is_null($_GET["fallback"])) {
     27         $fallback = $_GET["fallback"];
     28     } elseif (!is_null($_COOKIE["fallback"])) {
     29         $fallback = $_COOKIE["fallback"];
     30         /* refresh cookie */
     31         header(
     32             "Set-Cookie: " .
     33             "fallback=" . $fallback . "; " .
     34             "Max-Age=" . 31536000 . "; " . /* 60 x 60 x 24 x 365 = 1 year */
     35             "Domain=" . $_SERVER["SERVER_NAME"] . "; " .
     36             "SameSite=Strict;"
     37         );
     38     }
     39 
     40     if (strlen($query) > 0) {
     41 
     42         /* Find keywords (only first one is considered) */
     43         $keyword = preg_replace(
     44             '/^.*?\!([A-Za-z0-9_\-\.]+).*$/',
     45             '${1}',
     46             $query
     47         );
     48         $keyword = strtolower($keyword);
     49 
     50         /* Based on given keyword, choose a search engine or the fallback */
     51         if (array_search($keyword, array_keys($searchkeys)) !== false) {
     52             $search = $searchkeys[$keyword];
     53         } else {
     54             $search = $fallback;
     55         }
     56 
     57         /* Get options from keyword (syntax: !key:opt)*/
     58         if (preg_match('/\![A-Za-z0-9_\-\.]+:[A-Za-z0-9_\-\.\/]+/', $query) === 1) {
     59             $keyoption = preg_replace(
     60                 '/^.*?\![A-Za-z0-9_\-\.]+:([A-Za-z0-9_\-\.\/]+).*$/',
     61                 '${1}',
     62                 $query
     63             );
     64             $keyoption = strtolower($keyoption);
     65         } elseif (array_key_exists("default_opts", $searches[$search])) {
     66             $keyoption = $searches[$search]["default_opts"];
     67         } else {
     68             $keyoption = "";
     69         }
     70 
     71         /* Strip keyword from search term */
     72         $search_term = preg_replace(
     73             '/\![A-Za-z0-9_\-\.]+:{0,1}[A-Za-z0-9_\-\.\/]*/',
     74             '',
     75             $query
     76         );
     77 
     78         /* Remove preceding and trailing spaces */
     79         $search_term = preg_replace(
     80             '/^\s+|\s+$/',
     81             '',
     82             $search_term
     83         );
     84 
     85         /* Construct search query */
     86         $target = str_replace(
     87             '%s',
     88             rawurlencode($search_term),
     89             /* insert keyoption */
     90             str_replace(
     91                 '%opt',
     92                 $keyoption,
     93                 $searches[$search]["query"]
     94             )
     95         );
     96 
     97         /* Redirect to target search engine: 307 - Temporary Redirect */
     98         header("Location: " . $target, true, 307);
     99         die();
    100     }
    101 
    102 ?>
    103 
    104     <!-- Head -->
    105     <head>
    106         <meta charset=utf-8>
    107         <meta name=viewport content="width=device-width,initial-scale=1">
    108         <link rel=icon href=/assets/img/favicon.png type=image/png>
    109         <link rel=icon href=/assets/img/favicon.ico type=x-image/ico>
    110         <link rel=stylesheet href=/assets/css/simple.min.css media=all>
    111         <link rel=stylesheet href=/assets/css/custom.css>
    112         <link rel="manifest" href="manifest.json">
    113         <link
    114             rel="search"
    115             type="application/opensearchdescription+xml"
    116             href="/opensearch.xml"
    117             title="serĉi - search with !keywords"
    118         >
    119         <script async src=/assets/js/filter_engines.js></script>
    120         <title>serĉi - search with !keywords</title>
    121     </head>
    122 
    123     <!-- Body -->
    124     <body>
    125 
    126         <!-- Header -->
    127         <header>
    128             <nav>
    129                 <a href="#engines">
    130                     Engines
    131                 </a>
    132                 <a href="#faqs">
    133                     FAQs
    134                 </a>
    135                 <a href="https://src.jayvii.de/pub/serci/" target="_blank">
    136                     Development
    137                 </a>
    138             </nav>
    139             <h1>serĉi</h1>
    140             <p>Search with Keywords</p>
    141         </header>
    142 
    143         <!-- Search Bar -->
    144         <form id="searchform" action="/" method="get">
    145             <input
    146                 id="searchbar"
    147                 name="query"
    148                 type="text"
    149                 autofocus
    150                 placeholder="I am thinking about... !keyword"
    151                 alt="Search the web"
    152                 onkeydown="if(event.keyCode===13)return this.form.submit(),!1"
    153             >
    154             <input
    155                 name="fallback"
    156                 id="fallback"
    157                 type="hidden"
    158                 value="<?php echo $fallback; ?>"
    159             >
    160             <input
    161                 id="searchbutton"
    162                 name="submit"
    163                 type="submit"
    164                 value="&#128270; Search"
    165             >
    166         </form>
    167 
    168         <!-- Description -->
    169         <div class="description">
    170             <strong style="font-size: 133%;">
    171                 The keyword engine for power users that sits on top of your
    172                 favorite search engines!
    173             </strong>
    174             <p>
    175                 Have all your favorite search providers right at your finger
    176                 tips all the time and use them directly via
    177                 <code>!keywords</code> within your search query. Serĉi uses
    178                 your favorite search engine as fallback, whenever you do not
    179                 provide a keyword.
    180             </p>
    181             <a href="#engines" class="button">
    182                 Explore
    183             </a>
    184             <a href="#faqs" class="button">
    185                 Learn more
    186             </a>
    187         </div>
    188 
    189         <!-- Search Engine Lists -->
    190         <h3 id="engines">Available Search Engines</h3>
    191 
    192         <p>
    193             This serĉi instance supports
    194             <mark><?php echo count($searches); ?> search engines</mark> within
    195             <mark><?php echo count($categories); ?> categories</mark> and
    196             <mark><?php echo count($searchkeys); ?> keywords</mark>.
    197         </p>
    198 
    199         <!-- Search Engine Filterbar -->
    200         <input
    201             id="engines_filterbar"
    202             name="engines"
    203             type="text"
    204             placeholder="Filter available Search Engines..."
    205             oninput="filter_engines('engines_filterbar');"
    206         >
    207         <noscript>
    208             <div class="notice">
    209                 <p>
    210                     Exploring the available search engines with the filter bar
    211                     above as well as choosing your fallback search engine
    212                     requires javascript.
    213                     <strong>However, using serĉi itself does not</strong>!
    214                 </p>
    215                 <p>
    216                     Read the <a href="#faqs">FAQs</a> on how to choose a
    217                     fallback search engine when javascript or cookies are
    218                     disabled.
    219                 </p>
    220             </div>
    221         </noscript>
    222 
    223         <!-- Search Engine Category Buttons -->
    224         <details id="categories">
    225             <summary>Categories</summary>
    226             
    227             <div class="row">
    228             
    229                 <!-- Always insert a "Fallback" category button -->
    230                 <button
    231                     onclick="filter_category('Fallback');"
    232                     title="Search Engine that is choosen as fallback"
    233                 >
    234                     #Fallback
    235                 </button>
    236 
    237                 <!-- List all configured categories -->
    238                 <?php
    239                     foreach (array_keys($categories) as $cid) {
    240                         $cat_name = $categories[$cid]["name"];
    241                 ?>
    242                 <button
    243                     onclick="filter_category('<?php echo $cat_name; ?>');"
    244                     title="<?php echo $categories[$cid]["description"]; ?>"
    245                 >
    246                     <?php echo "#" . $cat_name; ?>
    247                 </button>
    248                 <?php
    249                     }
    250                 ?>
    251 
    252             </div>
    253 
    254         </details>
    255 
    256         <!-- Search Engine List -->
    257         <?php
    258             foreach (array_keys($searches) as $sid) {
    259                 $search = $searches[$sid];
    260         ?>
    261         <article
    262             id="<?php echo $sid; ?>"
    263             class="<?php if ($sid == $fallback) { echo "selected"; }?>"
    264         >
    265             <!-- Entry-Head -->
    266             <h3>
    267                 <a href="<?php echo $search["website"]; ?>" target="_blank">
    268                     <?php echo $search["name"]; ?>
    269                 </a>
    270             </h3>
    271 
    272             <!-- Entry-Description -->
    273             <p><?php echo $search["description"]; ?></p>
    274 
    275             <!-- Entry-Categories -->
    276             <div class="categories">
    277 
    278                 <?php
    279                     /* If current entry is the fallback search, add the Mark */
    280                     if ($sid == $fallback) {
    281                 ?>
    282                 <mark id="fallback_marker">#Fallback</mark>
    283                 <?php
    284                     }
    285                 ?>
    286 
    287                 <?php
    288                     /* List all categories of current entry */
    289                     foreach ($search["categories"] as $cid) {
    290                 ?>
    291                 <mark title="<?php echo $categories[$cid]["description"];?>">
    292                     <?php echo "#" . $categories[$cid]["name"]; ?>
    293                 </mark>
    294                 <?php
    295                     }
    296                 ?>
    297 
    298             </div>
    299 
    300             <!-- Entry-Keywords -->
    301             <strong>Keywords: </strong>
    302             <code>
    303                 <?php
    304                     echo "!" .
    305                         implode(
    306                             "</code><code>!",
    307                             $search["keywords"]
    308                         );
    309                 ?>
    310             </code>
    311             <br><br>
    312 
    313             <!-- "Make-Fallback" Button -->
    314             <button onclick="make_fallback('<?php echo $sid; ?>')">
    315                 Choose as fallback
    316             </button>
    317 
    318         </article>
    319         <?php
    320             }
    321         ?>
    322 
    323         <!-- FAQs / About-Section -->
    324         <section id="faqs">
    325 
    326             <?php
    327                 /* Random entry from search array: used within examples below */
    328                 $rsi = array_rand($searches, 1);
    329             ?>
    330 
    331             <h3>About serĉi</h3>
    332 
    333             <!-- meaning of name -->
    334             <details>
    335                 <summary>What does serĉi mean?</summary>
    336                 <p>
    337                     It is the Esperanto term for "to search".This may not be the
    338                     most creative name for such a software project but to the
    339                     best of my knowledge, it is a unique one.
    340                 </p>
    341             </details>
    342 
    343             <!-- what are keywords -->
    344             <details>
    345                 <summary>What are keywords?</summary>
    346                 <p>
    347                     An idea lent from the search Engine
    348                     <a href="https://duckduckgo.com/bangs" target="_blank">
    349                         DuckDuckGo
    350                     </a>, which has been utilized by many others since. They
    351                     call their keywords bangs, but it is the same concept and
    352                     usability. In essence, keywords are shortcuts for searching
    353                     on other websites.
    354                 </p>
    355                 <p>
    356                     For example, you can conduct a search on the website 
    357                     <a
    358                         href="<?php echo $searches[$rsi]["website"]; ?>"
    359                         target="_blank"
    360                     >
    361                         <?php echo $searches[$rsi]["name"]; ?>
    362                     </a>
    363                     directly from <?php echo $_SERVER["SERVER_NAME"]; ?> by
    364                     adding the keyword
    365                     <code>!<?php echo $searches[$rsi]["keywords"][0]; ?></code>
    366                     to your search query.
    367                 </p>
    368                 <p>
    369                     You can find all keywords associated with each search engine
    370                     in the <a href="#engines">list above</a>.
    371                 </p>
    372             </details>
    373 
    374             <!-- how to use -->
    375             <details>
    376                 <summary>How can I use serĉi?</summary>
    377                 <p>
    378                     You can try serĉi directly
    379                     <a href="#searchbar">on this site</a> or
    380                     <a
    381                         href="https://src.jayvii.de/pub/serci/#hosting"
    382                         target="_blank"
    383                     >
    384                         host it yourself
    385                     </a>!
    386                     It barely needs any server resources, no database or lots of
    387                     RAM. serĉi has minimal footprint (also on user data: there
    388                     are <strong>none</strong>).
    389                 </p>
    390                 <p>
    391                     Either type your search directly into the
    392                     <a href="#searchbar">search bar at the very top</a>
    393                     or add the search to your browser by rightclicking in the
    394                     URL-bar of your web browser and choose
    395                     <emph>add serĉi - Search with !keywords</emph>.
    396                 </p>
    397                 <p>
    398                     Some browsers (for example Firefox on Android / Fennec)
    399                     allow to configure custom search engines via a so-called
    400                     search URL. Simply list following URL as
    401                     <emph>search-URL</emph> there and choose it as your fallback
    402                     search option:
    403                 </p>
    404                 <pre>https://<?php echo $_SERVER["SERVER_NAME"]; ?>/?q=%s</pre>
    405                 <p>
    406                     You can also choose the fallback search engine, used by
    407                     serĉi as fallback, when no keyword is given, through the URL
    408                     instead of choosing it from the
    409                     <a href="#engines">list above</a>, in case you do not want
    410                     serĉi to store any cookie on your device. For example, if
    411                     you wanted to use
    412                     <a
    413                         href="<?php echo $searches[$rsi]["website"]; ?>"
    414                         target="_blank"
    415                     >
    416                         <?php echo $searches[$rsi]["name"]; ?>
    417                     </a>
    418                     as your fallback search, you could use following search-URL:
    419                 </p>
    420                 <pre><?php
    421                     echo "https://" . $_SERVER["SERVER_NAME"] .
    422                         "/?fallback=" . $rsi . "&q=%s";
    423                 ?></pre>
    424             </details>
    425 
    426             <!-- no js or cookies -->
    427             <details>
    428                 <summary>
    429                     Choosing a fallback search without cookies or Javascript
    430                 </summary>
    431                 <p>
    432                     You can simply choose a fallback search by adding the
    433                     <code>fallback</code> URL parameter. For example, if you
    434                     wanted to use
    435                     <a
    436                         href="<?php echo $searches[$rsi]["website"]; ?>"
    437                         target="_blank"
    438                     >
    439                         <?php echo $searches[$rsi]["name"]; ?>
    440                     </a>
    441                     as your fallback search, you can simply add
    442                     <code>/?fallback=<?php echo $rsi; ?></code> to the serĉi
    443                     URL:
    444                     <br>
    445                     <a href="/?fallback=<?php echo $rsi; ?>">
    446                         <?php
    447                             echo "https://" . $_SERVER["SERVER_NAME"] .
    448                                 "/?fallback=" . $rsi;
    449                         ?>
    450                     </a>
    451                 </p>
    452             </details>
    453 
    454         </section>
    455 
    456     </body>
    457 
    458 </html>