diff options
author | 2021-08-11 15:04:09 -0700 | |
---|---|---|
committer | 2021-08-11 15:04:09 -0700 | |
commit | 0f0cc2b9d83ffeee125b85c95d2d51080f21074d (patch) | |
tree | 4960e84e8654108e9c88f8392e1b04a2ce5ab667 /examples/blog-multiple-authors/src | |
parent | b54c01bf66a75bea7cde909418cc5373e666b7fa (diff) | |
download | astro-0f0cc2b9d83ffeee125b85c95d2d51080f21074d.tar.gz astro-0f0cc2b9d83ffeee125b85c95d2d51080f21074d.tar.zst astro-0f0cc2b9d83ffeee125b85c95d2d51080f21074d.zip |
Add file-based routing /w dynamic paths (#1010)
* wip: add file-based routing
* add pagination tests and nested pagination support
Diffstat (limited to 'examples/blog-multiple-authors/src')
6 files changed, 167 insertions, 182 deletions
diff --git a/examples/blog-multiple-authors/src/components/Nav.astro b/examples/blog-multiple-authors/src/components/Nav.astro index a7ef0985f..04a537f87 100644 --- a/examples/blog-multiple-authors/src/components/Nav.astro +++ b/examples/blog-multiple-authors/src/components/Nav.astro @@ -56,8 +56,8 @@ a { <ul class="nav"> <li><a href="/">Home</a></li> <li><a href="/posts">All Posts</a></li> - <li><a href="/author/don">Author: Don</a></li> - <li><a href="/author/sancho">Author: Sancho</a></li> + <li><a href="/authors/don">Author: Don</a></li> + <li><a href="/authors/sancho">Author: Sancho</a></li> <li><a href="/about">About</a></li> </ul> </nav> diff --git a/examples/blog-multiple-authors/src/components/PostPreview.astro b/examples/blog-multiple-authors/src/components/PostPreview.astro index b126ca2fb..19e1362e5 100644 --- a/examples/blog-multiple-authors/src/components/PostPreview.astro +++ b/examples/blog-multiple-authors/src/components/PostPreview.astro @@ -56,7 +56,7 @@ time { <div class="data"> <h2>{post.title}</h2> - <a class="author" href={`/author/${post.author}`}>{author.name}</a> + <a class="author" href={`/authors/${post.author}`}>{author.name}</a> <time class="date" datetime={post.date}>{formatDate(post.date)}</time> <p class="description"> {post.description} diff --git a/examples/blog-multiple-authors/src/pages/$author.astro b/examples/blog-multiple-authors/src/pages/$author.astro deleted file mode 100644 index 76b372897..000000000 --- a/examples/blog-multiple-authors/src/pages/$author.astro +++ /dev/null @@ -1,105 +0,0 @@ ---- -import MainHead from '../components/MainHead.astro'; -import Nav from '../components/Nav.astro'; -import PostPreview from '../components/PostPreview.astro'; -import Pagination from '../components/Pagination.astro'; - -// page -let title = 'Don’s Blog'; -let description = 'An example blog on Astro'; -let canonicalURL = Astro.request.canonicalURL; - -// collection -import authorData from '../data/authors.json'; - -export function createCollection() { - /** Load posts */ - let allPosts = Astro.fetchContent('./post/*.md'); - return { - paginate: true, - route: `/author/:author/:page?`, - paths() { - let allAuthorsUnique = [...new Set(allPosts.map(p => p.author))]; - return allAuthorsUnique.map(author => ({params: {author}})) - }, - async props({ params, paginate }) { - /** filter posts by author, sort by date */ - const filteredPosts = allPosts - .filter((post) => post.author === params.author) - .sort((a, b) => new Date(b.date) - new Date(a.date)); - return { - posts: paginate(filteredPosts, {pageSize: 1}), - } - }, - }; -} - - -const { posts } = Astro.props; -const { params } = Astro.request; -const author = authorData[posts.data[0].author]; ---- - -<html lang="en"> - <head> - <title>{title}</title> - <MainHead - title={title} - description={description} - image={posts.data[0].image} - canonicalURL={canonicalURL} - prev={posts.url.prev} - next={posts.url.next} - /> - - <style lang="scss"> - .title { - display: flex; - align-items: center; - justify-content: center; - font-size: 3em; - letter-spacing: -0.04em; - margin-top: 2rem; - margin-bottom: 0; - } - - .avatar { - width: 1em; - height: 1em; - margin-right: 0.5em; - border-radius: 50%; - overflow:hidden; - - &-img { - display: block; - width: 100%; - height: 100%; - object-fit: cover; - } - } - - .count { - font-size: 1em; - display: block; - text-align: center; - } - </style> - </head> - - <body> - <Nav title={title} /> - - <main class="wrapper"> - <h2 class="title"> - <div class="avatar"><img class="avatar-img" src={author.image} alt=""}></div> - {author.name} - </h2> - <small class="count">{posts.start + 1}–{posts.end + 1} of {posts.total}</small> - {posts.data.map((post) => <PostPreview post={post} author={author} />)} - </main> - - <footer> - <Pagination prevUrl={posts.url.prev} nextUrl={posts.url.next} /> - </footer> - </body> -</html> diff --git a/examples/blog-multiple-authors/src/pages/$posts.astro b/examples/blog-multiple-authors/src/pages/$posts.astro deleted file mode 100644 index d135beff0..000000000 --- a/examples/blog-multiple-authors/src/pages/$posts.astro +++ /dev/null @@ -1,74 +0,0 @@ ---- -import MainHead from '../components/MainHead.astro'; -import Nav from '../components/Nav.astro'; -import PostPreview from '../components/PostPreview.astro'; -import Pagination from '../components/Pagination.astro'; - -// page -let title = 'Don’s Blog'; -let description = 'An example blog on Astro'; -let canonicalURL = Astro.request.canonicalURL; - -// collection -import authorData from '../data/authors.json'; -export function createCollection() { - return { - route: `/posts/:page?`, - paginate: true, - async props({ paginate }) { - /** filter posts by author, sort by date */ - const allPosts = Astro.fetchContent('./post/*.md'); - const sortedPosts = allPosts.sort((a, b) => new Date(b.date) - new Date(a.date)); - return { - posts: paginate(sortedPosts, {pageSize: 2}), - } - }, - }; -} - -const { posts } = Astro.props; ---- - -<html lang="en"> - <head> - <title>{title}</title> - <MainHead - title={title} - description={description} - image={posts.data[0].image} - canonicalURL={canonicalURL} - prev={posts.url.prev} - next={posts.url.next} - /> - - <style lang="scss"> - .title { - font-size: 3em; - letter-spacing: -0.04em; - margin-top: 2rem; - margin-bottom: 0; - text-align: center; - } - - .count { - font-size: 1em; - display: block; - text-align: center; - } - </style> - </head> - - <body> - <Nav title={title} /> - - <main class="wrapper"> - <h2 class="title">All Posts</h2> - <small class="count">{posts.start + 1}–{posts.end + 1} of {posts.total}</small> - {posts.data.map((post) => <PostPreview post={post} author={authorData[post.author]} />)} - </main> - - <footer> - <Pagination prevUrl={posts.url.prev} nextUrl={posts.url.next} /> - </footer> - </body> -</html> diff --git a/examples/blog-multiple-authors/src/pages/authors/[author].astro b/examples/blog-multiple-authors/src/pages/authors/[author].astro new file mode 100644 index 000000000..084fb7ff8 --- /dev/null +++ b/examples/blog-multiple-authors/src/pages/authors/[author].astro @@ -0,0 +1,85 @@ +--- +import MainHead from '../../components/MainHead.astro'; +import Nav from '../../components/Nav.astro'; +import PostPreview from '../../components/PostPreview.astro'; +import Pagination from '../../components/Pagination.astro'; + +// page +let title = 'Don’s Blog'; +let description = 'An example blog on Astro'; +let canonicalURL = Astro.request.canonicalURL; + +// collection +import authorData from '../../data/authors.json'; +export function getStaticPaths() { + const allPosts = Astro.fetchContent('../post/*.md'); + let allAuthorsUnique = [...new Set(allPosts.map(p => p.author))]; + return allAuthorsUnique.map(author => ({params: {author}, props: {allPosts}})); +} + +const { allPosts } = Astro.props; +const { params } = Astro.request; + +/** filter posts by author, sort by date */ +const posts = allPosts + .filter((post) => post.author === params.author) + .sort((a, b) => new Date(b.date) - new Date(a.date)); +const author = authorData[posts[0].author]; +--- + +<html lang="en"> + <head> + <title>{title}</title> + <MainHead + title={title} + description={description} + image={posts[0].image} + canonicalURL={canonicalURL} + /> + + <style lang="scss"> + .title { + display: flex; + align-items: center; + justify-content: center; + font-size: 3em; + letter-spacing: -0.04em; + margin-top: 2rem; + margin-bottom: 0; + } + + .avatar { + width: 1em; + height: 1em; + margin-right: 0.5em; + border-radius: 50%; + overflow:hidden; + + &-img { + display: block; + width: 100%; + height: 100%; + object-fit: cover; + } + } + + .count { + font-size: 1em; + display: block; + text-align: center; + } + </style> + </head> + + <body> + <Nav title={title} /> + + <main class="wrapper"> + <h2 class="title"> + <div class="avatar"><img class="avatar-img" src={author.image} alt=""}></div> + {author.name} + </h2> + {posts.map((post) => <PostPreview post={post} author={author} />)} + </main> + </body> +</html> diff --git a/examples/blog-multiple-authors/src/pages/posts/[...page].astro b/examples/blog-multiple-authors/src/pages/posts/[...page].astro new file mode 100644 index 000000000..028d17e34 --- /dev/null +++ b/examples/blog-multiple-authors/src/pages/posts/[...page].astro @@ -0,0 +1,79 @@ +--- +import MainHead from '../../components/MainHead.astro'; +import Nav from '../../components/Nav.astro'; +import PostPreview from '../../components/PostPreview.astro'; +import Pagination from '../../components/Pagination.astro'; + +// page +let title = 'Don’s Blog'; +let description = 'An example blog on Astro'; +let canonicalURL = Astro.request.canonicalURL; + +// collection +import authorData from '../../data/authors.json'; +export async function getStaticPaths({paginate, rss}) { + const allPosts = Astro.fetchContent('../post/*.md'); + const sortedPosts = allPosts.sort((a, b) => new Date(b.date) - new Date(a.date)); + // Generate an RSS feed from this collection + // TODO: DONT MERGE: This requires buildOptions.site to be set, which can't be set in a template + rss({ + title: 'Don’s Blog', + description: 'An example blog on Astro', + customData: `<language>en-us</language>`, + items: sortedPosts.map(item => ({ + title: item.title, + description: item.description, + link: item.url, + pubDate: item.date, + })), + }); + // Return a paginated collection of paths for all posts + return paginate(sortedPosts, {pageSize: 1}); +} + +const { page } = Astro.props; +--- + +<html lang="en"> + <head> + <title>{title}</title> + <MainHead + title={title} + description={description} + image={page.data[0].image} + canonicalURL={canonicalURL} + prev={page.url.prev} + next={page.url.next} + /> + + <style lang="scss"> + .title { + font-size: 3em; + letter-spacing: -0.04em; + margin-top: 2rem; + margin-bottom: 0; + text-align: center; + } + + .count { + font-size: 1em; + display: block; + text-align: center; + } + </style> + </head> + + <body> + <Nav title={title} /> + + <main class="wrapper"> + <h2 class="title">All Posts</h2> + <small class="count">{page.start + 1}–{page.end + 1} of {page.total}</small> + {page.data.map((post) => <PostPreview post={post} author={authorData[post.author]} />)} + </main> + + <footer> + <Pagination prevUrl={page.url.prev} nextUrl={page.url.next} /> + </footer> + </body> +</html> |