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 fs from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { storage } from "./storage";
|
import { storage } from "./storage";
|
||||||
|
import sharp from "sharp";
|
||||||
|
|
||||||
function escapeHtml(str: string): string {
|
function escapeHtml(str: string): string {
|
||||||
return str.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
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 {
|
function ogImageUrl(coverImage: string, baseUrl: string): string {
|
||||||
if (!coverImage) return "";
|
if (!coverImage) return "";
|
||||||
let imgPath = coverImage;
|
let imgPath = coverImage;
|
||||||
@@ -173,6 +203,10 @@ export function serveStatic(app: Express) {
|
|||||||
const articleUrl = `${canonicalBase}/article/${article.slug}`;
|
const articleUrl = `${canonicalBase}/article/${article.slug}`;
|
||||||
const imageUrl = ogImageUrl(article.coverImage || "", canonicalBase);
|
const imageUrl = ogImageUrl(article.coverImage || "", canonicalBase);
|
||||||
const finalImage = imageUrl || `${canonicalBase}/og-image.jpg`;
|
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");
|
let template = await fs.promises.readFile(indexPath, "utf-8");
|
||||||
template = stripExistingMeta(template);
|
template = stripExistingMeta(template);
|
||||||
@@ -249,8 +283,10 @@ export function serveStatic(app: Express) {
|
|||||||
`<meta property="og:url" content="${escapeHtml(articleUrl)}" />`,
|
`<meta property="og:url" content="${escapeHtml(articleUrl)}" />`,
|
||||||
`<meta property="og:image" content="${escapeHtml(finalImage)}" />`,
|
`<meta property="og:image" content="${escapeHtml(finalImage)}" />`,
|
||||||
`<meta property="og:image:secure_url" content="${escapeHtml(finalImage)}" />`,
|
`<meta property="og:image:secure_url" content="${escapeHtml(finalImage)}" />`,
|
||||||
`<meta property="og:image:width" content="1200" />`,
|
...(articleImgDims
|
||||||
`<meta property="og:image:height" content="630" />`,
|
? [`<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:image:type" content="image/jpeg" />`,
|
||||||
`<meta property="og:site_name" content="Folx Music Television" />`,
|
`<meta property="og:site_name" content="Folx Music Television" />`,
|
||||||
`<meta property="og:locale" content="de_DE" />`,
|
`<meta property="og:locale" content="de_DE" />`,
|
||||||
|
|||||||
Reference in New Issue
Block a user