【问题标题】:Download files before build in gatsby wordpress在构建 gatsby wordpress 之前下载文件
【发布时间】:2020-04-16 20:49:41
【问题描述】:

我有一个客户,我正在与他合作的客户需要他的 pdf 文件可以在浏览器中读取,并且用户不需要先下载它们,结果证明这不是通过 Wordpress 完成的选项,所以我认为我可以如果它们不存在,每次构建之前在 gatsby 中下载它们,我想知道这是否可能。

我找到了这个仓库:https://github.com/jamstack-cms/jamstack-ecommerce

显示了使用此代码的方法:

function getImageKey(url) {
  const split = url.split('/')
  const key = split[split.length - 1]
  const keyItems = key.split('?')
  const imageKey = keyItems[0]
  return imageKey
}

function getPathName(url, pathName = 'downloads') {
  let reqPath = path.join(__dirname, '..')
  let key = getImageKey(url)
  key = key.replace(/%/g, "")
  const rawPath = `${reqPath}/public/${pathName}/${key}`
  return rawPath
}

async function downloadImage (url) {
  return new Promise(async (resolve, reject) => {
    const path = getPathName(url)
    const writer = fs.createWriteStream(path)
    const response = await axios({
      url,
      method: 'GET',
      responseType: 'stream'
    })
    response.data.pipe(writer)
    writer.on('finish', resolve)
    writer.on('error', reject)
  })
}

但是如果我把它放在我的 createPages 中并且我也不能在它之外使用它,它似乎不起作用,因为我无权访问 graphql 来首先查询数据。

知道怎么做吗?

【问题讨论】:

  • 什么不起作用?
  • 当我将代码放入 createPages 中时,查询不会运行,并且无法在“Query”类型上查询字段“allWordpressWpTechnicalInfo”。例如。
  • 您是否尝试过查看一些 other APIs 的 gatsby 节点?

标签: node.js reactjs wordpress gatsby


【解决方案1】:

WordPress源示例定义为async:

exports.createPages = async ({ graphql, actions }) => {

...所以您已经可以在查询数据之后(以及在createQuery() 调用之前)使用await 下载您的文件(-s)。它应该(未测试)很简单:

// Check for any errors
if (result.errors) {
  console.error(result.errors)
}

// Access query results via object destructuring
const { allWordpressPage, allWordpressPost } = result.data

const pageTemplate = path.resolve(`./src/templates/page.js`)
allWordpressPage.edges.forEach(edge => {

  // for one file per edge
  // url taken/constructed from some edge property
  await downloadImage (url);

  createPage({

当然,对于多个文件,您应该使用 Promise.all 在创建页面之前等待 [resolving] 所有 [returned promise] 下载:

allWordpressPage.edges.forEach(edge => {

  // for multiple files per edge(page)
  // url taken/constructed from some edge properties in a loop

  // adapth 'paths' of iterable (edge.xxx.yyy...)
  // and/or downloadImage(image) argument, f.e. 'image.someUrl'
  await Promise.all( 
    edge.node.someImageArrayNode.map( image => { return downloadImage(image); }
  );

  createPage({

如果您需要传递/更新图像节点(用于组件使用),您应该能够改变节点,例如:

  await Promise.all( 
    edge.node.someImageArrayNode.map( image => { 
      image["fullUrl"] = `/publicPath/${image.url}`;
      return downloadImage(image.url); // return Promise at the end
    }
  );

  createPage({
    path: slugify(item.name),
    component: ItemView,
    context: {
      content: item,
      title: item.name,
      firstImageUrl: edge.node.someImageArrayNode[0].fullUrl,
      images: edge.node.someImageArrayNode

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 1970-01-01
    • 2015-03-28
    • 2021-11-27
    相关资源
    最近更新 更多