og:image: prave dimenzije naslovnice namesto fiksnih 1200x630 (slike so 1200x900); nadomestni logotip zdaj 1200x675, prej 1050x630 pod Googlovim minimumom; opozorilo v log, ko clanek nima naslovnice
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 141 KiB |
+38
-2
@@ -2,11 +2,41 @@ import express, { type Express } from "express";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { storage } from "./storage";
|
||||
import sharp from "sharp";
|
||||
|
||||
function escapeHtml(str: string): string {
|
||||
return str.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
||||
}
|
||||
|
||||
// Dejanske dimenzije naslovnice. Prej sta bili sirina in visina v meta
|
||||
// oznakah fiksno zapisani kot 1200x630, slike pa so v resnici 1200x900 —
|
||||
// Facebook in Google sta dobila napacno vrednost. Ce dimenzij ne moremo
|
||||
// prebrati, oznak raje ne zapisemo.
|
||||
const ogDimCache = new Map<string, { w: number; h: number } | null>();
|
||||
|
||||
async function ogImageDims(imgUrl: string, publicDir: string) {
|
||||
if (ogDimCache.has(imgUrl)) return ogDimCache.get(imgUrl) ?? null;
|
||||
let dims: { w: number; h: number } | null = null;
|
||||
try {
|
||||
const m = /\/(uploads|images)\/([^/?#]+)$/.exec(imgUrl);
|
||||
if (m) {
|
||||
const cand = [
|
||||
path.join(publicDir, m[1], m[2]),
|
||||
path.join(publicDir, m[1], m[2].replace(/\.jpg$/, ".webp")),
|
||||
];
|
||||
for (const p of cand) {
|
||||
if (!fs.existsSync(p)) continue;
|
||||
const meta = await sharp(p).metadata();
|
||||
if (meta.width && meta.height) { dims = { w: meta.width, h: meta.height }; break; }
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
dims = null;
|
||||
}
|
||||
ogDimCache.set(imgUrl, dims);
|
||||
return dims;
|
||||
}
|
||||
|
||||
function ogImageUrl(coverImage: string, baseUrl: string): string {
|
||||
if (!coverImage) return "";
|
||||
let imgPath = coverImage;
|
||||
@@ -173,6 +203,10 @@ export function serveStatic(app: Express) {
|
||||
const articleUrl = `${canonicalBase}/article/${article.slug}`;
|
||||
const imageUrl = ogImageUrl(article.coverImage || "", canonicalBase);
|
||||
const finalImage = imageUrl || `${canonicalBase}/og-image.jpg`;
|
||||
const articleImgDims = await ogImageDims(finalImage, distPath);
|
||||
if (!imageUrl) {
|
||||
console.warn(`[og] clanek brez naslovnice, pada na logotip: ${article.slug}`);
|
||||
}
|
||||
|
||||
let template = await fs.promises.readFile(indexPath, "utf-8");
|
||||
template = stripExistingMeta(template);
|
||||
@@ -249,8 +283,10 @@ export function serveStatic(app: Express) {
|
||||
`<meta property="og:url" content="${escapeHtml(articleUrl)}" />`,
|
||||
`<meta property="og:image" content="${escapeHtml(finalImage)}" />`,
|
||||
`<meta property="og:image:secure_url" content="${escapeHtml(finalImage)}" />`,
|
||||
`<meta property="og:image:width" content="1200" />`,
|
||||
`<meta property="og:image:height" content="630" />`,
|
||||
...(articleImgDims
|
||||
? [`<meta property="og:image:width" content="${articleImgDims.w}" />`,
|
||||
`<meta property="og:image:height" content="${articleImgDims.h}" />`]
|
||||
: []),
|
||||
`<meta property="og:image:type" content="image/jpeg" />`,
|
||||
`<meta property="og:site_name" content="Folx Music Television" />`,
|
||||
`<meta property="og:locale" content="de_DE" />`,
|
||||
|
||||
Reference in New Issue
Block a user