Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pull entry drafts? #23

Closed
keithmancuso opened this issue Oct 16, 2017 · 14 comments
Closed

Pull entry drafts? #23

keithmancuso opened this issue Oct 16, 2017 · 14 comments

Comments

@keithmancuso
Copy link

Is it possible to pull entry drafts via CraftQL?

@markhuot
Copy link
Owner

Not yet… but I can look at adding something for it in the next few days. How would you envision something like this working?

Maybe,

{
  drafts(id:123) { # takes all the same parameters that `craft.entries` takes
    title
    ...on News { # uses the same types as the `entries` query uses
      body
    }
  }
}

That's sort of a hack, and what I think I like a little more is adding it in to the Connections approach. The downside is all the added complexity for users just getting started with GraphQL.

{
  entriesConnection(id: 123) {
    edges {
      node {
        # published field data
      }
      drafts {   # an array of drafts for each edge
        edges {  # the draft edges
          node { # each draft node
            # draft field data
          }
        }
      }
    }
  }
}

@keithmancuso
Copy link
Author

Yea the connections approach seems way more powerful.

The syntax seems a bit confusing to me but that’s just cause I’m pretty new to graphql in general, so I’m sure it will make more sense to me once I start using it.

Thanks mark, really loving the plugin so far and excited to be able to really start using it on sites!

@markhuot
Copy link
Owner

This is implemented on dev-master, if you'd like to take a peek. It's still in flux a bit so things may change, but it's stable enough to use for development purposes. I've exposed drafts in two ways,

{
  drafts(id: 1) {
    draftId
    name
    notes
    ...on PostDraft {
      body
    }
  }
}

This is my least favorite implementation, but it's the easiest to wrap your head around so I'm looking to clean up the code that drives this.

A much more powerful approach is to use connections. Connections add a level of abstraction between your craft.entries call and the returned entry. The benefit of this abstraction is that it provides more places to "hook" in to the result set. For example, take the following,

{
  entries {
    id
  }
}

There's no place there to provide any info about the total number returned, where you are in the loop, or how many pages. By converting entries to a connection you now have room for that with,

{
  entriesConnection {
    edges { ... } # `entries` is now placed here
    pageInfo { # we have room in the result set for pagination
      currentPage
      totalPages
    }
  }
}

Taking the above one step further we can even abstract out the actual entry (edge) and provide additional detail on the entry. This is done through nodes,

{
  entriesConnection {
    edges {
      node { ... } # `entries` is now all the way down here
      drafts { # for each `edge` (or entry) we now have all the draft data per entry!
        …
      }
    }
  }
}

Let me know if this is helpful. I'll clean up the code and get this into the stable release soon-ish.

@markhuot
Copy link
Owner

This is implemented as described above. You can find this on release 1.0.0-beta.20.

@edolyne
Copy link

edolyne commented Feb 9, 2018

@markhuot Is there still a way to be able to pull a specific entry draft, or is it just all drafts at this point?

@markhuot
Copy link
Owner

How are you getting the draft id to pull? I think I can support pulling a specific draft, but I’m not sure how useful that is outside of the context of the entry…

@markhuot
Copy link
Owner

Re-opening this until we get this figured out.

@markhuot markhuot reopened this Feb 10, 2018
@edolyne
Copy link

edolyne commented Feb 12, 2018

I'm looking to be able to use the preview button plugin and be able to pull a single draft in relation to an entry.

For example https://mydomain.com/page?draftId=23 would allow me to pull draft 23 of an entry with the slug of page

@markhuot
Copy link
Owner

markhuot commented Feb 12, 2018

Ah, I see. I'm curious though, where is the 23 coming from originally? Is this a Craft template that's passing it though to JS?

In any event, dev-master adds back in a top level draft field.

{
  draft(draftId:123) {
    entryId: id
    ...on EntryType {
      draftData: customField
    }
  }
}

@edolyne
Copy link

edolyne commented Feb 13, 2018

Thanks for adding this back in!

The 23 was just an example of a specific draft id being passed from the control panel to preview the draft version. This way I can use it as a graphql variable for my query.

@markhuot
Copy link
Owner

Bringing drafts back in is now tagged in 1.0.0-beta.29.

@Jones-S
Copy link

Jones-S commented Aug 16, 2019

I understand that I can query the drafts for an article with the id = 5
like this

{
  entriesConnection(id:5) {
    edges {
      node { # the published node, as `craft.entries` would return
        id
        title
      }
      drafts { # an array of drafts
        edges {
          draftInfo {
            draftId
            name
          }
          node { # the draft content
            id
            title
          }
        }
      }
    }
  }
}

But how could I only get the newest draft?
limiting edges does not work.
edges (limit: 1) {...

Sorry I am pretty new to graphql

@narration-sd
Copy link
Contributor

@Jones-S , no need to apologize at all.

I think:

  • no form of GraphQL itself supports this; those in charge of it are very adamant they don't want to get into implementing detail db queries. Only a special resolver function, which you can't add from outside CraftQL, could do what you want.
  • of course people have provided front-ends that do such things, but they would have had to be implemented within CraftQL
  • it's possible that cursors in GraphQL could be employed, but doesn't look advantageous, and in fact CraftQL doesn't appear to support them -- I get empty "" for cursor ids, and other parts missing.

However, what you'd do in a resolver, you can do outside, and I consider that the way. You lose on any efficiency the database might have given with its hyper-optimized manipulations and searches, but for data sizes generally with Craft, and in the case of drafts specifically, shouldn't be an issue.

So, you can pull your list of drafts via CraftQL, and then select the one you want via PHP or JS. I'd use a map (php array_map) I think, and just look for a date or draftNo as you go through the results array, holding the record with max for the return. Something like that, anyway, rather than bother with a sort, since you don't need the code or cpu exercise to get results actually in order.

A last or perhaps first point would be to look into why you want to do this. You may have a goal that needs it, but if it's just to find the draft Craft would be working on in a preview, you can get that directly, as @brandonkelly explains here: #31 (comment)

@Jones-S
Copy link

Jones-S commented Aug 29, 2019

Thank you for your explanation. It was indeed about previews and in the meantime I got to work both of them. For the moment not with apollo, but just with an axios call where I forward the token. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants