Гэтсби JS / GraphQL простой блог - PullRequest
1 голос
/ 17 апреля 2020

Я создаю простой блог с Gatsby JS, используя Contentful. У меня есть страница блога со списком всех постов с названиями и датами. Я хочу добавить только для последнего поста первые строки статьи и изображение, использованное в статье.

...

import React from 'react'
import Layout from '../components/layout'
import { Link, graphql, useStaticQuery } from 'gatsby'
import { documentToReactComponents } from "@contentful/rich-text-react-renderer"

import blogStyles from './blog.module.scss'
import Head from '../components/head'

import TransitionLink from "gatsby-plugin-transition-link"
import AniLink from "gatsby-plugin-transition-link/AniLink"

const BlogPage = () => {
    const data = useStaticQuery(graphql`
    query{
         allContentfulBlogPost (sort: { fields: publishedDate, order: DESC}){
             edges{
                 node{
                     title
                     slug
                     publishedDate(formatString:"MMMM Do, YYYY")
                 }
             }
         }

    }
`)

    return (
        <Layout>
            <Head title = "Post" />
            <h1>Post</h1>

            <ol data-sal="slide-up" data-sal-delay="300" data-sal-easing="ease" 
            className={blogStyles.posts}>
                {data.allContentfulBlogPost.edges.map((edge) => {
                    return (
                    <li className={blogStyles.post}>
                        <Link to={`/blog/${edge.node.slug}`}>
                            <h2>{edge.node.title}</h2>
                            <p>{edge.node.publishedDate }</p>
                        </Link>
                    </li>
                )
                })}
            </ol>
        </Layout>
    )
}

export default BlogPage

1 Ответ

1 голос
/ 17 апреля 2020

Примечание: я предположил, что вы имеете в виду последний пост вместо последний пост.


Вы можете использовать Псевдонимы , чтобы разделить ваш запрос на две части.

latestArticle имеет limit: 1 и запрашивает дополнительные поля, необходимые для первых строк статьи и изображения, используемого в статье (а также title, slugExt, publishDate).

allOtherArticles имеет skip: 1 и просто запрашивает title, slugExt, publishDate.

const BlogPage = () => {
  const { latestArticle, allOtherArticles } = useStaticQuery(graphql`
    query MyQuery {
      latestArticle: allContentfulBlogPost(sort: {order: DESC, fields: publishDate}, limit: 1) {
        nodes {
          title
          slug
          publishDate
          excerpt {
            excerpt
          }
          thumbnailImage {
            imageFile {
              id
              fluid {
                ...GatsbyContentfulFluid
              }
            }
          }
        }
      }
      allOtherArticles: allContentfulBlogPost(sort: {order: DESC, fields: publishDate}, skip: 1) {
        nodes {
          title
          slug
          publishDate
        }
      }
    }
  `)

  const latest = latestArticle.edges[0].node

  return (
    <Layout>
      <ol data-sal="slide-up" data-sal-delay="300" data-sal-easing="ease" className={blogStyles.posts}>
        <li className="latest-post">
          <Link to={`/blog/${latest.slug}`}>
            <h2>{latest.title}</h2>
            <p>{latest.excerpt.excerpt}</p>
            <Img fluid={latest.thumbnailImage.imageFile.fluid} />
          </Link>
        </li>
        {allOtherArticles.edges.map((edge) => {
          return (
            <li className={blogStyles.post}>
              <Link to={`/blog/${edge.node.slug}`}>
                <h2>{edge.node.title}</h2>
                <p>{edge.node.publishedDate }</p>
              </Link>
            </li>
          )
        })}
      </ol>
    </Layout>
  )
}

export default BlogPage

Другой вариант - просто запросить все необходимые поля. Когда вы наносите на карту данные, вы можете проверить индекс и условно отобразить миниатюру и выдержку (а также другие элементы).

{data.allContentfulBlogPost.edges.map((edge, index) => {
  const firstArticle = index === 0

  return (
    <li className={ blogStyles.post }>
      <Link to={ `/blog/${edge.node.slug }`}>
        { firstArticle && (<Img fluid={edge.node.thumbnailImage.imageFile.fluid } />)}
        <h2>{ edge.node.title }</h2>
        { firstArticle && (<p>{ edge.node.title }</p>)}
        <p>{ edge.node.publishedDate }</p>
      </Link>
    </li>
  )
})}
...