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

Feature Request: Markdown Directive in GraphQL #4832

Closed
AugustMiller opened this issue Aug 28, 2019 · 15 comments
Closed

Feature Request: Markdown Directive in GraphQL #4832

AugustMiller opened this issue Aug 28, 2019 · 15 comments
Assignees
Labels
enhancement improvements to existing features graphql ⚙️ features related to the GraphQL API

Comments

@AugustMiller
Copy link
Contributor

Sorry, I did this out of order—might have been quicker (and less overhead) to just suggest it, but it felt like a fun hacking project to get familiar with the internals of the new GraphQL API! ❤️

Basically, it'd be great to be able to process a field in a GraphQL response as Markdown, like we can with {{ entry.myField | md }} in Twig.

The PR I just issued (#4831) should address this.

@AugustMiller AugustMiller changed the title Feature Request: Markdown Support Feature Request: Markdown Directive in GraphQL Aug 28, 2019
@narration-sd
Copy link
Contributor

narration-sd commented Aug 28, 2019

@AugustMiller , this does sound interesting, and useful.

I'd like to write a note here not only for you, as it's clear from responses that there's a pent-up urge which Craft's own GraphQL will be better at setting free.

The problem point in this I believe is directives. Attractive surely, and in many regards easy to do. In fact I did kind of an involved one more than a year ago for CraftQL, made complicated only because of how that code was arranged. The owner decided he wanted to do it his way. This had less power than mine, but did cover the immediate need, so I let it go. This is just experience.

But there are issues with directives. They require a GraphQL engine which lets you enact the ones you want.

Craft Gql is likely to be flexible, in the spirit this project holds, and that you're attempting to exercise. But other engines aren't, and in the world of JavaScript frameworks, where the embedded engine must in turn call into Craft's, it doesn't seem that they generally are.

The ones I'm speaking towards directly are Gatsby and Gridsome. These, as others will, use internal GraphQL engines so that they can query information in the filesystem -- in fact specifically Markdown. That they can go outside this, as to Craft, is because plugins have been invented to merge in remote GraphQL schemas and their sources. I believe it's commonly done by engaging the 'schema stitching' aspect of GraphQL.

But these engines don't deal with directives except for the ones they know. Thus even if you try CraftQL's very simple @date formatter directive from Gatsby or Gridsome, the query fails, founders on this. It's a general case.

Why this is so may well go back to the originators of GraphQL, Facebook. Their project leads have been very definite that they're sorry they invented directives, and don't want to support more than the trivial early examples. This may be a pairing with their embedded in rock position on keeping GraphQL very simpleminded about actual query capabilities.

Keeping this discussion to the point, where do we begin to see issues with directives? I've been talking with Andris, who's been doing yeoman work -- and has clear thinking and great ideas aplenty including on this subject, about (among a few other things) the present way Gql handles image transforms.

It's at present done as a directive. It fails immediately in both the Gatsby and Gridsome engines. I know because I've been long preparing a fully workable, simple to use solution for previews with both of those on Craft, and I've held it up again to get Gql in there, before it goes out the door. Andris is considering, and I'm sure I don't know all the magic he's got in mind!

I just did a more careful search than ever to see if there was any action on non-native directives for either Gatsby or Gridsome.

Gridsome is the elegant one, likely to be a favorite for Craft, and it has nothing, while all the rest of it feels very nice at least as I've touched it. Gatsby, I've managed to find a few tendrils, labeled as 'nice to have', which don't look like they're going anywhere fast. I'm not confident if what I found would actually support what we'd need if it were to be implemented, as they always have their own purposes. One of those being a $600/year previewer, for what thoughts that may bring.

So, a Markdown directive is likely a very nice thing to have if you don't want to use a Gridsome or a Gatsby, and cheers on making one, August.

I guess I'm thinking the general idea of extending what Craft Gql can do by directives remains that seemingly attractive notion, as it first was indeed to me, but which won't work in scenarios important to the larger context.

A Gridsome etc. is a lot of work; you can look at the (quite cheerful, intelligent, and even-tempered) project, there particularly to see. Gatsby is looser and larger. Do we want to be doing that as independent one-off work often, even the more skilled and name-your-package mavens?

If we do think of js compiled page engines as a great component, to give wonderful web performance when driven from the flexibility of a Craft content machine, what's another approach?

I guess what occurs to me is direct Craft custom fields. In this Markdown case, where you could write the Markdown in the field -- or paste it in from a good Markdown editor, like Typora, and then the field would deliver the Rich Text result, just as Redactor does today.

If that works, than probably any solution where a directive might have appealed could play as well as a Craft field. The underlying code which does the business would anyway be the same, no?

Ok, this was a definite opinion piece, and may have its flaws, composed on the moment, and just on how things seem to me. I hope it's useful to have put it 'out there'. None of us know all the answers, and we can just try to accumulate the judgement each time, so surely it feels in this software world...

Again, a good smile on what you did, August :)
Clive

@narration-sd
Copy link
Contributor

[forgot again to use Preview, so edited that epistle after first up. Best to read then online in Github, rather than in mail...]

@AugustMiller
Copy link
Contributor Author

Thanks for the thoughtful response, @narration-sd!

If I understand—Directives can be easily confused with native GraphQL functionality that ends up not be portable between implementations? I can imagine the frustration after using the @markdown directive in Craft, then turning to a Gatsby project and it it being unavailable (or vice-versa, as you may be suggesting re: pace/spirit of development in other GraphQL-aware systems).

I could have sworn I was just (this evening) looking at a feature request for a proper Markdown field that handled this in the way you're describing—a sort of "default" behavior for the Field class that would produce HTML instead of plain Markdown. Can't find it, now!

This is something I hadn't considered, and I'd love to hear the team's thoughts. I suppose the best option might be to allow Directives to be registered via an Event by Plugins, so that developers will be fully aware of where they come from. 🤞

@andris-sevcenko
Copy link
Contributor

This is something I hadn't considered, and I'd love to hear the team's thoughts. I suppose the best option might be to allow Directives to be registered via an Event by Plugins, so that developers will be fully aware of where they come from.

If only... :)

I'm not sure if this would belong in the core, because, arguably, it assumes the end target is an HTML page/view/component. I'll leave this one open as a starting point for a conversation we should have internally, anyway.

@narration-sd
Copy link
Contributor

Nice reply, @AugustMiller , reading late...

Yes, what the field would deliver would be for Gql a String, be it HTML, and that's just what the eventually receiving Gridsome/Gatsby/et al needs to see.

I kind of thought I'd heard of something like this also, but can't place it -- may have been in another venue...

@ghost
Copy link

ghost commented Aug 28, 2019

I admit i have no idea of Graphql internals, so this may be a silly question...

Would it be somehow possible to add methods of a custom behavior class as a field to the graphql schema?

We do this a lot in element-api, for example for unit/currency conversions, or complex matrix block queries with additional joins involved etc.

Currently i see no way of porting such stuff over to graphql...

(Could also be used for markdown, transforms etc.)

@AugustMiller
Copy link
Contributor Author

@andris-sevcenko Ohhhh, boy. Somehow I missed this, despite making a change within a few lines? 🙄 At least we're on the same wavelength…

Another great argument, re: assumption that data will be consumed by a web-based tool. ✌️ It might be a bit different though, in that Directives allow the client to decide whether it gets Markdown or HTML?

Either way, I'm inclined to close the PR so as not to get hopes up (or encourage other trivial ones with more Directives), and work on a little GraphQL toolkit plugin with a variety of handy Directives—instead of having one 20-line plugin per string manipulation method!

Thanks for all the feedback! 💞

@wsydney76 I may need some additional details, or it could be that I'm hung up on "Behavior" as a Yii-ism, but is what you're asking in relation to custom functionality you've patched in (say, like $myEntry->getFrontEndEditUrl() to point at a custom route in your app) that you want to access via GraphQL? I can imagine these attached Behaviors as well as a number of Craft/Twig template helpers being valuable, and I suspect that's what Andris and the Craft team would talk about in response to first-party support/encouragement for use of Directives.

Maybe the more direct answer is "I don't know, either?" 😉 Still getting the hang of GraphQL, so there may be more appropriate terms for what you're describing than Directives. Immediately, though, I can see major hurdles in dealing with the security of a system that allows the Client to run methods/behaviors on Craft objects that may or may not mutate or expose data that otherwise should be inaccessible.

There's definitely a tipping point (in our case, reached at about 10pm last night) where the "right" path forward was to resort to tried-and-true server-rendered Twig—still feeling spoiled by the maturity of the native Craft template APIs… 🤤 💭

@brandonkelly
Copy link
Member

I think we should add it. If it's not being consumed by an HTML page, they won't be adding the directive to the query in the first place. We're not assuming anything here.

@brandonkelly brandonkelly added graphql ⚙️ features related to the GraphQL API enhancement improvements to existing features labels Aug 28, 2019
@narration-sd
Copy link
Contributor

narration-sd commented Aug 28, 2019

You mean add as a field type, not as a directive, I hope, @brandonkelly ?

As in carefully backgrounded note above, custom directives being a no-go in Gatsby, Gridsome, no doubt other js frameworks which use [their own fronting] GraphQL...

@brandonkelly
Copy link
Member

Wouldn’t it be better to do the Markdown processing in Gatsby anyways though?

@narration-sd
Copy link
Contributor

narration-sd commented Aug 28, 2019

It wouldn't expect to do it on a String returned from GraphQL, I think, thus be able.

The underlying thing about (not) using directives is I believe very important, and not going to be solved by the js packages. See note?

And of course I also liked directives very well until running into the support stone wall.

As you probably know, Andris and I have been talking about it, so that we get back to being able to use image transforms. I could show you pictures ;) -- reminding of Antonioni's 'Blowup'...not a bad film at all if you want to experience 60s London youngish life...

@ghost
Copy link

ghost commented Aug 29, 2019

@AugustMiller Yes, i was thinking of Yii behaviors, just because it feels the most natural way for me. But anything would be welcome to overcome the limitations of this 1:1 representation of db content. You just need the api to be able to deliver the results of some business logic or complex querying.

Security: for sure you can't expose all behavior methods, instead you'll have to register them with something like For entry type Actress add a field roles, resolved by $entry->getRoles(), returning an array of cast_role_BlockType (By the way also some native fields may need be hidden...),

And yes, in general this graphql headless thing has to mature a lot, more questions than answers right now. Sticking to old fashioned twig or element-api for now.

@andris-sevcenko
Copy link
Contributor

@wsydney76 Can you open this as a new feature request, please?

Overall, I like the idea of being able to customize the fields available - whether it's to add new fields or to hide existing ones.

The question remains whether it should be in core or a "GraphQL power user" plugin, but for it to be a plugin, we'll need to add some events.

@andris-sevcenko
Copy link
Contributor

Closing this issue as per #4831

@ghost
Copy link

ghost commented Aug 29, 2019

@andris-sevcenko Thanks, FR done in #4850

brandonkelly added a commit that referenced this issue Aug 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement improvements to existing features graphql ⚙️ features related to the GraphQL API
Projects
None yet
Development

No branches or pull requests

4 participants