1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2025-04-26 04:45:22 -04:00

fix post title encoding

This commit is contained in:
Jake Jarvis 2025-03-14 15:08:00 -04:00
parent 3932660acc
commit 6e572a8f48
Signed by: jake
SSH Key Fingerprint: SHA256:nCkvAjYA6XaSPUqc4TfbBQTpzr8Xj7ritg/sGInCdkc
7 changed files with 29 additions and 12 deletions

View File

@ -1,6 +1,6 @@
import Image from "next/image";
import clsx from "clsx";
import Link from "../Link";
import Image from "../Image";
import Menu from "../Menu";
import * as config from "../../lib/config";
import { MAX_WIDTH } from "../../lib/config/constants";

View File

@ -0,0 +1,5 @@
.image {
display: block;
margin: 1em auto;
max-width: 100%;
}

View File

@ -1,11 +1,14 @@
import NextImage from "next/image";
import clsx from "clsx";
import { MAX_WIDTH } from "../../lib/config/constants";
import type { ComponentPropsWithoutRef } from "react";
import type { StaticImageData } from "next/image";
import styles from "./Image.module.css";
export type ImageProps = ComponentPropsWithoutRef<typeof NextImage>;
const Image = ({ src, height, width, quality, placeholder, style, ...rest }: ImageProps) => {
const Image = ({ src, height, width, placeholder, className, ...rest }: ImageProps) => {
const constrainWidth = (width?: number | `${number}`) => {
if (!width) return MAX_WIDTH;
@ -16,16 +19,11 @@ const Image = ({ src, height, width, quality, placeholder, style, ...rest }: Ima
src,
height,
width: constrainWidth(width || (src as StaticImageData).width),
quality: quality || 75,
placeholder: placeholder || (typeof src === "string" ? "empty" : "blur"),
style: {
height: "auto",
...style,
},
...rest,
};
return <NextImage {...imageProps} />;
return <NextImage className={clsx(styles.image, className)} {...imageProps} />;
};
export default Image;

View File

@ -3,7 +3,7 @@ export const siteName = "Jake Jarvis";
export const siteLocale = "en-US";
export const timeZone = "America/New_York"; // https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
export const onionDomain = "jarvis2i2vp4j4tbxjogsnqdemnte5xhzyi7hziiyzxwge3hzmh57zad.onion";
export const shortDescription = "Front-End Web Developer in Boston; MA";
export const shortDescription = "Front-End Web Developer in Boston, MA";
export const longDescription =
"Hi there! I'm a frontend web developer based in Boston, Massachusetts specializing in the JAMstack, modern JavaScript frameworks, and progressive web apps.";
export const license = "Creative Commons Attribution 4.0 International";

View File

@ -2,6 +2,7 @@ import path from "path";
import glob from "fast-glob";
import pMap from "p-map";
import pMemoize from "p-memoize";
import { decode } from "html-entities";
import { formatDate } from "./format-date";
import { BASE_URL, POSTS_DIR } from "../config/constants";
@ -32,7 +33,7 @@ export const getFrontMatter = async (slug: string): Promise<FrontMatter> => {
// allow *very* limited markdown to be used in post titles
const parseTitle = async (title: string, allowedTags: string[] = []): Promise<string> => {
return String(
const newTitle = (
await unified()
.use(remarkParse)
.use(remarkSmartypants, {
@ -45,7 +46,10 @@ export const getFrontMatter = async (slug: string): Promise<FrontMatter> => {
.use(rehypeSanitize, { tagNames: allowedTags })
.use(rehypeStringify)
.process(title)
);
).toString();
// assume if we don't want any html titles then we don't want encoded html entities either
return allowedTags.length === 0 ? decode(newTitle) : newTitle;
};
// process title as both plain and stylized
@ -57,8 +61,9 @@ export const getFrontMatter = async (slug: string): Promise<FrontMatter> => {
// return both the parsed YAML front matter (with a few amendments) and the raw, unparsed markdown content
return {
...(frontmatter as Partial<FrontMatter>),
// zero markdown title:
// plain title without html or markdown syntax:
title,
// stylized title with limited html tags:
htmlTitle,
slug,
date: formatDate(frontmatter.date), // validate/normalize the date string provided from front matter

View File

@ -35,6 +35,7 @@
"fast-glob": "^3.3.3",
"feed": "^4.2.2",
"geist": "^1.3.1",
"html-entities": "^2.5.2",
"lucide-react": "0.481.0",
"modern-normalize": "^3.0.1",
"next": "15.3.0-canary.8",

8
pnpm-lock.yaml generated
View File

@ -59,6 +59,9 @@ importers:
geist:
specifier: ^1.3.1
version: 1.3.1(next@15.3.0-canary.8(react-dom@19.0.0(react@19.0.0))(react@19.0.0))
html-entities:
specifier: ^2.5.2
version: 2.5.2
lucide-react:
specifier: 0.481.0
version: 0.481.0(react@19.0.0)
@ -1944,6 +1947,9 @@ packages:
resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==}
engines: {node: ^16.14.0 || >=18.0.0}
html-entities@2.5.2:
resolution: {integrity: sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==}
html-escaper@2.0.2:
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
@ -5542,6 +5548,8 @@ snapshots:
dependencies:
lru-cache: 10.4.3
html-entities@2.5.2: {}
html-escaper@2.0.2: {}
html-tags@3.3.1: {}