Скачать файлы перед сборкой в ​​гэтсби WordPress - PullRequest
1 голос
/ 16 апреля 2020

У меня есть клиент, с которым я работаю, которому нужно, чтобы его 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 для запроса данных в первую очередь.

Есть идеи, как это сделать?

1 Ответ

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

Пример источника WordPress определен как async:

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

... поэтому вы уже можете использовать await для загрузки вашего файла (-ов) сразу после запроса данных (и до * 1006) * вызов). Это должно быть (НЕ ПРОВЕРЕНО) так же просто, как:

// 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, чтобы дождаться [разрешения] всех загрузок [возвращенного обещания] перед созданием страницы:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...