gatsbyjs / gatsby

The best React-based framework with performance, scalability and security built in.
https://www.gatsbyjs.com
MIT License
55.29k stars 10.31k forks source link

[question] How does Gatsby know about new content when using gatsby-source-wordpress? #2753

Closed selrond closed 6 years ago

selrond commented 7 years ago

Do I have to manually regenerate the whole site? How does it work?

KyleAMathews commented 7 years ago

Yeah — you'll need to trigger a new build when the WordPress content is updated.

I believe @sebastienfi has a wordpress plugin he's using with Netlify to automate this.

selrond commented 7 years ago

@KyleAMathews you mean sebastienfi/gatsby-wordpress-netlify-starter?

I've glanced into the source but don't see where he's automating it.

Is there something sensible that can be done so it runs automatically? Because in current form it's not very useful.

KyleAMathews commented 7 years ago

He mentioned there's a wordpress plugin he uses that can fire a webhook when content is added or updated.

garytokyo commented 7 years ago

@selrond you can add the following to your functions.php file (or create a plugin)

add_action( 'save_post', 'fireFunctionOnSave' );
function fireFunctionOnSave($post_id)
{
  if(wp_is_post_revision( $post_id) || wp_is_post_autosave( $post_id )) {
    return;
  }
  // Send post request or whatever here
}

Hope that helps

crgeary commented 6 years ago

You should be able to use HookPress too. This will allow you to define webhooks for particular actions/filters in WordPress.

Personally I prefer adding a button to the toolbar that says "publish/deploy" which triggers the webhook.

selrond commented 6 years ago

@garytokyo @crgeary good idea, but I still have to host my static site on a nodejs server in order to rebuild it there right?

garytokyo commented 6 years ago

@selrond not necessarily host it on a nodejs server - you would just have to have node and npm installed on your server (or a server). You could fire off a post request to a php script for instance that then triggers the gatsby build process (I'm pretty sure that is possible to run shell commands from PHP). I haven't set it up yet but I am also fairly sure you can use thirdparty services like DeployBot - set up a webhook that is triggered on wordpress save which runs your deploy commands.

crgeary commented 6 years ago

@selrond If you're hosting your Gatsby site on Netlify (if not, you probably should cos it's awesome), then they include a CI environment that supports Node JS for builds & deployments. :)

selrond commented 6 years ago

@garytokyo right, either way though - you have to have some kind of a private server, instead of shared hosting (which is enough for WordPress alone). It makes it a bit pricier

zetdotcom commented 6 years ago

Hi guys, I know the topic is closed, but when I was looking at this it didn't provide me with the answer (maybe it's just me). I have done a little blog post on how to trigger Gatsby build on new Wordpress post. However, the site needs to be hosted on Netlify (which I find awesome so why not use it).

gatsby-wordpress-netlify-auto-update.

Disclaimer: I am still a newbie so if there is anything wrong with the post let me know.

bogdancss commented 6 years ago

hey @zetdotcom - I tried following the example. I have a Netlify webhook ready and added this to the end of the functions.php file:

add_action( 'save_post', 'fireFunctionOnSave' );
function fireFunctionOnSave($post_id)
{
  if(wp_is_post_revision( $post_id) || wp_is_post_autosave( $post_id )) {
    return;
  }
    $curl = curl_init( 'https://api.netlify.com/build_hooks/123123123' );
    curl_setopt( $curl, CURLOPT_POST, true );
    curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
    $response = curl_exec( $curl );
    curl_close( $curl );
}

After adding/deleting/updating a post, it does not trigger any builds - what am I missing?

Thanks

zetdotcom commented 6 years ago

Hi. Have you set up your deploy settings in Netlify? I.e. give your repository url, ,set build command as 'gatsby build', public directory 'public/', and production branch to 'master'. Is build triggered when you push to your github repo?

gapgag55 commented 6 years ago

@b0gd4n I finally solve this problem by using code below.

$response = Requests::post( NETLIFY_BUILD_HOOK );

Reference: https://deliciousbrains.com/php-curl-how-wordpress-makes-http-requests/

gapgag55 commented 6 years ago

@zetdotcom Absolutely yes!!

bogdancss commented 6 years ago

@gapgag55 so replace

$response = curl_exec( $curl ); with $response = Requests::post( NETLIFY_BUILD_HOOK ); ?

gapgag55 commented 6 years ago

@b0gd4n Do like this,

add_action( 'save_post', 'fireFunctionOnSave' );
function fireFunctionOnSave($post_id)
{
   if(wp_is_post_revision($post_id) || wp_is_post_autosave($post_id)) {
      return;
   }
   $response = Requests::post( NETLIFY_BUILD_HOOK_URL );
}
bogdancss commented 6 years ago

@gapgag55 damn - that worked. Thank you!

bogdancss commented 6 years ago

hey @gapgag55 - is there a way of not triggering a build when a user logs in? - the code above seems to trigger the hook as soon as I log in, as well as when I bin a draft post and if I save a draft of a post.

Would there be a way of only triggering the hook when you bin a published post, when you change a published post to un-published, and when you publish a post?

Thanks

gapgag55 commented 6 years ago

@b0gd4n Change the WP hook to fit your solution A link below might help you.

https://stackoverflow.com/questions/4043976/how-to-filter-post-content-during-publish-save-routine-with-str-ireplace?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

crgeary commented 6 years ago

I'll probably make a WordPress plugin for this in the near future. I'll make it work for anything that uses webhooks, but with extra bits specifically for Netlify (as they have an API I can access).

I was thinking..

  1. A "deploy" button that you can press to manually trigger a deployment.
  2. Hooking into the common CRUD events that WP fires for posts/pages & taxonomies.
  3. Pulling in Netlify deployment history via their API.
  4. Supporting custom actions/filters so you can hook in as you need to for custom stuff.

Does anyone want/need anything else? :)

crgeary commented 6 years ago

TLDR... Here's a plugin I wrote to do it for you: crgeary/wp-jamstack-deployments.


@b0gd4n the save_post hook will fire anytime a post is changed. Whether that be an edit you've made, trashing a post, or even just clicking "new post" as this will create a draft for you.

Just to make things more annoying, WordPress uses posts for menus & menu items (among other things). Therefore saving menus will trigger a build per menu item + the menu itself. So basically a navigation menu with 10 items will fire 11 save_post hooks when you save it.

This is probably why that code runs when you login to the site. WordPress is probably saving some kind of a post in the background, which usually only happens when someone is actively using the site due to how WP-Cron works.


@b0gd4n & @zetdotcom I see you're using curl_* functions to make a request to Netlify. I would recommend you use wp_remote_post or wp_safe_remote_post to abstract away the possible complexities and let WordPress core handle it.


With this in mind, I've built a plugin that has a manual deploy button as part of the admin bar, and also automatically deploys whenever you change a post type (save_post hook), or when you change a term (created_term, delete_term, edit_term hooks). With the ability to extend this and add your own hooks programmatically.

I have some additional features to add, but the core work is done around triggering builds.

The future roadmap is to add better integration with Netlify, and decrease the number of requests made by deferring them. If you ran a script that updated 10 posts, currently it would fire 10 requests. However, I'd like to make it so that 10 updates happen, and then 1 request is made after the 10th. But this is a future todo.

For now, here is the plugin: crgeary/wp-jamstack-deployments

I'll look at getting this onto the WordPress repository, but for now (at least while it's BETA) it's going to be Github only.

KyleAMathews commented 6 years ago

Due to the high volume of issues, we're closing out older ones without recent activity. Please open a new issue if you need help!

dbismut commented 6 years ago

Hey, just for the sake of reference, if anyone gets here.

I've set up a basic prototype using the following stack.

Features

What's missing

Total cost

Gatsby repo is available here. It's very simple, can probably be optimized. In Wordpress enabled theme functions.php, here is how I manage to enable live preview changes. I'm far from being a php / wordpress pro so this can also be optimized.

// functions.php
function preview_link_fix( $preview_link, $post ) {
  $id = $post->ID;

  $latest_revision_id = '';

  if($post->post_status !== 'draft') {
    $revisions = wp_get_post_revisions($id);
    $last_revision = array_shift($revisions);
    $latest_revision_id = $last_revision ? $last_revision->ID : '';
  }

  $nonce = wp_create_nonce( 'wp_rest' );

  $parsedUrl = parse_url( $preview_link );
  $path = $parsedUrl['path'];
  if ($path === '/') $path = "/preview";

  $scheme = $parsedUrl['scheme'];
  $host = $parsedUrl['host'];
  $query = $parsedUrl['query'];

  return "$scheme://$host$path?$query&revision_id=$latest_revision_id&_wpnonce=$nonce&status=$post->post_status";
}

add_filter( 'preview_post_link', 'preview_link_fix', 10, 2);

Happy to help.

jimmysafe commented 5 years ago

Hey, I have setup a docker with gatsby and wordpress but for some reason I would like to keep everything together and not use netlify to host my gatsby site.

What I would like to do is to host the whole app with wordpress, db and gatsby on Digital Ocean.

Is there a way to trigger the gatsby site build on wordpress update button click with this setup?

hopefully someone can help me with this, :)

jonniebigodes commented 5 years ago

@jimmysafe to the best of my knowledge, for the time being, when you use gatsby and probably gatsby-source-wordpress, basically it's a one way process, you fetch the data at build time. When you update wordpress, gatsby has no way to to know about the update. You might need to setup some webhooks to trigger a new deployment when content changes, for instance when you add a post/page.

slaterbbx commented 4 years ago

This might be something to mention, you can host on "Firebase Webhosting" for free, it also has cloud functions for the node backend, you can host there, do your backend on prismic.io ( also free and has graphql ) and prismic.io has webhooks available.

Now you can have everything hosting and scripted in JS for free 100% with all your needs filled.

You will not get to use wordpress headless, but really, prismic is 1000 times better and more efficient + its a CDN and its 100% freemium up to some crazy limits like firebase is.

Koli14 commented 4 years ago

I just find this project, seems promising: https://github.com/staticfuse/create-gatsby-theme-publisher They created a WP plugin, which handles automatic deployment, and they have a quite detaild doc+tutorial. ;)

ozluy commented 4 years ago

If you use Netlify,

on your Netlify account go to Settings > Build & deploy > Build hooks > Add build hook

then you will have hook looks like this https://api.netlify.com/build_hooks/{uuid}

copy that and use it on Wordpress go to WP Admin > Settings > Webhooks > Add webhook paste your Netlify webhook by choosing one of publish_post, publish_page or comment_post.

It worked for me 🎉