some work on meta tags
This commit is contained in:
parent
eba9cd46df
commit
05fb6fbffb
@ -95,9 +95,48 @@ function add_static(string ...$files): void {
|
||||
$SkinState->static[] = $file;
|
||||
}
|
||||
|
||||
function add_meta(array ...$data) {
|
||||
function add_meta(array $data) {
|
||||
global $SkinState;
|
||||
$SkinState->meta = array_merge($SkinState->meta, $data);
|
||||
static $twitter_limits = [
|
||||
'title' => 70,
|
||||
'description' => 200
|
||||
];
|
||||
$real_meta = [];
|
||||
$add_og_twitter = function($key, $value) use (&$real_meta, $twitter_limits) {
|
||||
foreach (['og', 'twitter'] as $social) {
|
||||
if ($social == 'twitter' && isset($twitter_limits[$key])) {
|
||||
if (mb_strlen($value) > $twitter_limits[$key])
|
||||
$value = mb_substr($value, 0, $twitter_limits[$key]-3).'...';
|
||||
}
|
||||
$real_meta[] = [
|
||||
$social == 'twitter' ? 'name' : 'property' => $social.':'.$key,
|
||||
'content' => $value
|
||||
];
|
||||
}
|
||||
};
|
||||
foreach ($data as $key => $value) {
|
||||
switch ($key) {
|
||||
case '$url':
|
||||
case '$title':
|
||||
case '$image':
|
||||
$add_og_twitter(substr($key, 1), $value);
|
||||
break;
|
||||
|
||||
case '$description':
|
||||
$add_og_twitter(substr($key, 1), $value);
|
||||
$real_meta[] = ['name' => 'description', 'content' => $value];
|
||||
break;
|
||||
|
||||
default:
|
||||
if (str_starts_with($key, 'og:')) {
|
||||
$real_meta[] = ['property' => $key, 'content' => $value];
|
||||
} else {
|
||||
logWarning("unsupported meta: $key => $value");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
$SkinState->meta = array_merge($SkinState->meta, $real_meta);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3,6 +3,15 @@
|
||||
class MainHandler extends request_handler {
|
||||
|
||||
function GET_index() {
|
||||
global $config;
|
||||
add_meta([
|
||||
'og:type' => 'website',
|
||||
'$url' => 'https://'.$config['domain'].'/',
|
||||
'$title' => lang('meta_index_title'),
|
||||
'$description' => lang('meta_index_description'),
|
||||
'$image' => 'https://'.$config['domain'].'/img/4in1-preview.jpg'
|
||||
]);
|
||||
|
||||
set_title('$site_title');
|
||||
set_skin_opts(['is_index' => true]);
|
||||
render('main/index');
|
||||
@ -77,18 +86,13 @@ class MainHandler extends request_handler {
|
||||
$other_langs[] = $pl->value;
|
||||
}
|
||||
|
||||
add_meta(
|
||||
['property' => 'og:title', 'content' => $pt->title],
|
||||
['property' => 'og:url', 'content' => $config['domain'].$post->getUrl()]
|
||||
);
|
||||
if (($img = $pt->getFirstImage()) !== null)
|
||||
add_meta(['property' => 'og:image', 'content' => $img->getDirectUrl()]);
|
||||
|
||||
add_meta([
|
||||
'name' => 'description',
|
||||
'property' => 'og:description',
|
||||
'content' => $pt->getDescriptionPreview(155)
|
||||
'$title' => $pt->title,
|
||||
'$url', $config['domain'].$post->getUrl(),
|
||||
'$description' => $pt->getDescriptionPreview(155)
|
||||
]);
|
||||
if (($img = $pt->getFirstImage()) !== null)
|
||||
add_meta(['$image' => $img->getDirectUrl()]);
|
||||
|
||||
set_skin_opts(['articles_lang' => $lang->value]);
|
||||
|
||||
|
BIN
htdocs/img/4in1-preview.jpg
Normal file
BIN
htdocs/img/4in1-preview.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
@ -29,7 +29,7 @@ return <<<HTML
|
||||
<link rel="alternate" type="application/rss+xml" href="/feed.rss">
|
||||
<title>{$title}</title>
|
||||
<script type="text/javascript">window.appConfig = {$app_config};</script>
|
||||
{$ctx->renderMeta($meta)}
|
||||
{$ctx->meta($meta)}
|
||||
{$ctx->renderStatic($static, $theme)}
|
||||
</head>
|
||||
<body{$ctx->if_true($body_class, ' class="'.implode(' ', $body_class).'"')}>
|
||||
@ -100,7 +100,7 @@ ThemeSwitcher.init();
|
||||
HTML;
|
||||
}
|
||||
|
||||
function renderMeta($ctx, $meta) {
|
||||
function meta($ctx, $meta) {
|
||||
if (empty($meta))
|
||||
return '';
|
||||
return implode('', array_map(function(array $item): string {
|
||||
@ -108,6 +108,7 @@ function renderMeta($ctx, $meta) {
|
||||
foreach ($item as $k => $v)
|
||||
$s .= ' '.htmlescape($k).'="'.htmlescape($v).'"';
|
||||
$s .= '>';
|
||||
$s .= "\n";
|
||||
return $s;
|
||||
}, $meta));
|
||||
}
|
||||
|
@ -20,6 +20,10 @@ toc: 'Table of Contents'
|
||||
lang_en: "English"
|
||||
lang_ru: "Русский"
|
||||
|
||||
# meta
|
||||
meta_index_title: "4in1. Mask of Shakespeare, mysteries of Bacon, book by Cartier, secrets of the NSA"
|
||||
meta_index_description: "This is the official web site of the book \"4in1\". The book has emerged as an outcome of many years of journalistic investigations, published as a series of articles over the last few years on the kiwi arXiv website."
|
||||
|
||||
# blog
|
||||
blog_new_post: "New post"
|
||||
blog_view_post: "View post"
|
||||
|
Loading…
x
Reference in New Issue
Block a user