diff options
author | Christian Cleberg <hello@cleberg.net> | 2023-05-31 20:58:43 -0500 |
---|---|---|
committer | Christian Cleberg <hello@cleberg.net> | 2023-05-31 20:58:43 -0500 |
commit | 468bc55ada06979e53b1d03b040b2dfe6beaf017 (patch) | |
tree | 472b23c050ab8ce7d1ae1cab30bcb37ebfe031e5 | |
download | hn-468bc55ada06979e53b1d03b040b2dfe6beaf017.tar.gz hn-468bc55ada06979e53b1d03b040b2dfe6beaf017.tar.bz2 hn-468bc55ada06979e53b1d03b040b2dfe6beaf017.zip |
initial commit
-rw-r--r-- | LICENSE | 24 | ||||
-rw-r--r-- | README.md | 5 | ||||
-rw-r--r-- | index.php | 112 | ||||
-rw-r--r-- | src/View/class-template.php | 39 | ||||
-rw-r--r-- | templates/template.html | 37 |
5 files changed, 217 insertions, 0 deletions
@@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to <http://unlicense.org/> diff --git a/README.md b/README.md new file mode 100644 index 0000000..de3700d --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# hn + +[hn](https://hn.cleberg.net) is a simple front-end alternative for Hacker News. +hn focuses on the links shared on Hacker News, currently leaving out an options +to login or view comments. diff --git a/index.php b/index.php new file mode 100644 index 0000000..f5f7438 --- /dev/null +++ b/index.php @@ -0,0 +1,112 @@ +<?php + +$full_domain = 'https://hn.cleberg.net'; +$path = ltrim($_SERVER['REQUEST_URI'], '/'); +$elements = explode('/', $path); + +if (empty($elements[0])) { + get_stories( + 'https://hacker-news.firebaseio.com/v0/topstories.json?limitToFirst=30&orderBy="$key"', + 'Top' + ); + echo_html( + $GLOBALS['full_domain'] . '/best/', + 'The top 30 stories from Hacker News. Proxied by hn.', + 'hn', + $html_output + ); +} else { + switch (array_shift($elements)) { + case 'top': + get_stories( + 'https://hacker-news.firebaseio.com/v0/topstories.json?limitToFirst=30&orderBy="$key"', + 'Top' + ); + echo_html( + $GLOBALS['full_domain'] . '/best/', + 'The top 30 stories from Hacker News. Proxied by hn.', + 'hn', + $html_output + ); + break; + + case 'best': + echo 'best'; + break; + + case 'new': + echo 'new'; + break; + + case 'ask': + echo 'ask'; + break; + + case 'show': + echo 'show'; + break; + + case 'job': + echo 'job'; + break; + + default: + header('HTTP/1.1 404 Not Found'); + } +} + +/** + * Extract a set of stories from Hacker News API and format in HTML + * + * @access public + * @author cmc <hello@cleberg.net> + * @param string $api_url The API endpoint to use for extraction + * @param string $inline_title The <h1> title to use in the HTML + * @return string $html_output The formatted HTML result of stories from the API + */ +function get_stories($api_url, $inline_title) +{ + $response_raw = file_get_contents($api_url); + $response = json_decode($response_raw, true); + + $html_output = '<h1>' . $inline_title . '</h1>'; + + for ($i = 0; $i < count($response); $i++) { + $sub_url = 'https://hacker-news.firebaseio.com/v0/item/' . $response[$i] . '.json'; + $sub_response_raw = file_get_contents($sub_url); + $sub_response = json_decode($sub_response_raw, true); + + $html = '<div><a href="' . $sub_response['url'] . '">' . $sub_response['title'] . '</a>'; + $html .= '<p><time datetime="' . date('Y-m-d h:m:s', $sub_response['time']) . '">'; + $html .= date('Y-m-d h:m:s', $sub_response['time']) . '</time> by '; + $html .= $sub_response['by'] . ' | ' . $sub_response['score'] . ' points</p></div>'; + $html_output .= $html; + } + + return $html_output; +} + +/** + * Send formatted HTML results to the user via a template + * + * @access public + * @author cmc <hello@cleberg.net> + * @param string $page_url Canoncial URL for HTML header + * @param string $page_description Page description for HTML header + * @param string $page_title Page title for HTML header + * @param string $page_content Page content to display in <main> + */ +function echo_html(string $page_url, string $page_description, string $page_title, string $page_content) { + include_once '_classes/template.php'; + + $template = new HN\View\Template( + $page_url, + $page_description, + $page_title, + $page_content + ); + + $template->echo_template(); +} + +// EOF diff --git a/src/View/class-template.php b/src/View/class-template.php new file mode 100644 index 0000000..ea75648 --- /dev/null +++ b/src/View/class-template.php @@ -0,0 +1,39 @@ +<?php + +namespace HN\View; + +/** + * Template View + * + * @author cmc <hello@cleberg.net> + */ +class Template +{ + public function __construct(string $canonical_url, string $page_description, string $page_title, string $content_col) + { + $this->canonical_url = $canonical_url; + $this->description = $page_description; + $this->title = $page_title; + $this->content = $content_col; + $this->current_year = date("Y"); + } + + public function echo_template() + { + // Get the template file + $template_file = 'templates/template.html'; + $page = file_get_contents($template_file); + + // Replace the template variables + $page = str_replace('{page_title}', $this->title, $page); + $page = str_replace('{page_description}', $this->description, $page); + $page = str_replace('{canonical_url}', $this->canonical_url, $page); + $page = str_replace('{content}', $this->content, $page); + $page = str_replace('{current_year}', $this->current_year, $page); + + // Echo the filled-out template + echo $page; + } +} + +// EOF diff --git a/templates/template.html b/templates/template.html new file mode 100644 index 0000000..638562a --- /dev/null +++ b/templates/template.html @@ -0,0 +1,37 @@ +<!doctype html> +<html lang="en"> + +<head> + <title>{page_title}</title> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + <meta http-equiv="x-ua-compatible" content="ie=edge"> + <meta name="author" content="My Name"> + <meta name="description" content="{page_description}"> + <link rel="canonical" href="{canoncial_url}"> + <link rel="icon" href="/favicon.ico"> + <link rel="stylesheet" href="/static/styles.css"> +</head> + +<body> +<main id="main"> + <nav class="links"> + <span><a href="/">Top</a> · </span> + <span><a href="/best/">Best</a> ·</span> + <span><a href="/new/">New</a> ·</span> + <span><a href="/ask/">Ask</a> ·</span> + <span><a href="/show/">Show</a> ·</span> + <span><a href="/job/">Job</a></span> + </nav> + {content} +</main> + +<footer> + <h2>Contact</h2> + <p><a href="https://sr.ht/~cmc/hn/"></a></p> + <p>Copyright © 2023 - {current_year}</p> +</footer> + +</body> + +</html> |