}[] */ protected array $tags = []; protected string $rawContent = ''; #[Override] public function __toString(): string { helper('misc'); $this ->tag('meta', null, [ 'charset' => 'UTF-8', ]) ->meta('viewport', 'width=device-width, initial-scale=1.0') ->tag('link', null, [ 'rel' => 'icon', 'type' => 'image/x-icon', 'href' => get_site_icon_url('ico'), ]) ->tag('link', null, [ 'rel' => 'apple-touch-icon', 'href' => get_site_icon_url('180'), ]) ->tag('link', null, [ 'rel' => 'manifest', // @phpstan-ignore-next-line 'href' => isset($podcast) ? route_to('podcast-webmanifest', esc($podcast->handle)) : route_to( 'webmanifest', ), ]) ->meta( 'theme-color', WebmanifestController::THEME_COLORS[service('settings')->get('App.theme')]['theme'], ) ->tag('link', null, [ 'rel' => 'stylesheet', 'type' => 'text/css', 'href' => route_to('themes-colors-css'), ]) ->appendRawContent(<< // Check that service workers are supported if ('serviceWorker' in navigator) { // Use the window load event to keep the page load performant window.addEventListener('load', () => { navigator.serviceWorker.register('/assets/sw.js'); }); } HTML); if ($this->title) { $this->tag('title', esc($this->title)); } if (url_is(route_to('admin') . '*') || url_is(base_url(config('Auth')->gateway) . '*')) { // restricted admin and auth areas, do not index $this->meta('robots', 'noindex'); } else { // public website, set siteHead hook only there service('plugins') ->siteHead($this); } $head = '
'; foreach ($this->tags as $tag) { if ($tag['value'] === null) { $head .= <<stringify_attributes($tag['attributes'])}/> HTML; } else { $head .= <<stringify_attributes($tag['attributes'])}>{$tag['value']}{$tag['name']}> HTML; } } $head .= $this->rawContent . ''; // reset head for next render $this->title = null; $this->tags = []; $this->rawContent = ''; return $head; } public function title(string $title): self { $this->title = $title; return $this->meta('title', $title) ->og('title', $title) ->twitter('title', $title); } public function description(string $desc): self { return $this->meta('description', $desc) ->og('description', $desc) ->twitter('description', $desc); } public function image(string $url, string $card = 'summary_large_image'): self { return $this->og('image', $url) ->twitter('card', $card) ->twitter('image', $url); } public function canonical(string $url): self { return $this->tag('link', null, [ 'rel' => 'canonical', 'href' => $url, ]); } public function twitter(string $name, string $value): self { $this->meta("twitter:{$name}", $value); return $this; } /** * @param array