pub / serci

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

index.php (15877B)


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