feat(fonts): allow PageTitle to have its own font subset (#1848)
* fix(explorer): vertically center the Explorer toggle under mobile view * Added a separate title font configuration * Added googleSubFontHref function * Applied --titleFont to PageTitle * Made googleFontHref return array of URLs * Dealing with empty and undefined title * Minor update * Dealing with empty and undefined title * Refined font inclusion logic * Adopted the googleFontHref + googleFontSubsetHref method * Adaptively include font subset for PageTitle * Restored default config * Minor changes on configuration docs * Formatted source code
This commit is contained in:
		
							parent
							
								
									9818e1ad57
								
							
						
					
					
						commit
						25979ab216
					
				| @ -41,11 +41,12 @@ This part of the configuration concerns anything that can affect the whole site. | |||||||
| - `ignorePatterns`: a list of [glob](<https://en.wikipedia.org/wiki/Glob_(programming)>) patterns that Quartz should ignore and not search through when looking for files inside the `content` folder. See [[private pages]] for more details. | - `ignorePatterns`: a list of [glob](<https://en.wikipedia.org/wiki/Glob_(programming)>) patterns that Quartz should ignore and not search through when looking for files inside the `content` folder. See [[private pages]] for more details. | ||||||
| - `defaultDateType`: whether to use created, modified, or published as the default date to display on pages and page listings. | - `defaultDateType`: whether to use created, modified, or published as the default date to display on pages and page listings. | ||||||
| - `theme`: configure how the site looks. | - `theme`: configure how the site looks. | ||||||
|   - `cdnCaching`: If `true` (default), use Google CDN to cache the fonts. This will generally will be faster. Disable (`false`) this if you want Quartz to download the fonts to be self-contained. |   - `cdnCaching`: if `true` (default), use Google CDN to cache the fonts. This will generally be faster. Disable (`false`) this if you want Quartz to download the fonts to be self-contained. | ||||||
|   - `typography`: what fonts to use. Any font available on [Google Fonts](https://fonts.google.com/) works here. |   - `typography`: what fonts to use. Any font available on [Google Fonts](https://fonts.google.com/) works here. | ||||||
|     - `header`: Font to use for headers |     - `title`: font for the title of the site (optional, same as `header` by default) | ||||||
|     - `code`: Font for inline and block quotes. |     - `header`: font to use for headers | ||||||
|     - `body`: Font for everything |     - `code`: font for inline and block quotes | ||||||
|  |     - `body`: font for everything | ||||||
|   - `colors`: controls the theming of the site. |   - `colors`: controls the theming of the site. | ||||||
|     - `light`: page background |     - `light`: page background | ||||||
|     - `lightgray`: borders |     - `lightgray`: borders | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { i18n } from "../i18n" | import { i18n } from "../i18n" | ||||||
| import { FullSlug, getFileExtension, joinSegments, pathToRoot } from "../util/path" | import { FullSlug, getFileExtension, joinSegments, pathToRoot } from "../util/path" | ||||||
| import { CSSResourceToStyleElement, JSResourceToScriptElement } from "../util/resources" | import { CSSResourceToStyleElement, JSResourceToScriptElement } from "../util/resources" | ||||||
| import { googleFontHref } from "../util/theme" | import { googleFontHref, googleFontSubsetHref } from "../util/theme" | ||||||
| import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" | import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" | ||||||
| import { unescapeHTML } from "../util/escape" | import { unescapeHTML } from "../util/escape" | ||||||
| import { CustomOgImagesEmitterName } from "../plugins/emitters/ogImage" | import { CustomOgImagesEmitterName } from "../plugins/emitters/ogImage" | ||||||
| @ -45,6 +45,9 @@ export default (() => { | |||||||
|             <link rel="preconnect" href="https://fonts.googleapis.com" /> |             <link rel="preconnect" href="https://fonts.googleapis.com" /> | ||||||
|             <link rel="preconnect" href="https://fonts.gstatic.com" /> |             <link rel="preconnect" href="https://fonts.gstatic.com" /> | ||||||
|             <link rel="stylesheet" href={googleFontHref(cfg.theme)} /> |             <link rel="stylesheet" href={googleFontHref(cfg.theme)} /> | ||||||
|  |             {cfg.theme.typography.title && ( | ||||||
|  |               <link rel="stylesheet" href={googleFontSubsetHref(cfg.theme, cfg.pageTitle)} /> | ||||||
|  |             )} | ||||||
|           </> |           </> | ||||||
|         )} |         )} | ||||||
|         <link rel="preconnect" href="https://cdnjs.cloudflare.com" crossOrigin="anonymous" /> |         <link rel="preconnect" href="https://cdnjs.cloudflare.com" crossOrigin="anonymous" /> | ||||||
|  | |||||||
| @ -17,6 +17,7 @@ PageTitle.css = ` | |||||||
| .page-title { | .page-title { | ||||||
|   font-size: 1.75rem; |   font-size: 1.75rem; | ||||||
|   margin: 0; |   margin: 0; | ||||||
|  |   font-family: var(--titleFont); | ||||||
| } | } | ||||||
| ` | ` | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -9,7 +9,12 @@ import styles from "../../styles/custom.scss" | |||||||
| import popoverStyle from "../../components/styles/popover.scss" | import popoverStyle from "../../components/styles/popover.scss" | ||||||
| import { BuildCtx } from "../../util/ctx" | import { BuildCtx } from "../../util/ctx" | ||||||
| import { QuartzComponent } from "../../components/types" | import { QuartzComponent } from "../../components/types" | ||||||
| import { googleFontHref, joinStyles, processGoogleFonts } from "../../util/theme" | import { | ||||||
|  |   googleFontHref, | ||||||
|  |   googleFontSubsetHref, | ||||||
|  |   joinStyles, | ||||||
|  |   processGoogleFonts, | ||||||
|  | } from "../../util/theme" | ||||||
| import { Features, transform } from "lightningcss" | import { Features, transform } from "lightningcss" | ||||||
| import { transform as transpile } from "esbuild" | import { transform as transpile } from "esbuild" | ||||||
| import { write } from "./helpers" | import { write } from "./helpers" | ||||||
| @ -211,9 +216,16 @@ export const ComponentResources: QuartzEmitterPlugin = () => { | |||||||
|         // let the user do it themselves in css
 |         // let the user do it themselves in css
 | ||||||
|       } else if (cfg.theme.fontOrigin === "googleFonts" && !cfg.theme.cdnCaching) { |       } else if (cfg.theme.fontOrigin === "googleFonts" && !cfg.theme.cdnCaching) { | ||||||
|         // when cdnCaching is true, we link to google fonts in Head.tsx
 |         // when cdnCaching is true, we link to google fonts in Head.tsx
 | ||||||
|         const response = await fetch(googleFontHref(ctx.cfg.configuration.theme)) |         const theme = ctx.cfg.configuration.theme | ||||||
|  |         const response = await fetch(googleFontHref(theme)) | ||||||
|         googleFontsStyleSheet = await response.text() |         googleFontsStyleSheet = await response.text() | ||||||
| 
 | 
 | ||||||
|  |         if (theme.typography.title) { | ||||||
|  |           const title = ctx.cfg.configuration.pageTitle | ||||||
|  |           const response = await fetch(googleFontSubsetHref(theme, title)) | ||||||
|  |           googleFontsStyleSheet += `\n${await response.text()}` | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         if (!cfg.baseUrl) { |         if (!cfg.baseUrl) { | ||||||
|           throw new Error( |           throw new Error( | ||||||
|             "baseUrl must be defined when using Google Fonts without cfg.theme.cdnCaching", |             "baseUrl must be defined when using Google Fonts without cfg.theme.cdnCaching", | ||||||
|  | |||||||
| @ -25,6 +25,7 @@ export type FontSpecification = | |||||||
| 
 | 
 | ||||||
| export interface Theme { | export interface Theme { | ||||||
|   typography: { |   typography: { | ||||||
|  |     title?: FontSpecification | ||||||
|     header: FontSpecification |     header: FontSpecification | ||||||
|     body: FontSpecification |     body: FontSpecification | ||||||
|     code: FontSpecification |     code: FontSpecification | ||||||
| @ -48,7 +49,10 @@ export function getFontSpecificationName(spec: FontSpecification): string { | |||||||
|   return spec.name |   return spec.name | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function formatFontSpecification(type: "header" | "body" | "code", spec: FontSpecification) { | function formatFontSpecification( | ||||||
|  |   type: "title" | "header" | "body" | "code", | ||||||
|  |   spec: FontSpecification, | ||||||
|  | ) { | ||||||
|   if (typeof spec === "string") { |   if (typeof spec === "string") { | ||||||
|     spec = { name: spec } |     spec = { name: spec } | ||||||
|   } |   } | ||||||
| @ -82,12 +86,19 @@ function formatFontSpecification(type: "header" | "body" | "code", spec: FontSpe | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function googleFontHref(theme: Theme) { | export function googleFontHref(theme: Theme) { | ||||||
|   const { code, header, body } = theme.typography |   const { header, body, code } = theme.typography | ||||||
|   const headerFont = formatFontSpecification("header", header) |   const headerFont = formatFontSpecification("header", header) | ||||||
|   const bodyFont = formatFontSpecification("body", body) |   const bodyFont = formatFontSpecification("body", body) | ||||||
|   const codeFont = formatFontSpecification("code", code) |   const codeFont = formatFontSpecification("code", code) | ||||||
| 
 | 
 | ||||||
|   return `https://fonts.googleapis.com/css2?family=${bodyFont}&family=${headerFont}&family=${codeFont}&display=swap` |   return `https://fonts.googleapis.com/css2?family=${headerFont}&family=${bodyFont}&family=${codeFont}&display=swap` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export function googleFontSubsetHref(theme: Theme, text: string) { | ||||||
|  |   const title = theme.typography.title || theme.typography.header | ||||||
|  |   const titleFont = formatFontSpecification("title", title) | ||||||
|  | 
 | ||||||
|  |   return `https://fonts.googleapis.com/css2?family=${titleFont}&text=${encodeURIComponent(text)}&display=swap` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export interface GoogleFontFile { | export interface GoogleFontFile { | ||||||
| @ -135,6 +146,7 @@ ${stylesheet.join("\n\n")} | |||||||
|   --highlight: ${theme.colors.lightMode.highlight}; |   --highlight: ${theme.colors.lightMode.highlight}; | ||||||
|   --textHighlight: ${theme.colors.lightMode.textHighlight}; |   --textHighlight: ${theme.colors.lightMode.textHighlight}; | ||||||
| 
 | 
 | ||||||
|  |   --titleFont: "${getFontSpecificationName(theme.typography.title || theme.typography.header)}", ${DEFAULT_SANS_SERIF}; | ||||||
|   --headerFont: "${getFontSpecificationName(theme.typography.header)}", ${DEFAULT_SANS_SERIF}; |   --headerFont: "${getFontSpecificationName(theme.typography.header)}", ${DEFAULT_SANS_SERIF}; | ||||||
|   --bodyFont: "${getFontSpecificationName(theme.typography.body)}", ${DEFAULT_SANS_SERIF}; |   --bodyFont: "${getFontSpecificationName(theme.typography.body)}", ${DEFAULT_SANS_SERIF}; | ||||||
|   --codeFont: "${getFontSpecificationName(theme.typography.code)}", ${DEFAULT_MONO}; |   --codeFont: "${getFontSpecificationName(theme.typography.code)}", ${DEFAULT_MONO}; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user