diff --git a/core/basepage.php b/core/basepage.php index 9aa89091..29371e4a 100644 --- a/core/basepage.php +++ b/core/basepage.php @@ -6,7 +6,7 @@ namespace Shimmie2; use MicroHTML\HTMLElement; -use function MicroHTML\{emptyHTML,rawHTML,HTML,HEAD,BODY}; +use function MicroHTML\{emptyHTML,rawHTML,HTML,HEAD,BODY,TITLE, LINK, SCRIPT}; require_once "core/event.php"; @@ -131,7 +131,7 @@ class BasePage public string $subheading = ""; public bool $left_enabled = true; - /** @var string[] */ + /** @var HTMLElement[] */ public array $html_headers = []; /** @var string[] */ @@ -179,17 +179,6 @@ class BasePage $this->left_enabled = false; } - /** - * Add a line to the HTML head section. - */ - public function add_html_header(string $line, int $position = 50): void - { - while (isset($this->html_headers[$position])) { - $position++; - } - $this->html_headers[$position] = $line; - } - /** * Add a http header to be sent to the client. */ @@ -222,17 +211,26 @@ class BasePage } } + /** + * Add a line to the HTML head section. + */ + public function add_html_header(HTMLElement $line, int $position = 50): void + { + while (isset($this->html_headers[$position])) { + $position++; + } + $this->html_headers[$position] = $line; + } + /** * Get all the HTML headers that are currently set and return as a string. */ - public function get_all_html_headers(): string + public function get_all_html_headers(): HTMLElement { - $data = ''; ksort($this->html_headers); - foreach ($this->html_headers as $line) { - $data .= "\t\t" . $line . "\n"; - } - return $data; + return emptyHTML( + ...$this->html_headers + ); } /** @@ -384,8 +382,15 @@ class BasePage $theme_name = $config->get_string(SetupConfig::THEME, 'default'); # static handler will map these to themes/foo/static/bar.ico or ext/static_files/static/bar.ico - $this->add_html_header("", 41); - $this->add_html_header("", 42); + $this->add_html_header(LINK([ + 'rel' => 'icon', + 'type' => 'image/x-icon', + 'href' => "$data_href/favicon.ico" + ]), 41); + $this->add_html_header(LINK([ + 'rel' => 'apple-touch-icon', + 'href' => "$data_href/apple-touch-icon.png" + ]), 42); //We use $config_latest to make sure cache is reset if config is ever updated. $config_latest = 0; @@ -394,13 +399,24 @@ class BasePage } $css_cache_file = $this->get_css_cache_file($theme_name, $config_latest); - $this->add_html_header("", 43); + $this->add_html_header(LINK([ + 'rel' => 'stylesheet', + 'href' => "$data_href/$css_cache_file", + 'type' => 'text/css' + ]), 43); $initjs_cache_file = $this->get_initjs_cache_file($theme_name, $config_latest); - $this->add_html_header("", 44); + $this->add_html_header(SCRIPT([ + 'src' => "$data_href/$initjs_cache_file", + 'type' => 'text/javascript' + ])); $js_cache_file = $this->get_js_cache_file($theme_name, $config_latest); - $this->add_html_header("", 44); + $this->add_html_header(SCRIPT([ + 'defer' => true, + 'src' => "$data_href/$js_cache_file", + 'type' => 'text/javascript' + ])); } private function get_css_cache_file(string $theme_name, int $config_latest): string @@ -549,10 +565,15 @@ class BasePage */ public function render(): void { - global $config, $user; + print (string)$this->html_html( + $this->head_html(), + $this->body_html() + ); + } - $head = $this->head_html(); - $body = $this->body_html(); + public function html_html(HTMLElement $head, string|HTMLElement $body): HTMLElement + { + global $user; $body_attrs = [ "data-userclass" => $user->class->name, @@ -560,24 +581,22 @@ class BasePage "data-base-link" => make_link(""), ]; - print emptyHTML( + return emptyHTML( rawHTML(""), HTML( ["lang" => "en"], - HEAD(rawHTML($head)), - BODY($body_attrs, rawHTML($body)) + HEAD($head), + BODY($body_attrs, rawHTML((string)$body)) ) ); } - protected function head_html(): string + protected function head_html(): HTMLElement { - $html_header_html = $this->get_all_html_headers(); - - return " - {$this->title} - $html_header_html - "; + return emptyHTML( + TITLE($this->title), + $this->get_all_html_headers(), + ); } protected function body_html(): string diff --git a/core/basethemelet.php b/core/basethemelet.php index 07b93bf6..2daefd7d 100644 --- a/core/basethemelet.php +++ b/core/basethemelet.php @@ -6,7 +6,7 @@ namespace Shimmie2; use MicroHTML\HTMLElement; -use function MicroHTML\{A,B,BR,IMG,emptyHTML,joinHTML}; +use function MicroHTML\{A,B,BR,IMG,emptyHTML,joinHTML,LINK}; /** * Class BaseThemelet @@ -112,15 +112,15 @@ class BaseThemelet $body = $this->build_paginator($page_number, $total_pages, $base, $query, $show_random); $page->add_block(new Block(null, $body, "main", 90, "paginator")); - $page->add_html_header(""); + $page->add_html_header(LINK(['rel' => 'first', 'href' => make_link($base.'/1', $query)])); if ($page_number < $total_pages) { - $page->add_html_header(""); - $page->add_html_header(""); + $page->add_html_header(LINK(['rel' => 'prefetch', 'href' => make_link($base.'/'.($page_number + 1), $query)])); + $page->add_html_header(LINK(['rel' => 'next', 'href' => make_link($base.'/'.($page_number + 1), $query)])); } if ($page_number > 1) { - $page->add_html_header(""); + $page->add_html_header(LINK(['rel' => 'previous', 'href' => make_link($base.'/'.($page_number - 1), $query)])); } - $page->add_html_header(""); + $page->add_html_header(LINK(['rel' => 'last', 'href' => make_link($base.'/'.$total_pages, $query)])); } private function gen_page_link(string $base_url, ?string $query, int $page, string $name): HTMLElement diff --git a/ext/browser_search/main.php b/ext/browser_search/main.php index 74a5e971..5ca67efc 100644 --- a/ext/browser_search/main.php +++ b/ext/browser_search/main.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Shimmie2; +use function MicroHTML\LINK; + class BrowserSearch extends Extension { public function onInitExt(InitExtEvent $event): void @@ -20,7 +22,12 @@ class BrowserSearch extends Extension // We need to build the data for the header $search_title = $config->get_string(SetupConfig::TITLE); $search_file_url = make_link('browser_search.xml'); - $page->add_html_header(""); + $page->add_html_header(LINK([ + 'rel' => 'search', + 'type' => 'application/opensearchdescription+xml', + 'title' => $search_title, + 'href' => $search_file_url + ])); // The search.xml file that is generated on the fly if ($event->page_matches("browser_search.xml")) { diff --git a/ext/custom_html_headers/main.php b/ext/custom_html_headers/main.php index 87f90033..97509523 100644 --- a/ext/custom_html_headers/main.php +++ b/ext/custom_html_headers/main.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Shimmie2; +use function MicroHTML\rawHTML; + class CustomHtmlHeaders extends Extension { # Adds setup block for custom content @@ -44,7 +46,7 @@ class CustomHtmlHeaders extends Extension $header = $config->get_string('custom_html_headers', ''); if ($header != '') { - $page->add_html_header($header); + $page->add_html_header(rawHTML($header)); } } diff --git a/ext/downtime/theme.php b/ext/downtime/theme.php index b0298b50..8ac365b2 100644 --- a/ext/downtime/theme.php +++ b/ext/downtime/theme.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Shimmie2; +use function MicroHTML\{emptyHTML, TITLE, LINK}; + class DowntimeTheme extends Themelet { /** @@ -30,45 +32,40 @@ class DowntimeTheme extends Themelet $login_link = make_link("user_admin/login"); $form = make_form($login_link); + $head = emptyHTML( + TITLE("Downtime"), + LINK(["rel" => "stylesheet", "href" => "$data_href/themes/$theme_name/style.css", "type" => "text/css"]) + ); + $body = << +
+

Down for Maintenance

+
+ $message +
+
+
+

Admin Login

+
+ $form + + + + + + + + + + +
+ +
+
+ +EOD; $page->set_mode(PageMode::DATA); $page->set_code(503); - $page->set_data( - << - - Downtime - - - -
-
-

Down for Maintenance

-
- $message -
-
-
-

Admin Login

-
- $form - - - - - - - - - - -
- -
-
-
- - -EOD - ); + $page->set_data((string)$page->html_html($head, $body)); } } diff --git a/ext/emoticons_list/theme.php b/ext/emoticons_list/theme.php index 5d770d70..fdab1e93 100644 --- a/ext/emoticons_list/theme.php +++ b/ext/emoticons_list/theme.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Shimmie2; +use function MicroHTML\TITLE; + class EmoticonListTheme extends Themelet { /** @@ -13,19 +15,21 @@ class EmoticonListTheme extends Themelet { global $page; $data_href = get_base_href(); - $html = "Emoticon list"; - $html .= ""; + $body = "
"; $n = 1; foreach ($list as $item) { $name = pathinfo($item, PATHINFO_FILENAME); - $html .= ""; + $body .= ""; if ($n++ % 3 == 0) { - $html .= ""; + $body .= ""; } } - $html .= "
$name :$name:$name :$name:
"; - $html .= ""; + $body .= ""; + $page->set_mode(PageMode::DATA); - $page->set_data($html); + $page->set_data((string)$page->html_html( + TITLE("Emoticon list"), + $body + )); } } diff --git a/ext/filter/main.php b/ext/filter/main.php index 1735b13c..88f5f2aa 100644 --- a/ext/filter/main.php +++ b/ext/filter/main.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Shimmie2; +use function MicroHTML\SCRIPT; + class Filter extends Extension { /** @var FilterTheme */ @@ -19,10 +21,10 @@ class Filter extends Extension { global $page; $this->theme->addFilterBox(); - $page->add_html_header(""); + });")); } public function onSetupBuilding(SetupBuildingEvent $event): void diff --git a/ext/filter/theme.php b/ext/filter/theme.php index 53206d14..1db59f1d 100644 --- a/ext/filter/theme.php +++ b/ext/filter/theme.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Shimmie2; +use function MicroHTML\{META}; + class FilterTheme extends Themelet { public function addFilterBox(): void @@ -21,7 +23,7 @@ class FilterTheme extends Themelet "; - $page->add_html_header(""); + $page->add_html_header(META(['id' => 'filter-tags', 'tags' => $tags])); $page->add_block(new Block("Filters", $html, "left", 10)); } } diff --git a/ext/google_analytics/main.php b/ext/google_analytics/main.php index ee7cd278..c39c9875 100644 --- a/ext/google_analytics/main.php +++ b/ext/google_analytics/main.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Shimmie2; +use function MicroHTML\SCRIPT; + class GoogleAnalytics extends Extension { # Add analytics to config @@ -21,15 +23,16 @@ class GoogleAnalytics extends Extension $google_analytics_id = $config->get_string('google_analytics_id', ''); if (stristr($google_analytics_id, "UA-")) { - $page->add_html_header(""); + $page->add_html_header(SCRIPT(["type" => 'text/javascript'], " + var _gaq = _gaq || []; + _gaq.push(['_setAccount', '$google_analytics_id']); + _gaq.push(['_trackPageview']); + (function() { + var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; + ga.src = ('https:' === document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; + var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); + })(); + ")); } } } diff --git a/ext/handle_mp3/theme.php b/ext/handle_mp3/theme.php index ea94094c..20257d34 100644 --- a/ext/handle_mp3/theme.php +++ b/ext/handle_mp3/theme.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Shimmie2; +use function MicroHTML\{SCRIPT}; + class MP3FileHandlerTheme extends Themelet { public function display_image(Image $image): void @@ -20,7 +22,10 @@ class MP3FileHandlerTheme extends Themelet

Download"; - $page->add_html_header(""); + $page->add_html_header(SCRIPT([ + 'src' => "$data_href/ext/handle_mp3/lib/jsmediatags.min.js", + 'type' => 'text/javascript' + ])); $page->add_block(new Block("Music", $html, "main", 10)); } } diff --git a/ext/holiday/main.php b/ext/holiday/main.php index b1c8fe45..594f0304 100644 --- a/ext/holiday/main.php +++ b/ext/holiday/main.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Shimmie2; +use function MicroHTML\LINK; + class Holiday extends Extension { public function onInitExt(InitExtEvent $event): void @@ -22,9 +24,11 @@ class Holiday extends Extension { global $config, $page; if (date('d/m') == '01/04' && $config->get_bool("holiday_aprilfools")) { - $page->add_html_header( - "" - ); + $page->add_html_header(LINK([ + 'rel' => 'stylesheet', + 'href' => get_base_href() . '/ext/holiday/stylesheets/aprilfools.css', + 'type' => 'text/css' + ])); } } } diff --git a/ext/home/theme.php b/ext/home/theme.php index 574e7eb4..81942424 100644 --- a/ext/home/theme.php +++ b/ext/home/theme.php @@ -4,29 +4,24 @@ declare(strict_types=1); namespace Shimmie2; +use function MicroHTML\{emptyHTML, TITLE, META, rawHTML}; + class HomeTheme extends Themelet { public function display_page(Page $page, string $sitename, string $base_href, string $theme_name, string $body): void { $page->set_mode(PageMode::DATA); $page->add_auto_html_headers(); - $hh = $page->get_all_html_headers(); - $page->set_data( - << - - - $sitename - - - $hh - - - $body - - -EOD - ); + + $page->set_data((string)$page->html_html( + emptyHTML( + TITLE($sitename), + META(["http-equiv" => "Content-Type", "content" => "text/html;charset=utf-8"]), + META(["name" => "viewport", "content" => "width=device-width, initial-scale=1"]), + $page->get_all_html_headers(), + ), + $body + )); } public function build_body(string $sitename, string $main_links, string $main_text, string $contact_link, string $num_comma, string $counter_text): string diff --git a/ext/image/main.php b/ext/image/main.php index 089dd217..d60724ec 100644 --- a/ext/image/main.php +++ b/ext/image/main.php @@ -8,7 +8,7 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\{InputInterface,InputArgument}; use Symfony\Component\Console\Output\OutputInterface; -use function MicroHTML\{INPUT, emptyHTML}; +use function MicroHTML\{INPUT, emptyHTML, STYLE}; require_once "config.php"; @@ -86,7 +86,7 @@ class ImageIO extends Extension $thumb_width = $config->get_int(ImageConfig::THUMB_WIDTH, 192); $thumb_height = $config->get_int(ImageConfig::THUMB_HEIGHT, 192); - $page->add_html_header(""); + $page->add_html_header(STYLE(":root {--thumb-width: {$thumb_width}px; --thumb-height: {$thumb_height}px;}")); if ($event->page_matches("image/delete", method: "POST", permission: Permissions::DELETE_IMAGE)) { global $page, $user; diff --git a/ext/index/theme.php b/ext/index/theme.php index 4e10960b..ec869c33 100644 --- a/ext/index/theme.php +++ b/ext/index/theme.php @@ -7,7 +7,7 @@ namespace Shimmie2; use MicroHTML\HTMLElement; use function MicroHTML\emptyHTML; -use function MicroHTML\{BR,H3,HR,P}; +use function MicroHTML\{BR,H3,HR,P,META}; class IndexTheme extends Themelet { @@ -176,7 +176,7 @@ and of course start organising your images :-) if (count($this->search_terms) > 0) { if ($this->page_number > 3) { // only index the first pages of each term - $page->add_html_header(''); + $page->add_html_header(META(["name" => "robots", "content" => "noindex, nofollow"])); } $query = url_escape(Tag::implode($this->search_terms)); $page->add_block(new Block("Posts", $this->build_table($images, "#search=$query"), "main", 10, "image-list")); diff --git a/ext/notes/theme.php b/ext/notes/theme.php index 5743a4db..f8908ac4 100644 --- a/ext/notes/theme.php +++ b/ext/notes/theme.php @@ -6,7 +6,7 @@ namespace Shimmie2; use MicroHTML\HTMLElement; -use function MicroHTML\INPUT; +use function MicroHTML\{INPUT,SCRIPT}; /** * @phpstan-type NoteHistory array{image_id:int,note_id:int,review_id:int,user_name:string,note:string,date:string} @@ -61,12 +61,15 @@ class NotesTheme extends Themelet 'note_id' => $note["id"], ]; } - $page->add_html_header(""); + $page->add_html_header(SCRIPT( + ["type" => "text/javascript"], + " + window.notes = ".\Safe\json_encode($to_json)."; + window.notes_image_id = $image_id; + window.notes_admin = ".($adminOptions ? "true" : "false")."; + window.notes_edit = ".($editOptions ? "true" : "false")."; + " + )); } /** diff --git a/ext/regen_thumb/theme.php b/ext/regen_thumb/theme.php index 89b84750..12c50d98 100644 --- a/ext/regen_thumb/theme.php +++ b/ext/regen_thumb/theme.php @@ -4,7 +4,7 @@ declare(strict_types=1); namespace Shimmie2; -use function MicroHTML\INPUT; +use function MicroHTML\META; class RegenThumbTheme extends Themelet { @@ -15,7 +15,7 @@ class RegenThumbTheme extends Themelet { $page->set_title("Thumbnail Regenerated"); $page->set_heading("Thumbnail Regenerated"); - $page->add_html_header(""); + $page->add_html_header(META(['http-equiv' => 'cache-control', 'content' => 'no-cache'])); $page->add_block(new NavBlock()); $page->add_block(new Block("Thumbnail", $this->build_thumb_html($image))); } diff --git a/ext/rss_comments/main.php b/ext/rss_comments/main.php index e274a15c..14a616c6 100644 --- a/ext/rss_comments/main.php +++ b/ext/rss_comments/main.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Shimmie2; +use function MicroHTML\LINK; + class RSSComments extends Extension { public function onPostListBuilding(PostListBuildingEvent $event): void @@ -11,8 +13,12 @@ class RSSComments extends Extension global $config, $page; $title = $config->get_string(SetupConfig::TITLE); - $page->add_html_header(""); + $page->add_html_header(LINK([ + 'rel' => 'alternate', + 'type' => 'application/rss+xml', + 'title' => "$title - Comments", + 'href' => make_link("rss/comments") + ])); } public function onPageRequest(PageRequestEvent $event): void diff --git a/ext/rss_images/main.php b/ext/rss_images/main.php index 85d8ce8d..b08ada39 100644 --- a/ext/rss_images/main.php +++ b/ext/rss_images/main.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Shimmie2; +use function MicroHTML\{LINK}; + class RSSImages extends Extension { public function onPostListBuilding(PostListBuildingEvent $event): void @@ -13,11 +15,19 @@ class RSSImages extends Extension if (count($event->search_terms) > 0) { $search = url_escape(Tag::implode($event->search_terms)); - $page->add_html_header(""); + $page->add_html_header(LINK([ + 'rel' => 'alternate', + 'type' => 'application/rss+xml', + 'title' => "$title - Posts with tags: $search", + 'href' => make_link("rss/images/$search/1") + ])); } else { - $page->add_html_header(""); + $page->add_html_header(LINK([ + 'rel' => 'alternate', + 'type' => 'application/rss+xml', + 'title' => "$title - Posts", + 'href' => make_link("rss/images/1") + ])); } } diff --git a/ext/site_description/main.php b/ext/site_description/main.php index fe2961cc..55b14a9a 100644 --- a/ext/site_description/main.php +++ b/ext/site_description/main.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Shimmie2; +use function MicroHTML\{META}; + class SiteDescription extends Extension { public function onPageRequest(PageRequestEvent $event): void @@ -11,11 +13,17 @@ class SiteDescription extends Extension global $config, $page; if (!empty($config->get_string("site_description"))) { $description = $config->get_string("site_description"); - $page->add_html_header(""); + $page->add_html_header(META([ + 'name' => 'description', + 'content' => $description + ])); } if (!empty($config->get_string("site_keywords"))) { $keywords = $config->get_string("site_keywords"); - $page->add_html_header(""); + $page->add_html_header(META([ + 'name' => 'keywords', + 'content' => $keywords + ])); } } diff --git a/ext/site_description/test.php b/ext/site_description/test.php index b2af0dbf..c28359aa 100644 --- a/ext/site_description/test.php +++ b/ext/site_description/test.php @@ -12,8 +12,8 @@ class SiteDescriptionTest extends ShimmiePHPUnitTestCase $config->set_string("site_description", "A Shimmie testbed"); $this->get_page("post/list"); $this->assertStringContainsString( - '', - $page->get_all_html_headers() + "", + (string)$page->get_all_html_headers() ); } @@ -23,8 +23,8 @@ class SiteDescriptionTest extends ShimmiePHPUnitTestCase $config->set_string("site_keywords", "foo,bar,baz"); $this->get_page("post/list"); $this->assertStringContainsString( - '', - $page->get_all_html_headers() + "", + (string)$page->get_all_html_headers() ); } } diff --git a/ext/terms/theme.php b/ext/terms/theme.php index 4f592fde..1cc554e1 100644 --- a/ext/terms/theme.php +++ b/ext/terms/theme.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Shimmie2; +use function MicroHTML\{emptyHTML, TITLE, META, rawHTML}; + class TermsTheme extends Themelet { public function display_page(Page $page, string $sitename, string $path, string $body): void diff --git a/ext/user/main.php b/ext/user/main.php index bd7d8ee0..22323cc3 100644 --- a/ext/user/main.php +++ b/ext/user/main.php @@ -18,7 +18,7 @@ use MicroCRUD\TextColumn; use MicroCRUD\DateColumn; use MicroCRUD\Table; -use function MicroHTML\A; +use function MicroHTML\{A, STYLE}; class UserNameColumn extends TextColumn { @@ -160,9 +160,9 @@ class UserPage extends Extension $this->show_user_info(); if ($user->can(Permissions::VIEW_HELLBANNED)) { - $page->add_html_header(""); + $page->add_html_header(STYLE("DIV.hb, TR.hb TD {border: 1px solid red !important;}")); } elseif (!$user->can(Permissions::HELLBANNED)) { - $page->add_html_header(""); + $page->add_html_header(STYLE(".hb {display: none !important;}")); } if ($event->page_matches("user_admin/login", method: "GET")) { diff --git a/ext/view/theme.php b/ext/view/theme.php index 800ef830..544645a4 100644 --- a/ext/view/theme.php +++ b/ext/view/theme.php @@ -6,7 +6,7 @@ namespace Shimmie2; use MicroHTML\HTMLElement; -use function MicroHTML\{A, joinHTML, TABLE, TR, TD, INPUT, emptyHTML, DIV, BR}; +use function MicroHTML\{A, joinHTML, TABLE, TR, TD, INPUT, emptyHTML, DIV, BR, META, LINK}; class ViewPostTheme extends Themelet { @@ -14,12 +14,12 @@ class ViewPostTheme extends Themelet { global $page; - $h_metatags = str_replace(" ", ", ", html_escape($image->get_tag_list())); - $page->add_html_header(""); - $page->add_html_header(""); - $page->add_html_header(""); - $page->add_html_header("get_thumb_link())."\">"); - $page->add_html_header("id}"))."\">"); + $h_metatags = str_replace(" ", ", ", $image->get_tag_list()); + $page->add_html_header(META(["name" => "keywords", "content" => $h_metatags])); + $page->add_html_header(META(["property" => "og:title", "content" => $h_metatags])); + $page->add_html_header(META(["property" => "og:type", "content" => "article"])); + $page->add_html_header(META(["property" => "og:image", "content" => make_http($image->get_thumb_link())])); + $page->add_html_header(META(["property" => "og:url", "content" => make_http(make_link("post/view/{$image->id}"))])); } /** @@ -38,8 +38,8 @@ class ViewPostTheme extends Themelet $query = $this->get_query(); if(!$this->is_ordered_search()) { - $page->add_html_header(""); - $page->add_html_header(""); + $page->add_html_header(LINK(["id" => "nextlink", "rel" => "next", "href" => make_link("post/next/{$image->id}", $query)])); + $page->add_html_header(LINK(["id" => "prevlink", "rel" => "previous", "href" => make_link("post/prev/{$image->id}", $query)])); } }