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

Issue with syntax for renderHTML of custom extension with nested HTML #43

Open
mgtcampbell opened this issue Dec 11, 2023 · 1 comment

Comments

@mgtcampbell
Copy link

Hi there,

Here's my situation:

  • I have some Tiptap content stored in my database as JSON
  • I need to render this content as HTML using this PHP library (Laravel project) in order to send the content in an email notification
  • I am trying to recreate the rendered HTML markup a custom Mention extension that works in my Vue/JS version of Tiptap

Here is my working Javascript version of the renderHTML function:

return [
  "span",
  {
    ...HTMLAttributes,
    "data-id": node.attrs.id,
    "data-type": "mention",
    "data-label": node.attrs.label.full_name,
    contenteditable: false,
    class: "mention",
  },
  ["img", { src: `${node.attrs.label.avatar}`, class: "mention__avatar" }],
  ` ${node.attrs.label.first_name}`,
]

When I try and do something similar in the PHP version:

return [
    'span',
    HTML::mergeAttributes(
        [
            'class' => 'mention',
            'data-id' => $node->attrs->id,
            'data-type' => 'mention',
            'data-label' => $user->full_name,
        ],
        $this->options['HTMLAttributes'],
        $HTMLAttributes,
    ),
    ['img', [
            'src' => 'https://canary.imgix.net/' . $user->avatar . '?auto=format&dpr=2&w=72&h=72&fit=facearea&faceindex=1&facepad=3&q=90',
            'class' => 'mention__avatar',
        ]
    ],
    $user->first_name
];

I don't get the same output... The outer span tag renders correctly with the appropriate data attributes, and the image tag also renders and shows the user's avatar.

The issue then is what happens after that image tag - as I simply cannot get the user's name to render.

If I have it as per the code above, then what happens is it outputs an additional html tag after the img tag, with that tag being the user's first name. For example, if the user is named "Dave", then it will render a <dave></dave> tag pair.

It may perhaps simply be a syntax thing that I'm missing, but I've tried a number of other combinations:

  1. Changing the last part to strval(" " . $user->first_name) to try and return a string with a space in front of it - however this causes and error
  2. I've tried adding another span tag after the image tag like so:
return [
    'span',
    HTML::mergeAttributes(
        [
            'class' => 'mention',
            'data-id' => $node->attrs->id,
            'data-type' => 'mention',
            'data-label' => $user->full_name,
        ],
        $this->options['HTMLAttributes'],
        $HTMLAttributes,
    ),
    ['img', [
            'src' => 'https://canary.imgix.net/' . $user->avatar . '?auto=format&dpr=2&w=72&h=72&fit=facearea&faceindex=1&facepad=3&q=90',
            'class' => 'mention__avatar',
        ]
    ],
    'span',
    ['class' => 'mention__name'],
    $user->first_name,
];

which actually does render the extra span tag, including adding the mention__name class to that span... but then throws an error that it's expecting the last part to be an array, not a string.

  1. I've also tried then putting both the image tag and the name string inside of an array to make this combined content array be the third part of the returned array, but this also causes other errors.
  2. I also tried other combinations of elements such as making the parent a div, or wrapping the name in a p tag thinking it may be a semantics thing, but still got the same sort of errors

So my thinking is that either:

  • I'm missing some simple syntax issue in order to render something like <span class="mention"><img src="url" class="mention__avatar"> Name</span>
  • OR, the renderHTML function for the PHP version of Tiptap wasn't written to accomodate this kind of nesting of content

Any help or tips would be greatly appreciated.

@mgtcampbell
Copy link
Author

FWIW I managed to overcome this by overriding the renderText function in my CustomMention.php class:

public function renderText($node)
{
    $user = UserController::getInfoStatic($node->attrs->id);

    if($user->avatar) {
        return ' ' . $user->first_name;
    } else {
        return '<span class="mention__avatar">' . $user->first_name[0] . '</span> ' . $user->first_name;
    }
}

and updating my renderHTML function like so, with the 0 indicating where the result of the renderText function gets inserted:

public function renderHTML($node, $HTMLAttributes = [])
{
    $user = UserController::getInfoStatic($node->attrs->id);

    if($user->avatar) {
        return [
            'span',
            HTML::mergeAttributes(
                [
                    'class' => 'mention',
                    'data-id' => $node->attrs->id,
                    'data-type' => 'mention',
                    'data-label' => $user->full_name,
                ],
                $this->options['HTMLAttributes'],
                $HTMLAttributes,
            ),
            ['img', [
                    'src' => 'https://canary.imgix.net/' . $user->avatar . '?auto=format&dpr=2&w=72&h=72&fit=facearea&faceindex=1&facepad=3&q=90',
                    'class' => 'mention__avatar',
                ]
            ],
            0
        ];
    } else {
        return [
            'span',
            HTML::mergeAttributes(
                [
                    'class' => 'mention',
                    'data-id' => $node->attrs->id,
                    'data-type' => 'mention',
                    'data-label' => $user->full_name,
                ],
                $this->options['HTMLAttributes'],
                $HTMLAttributes,
            ),
            0
        ];
    }
}

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

No branches or pull requests

1 participant