Relationships and SlateJS

default discord avatar
richardvanbergen3 years ago
1 1

Hey guys,

I'm looking to create a "CTA" block for editors to add buttons into rich text fields and I have a couple of notes/questions:

  1. Is there any way to leverage the existing relationship UI to link to internal documents?
  2. The purpose of referencing documents as described in the documentation is unclear. Could I use this as a mechanism to add CTA's at the bottom. Or does it have another intended purpose?

Thanks!

  • Selected Answer
    discord user avatar
    jmikrut
    3 years ago

    Yo Richard,

    There are a few ways to do what you are looking for!

    To answer your first question, yes, you can use Relationships to link to existing documents within the Rich Text field. For this to work, you need to do a few things:

    1. Within the collection that you actually want to reference, set enableRichTextRelationship to true within that collection's admin options - see here for an example in our demo app
    2. Then, in your actual rich text field(s), specify the 'relationship' field type within the rich text field's admin.elements property like this:
        {
          name: 'richTextDemo',
          type: 'richText',
          label: 'Rich Text Demo',
          admin: {
            elements: [
              'h2',
              'h3',
              'relationship', // <- check it out
            ],
          },
        },

    The above config will give you a new icon in your toolbar that looks like a little "open in new tab" icon, that, when clicked, allows you to choose a related document, which will be displayed in the Rich Text editor like this::

    Screen Shot 2021-03-01 at 4 16 27 PM

    Alternatively, if you want to get a bit more specific and intentional, you should check out our demo app's Rich Text collection which actually shows an example for how to add your own custom Button element. This or something similar is typically what we do for this type of application.

    What do you think?

    PS: we'll definitely improve the docs here because I personally think the above patterns are super cool!

    7 replies
  • default discord avatar
    richardvanbergen3 years ago

    Hi @jmikrut,

    Thank you for pointing me towards the examples. I did see them before but I was looking at the wrong definition of Button so I copied the wrong thing. 🤗

    I think my point regarding the relationship is that I don't understand what the use-case for it is. When I tried it I didn't see the relationship put out in the data from the REST endpoint I'm using and it always appears at the bottom of the text area so I just don't see what it enables for the editors.

    After a bit of shameless copy-pasting - I've now implemented the button and I can start editing it to add some more functionality. A couple of points based on my experience:

    1. Yes, it could use a bit more documentation.
    2. It would be nice to be a little more abstracted from slate, an (optional) library of UI components to build on top of rather than having to do basic things like define toolbar button styles just to make it look like the rest of the toolbar buttons. Another example might be creating a SlateModalButton rather than wiring up everything manually for common UI patterns?
  • discord user avatar
    jmikrut
    3 years ago

    I think my point regarding the relationship is that I don't understand what the use-case for it is. When I tried it I didn't see the relationship put out in the data from the REST endpoint I'm using and it always appears at the bottom of the text area so I just don't see what it enables for the editors.

    You should actually be able to place the relationship, and its data, anywhere you want within your Rich Text.

    Within the above screenshot, here's what the data looks like:

    Screen Shot 2021-03-02 at 8 20 44 AM

    As you can see, the defaultRichText field has three objects in its array:

    1. a blank line
    2. a relationship to a Media file, in this case
    3. "test" text

    Basically, what the Relationship element does is automatically fetches a relationship from another collection and embeds its data into wherever it sits in the relationship field. This is basically the Contentful way of doing things, where something even as simple as a Button would need to be a separate Content Type within Contentful, and you'd just add a Reference to it within your Rich Text editor.

    Are you seeing different results?

    Also - your note about adding UI components to build on top of - that is absolutely in our plans. Lots more will be announced about that soon but yes, there would be a ton of value in something like that. More on that soon.

  • default discord avatar
    richardvanbergen3 years ago

    Hey so I just got back on to this and yes I am seeing the relationship coming back in the data now. I've upgraded so that might be related.

    Still one more issue with it though:

    1. Write some text
    2. Click to beginning of line
    3. Insert a relationship (or any element with Transform.insertNode)
    4. Relationship gets inserted at end of the document

    This also affects any custom plugins using the example you provide for buttons. The reason is an issue with the current cursor position getting deselected when you click on the toolbar: https://stackoverflow.com/questions/61226933/how-to-add-slate-node-in-particular-empty-space-without-selection

    There is a workaround it seems. However, it's still a problem for any custom plugins because as far as I'm aware, we don't have any direct access to things like the blur events on the editor so I'm unable to implement the workaround myself.

  • discord user avatar
    jmikrut
    3 years ago

    Hey @richardvanbergen — I am going to look into how this can be accomplished right now. Will report back shortly.

    On that note, another thing we are working on improving is how richText relationship documents are populated. Right now, they are only snapshots of the relationship data as it was when the parent document was last saved—but I want to improve that by only saving the slug of the collection and the id of the related document. Then, we could auto-populate related documents on retrieval, ensuring their data is always up to date.

    Then, the depth param in REST API would control the population of the related documents, and we'd add a new arg to the the richText GraphQL equivalent.

    Obviously this would be a breaking change and would require content migration so if this hits ends up merging in we will make sure to note all repercussions as well as migration strategies.

    What do you think about all of this?

  • discord user avatar
    jmikrut
    3 years ago

    Hey @richardvanbergen — following up. I just opened a PR with a fix from the thread you linked. Had to do a bit more than was mentioned, but it works great! Will do some additional testing tomorrow and then if all goes well, we’ll publish.

    #114

    Check it out - and let me know what you think about the "copy" of relationship data vs. a "population"-style approach. That would be next on my list to tackle as I'd rather get a change like that out of the way sooner than later.

  • default discord avatar
    richardvanbergen3 years ago

    Hi @jmikrut thank you very much for the fast response. I do think it should definitely be a population approach. Simply because as a user that's what I was expecting when I see a term like "relationship". Also because if you're using typescript and you update a related type you would expect that the data model you're pulling from updated too.

    I don't know if this is necessary or if it would be too much work for not much benefit. You could also add an 'embedRichTextRelationship' option to the collection? Again though, I don't see a scenario where I'd rather it was embedded vs populated.

    I just opened a PR with a fix from the thread you linked.

    If I'm reading #114 correctly. Does that mean I can get access to editor.blurSection in my custom plugin as well?

  • discord user avatar
    jmikrut
    3 years ago

    If I'm reading #114 correctly. Does that mean I can get access to editor.blurSection in my custom plugin as well?

    Yeah! You can. We will be updating docs with this info today but yes, you have access to it just like as seen in the Button demo. 👍

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

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