Skip to content

Instantly share code, notes, and snippets.

@timbroder
Created February 15, 2023 21:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timbroder/55ec25b5dd1b4f3e70aaa1bbf0bf2e57 to your computer and use it in GitHub Desktop.
Save timbroder/55ec25b5dd1b4f3e70aaa1bbf0bf2e57 to your computer and use it in GitHub Desktop.
<!DOCTYPE html><html><head> <title>Chat GPT: Gatsby JS Blog System</title> <meta name="generator" content="chatGPT Saving Bookmark"/><style>body { background-color: rgb(32,33,35); color: rgb(236,236,241); font-size: 16px; font-family: sans-serif; line-height: 28px; margin: -10px;}body > .w-full { padding: 30px;}/* prompt */body > .w-full:nth-child(2n+1) { background: rgb(52,53,65);}/* response */body > .w-full:nth-child(2n+2) { background: rgb(68,70,84);}a, a:visited { color: #7792cd;}pre { margin: 0 0 1em 0; display: inline-block; width: 100%;}pre code.hljs { margin-bottom: 1em; border-radius: 5px;}.whitespace-pre-wrap { white-space: pre-wrap;}.flex-col { max-width: 850px; margin: 0px auto;}</style><link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.7.0/build/styles/default.min.css"/></head><body><div class="w-full border-b border-black/10 dark:border-gray-900/50 text-gray-800 dark:text-gray-100 group dark:bg-gray-800"><div class="text-base gap-4 md:gap-6 m-auto md:max-w-2xl lg:max-w-2xl xl:max-w-3xl p-4 md:py-6 flex lg:px-0"><div class="relative flex w-[calc(100%-50px)] flex-col gap-1 md:gap-3 lg:w-[calc(100%-115px)]"><div class="flex flex-grow flex-col gap-3"><div class="min-h-[20px] flex flex-col items-start gap-4 whitespace-pre-wrap">do you understand gatsby js, the blog system?</div></div></div></div></div><div class="w-full border-b border-black/10 dark:border-gray-900/50 text-gray-800 dark:text-gray-100 group bg-gray-50 dark:bg-[#444654]"><div class="text-base gap-4 md:gap-6 m-auto md:max-w-2xl lg:max-w-2xl xl:max-w-3xl p-4 md:py-6 flex lg:px-0"><div class="relative flex w-[calc(100%-50px)] flex-col gap-1 md:gap-3 lg:w-[calc(100%-115px)]"><div class="flex flex-grow flex-col gap-3"><div class="min-h-[20px] flex flex-col items-start gap-4 whitespace-pre-wrap"><div class="markdown prose w-full break-words dark:prose-invert light"><p>Yes, I am familiar with Gatsby JS, which is a static site generator built on top of React. It can be used to create various types of websites, including blogs.</p><p>To create a blog with Gatsby JS, you would typically use one of the many available starter templates as a foundation, and then customize it to fit your needs. Gatsby has a rich plugin ecosystem, which allows you to easily add features like SEO optimization, image optimization, and more</p></div></div></div><div class="flex justify-between"></div></div></div></div><div class="w-full border-b border-black/10 dark:border-gray-900/50 text-gray-800 dark:text-gray-100 group dark:bg-gray-800"><div class="text-base gap-4 md:gap-6 m-auto md:max-w-2xl lg:max-w-2xl xl:max-w-3xl p-4 md:py-6 flex lg:px-0"><div class="relative flex w-[calc(100%-50px)] flex-col gap-1 md:gap-3 lg:w-[calc(100%-115px)]"><div class="flex flex-grow flex-col gap-3"><div class="min-h-[20px] flex flex-col items-start gap-4 whitespace-pre-wrap">If I wanted to list posts from a markdown source and a contently source in Gatsby JS on the same page, how would I do that?</div></div></div></div></div><div class="w-full border-b border-black/10 dark:border-gray-900/50 text-gray-800 dark:text-gray-100 group bg-gray-50 dark:bg-[#444654]"><div class="text-base gap-4 md:gap-6 m-auto md:max-w-2xl lg:max-w-2xl xl:max-w-3xl p-4 md:py-6 flex lg:px-0"><div class="relative flex w-[calc(100%-50px)] flex-col gap-1 md:gap-3 lg:w-[calc(100%-115px)]"><div class="flex flex-grow flex-col gap-3"><div class="min-h-[20px] flex flex-col items-start gap-4 whitespace-pre-wrap"><div class="markdown prose w-full break-words dark:prose-invert light"><p>To list posts from both a markdown source and a Contentful source on the same page in Gatsby JS, you would need to first retrieve the data from both sources and then combine them in your Gatsby component.</p><p>Here's an example of how you could do this:</p><ol><li><p>First, you need to install the required packages for retrieving data from both markdown files and Contentful. You can use <code>gatsby-source-filesystem</code> to retrieve data from markdown files and <code>gatsby-source-contentful</code> to retrieve data from Contentful.</p></li><li><p>In your Gatsby config file, you would configure both sources:</p></li></ol><pre><div class="bg-black mb-4 rounded-md"><div class="flex items-center relative text-gray-200 bg-gray-800 px-4 py-2 text-xs font-sans"><span class="">yaml</span></div><div class="p-4 overflow-y-auto"><code class="!whitespace-pre hljs language-yaml"><span class="hljs-string">module.exports</span> <span class="hljs-string">=</span> {
<span class="hljs-attr">plugins:</span> [
{
<span class="hljs-attr">resolve:</span> <span class="hljs-string">`gatsby-source-filesystem`</span>,
<span class="hljs-attr">options:</span> {
<span class="hljs-attr">name:</span> <span class="hljs-string">`markdown-pages`</span>,
<span class="hljs-attr">path:</span> <span class="hljs-string">`$</span>{<span class="hljs-string">__dirname</span>}<span class="hljs-string">/content/markdown`</span>,
},
},
{
<span class="hljs-attr">resolve:</span> <span class="hljs-string">`gatsby-source-contentful`</span>,
<span class="hljs-attr">options:</span> {
<span class="hljs-attr">spaceId:</span> <span class="hljs-string">`your_space_id`</span>,
<span class="hljs-attr">accessToken:</span> <span class="hljs-string">`your_access_token`</span>,
},
},
],
}
</code></div></div></pre><p>This would configure Gatsby to retrieve data from both the <code>content/markdown</code> directory and Contentful.</p><ol start="3"><li>In your Gatsby component, you would then query the data from both sources using GraphQL. For example, to retrieve all markdown posts, you could use the following query:</li></ol><pre><div class="bg-black mb-4 rounded-md"><div class="flex items-center relative text-gray-200 bg-gray-800 px-4 py-2 text-xs font-sans"><span class="">bash</span></div><div class="p-4 overflow-y-auto"><code class="!whitespace-pre hljs language-bash">query {
allMarkdownRemark {
edges {
node {
<span class="hljs-built_in">id</span>
frontmatter {
title
<span class="hljs-built_in">date</span>
}
excerpt
}
}
}
}
</code></div></div></pre><p>To retrieve all Contentful posts, you could use a similar query:</p><pre><div class="bg-black mb-4 rounded-md"><div class="flex items-center relative text-gray-200 bg-gray-800 px-4 py-2 text-xs font-sans"><span class="">bash</span></div><div class="p-4 overflow-y-auto"><code class="!whitespace-pre hljs language-bash">query {
allContentfulPost {
edges {
node {
<span class="hljs-built_in">id</span>
title
<span class="hljs-built_in">date</span>
excerpt
}
}
}
}
</code></div></div></pre><ol start="4"><li>Finally, you would combine the results of both queries in your component and render them as a list of posts.</li></ol><pre><div class="bg-black mb-4 rounded-md"><div class="flex items-center relative text-gray-200 bg-gray-800 px-4 py-2 text-xs font-sans"><span class="">javascript</span></div><div class="p-4 overflow-y-auto"><code class="!whitespace-pre hljs language-javascript"><span class="hljs-keyword">import</span> { graphql } <span class="hljs-keyword">from</span> <span class="hljs-string">"gatsby"</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> query = graphql<span class="hljs-string">`
query {
allMarkdownRemark {
edges {
node {
id
frontmatter {
title
date
}
excerpt
}
}
}
allContentfulPost {
edges {
node {
id
title
date
excerpt
}
}
}
}
`</span>
<span class="hljs-keyword">const</span> <span class="hljs-title function_">BlogPage</span> = (<span class="hljs-params">{ data }</span>) =&gt; {
<span class="hljs-keyword">const</span> posts = [
...data.<span class="hljs-property">allMarkdownRemark</span>.<span class="hljs-property">edges</span>.<span class="hljs-title function_">map</span>(<span class="hljs-function">(<span class="hljs-params">{ node }</span>) =&gt;</span> ({ ...node.<span class="hljs-property">frontmatter</span>, <span class="hljs-attr">excerpt</span>: node.<span class="hljs-property">excerpt</span> })),
...data.<span class="hljs-property">allContentfulPost</span>.<span class="hljs-property">edges</span>.<span class="hljs-title function_">map</span>(<span class="hljs-function">(<span class="hljs-params">{ node }</span>) =&gt;</span> ({ ...node })),
]
<span class="hljs-keyword">return</span> (
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
{posts.map(post =&gt; (
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{post.id}</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>{post.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{post.date}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{post.excerpt}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
))}
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
)
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">BlogPage</span>
</code></div></div></pre><p>In this example, we're using the spread operator to combine the data from both sources into a single array of post objects, which are then rendered as a list. Note that we're also mapping the <code>excerpt</code> field from the markdown data to match the field name in Contentful.</p></div></div></div><div class="flex justify-between"></div></div></div></div><div class="w-full border-b border-black/10 dark:border-gray-900/50 text-gray-800 dark:text-gray-100 group dark:bg-gray-800"><div class="text-base gap-4 md:gap-6 m-auto md:max-w-2xl lg:max-w-2xl xl:max-w-3xl p-4 md:py-6 flex lg:px-0"><div class="relative flex w-[calc(100%-50px)] flex-col gap-1 md:gap-3 lg:w-[calc(100%-115px)]"><div class="flex flex-grow flex-col gap-3"><div class="min-h-[20px] flex flex-col items-start gap-4 whitespace-pre-wrap">How would I sort both the markdown posts and the contenful posts so they were all sorted by date?</div></div></div></div></div><div class="w-full border-b border-black/10 dark:border-gray-900/50 text-gray-800 dark:text-gray-100 group bg-gray-50 dark:bg-[#444654]"><div class="text-base gap-4 md:gap-6 m-auto md:max-w-2xl lg:max-w-2xl xl:max-w-3xl p-4 md:py-6 flex lg:px-0"><div class="relative flex w-[calc(100%-50px)] flex-col gap-1 md:gap-3 lg:w-[calc(100%-115px)]"><div class="flex flex-grow flex-col gap-3"><div class="min-h-[20px] flex flex-col items-start gap-4 whitespace-pre-wrap"><div class="markdown prose w-full break-words dark:prose-invert light"><p>To sort both the markdown posts and the Contentful posts by date, you can modify the GraphQL query to include a <code>sort</code> argument that sorts the posts by their respective <code>date</code> fields. Here's an example:</p><pre><div class="bg-black mb-4 rounded-md"><div class="flex items-center relative text-gray-200 bg-gray-800 px-4 py-2 text-xs font-sans"><span class="">bash</span></div><div class="p-4 overflow-y-auto"><code class="!whitespace-pre hljs language-bash">query {
allMarkdownRemark(<span class="hljs-built_in">sort</span>: { fields: [frontmatter___date], order: DESC }) {
edges {
node {
<span class="hljs-built_in">id</span>
frontmatter {
title
<span class="hljs-built_in">date</span>
}
excerpt
}
}
}
allContentfulPost(<span class="hljs-built_in">sort</span>: { fields: [<span class="hljs-built_in">date</span>], order: DESC }) {
edges {
node {
<span class="hljs-built_in">id</span>
title
<span class="hljs-built_in">date</span>
excerpt
}
}
}
}
</code></div></div></pre><p>In this query, we're using the <code>sort</code> argument to sort the <code>allMarkdownRemark</code> and <code>allContentfulPost</code> queries by their respective <code>date</code> fields in descending order (<code>DESC</code>). The <code>fields</code> argument is an array that specifies the fields to sort by, and the <code>order</code> argument specifies the order in which to sort the results.</p><p>With this modification, the posts from both sources will be sorted by date in descending order, with the most recent posts appearing first. Once the posts are sorted, you can combine them into a single array as shown in the previous example, and then render them in your Gatsby component.</p></div></div></div><div class="flex justify-between"></div></div></div></div><div class="w-full border-b border-black/10 dark:border-gray-900/50 text-gray-800 dark:text-gray-100 group dark:bg-gray-800"><div class="text-base gap-4 md:gap-6 m-auto md:max-w-2xl lg:max-w-2xl xl:max-w-3xl p-4 md:py-6 flex lg:px-0"><div class="relative flex w-[calc(100%-50px)] flex-col gap-1 md:gap-3 lg:w-[calc(100%-115px)]"><div class="flex flex-grow flex-col gap-3"><div class="min-h-[20px] flex flex-col items-start gap-4 whitespace-pre-wrap">Would the array also be sorted by date?</div></div></div></div></div><div class="w-full border-b border-black/10 dark:border-gray-900/50 text-gray-800 dark:text-gray-100 group bg-gray-50 dark:bg-[#444654]"><div class="text-base gap-4 md:gap-6 m-auto md:max-w-2xl lg:max-w-2xl xl:max-w-3xl p-4 md:py-6 flex lg:px-0"><div class="relative flex w-[calc(100%-50px)] flex-col gap-1 md:gap-3 lg:w-[calc(100%-115px)]"><div class="flex flex-grow flex-col gap-3"><div class="min-h-[20px] flex flex-col items-start gap-4 whitespace-pre-wrap"><div class="markdown prose w-full break-words dark:prose-invert light"><p>Yes, if you modify your GraphQL query to sort both the markdown posts and the Contentful posts by date, and then combine them into a single array in your Gatsby component, the resulting array will also be sorted by date.</p><p>Here's an example of how you could combine and sort the posts in your Gatsby component:</p><pre><div class="bg-black mb-4 rounded-md"><div class="flex items-center relative text-gray-200 bg-gray-800 px-4 py-2 text-xs font-sans"><span class="">javascript</span></div><div class="p-4 overflow-y-auto"><code class="!whitespace-pre hljs language-javascript"><span class="hljs-keyword">import</span> { graphql } <span class="hljs-keyword">from</span> <span class="hljs-string">"gatsby"</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> query = graphql<span class="hljs-string">`
query {
allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
edges {
node {
id
frontmatter {
title
date
}
excerpt
}
}
}
allContentfulPost(sort: { fields: [date], order: DESC }) {
edges {
node {
id
title
date
excerpt
}
}
}
}
`</span>
<span class="hljs-keyword">const</span> <span class="hljs-title function_">BlogPage</span> = (<span class="hljs-params">{ data }</span>) =&gt; {
<span class="hljs-keyword">const</span> posts = [
...data.<span class="hljs-property">allMarkdownRemark</span>.<span class="hljs-property">edges</span>.<span class="hljs-title function_">map</span>(<span class="hljs-function">(<span class="hljs-params">{ node }</span>) =&gt;</span> ({ ...node.<span class="hljs-property">frontmatter</span>, <span class="hljs-attr">excerpt</span>: node.<span class="hljs-property">excerpt</span> })),
...data.<span class="hljs-property">allContentfulPost</span>.<span class="hljs-property">edges</span>.<span class="hljs-title function_">map</span>(<span class="hljs-function">(<span class="hljs-params">{ node }</span>) =&gt;</span> ({ ...node })),
].<span class="hljs-title function_">sort</span>(<span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>(b.<span class="hljs-property">date</span>) - <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>(a.<span class="hljs-property">date</span>))
<span class="hljs-keyword">return</span> (
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
{posts.map(post =&gt; (
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{post.id}</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>{post.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{post.date}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{post.excerpt}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
))}
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
)
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">BlogPage</span>
</code></div></div></pre><p>In this example, we're using the spread operator to combine the data from both sources into a single array of post objects, and then using the <code>sort</code> method to sort the resulting array by date in descending order (<code>order: DESC</code>). The <code>sort</code> function takes two arguments (<code>a</code> and <code>b</code>) and returns a negative value if <code>a</code> should come before <code>b</code> in the sorted array, a positive value if <code>a</code> should come after <code>b</code>, and 0 if they are equal.</p><p>By sorting the array of posts by date, you can ensure that the posts from both sources are combined and displayed in the correct order on your Gatsby page.</p></div></div></div><div class="flex justify-between"></div></div></div></div></body></html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment