Import posts from Wordpress

default discord avatar
stfn
8 months ago
20

Which is the best way to import post from Wordpress?


Thank you!


Cheers

  • discord user avatar
    denolfe
    Payload Team
    8 months ago

    Currently, we don't have a way to do this that doesn't involve scripting with the Local API. However, I think this is something that we may look into in the future.

  • default discord avatar
    stfn
    8 months ago

    Ok ok thank you

  • default discord avatar
    christopher.nowlan
    8 months ago

    @denolfe do you have an example of how to do that

  • discord user avatar
    denolfe
    Payload Team
    8 months ago

    Sure, you would do something like this:



    import payload from 'payload';
    
    require("dotenv").config();
    
    const { PAYLOAD_SECRET_KEY, MONGO_URL } = process.env;
    
    // This function ensures that there is at least one corresponding version for any document
    // within each of your draft-enabled collections.
    
    const migratePosts = async () => {
      // Initialize Payload
      // IMPORTANT: make sure your ENV variables are filled properly here
      // as the below variable names are just for reference.
      await payload.init({
        secret: PAYLOAD_SECRET_KEY,
        mongoURL: MONGO_URL,
        local: true,
      });
    
      // Read data from WordPress, you'll need to figure this part out
      const wpPosts = await getPostsFromWordPress();
    
      for (const wpPost of wpPosts) {
        await payload.create({
          collection: "posts",
          // data to be saved
          data: {
            title: wpPost.title,
            description: wpPost.description,
          },
      });
    };
    
    migratePosts();


    Local API docs here:

    https://payloadcms.com/docs/local-api/overview#local-api
  • default discord avatar
    christopher.nowlan
    7 months ago
    const payload = require('payload');
    const path = require('path');
    const slateSerializers = require('slate-serializers')
    
    const { htmlToSlate, payloadHtmlToSlateConfig } = slateSerializers
    require('dotenv').config();
    
    const {PAYLOAD_SECRET, MONGODB_URI} = process.env;
    
    
    const authorId = '' // Payload Author ID
    const websiteUrl = '' // WordPress website url 
    
    const transformWordPressData = ( data ) => {
        return {
            title: data.title.rendered,
            slug: data.slug,
            excerpt: data.excerpt.rendered,
            updatedAt: data.modified, // might actually be  data.modified_gmt
            publishedOn: data.date, // might actually be  data.date_gmt,
            _status: data.status === 'publish' ? 'published' : 'draft',
            author: authorId,
            layout: [
                {
                    blockType: 'content',
                    contentFields: {
                        richText: htmlToSlate(data.content.rendered, payloadHtmlToSlateConfig)
                    }
                }
            ]
        }
    }


    // This function ensures that there is at least one corresponding version for any document
    // within each of your draft-enabled collections.
    const importFromWordPress = async () => {
    
        const baseUrl = `${websiteUrl}/wp-json/wp/v2/posts?per_page=100`
        const defaultOptions = {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
            }
        }
    
        try {
    
            await payload.init({
                secret: PAYLOAD_SECRET,
                mongoURL: MONGODB_URI,
                local: true,
            });
    
            const wpPosts = []
    
            const getTotalPagesReq = await fetch(baseUrl, defaultOptions)
            // Get's the total number of post pages 
            const getTotalPagesRes = getTotalPagesReq.headers.get('x-WP-TotalPages')
    
    
            for (let i = 0; i < getTotalPagesRes; i++) {
               const wpPostReq = await fetch( `${baseUrl}&page=${i+1}`, defaultOptions)
               const wpPostRes = await wpPostReq.json()
               wpPosts.push(wpPostRes)
            }
    
    
            for (const wpPost of wpPosts.flat()) {
    
                await payload.create({
                    collection: 'news',
                    // data to be saved
                    data: transformWordPressData(wpPost),
                })
            }
    
    
        } catch (err) {
            console.log('Unable to import posts into payload from WordPress');
            console.error(err);
            process.exit(0);
        }
    
        console.log('WordPress import completed!');
        process.exit(0);
    };
    
    importFromWordPress();


    @stfn above is a simple example of using WordPress rest api to import post content into Payload



    I then have a simple package.json script I run -

    "import": "PAYLOAD_CONFIG_PATH=dist/payload.config.js node ./importFromWordPress.js"


    @denolfe above is a pretty crud example on how to import from WordPress to Payload using the WordPress Rest API

  • default discord avatar
    stfn
    7 months ago

    Woow thank you, it works! And have you found a solution also for convert Gutemberg blocks?

  • discord user avatar
    denolfe
    Payload Team
    7 months ago

    This is awesome, thanks for sharing! 🙏

  • default discord avatar
    christopher.nowlan
    7 months ago

    At the moment It just works with the WordPress content. Eventually I will look at importing media. @stfn do you have an example api endpoint using Gutenberg?



    If you have access to the theme or able to add plugins you could write a custom rest api endpoint with all the data you need to import into Payload. If you use ACF flexible content it would probably be pretty easy to match flexible content blocks with Payload blocks



    I think it would be tricker to import data from a WordPress website that is using a Page builder



    @denolfe I noticed that there is a filePath property in the local API -

    https://payloadcms.com/docs/local-api/overview

    . How do I specify which field I want to add that media too

  • discord user avatar
    denolfe
    Payload Team
    7 months ago

    That is specifically for if you have

    upload

    enabled for the collection. Payload will handle storing it accordingly.

  • default discord avatar
    christopher.nowlan
    7 months ago

    Ok. Is there way to add images to blocks or other fields



    @stfn I figured out how to add images from the WordPress rest API. If you need the code let me know and I can share

  • discord user avatar
    denolfe
    Payload Team
    5 months ago

    @christopher.nowlan Sharing it here would be great. These conversations eventually end up in the community-help on our website, so extremely helpful for discovery by other devs.

  • default discord avatar
    christopher.nowlan
    5 months ago

    No worries. Here is the file. @denolfe . If I had access to the theme or server I would be able to write an api with more data to import

Open the post
Continue the discussion in Discord
Like what we're doing?
Star us on GitHub!

Star

Connect with the Payload Community on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.