Skip to content

Commit 7d4a6d6

Browse files
committed
Add copyright notice with QRCode on print
1 parent 77d04fa commit 7d4a6d6

16 files changed

Lines changed: 305 additions & 132 deletions

File tree

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@
422422
"vmax",
423423
"VNIC",
424424
"vtbot",
425+
"WAAPI",
425426
"WHATWG",
426427
"Wolters",
427428
"wordprocessingml",

_TODO.md

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,27 @@ For printed pages, your header should shift from a navigation tool to a document
1010
- Brand Identity: A high-contrast version of your logo or the site name in plain text for brand recognition.
1111
- Document Title: The main title of the page (usually the <h1>), ensuring the reader knows exactly what the document is.
1212

13+
```css
14+
@bottom-center {
15+
content: "Page " counter(page) " of " counter(pages);
16+
font-family: Arial, sans-serif;
17+
font-size: 10pt;
18+
color: #000;
19+
}
20+
21+
@bottom-left {
22+
content: "Company Name";
23+
font-size: 9pt;
24+
color: #000;
25+
}
26+
27+
@bottom-right {
28+
content: "Confidential";
29+
font-size: 9pt;
30+
color: #000;
31+
}
32+
```
33+
1334
## PDF File Generation
1435

1536
- Need a workflow to generate PDF files from Markdown for downloads.
@@ -24,8 +45,6 @@ Paged.js Polyfill: Use the Paged.js library to handle sophisticated print layout
2445

2546
[Paged.js](https://pagedjs.org/en/documentation/) polyfills `@page` properties, and lays out an HTML document in print format where it can have page numbers generated to update in a table of contents.
2647

27-
This article has different approaches to [print pagination](https://www.customjs.space/blog/html-print-pagination-footer/). One approach overlaps with PagedJS's approach.
28-
2948
- Headers and Footers (Native Support)
3049

3150
Puppeteer can inject dynamic data into your headers and footers using specific CSS classes. To use this, you must set `displayHeaderFooter: true` in the `page.pdf()` options.
@@ -75,8 +94,6 @@ if (window.matchMedia) {
7594
}
7695
```
7796

78-
[This article](https://excessivelyadequate.com/posts/print.html) shows how to control the following properties in Chrome's Print Properties dialog box from CSS: Layout, Paper size, Margins, Headers and footers, and Background graphics. Headers and footers is the checkbox that by default is enabled and adds information on printed pages. It also shows how to use Chrome from the terminal in headless mode to output a PDF file from an HTML page.
79-
8097
Handling Dynamic Content
8198

8299
If your page fetches data (like an API call) that needs to be visible in the print, the load event might fire before your data arrives. In that case, you should call `print()` only after your data-fetching logic completes:

astro.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ const standardIntegrations = [
105105
})] : []),
106106
sitemap({
107107
serialize: createSerializeFunction({
108-
exclude: ['deep-dive', 'downloads', '/articles/demo', 'testing', 'hero', 'links'],
108+
exclude: ['deep-dive', 'downloads', 'pdf', '/articles/demo', 'testing', 'hero', 'links'],
109109
}),
110110
}),
111111
/**

src/components/Footer/index.astro

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ const footerTextLinkClasses = [
6161
].join(' ')
6262
---
6363

64-
<site-footer class="print:hidden!" transition:persist>
64+
<site-footer transition:persist>
6565
<footer class="w-full bg-page-offset mt-6 pt-4" role="contentinfo">
6666
<div
6767
id="footer-inner"
@@ -79,18 +79,22 @@ const footerTextLinkClasses = [
7979
<div class="mr-3 w-16">
8080
<Avatar name="Kevin Brown" />
8181
</div>
82+
{/* Mobile: company name */}
8283
<h2 class="font-bold text-2xl sm:hidden">{contactData.company.name}</h2>
8384
</div>
85+
{/* Address and Phone Numbers Block */}
8486
<address class="mt-3 text-base sm:mt-0">
85-
{/* Desktop: show company name here */}
87+
{/* Desktop: company name */}
8688
<h2 class="hidden font-bold text-2xl sm:block">{contactData.company.name}</h2>
89+
{/* Street Address */}
8790
<div class="mt-2 sm:ml-1">
8891
<p>{contactData.company.address}</p>
8992
<p>
9093
{contactData.company.city}, {contactData.company.state}
9194
{contactData.company.index}
9295
</p>
9396
</div>
97+
{/* Email Address */}
9498
<p class="hyphens-none">
9599
<a
96100
href={`mailto:${contactData.company.email}`}
@@ -103,6 +107,7 @@ const footerTextLinkClasses = [
103107
{contactData.company.email}
104108
</a>
105109
</p>
110+
{/* Toll Free Telephone Number */}
106111
<p itemprop="telephone">
107112
<a
108113
href={`tel:${contactData.company.telephoneTollFree}`}
@@ -116,6 +121,7 @@ const footerTextLinkClasses = [
116121
Toll Free {formatPhoneNumber(contactData.company.telephoneTollFree)}
117122
</a>
118123
</p>
124+
{/* Local Telephone Number */}
119125
<p itemprop="telephone">
120126
<a
121127
href={`tel:${contactData.company.telephoneLocal}`}
@@ -133,7 +139,11 @@ const footerTextLinkClasses = [
133139
</div>
134140

135141
{/* "Hire Me" block with current month and year set by script */}
136-
<div class:list={[styles.footerHireMe, 'hidden lg:block lg:self-end lg:mt-8']}>
142+
<div class:list={[
143+
styles.footerHireMe,
144+
'hidden lg:block lg:self-end lg:mt-8',
145+
'print:hidden!',
146+
]}>
137147
<a
138148
href="/contact"
139149
id="page-footer__hire-me-anchor"
@@ -149,7 +159,7 @@ const footerTextLinkClasses = [
149159
</div>
150160

151161
{/* Page footer Social Share links */}
152-
<nav class:list={["mt-5", styles.footerSocial]} aria-label="Social links">
162+
<nav class:list={["mt-5", styles.footerSocial, 'print:hidden!']} aria-label="Social links">
153163
<ul class="grid list-none gap-x-4 gap-y-3 p-0 sm:mb-0 sm:mt-0 sm:mx-0 lg:grid-cols-2">
154164
{
155165
contactData.company.social
@@ -187,6 +197,7 @@ const footerTextLinkClasses = [
187197
styles.footerBottomRow,
188198
'mt-4 px-1 pt-4 pb-3 sm:p-0',
189199
'lg:pl-8',
200+
'print:hidden!',
190201
]}
191202
>
192203
<div class="grid grid-cols-2 gap-x-4 gap-y-3 lg:grid-cols-1">

src/components/Header/index.astro

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ import './index.css'
1919

2020
{/* Hidden modal shown when theme picker icon selected - moved to BaseLayout for persistence */}
2121
{/* Header for all pages */}
22-
<div class="header-shell print:hidden!">
22+
<div class="header-shell">
2323
<div class="header-footprint print:hidden!" aria-hidden="true"></div>
24-
<div class="header-fixed print:hidden!">
24+
<div class="header-fixed">
2525
<header
2626
id="header"
2727
data-header-search-open="false"
28-
class="print:hidden! site-header group/header flex flex-row items-center justify-between relative"
28+
class="site-header group/header flex flex-row items-center justify-between relative"
2929
role="banner"
3030
>
3131
{/*- Element for animated background behind mobile navigation menu -*/}
@@ -54,15 +54,15 @@ import './index.css'
5454
{/* Theme picker toggle button to show modal */}
5555
<span
5656
id="header__theme-icon"
57-
class="header-icon order-3 lg:order-4 ml-2 mr-2 block shrink-0 w-(--header-icon-size) h-(--header-icon-size) relative z-(--z-content-overlay)"
57+
class="header-icon order-3 lg:order-4 ml-2 mr-2 block shrink-0 w-(--header-icon-size) h-(--header-icon-size) relative z-(--z-content-overlay) print:hidden!"
5858
>
5959
<ThemeButton />
6060
</span>
6161

6262
{/* Header search icon that expands left into a search panel */}
6363
<span
6464
id="header__search-icon"
65-
class="header-icon order-4 lg:order-5 mr-2 lg:mr-0 block shrink-0 w-(--header-icon-size) h-(--header-icon-size) relative z-(--z-content-overlay) group-data-[header-search-open=true]/header:z-(--z-modal) lg:z-(--z-nav)"
65+
class="header-icon order-4 lg:order-5 mr-2 lg:mr-0 block shrink-0 w-(--header-icon-size) h-(--header-icon-size) relative z-(--z-content-overlay) group-data-[header-search-open=true]/header:z-(--z-modal) lg:z-(--z-nav) print:hidden!"
6666
>
6767
<SearchBar variant="header" />
6868
</span>
Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,17 @@
11
---
2-
import Icon from '@components/Icon/index.astro'
2+
import DefaultCopyright from '@components/Layout/Copyright/layouts/default.astro'
3+
import PrintCopyright from '@components/Layout/Copyright/layouts/print.astro'
34
45
export interface Props {
6+
link?: string
57
publishDate: Date
8+
variant?: 'default' | 'print'
69
}
710
8-
const { publishDate } = Astro.props
11+
const { publishDate, variant = 'default', link } = Astro.props
912
const publishYear = publishDate.getFullYear()
1013
---
1114

12-
<div class="flex flex-col text-content-active text-xs mb-6">
13-
<div class="flex justify-center">
14-
<span class="mr-2">Copyright</span>
15-
<Icon
16-
icon="copyright"
17-
color="content-active"
18-
size={3}
19-
classes="mt-0"
20-
/>
21-
<span class="ml-2 mr-1">
22-
<time datetime={String(publishYear)}>{publishYear}</time>
23-
</span>
24-
<span class="">Webstack Builders, Inc.</span>
25-
</div>
26-
<div class="flex justify-center">
27-
<span class="mr-1">See our </span>
28-
<a
29-
href="/terms"
30-
class="inline-flex min-h-6 items-center align-middle underline transition-colors hover:text-primary-offset hover:decoration-primary-offset focus-visible:text-primary-offset focus-visible:decoration-primary-offset focus-visible:outline-2 focus-visible:outline-spotlight focus-visible:outline-offset-2 focus-visible:rounded-none"
31-
>
32-
terms of use
33-
</a>
34-
</div>
35-
</div>
15+
16+
{variant === 'default' && <DefaultCopyright publishYear={publishYear} />}
17+
{variant === 'print' && <PrintCopyright publishYear={publishYear} link={link} />}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
import Icon from '@components/Icon/index.astro'
3+
4+
export interface Props {
5+
publishYear: number
6+
}
7+
8+
const { publishYear } = Astro.props
9+
---
10+
11+
<div class="flex flex-col text-content-active text-xs mb-6 print:hidden">
12+
<div class="flex justify-center">
13+
<span class="mr-2">Copyright</span>
14+
<Icon
15+
icon="copyright"
16+
color="content-active"
17+
size={3}
18+
classes="mt-0"
19+
/>
20+
<span class="ml-2 mr-1">
21+
<time datetime={String(publishYear)}>{publishYear}</time>
22+
</span>
23+
<span class="">Webstack Builders, Inc.</span>
24+
</div>
25+
<div class="flex items-center justify-center">
26+
<span class="mr-1">See our </span>
27+
<a
28+
href="/terms"
29+
class="inline-flex min-h-6 items-center align-middle underline transition-colors hover:text-primary-offset hover:decoration-primary-offset focus-visible:text-primary-offset focus-visible:decoration-primary-offset focus-visible:outline-2 focus-visible:outline-spotlight focus-visible:outline-offset-2 focus-visible:rounded-none"
30+
>
31+
terms of use
32+
</a>
33+
</div>
34+
</div>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
import Icon from '@components/Icon/index.astro'
3+
4+
export interface Props {
5+
link?: string
6+
publishYear: number
7+
}
8+
9+
const { link, publishYear } = Astro.props
10+
11+
const companyName = 'Webstack Builders, Inc.'
12+
const creativeCommonsLicense = 'The text, diagrams, and images in this work are licensed under CC BY-NC 4.0'
13+
const mitLicense = 'All code samples in this article are licensed under the MIT License. Feel free to use, modify, and distribute them in any project.'
14+
---
15+
16+
<div class="flex flex-col gap-4">
17+
<div class="flex">
18+
<span>Copyright</span>
19+
<Icon
20+
icon="copyright"
21+
color="content-active"
22+
size={3}
23+
classes="ml-2 mt-1"
24+
/>
25+
<span class="ml-2 mr-1">
26+
<time datetime={String(publishYear)}>{publishYear}</time>
27+
</span>
28+
<span>{companyName}</span>
29+
</div>
30+
<div>{creativeCommonsLicense}</div>
31+
<div>{mitLicense}</div>
32+
<div>{link}</div>
33+
</div>
-1.33 MB
Binary file not shown.

src/components/Navigation/index.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export interface Props {
1010
const { path } = Astro.props
1111
---
1212

13-
<site-navigation class="contents" data-testid="site-navigation">
13+
<site-navigation class="contents print:hidden!" data-testid="site-navigation">
1414
<div id="mobile-nav-focus-container" class="contents">
1515
{/* Main Navigation Menu */}
1616
<span

0 commit comments

Comments
 (0)