Example blog rework (#3896)
* refactor: restructure components, kill dead code * nit: tweak base styles * nit: remove unneeded code comments * refactor: replace unused permalink with canonicalURL * refactor: add missing prop types * feat: make markdown examples more interesting * chore: consistent semis and quotes * chore: astro check failures * fix: bad url prop * fix: bad frontmatter quote * chore: more dead styles * chore: add header gap * refactor: use tsx for likebutton * fix: restore post sorting * chore: remove unused flex-row util * fix: small md formatting on README * chore: run through astro-plugin-prettier * fix: revert to double quotes * fix: manually move style outside <body> * fix: update file tree in README * refactor: publish-date -> time * refactor: remove unused div and margin * refactor: publishDate -> time on layout * refactor: .heroImage -> img * refactor: .logo -> svg * feat: update social image, remove jpg * fix: remove prism stylesheet!
This commit is contained in:
parent
4bf4736768
commit
ab232dd10f
19 changed files with 316 additions and 440 deletions
|
@ -18,9 +18,6 @@ Features:
|
|||
Inside of your Astro project, you'll see the following folders and files:
|
||||
|
||||
```
|
||||
├── README.md
|
||||
├── astro.config.mjs
|
||||
├── package.json
|
||||
├── public
|
||||
│ ├── assets
|
||||
│ │ └── blog
|
||||
|
@ -28,24 +25,26 @@ Inside of your Astro project, you'll see the following folders and files:
|
|||
│ ├── favicon.ico
|
||||
│ ├── social.jpg
|
||||
│ └── social.png
|
||||
├── sandbox.config.json
|
||||
├── src
|
||||
│ ├── components
|
||||
│ │ ├── Author.astro
|
||||
│ │ ├── BaseHead.astro
|
||||
│ │ ├── BlogHeader.astro
|
||||
│ │ ├── BlogPost.astro
|
||||
│ │ ├── BlogPostPreview.astro
|
||||
│ │ ├── Heading.astro
|
||||
│ │ └── Logo.astro
|
||||
│ │ ├── FollowMe.astro
|
||||
│ │ ├── Header.astro
|
||||
│ │ └── LikeButton.tsx
|
||||
│ ├── layouts
|
||||
│ │ └── BlogPost.astro
|
||||
│ ├── pages
|
||||
│ │ ├── index.astro
|
||||
│ │ └── posts
|
||||
│ │ └── index.md
|
||||
│ │ ├── interactive-content.md
|
||||
│ │ └── static-content.md
|
||||
│ └── styles
|
||||
│ └── blog.css
|
||||
├── astro.config.mjs
|
||||
├── README.md
|
||||
├── package.json
|
||||
└── tsconfig.json
|
||||
```
|
||||
|
||||
|
@ -60,7 +59,7 @@ Any static assets, like images, can be placed in the `public/` directory.
|
|||
All commands are run from the root of the project, from a terminal:
|
||||
|
||||
| Command | Action |
|
||||
|:---------------- |:-------------------------------------------- |
|
||||
| :---------------- | :------------------------------------------- |
|
||||
| `npm install` | Installs dependencies |
|
||||
| `npm run dev` | Starts local dev server at `localhost:3000` |
|
||||
| `npm run build` | Build your production site to `./dist/` |
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import preact from '@astrojs/preact';
|
||||
import { defineConfig } from "astro/config";
|
||||
import preact from "@astrojs/preact";
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 25 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 172 KiB |
|
@ -4,9 +4,9 @@ import "../styles/blog.css";
|
|||
export interface Props {
|
||||
title: string;
|
||||
description: string;
|
||||
permalink: string;
|
||||
}
|
||||
const { title, description, permalink } = Astro.props;
|
||||
|
||||
const { title, description } = Astro.props;
|
||||
---
|
||||
|
||||
<!-- Global Metadata -->
|
||||
|
@ -21,17 +21,17 @@ const { title, description, permalink } = Astro.props;
|
|||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content={permalink} />
|
||||
<meta property="og:url" content={Astro.canonicalURL} />
|
||||
<meta property="og:title" content={title} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:image" content="https://astro.build/social.png?v=1" />
|
||||
<meta property="og:image" content="https://astro.build/social.png" />
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta property="twitter:card" content="summary_large_image" />
|
||||
<meta property="twitter:url" content={permalink} />
|
||||
<meta property="twitter:url" content={Astro.canonicalURL} />
|
||||
<meta property="twitter:title" content={title} />
|
||||
<meta property="twitter:description" content={description} />
|
||||
<meta property="twitter:image" content="https://astro.build/social.png?v=1" />
|
||||
<meta property="twitter:image" content="https://astro.build/social.png" />
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
<header class="wrapper">
|
||||
<article>
|
||||
<h1>
|
||||
<a href="/">
|
||||
<svg
|
||||
class="logo"
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 256 256"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<style>
|
||||
#flame {
|
||||
fill: #ff5d01;
|
||||
}
|
||||
#a {
|
||||
fill: #000014;
|
||||
}
|
||||
</style>
|
||||
<title>Logo</title>
|
||||
<path
|
||||
id="a"
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M163.008 18.929c1.944 2.413 2.935 5.67 4.917 12.181l43.309 142.27a180.277 180.277 0 00-51.778-17.53l-28.198-95.29a3.67 3.67 0 00-7.042.01l-27.857 95.232a180.225 180.225 0 00-52.01 17.557l43.52-142.281c1.99-6.502 2.983-9.752 4.927-12.16a15.999 15.999 0 016.484-4.798c2.872-1.154 6.271-1.154 13.07-1.154h31.085c6.807 0 10.211 0 13.086 1.157a16.004 16.004 0 016.487 4.806z"
|
||||
></path>
|
||||
<path
|
||||
id="flame"
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M168.19 180.151c-7.139 6.105-21.39 10.268-37.804 10.268-20.147 0-37.033-6.272-41.513-14.707-1.602 4.835-1.961 10.367-1.961 13.902 0 0-1.056 17.355 11.015 29.426 0-6.268 5.081-11.349 11.349-11.349 10.743 0 10.731 9.373 10.721 16.977v.679c0 11.542 7.054 21.436 17.086 25.606a23.27 23.27 0 01-2.339-10.2c0-11.008 6.463-15.107 13.974-19.87 5.976-3.79 12.616-8.001 17.192-16.449a31.024 31.024 0 003.743-14.82c0-3.299-.513-6.479-1.463-9.463z"
|
||||
></path>
|
||||
</svg>
|
||||
<span>My Blog</span>
|
||||
</a>
|
||||
</h1>
|
||||
</article>
|
||||
</header>
|
||||
|
||||
<style>
|
||||
header {
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
height: 5rem;
|
||||
}
|
||||
article {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.header-subitem {
|
||||
display: flex;
|
||||
flex-grow: 0;
|
||||
gap: 0.5em;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--theme-text-lighter);
|
||||
font-size: initial;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
.header-subitem:hover {
|
||||
color: var(--theme-accent);
|
||||
}
|
||||
.header-subitem svg {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
}
|
||||
|
||||
@media (max-width: 32em) {
|
||||
.header-subitem {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
font-size: 1.5rem;
|
||||
max-width: 100%;
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.logo {
|
||||
transform: translateY(0.25rem);
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
h1 a {
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
}
|
||||
</style>
|
|
@ -1,97 +0,0 @@
|
|||
---
|
||||
import Author from "./Author.astro";
|
||||
|
||||
export interface Props {
|
||||
title: string;
|
||||
author: string;
|
||||
publishDate: string;
|
||||
heroImage: string;
|
||||
alt: string;
|
||||
}
|
||||
|
||||
const { title, author, publishDate, heroImage, alt } = Astro.props;
|
||||
---
|
||||
|
||||
<div class="layout">
|
||||
<article class="content">
|
||||
<div>
|
||||
<header>
|
||||
{heroImage && (
|
||||
<img
|
||||
width="720"
|
||||
height="420"
|
||||
class="hero-image"
|
||||
loading="lazy"
|
||||
src={heroImage}
|
||||
alt={alt}
|
||||
/>
|
||||
)}
|
||||
<p class="publish-date">{publishDate}</p>
|
||||
<h1 class="title">{title}</h1>
|
||||
<Author name="@FredKSchott" href="https://twitter.com/FredKSchott" />
|
||||
</header>
|
||||
<main>
|
||||
<slot />
|
||||
</main>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.hero-image {
|
||||
width: 100vw;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 4rem;
|
||||
max-width: 1280px;
|
||||
}
|
||||
|
||||
@media (max-width: 50em) {
|
||||
.hero-image {
|
||||
height: 260px;
|
||||
margin-top: 0;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-bottom: 8rem;
|
||||
}
|
||||
|
||||
.content :global(main > * + *) {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.content :global(h2) {
|
||||
margin-top: 4rem;
|
||||
}
|
||||
|
||||
header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
padding-bottom: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
border-bottom: 4px solid var(--theme-divider);
|
||||
}
|
||||
|
||||
.title,
|
||||
.author,
|
||||
.publish-date {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.publish-date,
|
||||
.author {
|
||||
color: var(--theme-text-lighter);
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.25rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
</style>
|
|
@ -1,48 +1,36 @@
|
|||
---
|
||||
export interface Props {
|
||||
post: any;
|
||||
title: string;
|
||||
description: string;
|
||||
publishDate: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
const { post } = Astro.props;
|
||||
const { title, description, publishDate, url } = Astro.props as Props;
|
||||
---
|
||||
|
||||
<article class="post-preview">
|
||||
<header>
|
||||
<p class="publish-date">{post.frontmatter.publishDate}</p>
|
||||
<a href={post.url}><h1 class="title">{post.frontmatter.title}</h1></a>
|
||||
<time>{publishDate}</time>
|
||||
<a href={url}><h1 class="title">{title}</h1></a>
|
||||
</header>
|
||||
<p>{post.frontmatter.description}</p>
|
||||
<a href={post.url}>Read more</a>
|
||||
<p>{description}</p>
|
||||
<a href={url}>Read more</a>
|
||||
</article>
|
||||
|
||||
<style>
|
||||
.content :global(main > * + *) {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.post-preview {
|
||||
padding-bottom: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
border-bottom: 4px solid var(--theme-divider);
|
||||
}
|
||||
|
||||
header {
|
||||
align-items: flex-start;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding-bottom: 2rem;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.title,
|
||||
.author,
|
||||
.publish-date {
|
||||
time {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.publish-date,
|
||||
.author {
|
||||
time {
|
||||
font-size: 1.25rem;
|
||||
color: var(--theme-text-lighter);
|
||||
}
|
||||
|
|
11
examples/blog/src/components/FollowMe.astro
Normal file
11
examples/blog/src/components/FollowMe.astro
Normal file
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
export interface Props {
|
||||
username: string;
|
||||
href: string;
|
||||
}
|
||||
|
||||
const { username, href } = Astro.props as Props;
|
||||
---
|
||||
|
||||
<p>Follow me <a {href} target="_blank" rel="noreferrer">@{username}</a></p>
|
||||
|
57
examples/blog/src/components/Header.astro
Normal file
57
examples/blog/src/components/Header.astro
Normal file
|
@ -0,0 +1,57 @@
|
|||
<header class="wrapper">
|
||||
<nav>
|
||||
<a href="/">
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 256 256"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<style>
|
||||
#flame {
|
||||
fill: #ff5d01;
|
||||
}
|
||||
#a {
|
||||
fill: #000014;
|
||||
}
|
||||
</style>
|
||||
<path
|
||||
id="a"
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M163.008 18.929c1.944 2.413 2.935 5.67 4.917 12.181l43.309 142.27a180.277 180.277 0 00-51.778-17.53l-28.198-95.29a3.67 3.67 0 00-7.042.01l-27.857 95.232a180.225 180.225 0 00-52.01 17.557l43.52-142.281c1.99-6.502 2.983-9.752 4.927-12.16a15.999 15.999 0 016.484-4.798c2.872-1.154 6.271-1.154 13.07-1.154h31.085c6.807 0 10.211 0 13.086 1.157a16.004 16.004 0 016.487 4.806z"
|
||||
></path>
|
||||
<path
|
||||
id="flame"
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M168.19 180.151c-7.139 6.105-21.39 10.268-37.804 10.268-20.147 0-37.033-6.272-41.513-14.707-1.602 4.835-1.961 10.367-1.961 13.902 0 0-1.056 17.355 11.015 29.426 0-6.268 5.081-11.349 11.349-11.349 10.743 0 10.731 9.373 10.721 16.977v.679c0 11.542 7.054 21.436 17.086 25.606a23.27 23.27 0 01-2.339-10.2c0-11.008 6.463-15.107 13.974-19.87 5.976-3.79 12.616-8.001 17.192-16.449a31.024 31.024 0 003.743-14.82c0-3.299-.513-6.479-1.463-9.463z"
|
||||
></path>
|
||||
</svg>
|
||||
<span>My Blog</span>
|
||||
</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<style>
|
||||
header {
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
height: 5rem;
|
||||
}
|
||||
nav {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
}
|
||||
</style>
|
|
@ -1,9 +0,0 @@
|
|||
<h1>
|
||||
<slot />
|
||||
</h1>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
35
examples/blog/src/components/LikeButton.tsx
Normal file
35
examples/blog/src/components/LikeButton.tsx
Normal file
|
@ -0,0 +1,35 @@
|
|||
import { useState } from "preact/hooks";
|
||||
|
||||
interface Props {
|
||||
pageUrl: string;
|
||||
}
|
||||
|
||||
export default function LikeButton({ pageUrl }: Props) {
|
||||
const persistedLike = localStorage.getItem(`liked-${pageUrl}`);
|
||||
const [liked, setLiked] = useState(persistedLike ? JSON.parse(persistedLike) : false);
|
||||
|
||||
function toggleLike() {
|
||||
const toggled = !liked;
|
||||
setLiked(toggled);
|
||||
// preserve your likes as you navigate the site
|
||||
localStorage.setItem(`liked-${pageUrl}`, JSON.stringify(toggled));
|
||||
}
|
||||
|
||||
return (
|
||||
<button onClick={toggleLike}>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
width="1em"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
{/* fill the heart when liked ♥ */}
|
||||
<path
|
||||
fill={liked ? "red" : "#ccc"}
|
||||
d="m12 21.35l-1.45-1.32C5.4 15.36 2 12.27 2 8.5C2 5.41 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.08C13.09 3.81 14.76 3 16.5 3C19.58 3 22 5.41 22 8.5c0 3.77-3.4 6.86-8.55 11.53L12 21.35Z"
|
||||
></path>
|
||||
</svg>
|
||||
</button>
|
||||
);
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
<svg
|
||||
class="logo"
|
||||
width="158"
|
||||
height="170"
|
||||
viewBox="0 0 158 170"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M96.5039 9.46441C97.4758 10.671 97.9714 12.2991 98.9626 15.5553L120.617 86.6902C112.611 82.5368 103.907 79.5413 94.7281 77.9252L80.6289 30.2798C80.3982 29.5002 79.6822 28.9654 78.8692 28.9654C78.0541 28.9654 77.3367 29.503 77.1079 30.2853L63.1795 77.9011C53.9579 79.51 45.2146 82.5109 37.1741 86.6793L58.9347 15.5388C59.929 12.2882 60.4262 10.6629 61.3981 9.45854C62.2562 8.39532 63.3723 7.56959 64.64 7.06003C66.076 6.48285 67.7756 6.48285 71.1749 6.48285H86.7174C90.1211 6.48285 91.823 6.48285 93.2603 7.06124C94.5291 7.575 95.6459 8.39925 96.5039 9.46441Z"
|
||||
fill="white"></path>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M99.0951 90.0755C95.5253 93.1279 88.4002 95.2097 80.1929 95.2097C70.1197 95.2097 61.6767 92.0737 59.4363 87.8561C58.6354 90.2733 58.4558 93.0397 58.4558 94.8069C58.4558 94.8069 57.9281 103.485 63.9636 109.52C63.9636 106.386 66.5042 103.846 69.6381 103.846C75.0097 103.846 75.0036 108.532 74.9987 112.334C74.9986 112.448 74.9984 112.561 74.9984 112.673C74.9984 118.444 78.5255 123.391 83.5416 125.477C82.7924 123.936 82.3721 122.205 82.3721 120.377C82.3721 114.873 85.6034 112.823 89.3588 110.441C92.3469 108.546 95.6668 106.441 97.9548 102.217C99.1486 100.013 99.8265 97.4893 99.8265 94.8069C99.8265 93.1573 99.5702 91.5676 99.0951 90.0755Z"
|
||||
fill="#FF5D01"></path>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M99.0951 90.0755C95.5253 93.1279 88.4002 95.2097 80.1929 95.2097C70.1197 95.2097 61.6767 92.0737 59.4363 87.8561C58.6354 90.2733 58.4558 93.0397 58.4558 94.8069C58.4558 94.8069 57.9281 103.485 63.9636 109.52C63.9636 106.386 66.5042 103.846 69.6381 103.846C75.0097 103.846 75.0036 108.532 74.9987 112.334C74.9986 112.448 74.9984 112.561 74.9984 112.673C74.9984 118.444 78.5255 123.391 83.5416 125.477C82.7924 123.936 82.3721 122.205 82.3721 120.377C82.3721 114.873 85.6034 112.823 89.3588 110.441C92.3469 108.546 95.6668 106.441 97.9548 102.217C99.1486 100.013 99.8265 97.4893 99.8265 94.8069C99.8265 93.1573 99.5702 91.5676 99.0951 90.0755Z"
|
||||
fill="url(#paint1_linear)"></path>
|
||||
<path
|
||||
d="M11.9957 169.024C20.0117 169.024 24.8597 167.104 27.6917 163.12C27.6917 164.896 27.7877 166.576 28.0277 168.112H32.7797C32.3477 165.616 32.2517 163.984 32.2517 159.472V153.328C32.2517 146.704 27.1157 143.2 17.3237 143.2C7.8677 143.2 1.7237 146.848 0.955701 152.128H5.9957C6.7637 148.576 10.7477 146.704 17.3237 146.704C23.8037 146.704 27.6437 148.96 27.6437 152.8V153.28L12.6677 154.144C6.5717 154.48 4.3157 155.344 2.5877 156.592C0.955701 157.792 0.0437012 159.664 0.0437012 161.824C0.0437012 166.384 4.7477 169.024 11.9957 169.024ZM13.5317 165.616C7.9637 165.616 4.8917 164.32 4.8917 161.728C4.8917 158.944 6.8117 157.696 13.5797 157.264L27.6437 156.4V157.504C27.6437 162.544 21.7397 165.616 13.5317 165.616Z"
|
||||
fill="white"></path>
|
||||
<path
|
||||
d="M55.9352 169.024C65.8712 169.024 69.8552 165.76 69.8552 161.008C69.8552 157.072 67.4072 155.056 61.1672 154.528L49.5032 153.616C46.3352 153.376 44.5592 152.464 44.5592 150.496C44.5592 148 47.2952 146.704 53.1992 146.704C59.9192 146.704 63.4232 148.048 65.7272 151.024L69.6152 149.152C67.2152 145.408 61.8872 143.2 53.6312 143.2C45.1352 143.2 40.0472 146.032 40.0472 150.688C40.0472 154.864 43.0712 156.88 48.7832 157.36L60.3512 158.272C64.1432 158.56 65.2952 159.328 65.2952 161.296C65.2952 164.128 62.3672 165.472 56.5592 165.472C49.5032 165.472 45.0392 163.552 42.8792 160.048L39.0872 162.112C42.0152 166.528 47.1512 169.024 55.9352 169.024Z"
|
||||
fill="white"></path>
|
||||
<path
|
||||
d="M79.6765 147.712V159.28C79.6765 164.032 81.3085 168.784 90.1885 168.784C92.4445 168.784 95.1805 168.352 96.3805 167.824V163.936C94.7005 164.32 92.6845 164.608 90.7165 164.608C86.5405 164.608 84.2845 162.976 84.2845 158.848V147.712H96.2845V144.112H84.2845V136L79.6765 137.872V144.112H72.1404V147.712H79.6765Z"
|
||||
fill="white"></path>
|
||||
<path
|
||||
d="M107.728 144.112H103.504V168.112H108.064V159.136C108.064 155.68 108.736 152.752 110.656 150.736C112.336 148.864 114.496 147.808 118.288 147.808C119.584 147.808 120.4 147.904 121.504 148.096V143.68C120.496 143.44 119.632 143.392 118.336 143.392C113.2 143.392 109.12 146.416 107.728 151.072V144.112Z"
|
||||
fill="white"></path>
|
||||
<path
|
||||
d="M140.724 169.024C150.948 169.024 157.956 163.84 157.956 156.112C157.956 148.384 150.948 143.2 140.724 143.2C130.5 143.2 123.492 148.384 123.492 156.112C123.492 163.84 130.5 169.024 140.724 169.024ZM140.724 165.232C133.188 165.232 128.34 161.68 128.34 156.112C128.34 150.544 133.188 146.992 140.724 146.992C148.212 146.992 153.108 150.544 153.108 156.112C153.108 161.68 148.212 165.232 140.724 165.232Z"
|
||||
fill="white"></path>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="paint1_linear"
|
||||
x1="115.168"
|
||||
y1="65.245"
|
||||
x2="94.0326"
|
||||
y2="109.491"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-color="#FF1639"></stop>
|
||||
<stop offset="1" stop-color="#FF1639" stop-opacity="0"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
<style lang="scss">
|
||||
.logo {
|
||||
margin: 2rem auto;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-family: var(--font-sans);
|
||||
font-size: 1rem;
|
||||
}
|
||||
.title svg {
|
||||
margin-right: -100%;
|
||||
}
|
||||
.title svg text {
|
||||
font-size: 16px;
|
||||
font-family: var(--font-sans);
|
||||
}
|
||||
.title svg text.span {
|
||||
fill: white;
|
||||
font-size: 16.2px;
|
||||
transform: translate(0, 18px);
|
||||
}
|
||||
.title svg text.em {
|
||||
fill: var(--color-green);
|
||||
transform: translate(0, 36px);
|
||||
}
|
||||
|
||||
@media (min-width: 40em) {
|
||||
.title svg {
|
||||
margin-right: 0;
|
||||
margin-bottom: -40px;
|
||||
}
|
||||
.title svg text.span {
|
||||
font-size: 16px;
|
||||
}
|
||||
.title svg text.em {
|
||||
transform: translate(190px, 18px);
|
||||
}
|
||||
}
|
||||
</style>
|
Before Width: | Height: | Size: 5.6 KiB |
|
@ -1,27 +1,102 @@
|
|||
---
|
||||
import BaseHead from "../components/BaseHead.astro";
|
||||
import BlogHeader from "../components/BlogHeader.astro";
|
||||
import BlogPost from "../components/BlogPost.astro";
|
||||
import Header from "../components/Header.astro";
|
||||
|
||||
const { content } = Astro.props;
|
||||
const { title, description, publishDate, author, heroImage, permalink, alt } = content;
|
||||
export interface Props {
|
||||
content: {
|
||||
title: string;
|
||||
description: string;
|
||||
publishDate: string;
|
||||
heroImage?: {
|
||||
src: string;
|
||||
alt: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const {
|
||||
content: { title, description, publishDate, heroImage },
|
||||
} = Astro.props as Props;
|
||||
---
|
||||
|
||||
<html lang={content.lang || "en"}>
|
||||
<html>
|
||||
<head>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/prism-themes@1.9.0/themes/prism-lucario.css"
|
||||
/>
|
||||
<BaseHead {title} {description} {permalink} />
|
||||
<BaseHead title={title} description={description} />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<BlogHeader />
|
||||
<div class="wrapper">
|
||||
<BlogPost {title} {author} {heroImage} {publishDate} {alt}>
|
||||
<slot />
|
||||
</BlogPost>
|
||||
</div>
|
||||
<Header />
|
||||
<article class="wrapper content">
|
||||
<header>
|
||||
{heroImage && (
|
||||
<img
|
||||
width="720"
|
||||
height="420"
|
||||
loading="lazy"
|
||||
src={heroImage.src}
|
||||
alt={heroImage.alt}
|
||||
/>
|
||||
)}
|
||||
<h1 class="title">{title}</h1>
|
||||
<time>{publishDate}</time>
|
||||
</header>
|
||||
<main>
|
||||
<slot></slot>
|
||||
</main>
|
||||
</article>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<style>
|
||||
img {
|
||||
width: 100vw;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 4rem;
|
||||
max-width: 1280px;
|
||||
}
|
||||
|
||||
@media (max-width: 50em) {
|
||||
img {
|
||||
height: 260px;
|
||||
margin-top: 0;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-bottom: 8rem;
|
||||
}
|
||||
|
||||
.content :global(h2) {
|
||||
margin-top: 4rem;
|
||||
}
|
||||
|
||||
header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
|
||||
padding-bottom: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
border-bottom: 4px solid var(--theme-divider);
|
||||
}
|
||||
|
||||
.title,
|
||||
time {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
time {
|
||||
color: var(--theme-text-lighter);
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.25rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,81 +1,62 @@
|
|||
---
|
||||
// Component Imports
|
||||
import BaseHead from "../components/BaseHead.astro";
|
||||
import BlogHeader from "../components/BlogHeader.astro";
|
||||
import Header from "../components/Header.astro";
|
||||
import BlogPostPreview from "../components/BlogPostPreview.astro";
|
||||
|
||||
// Component Script:
|
||||
// You can write any JavaScript/TypeScript that you'd like here.
|
||||
// It will run during the build, but never in the browser.
|
||||
// All variables are available to use in the HTML template below.
|
||||
let title = "Example Blog";
|
||||
let description = "The perfect starter for your perfect blog.";
|
||||
let permalink = "https://example.com/";
|
||||
|
||||
// Data Fetching: List all Markdown posts in the repo.
|
||||
|
||||
let allPosts = await Astro.glob("./posts/*.md");
|
||||
allPosts = allPosts.sort(
|
||||
(a, b) =>
|
||||
// Use Astro.glob to fetch all post with associated frontmatter
|
||||
const unsortedPosts = await Astro.glob("./posts/*.md");
|
||||
const posts = unsortedPosts.sort(function (a, b) {
|
||||
return (
|
||||
new Date(b.frontmatter.publishDate).valueOf() - new Date(a.frontmatter.publishDate).valueOf()
|
||||
);
|
||||
|
||||
// Full Astro Component Syntax:
|
||||
// https://docs.astro.build/core-concepts/astro-components/
|
||||
);
|
||||
});
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<BaseHead {title} {description} {permalink} />
|
||||
|
||||
<style>
|
||||
header {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: var(--theme-bg-offset);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-top: 4rem;
|
||||
margin-bottom: 8rem;
|
||||
}
|
||||
|
||||
.content :global(main > * + *) {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.intro {
|
||||
padding-bottom: 4rem;
|
||||
margin-bottom: 2rem;
|
||||
border-bottom: 4px solid var(--theme-divider);
|
||||
}
|
||||
|
||||
.intro > * {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.latest {
|
||||
font-size: 2.5rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
</style>
|
||||
<BaseHead title={title} description={description} />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<BlogHeader />
|
||||
<Header />
|
||||
<div class="wrapper">
|
||||
<main class="content">
|
||||
<section class="intro">
|
||||
<h1 class="latest">{title}</h1>
|
||||
<h1>{title}</h1>
|
||||
<p>{description}</p>
|
||||
</section>
|
||||
<section aria-label="Blog post list">
|
||||
{allPosts.map((p) => <BlogPostPreview post={p} />)}
|
||||
{posts.map(({ url, frontmatter }) => (
|
||||
<BlogPostPreview
|
||||
title={frontmatter.title}
|
||||
description={frontmatter.description}
|
||||
publishDate={frontmatter.publishDate}
|
||||
url={url}
|
||||
/>
|
||||
))}
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
margin-top: 4rem;
|
||||
margin-bottom: 8rem;
|
||||
}
|
||||
|
||||
.intro {
|
||||
padding-bottom: 4rem;
|
||||
margin-bottom: 2rem;
|
||||
border-bottom: 4px solid var(--theme-divider);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
---
|
||||
setup: |
|
||||
import Layout from '../../layouts/BlogPost.astro'
|
||||
import Cool from '../../components/Author.astro'
|
||||
title: Hello world!
|
||||
publishDate: 12 Sep 2021
|
||||
name: Nate Moore
|
||||
value: 128
|
||||
description: Just a Hello World Post!
|
||||
---
|
||||
|
||||
<Cool name={frontmatter.name} href="https://twitter.com/n_moore" client:load />
|
||||
|
||||
This is so cool!
|
||||
|
||||
Do variables work {frontmatter.value * 2}?
|
||||
|
||||
```javascript
|
||||
// Example JavaScript
|
||||
|
||||
const x = 7;
|
||||
function returnSeven() {
|
||||
return x;
|
||||
}
|
||||
|
||||
```
|
22
examples/blog/src/pages/posts/interactive-content.md
Normal file
22
examples/blog/src/pages/posts/interactive-content.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
layout: "../../layouts/BlogPost.astro"
|
||||
title: "Hello galaxy of possibilities!"
|
||||
description: "Take your blog to astronomical heights"
|
||||
publishDate: "12 Sep 2021"
|
||||
followMe:
|
||||
username: "bholmesdev"
|
||||
href: "https://twitter.com/bholmesdev"
|
||||
halfTheMeaning: 21
|
||||
heroImage:
|
||||
src: "/assets/blog/introducing-astro.jpg"
|
||||
alt: "Space shuttle leaving curved trail in the sky"
|
||||
setup: |
|
||||
import LikeButton from "../../components/LikeButton"
|
||||
import FollowMe from "../../components/FollowMe.astro"
|
||||
---
|
||||
|
||||
<FollowMe username={frontmatter.followMe.username} href={frontmatter.followMe.href} />
|
||||
|
||||
Access all exported properties with JSX expressions. For example, let's find the meaning of life: **{frontmatter.halfTheMeaning * 2}**
|
||||
|
||||
If this seems cool, consider giving my post a like with this Preact component: <LikeButton pageUrl={frontmatter.url} client:load />
|
28
examples/blog/src/pages/posts/static-content.md
Normal file
28
examples/blog/src/pages/posts/static-content.md
Normal file
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
layout: "../../layouts/BlogPost.astro"
|
||||
title: "Hello static content!"
|
||||
description: "Bring your markdown, we'll handle the rest"
|
||||
publishDate: "11 Jul 2022"
|
||||
heroImage:
|
||||
src: "/assets/blog/introducing-astro.jpg"
|
||||
alt: "Space shuttle leaving curved trail in the sky"
|
||||
---
|
||||
|
||||
**Astro has built-in support for markdown pages!** All frontmatter data will be available [via `Astro.glob` imports](https://docs.astro.build/en/reference/api-reference/#astroglob) as well, making blog landing pages easy to build.
|
||||
|
||||
**Code challenge:** Try editing the `title` frontmatter property for this post and [visiting the homepage](/) again.
|
||||
|
||||
## Code block demo
|
||||
|
||||
```typescript
|
||||
// Oh, and get Shiki syntax highlighting out-of-the-box!
|
||||
// See our docs for customization options:
|
||||
// https://docs.astro.build/en/guides/markdown-content/#syntax-highlighting
|
||||
function getDistance(amount: number) {
|
||||
if (amount === Infinity) {
|
||||
return "and beyond!";
|
||||
} else {
|
||||
return "and the normal distance!";
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,10 +1,10 @@
|
|||
:root {
|
||||
--font-fallback: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif,
|
||||
Apple Color Emoji, Segoe UI Emoji;
|
||||
--font-body: 'IBM Plex Sans', var(--font-fallback);
|
||||
--font-mono: 'IBM Plex Mono', Consolas, 'Andale Mono WT', 'Andale Mono', 'Lucida Console',
|
||||
'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Liberation Mono',
|
||||
'Nimbus Mono L', Monaco, 'Courier New', Courier, monospace;
|
||||
--font-body: "IBM Plex Sans", var(--font-fallback);
|
||||
--font-mono: "IBM Plex Mono", Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console",
|
||||
"Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono",
|
||||
"Nimbus Mono L", Monaco, "Courier New", Courier, monospace;
|
||||
|
||||
--color-white: #fff;
|
||||
--color-black: #000014;
|
||||
|
@ -32,6 +32,8 @@
|
|||
--color-red-rgb: 255, 22, 57;
|
||||
--color-yellow: #ffbe2d;
|
||||
--color-yellow-rgb: 255, 190, 45;
|
||||
|
||||
--content-max-width: 70ch;
|
||||
}
|
||||
|
||||
:root {
|
||||
|
@ -77,7 +79,6 @@ body {
|
|||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
|
@ -101,7 +102,7 @@ body {
|
|||
.wrapper {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: 65em;
|
||||
max-width: var(--content-max-width);
|
||||
padding-left: 2rem;
|
||||
padding-right: 2rem;
|
||||
width: 100%;
|
||||
|
@ -173,7 +174,7 @@ a > code {
|
|||
}
|
||||
|
||||
a > code::before {
|
||||
content: '';
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
|
|
Loading…
Reference in a new issue