Gatsbyのマークダウン投稿で注目の画像に絶対パスを使用する

avianey

マークダウンの投稿とページ画像を操作するためのGatsbyチュートリアルに従いましたがこれはうまく機能していますが、達成したいのは、画像の相対パスを使用するのではなく、静的な場所から画像をフェッチすることです。

このような画像を参照したい(フロントマター)

featuredImage: img/IMG_20190621_112048_2.jpg

IMG_20190621_112048_2.jpg/src/data/img下のマークダウンファイルと同じディレクトリの代わりにある場所/src/posts

私はgatsby-source-filesystemこのようにセットアップしようとしました

{
  resolve: `gatsby-source-filesystem`,
  options: {
    name: `posts`,
    path: `${__dirname}/src/posts`,
  },
},
{
  resolve: `gatsby-source-filesystem`,
  options: {
    name: `data`,
    path: `${__dirname}/src/data/`,
  },
},

しかし、投稿テンプレートのgraphQLクエリは失敗します:

export const query = graphql`
  query($slug: String!) {
    markdownRemark(fields: { slug: { eq: $slug } }) {
      html
      frontmatter {
        title
        featuredImage {
          childImageSharp {
            fluid(maxWidth: 800) {
              ...GatsbyImageSharpFluid
            }
          }
        }
      }
    }
  }

タイプ「String」にはサブフィールドがないため、GraphQLエラーフィールド「featuredImage」に選択を含めることはできません。

ポストマークダウンディレクトリとは別の場所から画像をフェッチする方法はありますか?

デレク・グエン

Gatsbyでこれを実現するのは以前はかなり面倒でしたが、新しいcreateSchemaCustomizationNode APIドキュメント(Gatsby 2.5以降)のおかげで比較的簡単です。

これが私があなたのリポジトリ構造を複製するデモです:github

関連するコードが存在する場所は次のとおりです:github

これを機能させるためのコードは次のとおりです。

// gatsby-node.js

const path = require('path')

exports.createSchemaCustomization = ({ actions }) => {
  const { createFieldExtension, createTypes } = actions

  createFieldExtension({
    name: 'fileByDataPath',
    extend: () => ({
      resolve: function (src, args, context, info) {
        const partialPath = src.featureImage
          if (!partialPath) {
            return null
          }

        const filePath = path.join(__dirname, 'src/data', partialPath)
        const fileNode = context.nodeModel.runQuery({
          firstOnly: true,
          type: 'File',
          query: {
            filter: {
              absolutePath: {
                eq: filePath
              }
            }
          }
        })

        if (!fileNode) {
          return null
        }

        return fileNode
      }
    })
  })

  const typeDefs = `
    type Frontmatter @infer {
      featureImage: File @fileByDataPath
    }

    type MarkdownRemark implements Node @infer {
      frontmatter: Frontmatter
    }
  `

  createTypes(typeDefs)
}

使い方:

これには2つの部分があります。

  1. markdownRemark.frontmatter.featureImagegraphqlが文字列ではなくファイルノードに解決されるように拡張します。createTypes
  2. @fileByDataPath介して新しい体の拡大作成しますcreateFieldExtension

createTypes

現在、ギャツビーfrontmatter.featureImageは文字列として推論しています。親タイプを変更して、代わりにfeatureImageを文字列として読み取るようにGatsbyに依頼します。

  type Frontmatter {
    featureImage: File
  }

これだけでは不十分ですが、このFrontmatterタイプもその親に渡す必要があります

  type Frontmatter {
    featureImage: File
  }

  type MarkdownRemark implements Node {
    frontmatter: Frontmatter
  }

我々はまた、追加します@inferつまり、ギャツビーが、それはこれらのタイプの他のフィールドを推測できることを知ることができますタグをfrontmatter.titlemarkdownRemark.htmlなど

次に、これらのカスタムタイプを次の宛先に渡しますcreateTypes

exports.createSchemaCustomization = ({ actions }) => {
  const { createTypes } = actions

  const typeDefs = `
    type Frontmatter @infer {
      featureImage: File
    }

    type MarkdownRemark implements Node @infer {
      frontmatter: Frontmatter
    }
  `

  createTypes(typeDefs)
}

これで、起動localhost:8000/___graphqlして画像のクエリを試すことができます

query Post {
  markdownRemark {
    frontmatter {
      featureImage {
        id
      }
    }
  }
}

そして、私たちは...

エラー:null不可能なフィールドFile.idに対してnullを返すことはできません。

これは、GatsbyfeatureImageがファイルノードであるべきだと理解している一方で、そのファイルをどこで取得するかがわからないためです。

この時点で、を使用createResolversしてフィールドを手動でファイルノードに解決createFileExtensionするか、同じことを行うことができます。createFileExtensionより多くのコードの再利用が可能になるため(任意のフィールドを拡張できます)、createResolversこの場合は特定のフィールドに対してより便利であるため、私は選択しますsrc/dataディレクトリからファイルを解決するだけでよいので、この拡張子を呼びますfieldByDataPath

createFileExtension

resolve属性を見てみましょう。これは、以下を取り込む関数です。

  • ソース:親フィールドのデータ(この場合はfrontmatter
  • args:featureImageクエリで渡される引数これは必要ありません
  • context:にはnodeModel、Gatsbyノードストアからノードを取得するために使用するが含まれます
  • info:このフィールドに関するメタデータ+スキーマ全体

img/photo.jpgから元のパス(を見つけsrc.featureImage、それをに接着してsrc/data完全な絶対パスを取得します。次に、nodeModelにクエリを実行して、絶対パスが一致するファイルノードを見つけます。すでにポイントgatsby-source-filesystemているのでsrc/data、画像(photo.jpg)はGatsbyノードストアにあります。

パスまたは一致するノードが見つからない場合は、を返しnullます。

  resolve: async function (src, args, context) {
    // look up original string, i.e img/photo.jpg
    const partialPath = src.featureImage
      if (!partialPath) {
        return null
      }

    // get the absolute path of the image file in the filesystem
    const filePath = path.join(__dirname, 'src/data', partialPath)
    
    // look for a node with matching path
    const fileNode = await context.nodeModel.runQuery({
      firstOnly: true,
      type: 'File',
      query: {
        filter: {
          absolutePath: {
            eq: filePath
          }
        }
      }
    })

    // no node? return
    if (!fileNode) {
      return null
    }

    // else return the node
    return fileNode
  }

作業の99%を完了しました。最後に行うことは、これを移動してこの解決関数をcreateFieldExtension;に渡すことです。createTypesに新しい拡張機能を追加するだけでなく

createFieldExtension({
  name: 'fileByDataPath' // we'll use it in createTypes as `@fileByDataPath`
  extend: () => ({
    resolve,             // the resolve function above
  })
})

const typeDef = `
  type Frontmatter @infer {
    featureImage: File @fileByDataPath // <---
  }
  ...
`

これで、src/data/フロントマターから相対パスを使用できるようになりました。

エクストラ

fileByDataPath実装方法では、という名前のフィールドでのみ機能しますfeatureImageこれはあまり役に立たないので、名前が_data;で終わるフィールドで機能するように変更する必要がありますまたは、少なくとも、作業するフィールド名のリストを受け入れます。

編集には少し時間があったので、これを行うプラグインを作成し、ブログも作成しました

Edit 2 Gatsbyはそれ以来runQuery非同期になり(2020年7月)、これを反映するように回答を更新しました。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

注目の画像の添付ページでパーマリンクを取得する

分類Dev

Wordpress / WooCommerceで商品画像/注目画像の絶対パスを取得する方法はありますか

分類Dev

jekyllのマークダウンプロセッサとして注目に値するものを使用

分類Dev

CMakeに絶対インクルードパスの使用を強制する

分類Dev

JavaScriptを使用して、相対リンク画像を文字列内の絶対パス画像に置き換えます

分類Dev

ウィンドウを最小化すると、ラッパーの外に表示される絶対位置の画像

分類Dev

Gatsby.js:マークダウンでの相対パスリンクの前処理

分類Dev

Wordpressの「投稿ページ」に注目の画像を表示する

分類Dev

別のページで注目の投稿画像を取得する

分類Dev

マークアップで絶対パスを使用して背景画像を追加する方法

分類Dev

インポートにtypescriptで絶対パスを使用する

分類Dev

相対ファイルパスを使用してRマークダウンチャンクに画像を挿入する方法

分類Dev

Gatsby-JSが注目の画像をランダムに失うのはなぜですか?

分類Dev

chrootの絶対パスを使用して-tproc proc proc /をマウントする方法は?

分類Dev

XAML で絶対パスを使用して画像を取得できるのに、コードの背後で機能しないのはなぜですか?

分類Dev

Django RestFrameworkで画像フィールドの絶対パスを取得する

分類Dev

マウスをクリックしたときにQTreeWidgetで現在選択されているアイテムの絶対パスを取得する方法

分類Dev

GitLabwikiに投稿されるマークダウンテーブル内のRegExパイプをエスケープする際の問題

分類Dev

画像のマークダウンを画像のhtmljavascriptに解析する正規表現

分類Dev

絶対システムパスにダウンロードするのではなく、オブジェクトとしてS3ファイルを取得する

分類Dev

'requests-html'を使用するときに絶対リンクパスを含む生のhtmlを取得する方法

分類Dev

Wordpress管理者:注目の画像メタボックスにIDの変更を投稿する

分類Dev

geditでマークダウンパネルをカスタマイズするのに役立ちます

分類Dev

geditでマークダウンパネルをカスタマイズするのに役立ちます

分類Dev

mysqlを介してワードプレスで注目の画像のない投稿を削除する方法は?

分類Dev

特定のユーザーに対して、すでにマウントされているパーティションの1つのNTFSフォルダーのみへのアクセスを許可するにはどうすればよいですか?

分類Dev

マルチパートhttp投稿リクエストで画像の配列を投稿する方法

分類Dev

Jekyllの投稿にマークダウンフォーマットを使用させ、CSSを無視させる方法です

分類Dev

パス変数を使用してRマークダウンに画像を挿入する

Related 関連記事

  1. 1

    注目の画像の添付ページでパーマリンクを取得する

  2. 2

    Wordpress / WooCommerceで商品画像/注目画像の絶対パスを取得する方法はありますか

  3. 3

    jekyllのマークダウンプロセッサとして注目に値するものを使用

  4. 4

    CMakeに絶対インクルードパスの使用を強制する

  5. 5

    JavaScriptを使用して、相対リンク画像を文字列内の絶対パス画像に置き換えます

  6. 6

    ウィンドウを最小化すると、ラッパーの外に表示される絶対位置の画像

  7. 7

    Gatsby.js:マークダウンでの相対パスリンクの前処理

  8. 8

    Wordpressの「投稿ページ」に注目の画像を表示する

  9. 9

    別のページで注目の投稿画像を取得する

  10. 10

    マークアップで絶対パスを使用して背景画像を追加する方法

  11. 11

    インポートにtypescriptで絶対パスを使用する

  12. 12

    相対ファイルパスを使用してRマークダウンチャンクに画像を挿入する方法

  13. 13

    Gatsby-JSが注目の画像をランダムに失うのはなぜですか?

  14. 14

    chrootの絶対パスを使用して-tproc proc proc /をマウントする方法は?

  15. 15

    XAML で絶対パスを使用して画像を取得できるのに、コードの背後で機能しないのはなぜですか?

  16. 16

    Django RestFrameworkで画像フィールドの絶対パスを取得する

  17. 17

    マウスをクリックしたときにQTreeWidgetで現在選択されているアイテムの絶対パスを取得する方法

  18. 18

    GitLabwikiに投稿されるマークダウンテーブル内のRegExパイプをエスケープする際の問題

  19. 19

    画像のマークダウンを画像のhtmljavascriptに解析する正規表現

  20. 20

    絶対システムパスにダウンロードするのではなく、オブジェクトとしてS3ファイルを取得する

  21. 21

    'requests-html'を使用するときに絶対リンクパスを含む生のhtmlを取得する方法

  22. 22

    Wordpress管理者:注目の画像メタボックスにIDの変更を投稿する

  23. 23

    geditでマークダウンパネルをカスタマイズするのに役立ちます

  24. 24

    geditでマークダウンパネルをカスタマイズするのに役立ちます

  25. 25

    mysqlを介してワードプレスで注目の画像のない投稿を削除する方法は?

  26. 26

    特定のユーザーに対して、すでにマウントされているパーティションの1つのNTFSフォルダーのみへのアクセスを許可するにはどうすればよいですか?

  27. 27

    マルチパートhttp投稿リクエストで画像の配列を投稿する方法

  28. 28

    Jekyllの投稿にマークダウンフォーマットを使用させ、CSSを無視させる方法です

  29. 29

    パス変数を使用してRマークダウンに画像を挿入する

ホットタグ

アーカイブ