My personal website powered by:
- Eleventy (aka 11ty) with:
- eleventy-plugin-rss: a pack of plugins for generating an RSS feed (actually an Atom feed, but who’s counting) using the Nunjucks templating engine.
- eleventy-plugin-reading-time: provides a template tag which prints the number of minutes or seconds required to read the given text.
- TailwindCSS for styling with:
- postcss for preprocessing
- @tailwindcss-typography to "autostyle" markdown
- @tailwindcss-forms to beautify form elements
example.com # → Root of your project
|
├── src/ # → Source directory
│ │
│ ├── assets/ # → Site assets
│ │ ├── fonts/
│ │ ├── images/
│ │ ├── scripts/
│ │ ├── styles/
│ │ │ └── tailwind.css
│ │ │
│ │ └── views/ # → Templatize with nunjucks!
│ │ ├── components/ # → Each component has a folder with a base njk component, njk macro, and story.
│ │ | └── component/ # → 3 possible flavors, depending on how/what it's used for
│ │ | ├── component.js
│ │ | ├── component.njk
│ │ | └── component.macro.njk
│ │ |
│ │ ├── layouts/ # → Combine partials and components (e.g. pages)
│ │ └── partials/ # → Combine components (e.g. navigation)
│ │
│ ├── config/ # → Eleventy configuration
│ │ ├── collections.js # → Add and configure collections (https://www.11ty.dev/docs/collections/)
│ │ ├── filters.js # → Add and configure filters (https://www.11ty.dev/docs/filters/)
│ │ ├── passthroughs.js # → Add and configure passthroughs (https://www.11ty.dev/docs/copy/)
│ │ ├── plugins.js # → Add and configure plugins (https://www.11ty.dev/docs/plugins/)
│ │ ├── shortcodes.js # → Add and configure shortcodes (https://www.11ty.dev/docs/shortcodes/)
│ │ └── watchtargets.js # → Add and configure watch targets (https://www.11ty.dev/docs/watch-serve/)
│ │
│ ├── data # → Customize site data (https://www.11ty.dev/docs/data/)
│ │ ├── navigation.json # → Site navigation configuration
│ │ └── site.json # → Site metadata configuration
│ │
│ ├── pages # → Add "pages" collection items here
│ │ ├── index.md # → Default index page
│ │ └── pages.json # → Shared pages attributes
│ │
│ └── posts # → Add "posts" collection items here
│ ├── index.md # → Default index page
│ ├── posts.11tydata.js # → Calculate if posts are drafts and skip publishing
│ └── posts.json # → Shared posts attributes
│
├── .eleventy.js # → Configure: Eleventy
├── .gitignore # → Ignores all the node stuff that doesn't need to take up space on GitHub
├── LICENSE # → Project license (for example: MIT)
├── netlify.toml # → Netlify deployment and plugin configuration (optional)
├── package.json # → Your project's metadata, dependencies, etc. for Node.js to do its thing
├── postcss.config.js # → Configure: PostCSS
├── README.md # → This file you're reading!
└── tailwind.config.js # → Configure: TailwindCSS
Clone this repo, then via command line go to the project's directory to install the dependencies.
cd directory/to/the/project
npm installAfter installing, run the site with live reload and a local backend.
npm startBuild a production version of the site (1) with clean CSS and (2) no drafts.
This is the build command for Netlify.
npm run build:prodBuild a staging version of the site (1) with clean CSS and (2) include all drafts. I use this for Netlify Deploy Previews so I can proof my drafts but with lean styles.
npm run build:stagingBuild a development version of the site (1) without purging CSS and (2) include all drafts. The output will be the same as when you use npm run watch:dev but without live reloading.
npm run build:dev| Filter | Description | Example/Usage |
|---|---|---|
| content | markdown body of a collection item | {{ content }} |
| raw | allows processing njk within markdown | {{ content | raw }} |
| readingTime | calculates time to read, i.e. content |
{{ content | readingTime }} |
| Filter | Description | Example/Usage |
|---|---|---|
| date | default unformatted date | {{ date }} |
| iso | display date in ISO format | {{ date | iso }} |
| readableDate | display date in 'dd MMMM yyyy' format | {{ date | readableDate }} |
| readableDate custom | or set a custom format | {{ date | readableDate('yyyy-LL-dd') }} |
| toIso | Used in meta for published time | {{ date | toIso }} |
| toRFC2822 | For RSS Feed | {{ date | toRFC2822 }} |
Shortcode: Add an image to a page or post with alt text, caption, and image credit.
| Parameter | Value |
|---|---|
| url | /path/to/the/image (required) |
| alt | alt text (required, unless it is decoration only) |
| credit* | image credit (optional) |
| caption | describe the image in a caption (optional) |
| fit | default: cover; additional values are contain, fill, scale-down, none) |
Example Usage:
<!-- Example input -->
{% Image {
src: 'https://images.unsplash.com/photo-1500754088824-ce0582cfe45f?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1776&q=80',
alt: 'Latern Fest',
caption: 'Lift off at Lantern Fest 2015',
fit: 'contain'
} %}<!-- Example output -->
<figure class="mb-8 media max-w-screen">
<img src="https://images.unsplash.com/photo-1500754088824-ce0582cfe45f?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1776&q=80" alt="Latern Fest" class="object-contain mb-3 aspect-w-4 aspect-h-3">
<figcaption>Lift off at Lantern Fest 2015</figcaption>
</figure><!-- Example input -->
{% ExternalLink {
url: 'https://google.com',
text: 'External Link via shortcode'
} %}<!-- Example output -->
<a class="external-link" href="https://google.com" title="Open external link in new tab" target="_blank" rel="noopener">External Link via shortcode</a>Enable additional CSS and Scripts under blocks in a post's YAML. Options available: youtube, twitch.
# List the webcomponent blocks to load on this page
blocks:
- youtube
- twitch<!-- Example input: YouTube -->
{% YouTube {
id: 'UO2gTHLwzSg',
title: 'BuiltOnAir [All Things Airtable] S03:E08 - Melanie Magdalena, Digital Consultant'
} %}<!-- Example output: YouTube -->
<youtube-embed
videoid="UO2gTHLwzSg"
videotitle="BuiltOnAir [All Things Airtable] S03:E08 - Melanie Magdalena, Digital Consultant"
style="background-image: url('https://i.ytimg.com/vi/UO2gTHLwzSg/hqdefault.jpg');">
<a href="https://youtube-nocookie.com/watch?v=UO2gTHLwzSg" class="lty-playbtn">
<span class="visually-hidden">Play: BuiltOnAir [All Things Airtable] S03:E08 - Melanie Magdalena, Digital Consultant</span>
</a>
</youtube-embed>
<a
href="https://youtube-nocookie.com/watch?v=UO2gTHLwzSg"
title="opens in new tab, watch 'BuiltOnAir [All Things Airtable] S03:E08 - Melanie Magdalena, Digital Consultant' on youtube-nocookie.com"
target="_blank">
Watch on YouTube
</a><!-- Example input: Twitch -->
{% Twitch {
id: '0WkbOP5xexWgGw',
title: 'Project: Shatter [Ship Saturday]',
type: 'collection',
thumbnail: '[optional, has fallback]'
} %}<!-- Example output: Twitch -->
<twitch-embed
videoid="0WkbOP5xexWgGw"
videotitle="Project: Shatter [Ship Saturday]"
videotype="collection"
class="twitch-playbtn mb-2" style="background-image:url('https://static-cdn.jtvnw.net/cf_vods/d2nvs31859zcd8/a16daa79e340800357c7_eli_archgirl_32268743152_1085421880/thumb/custom-45341f1f-72f0-4c76-9ed4-1b2628cf7f31-320x180.jpeg')">
<a href="https://www.twitch.tv/collections/0WkbOP5xexWgGw">
<span class="visually-hidden">Play Project: Shatter [Ship Saturday]</span>
</a>
</twitch-embed>
<a href="https://www.twitch.tv/collections/0WkbOP5xexWgGw"
title="opens in new tab, watch collection 'Project: Shatter [Ship Saturday]' on twitch.tv"
target="_blank">
Watch collection on Twitch
</a><!-- Example input: Transistor -->
{% Transistor {
id: 'f44edcde',
title: 'BuiltOnAir [All Things Airtable] S03:E08 - Melanie Magdalena, Digital Consultant'
} %}<!-- Example output: Transistor -->
<iframe
width="100%"
height="180"
frameborder="no"
scrolling="no"
seamless
class="mb-2"
src="https://share.transistor.fm/e/f44edcde"
></iframe>
<a
href="https://share.transistor.fm/s/f44edcde"
title="opens in new tab, listen to 'BuiltOnAir [All Things Airtable] S03:E08 - Melanie Magdalena, Digital Consultant' on transistor.fm"
target="_blank">
Listen on Transistor
</a>The following resources assisted in the creation of my site!
- About the Conventional Commits specification
- Nunjucks templating features (general documentation)
- "Flexible components in Eleventy with Nunjucks macros" by Iain Bean is a comprehensive guide to macros with plenty of examples.
- "Using parameters in your eleventy includes with nunjucks macros" by Thomas Michael Semmler showcases a parameter approach for macros. I haven't figured out how to use this and keep args in stories functioning.
I removed Storybook... but here's my reading list from when I got it working.
- On using nunjucks as a valid component format... This buried issue and reply was open on my phone for about six months until I finally got around to setting up Storybook on an 11ty project. Radum, thank you for sharing your knowledge.
- IMPORTANT: You have to use version
^2.*for the loader, not^3.*because Storybook uses Webpack 4. I only wasted an hour of my life with errors cuz I failed to read the nice notice on the loader's README. :face_palm:
- IMPORTANT: You have to use version
- Nunjucks-ifying: eleventy-starter-storybook is a great proof-of-concept for how to use njk components in stories. Plus it has a cool macro output that is only used in the story!
- tailwind-ui-alpinejs-storybook has a great visual for how to add Tailwind and Alpine to Storybook and have the thing actually work.